モーグルとカバとパウダーの日記

モーグルやカバ(EXカービング)山スキー(BC)などがメインの日記でした。今は仕事のコンピュータ系のネタが主になっています。以前はスパム対策関連が多かったのですが最近はディープラーニング関連が多めです。

prelinkによりlsなどの基本的なバイナリのmd5sum値が変化してしまう

先日、すんごい焦った事例がありました。


サーバがクラックされると、クラッカーにより/bin/lsや/bin/psなどの基本的なコマンドが置き換えられ、クラックされて置かれたファイルや動いているプロセスだけが見えなくなるようにして、クラックされていることがわからなくなるよう細工させられる場合があります。

そのため、そういったバイナリが置き換えられていないか、定期的にmd5sum値を取って確認するような簡単なチェック機構を入れていました。

(こういった用途にはTripwireのような専用ツールがありますが、あくまで簡易的な確認のためでここでは使っていませんでした。)

それが、確認するとmd5sumが先週と違っているという相談を受けました。

環境は CentOS 6.x です。


早速調べてみると、タイムスタンプは変化していないのにmd5sum値は違っていました。

また、md5sum値はサーバ毎に違っていたものの、バイナリサイズはどれも一緒でした。

ただ、先週はglibc脆弱性対応があり、/var/yum.log を確認してもupdateされていることが確認出来ました。

なので通常ならば glibc のアップデートのせいだね〜、で済むところなのですが、今回の glibc のアップデートは gethostbyname の脆弱性なので /bin/ls なんかが影響が受けるとは考えにくいところでした。


そこで、クラックされている可能性もある、という前提で調べてみることになりました。

とりあえず、新たに同じVPSで新規にCentOS6を生成して、そのmd5sum値を確認しました。

すると、その素のmd5sum値と、クラックされたことを疑っているサーバ群のmd5sum値はどれも違っており、バイナリサイズすら違っている状況でした。

また、glibcのアップデートを掛けて、その後の変化を確認したのですが、md5sum値もバイナリサイズも、どちらも変化ないことを確認できました。

となると、クラックされてしまったと考えるほうが俄然優勢になってきます…


そこに救世主が!

prelinkとは共有ライブラリのリンク情報から事前にリンクを行うというものです。
それまで、確かにcronの中で見かけるものの、prelinkが何やってくれるものなのか、良く認識していませんでした。


先ほどの新規で生成したCentOS6環境に対して、

# prelink /bin/ls

すると、見事にmd5sum値が変わり、他サーバのファイルサイズと同じになることが確認できました。

また、glibcのアップデート前にmd5sumを取ったものと、glibcアップデート後に取ったものを比較したところ、これも同様に変化しました。
これで、今回の変化はglibcのアップデート+prelinkによるもの、と考えることが出来ました。


これまでもglibcのような基本的なライブラリに変更があった場合、md5sum値が変わっていたはずですが、それは「glibc更新したからだね」ということで流していたのだと思います。

それが今回は「gethostbyname」使っているものしか影響がない、というふうに、予測される影響範囲がわかりやすく限定されていたため、「lsならば影響受けないはず」という心理が働いて、クラックの可能性を考えてしまったのでしした。


そもそも、rpm(yum)で入れたバイナリは、同じバイナリがコピーされるわけだから、サーバが違っていてもmd5sum値は同じになる気がするのに、なんでサーバ間で違ってるんだろう?という疑問はあったのですが、これまではあまり深く考えていませんでした。

実際、インストールされたprelinkが掛かる前のバイナリと、rpmからrpm2cpioで直接取り出したバイナリとをmd5sum値を比べたところ、まったく同じものになりました。

また

# prelink -u /bin/ls

でprelinkの処理を戻すと、やはりmd5sum値がおなじになることがわかります。


CentOS6だとprelinkは cron.dailyに設定入っていて、デイリーで動くようになっています。

しかし、CentOS7だとデフォルト設定ではprelinkされないようになっているそうです。

prelinkのせいでAIDEのような改竄検知が誤動作したりやrubyのバイナリが破壊したりする問題があったそうなので、そういったことが考慮されたのかもしれません。


また今回のようにrpmで入れたバイナリのチェックには、独自にmd5sumを取るのではなく、「rpm -Va」を使ったほうが良いようです。

この場合だと、内部で prelink を戻してから比較されるため問題ないそうです。


これ、prelinkについてどんなものか知らないと、なかなか真の理由に辿りつけないと思います。

なにかの際に遭遇して、クラックされたか!?と思って焦らないように、ちょこっと覚えておいていただければ。


僕が泣き入ってる時にtwitterで色々とアドバイスいただいた、@hATrayfloodさん、@DQNEOさん、そして@hkobaさんに多謝です!!


(関連)

rpmで入れたバイナリのchecksumが一致しないと思ったらprelinkのせいだった - As a Futurist...
CentOS7からprelinkが無効に変更されていた件 - Qiita
CentOS 4.7 では prelink が ruby 1.9.1 のバイナリを破壊する - MoreslowlyWiki
CentOS6にアップグレードしたときのAIDE(改ざん検知)の注意点 | 気になるボックス
SIOS "OSSよろず" ブログ出張所: prelink されたバイナリの "rpm -V" での検証は無問題Linux Hacks:Linuxのパフォーマンスを改善する3つのTips (3/3) - ITmedia エンタープライズ