セキュリティ・コンサルタント
村上 純一

 前回解説したテーブルの改ざんは,処理と処理の間,つまり接続点にパッチング(※プログラムの挙動を変更するためにプログラムの一部を書き換えること)を行う手法といえる。

 これに対して,処理自体にパッチングを実施する「Inline Function Hooking」(インライン関数フッキング)という手法がある。これは,フック(横取り)したい関数の先頭数バイトにジャンプ・コードを上書きすることで実行パスの変更を行うものである(図1)。フックされた関数が呼び出されるとジャンプ・コードが実行され,ジャンプ先のルートキット内部の処理が実行される仕組みである。

図1●Inline Function Hookingのイメージ
図1●Inline Function Hookingのイメージ

 実際には,ルートキット内部のフックした関数からフックされた元の関数を呼び出す必要のあるケースがよくあるため,実装時には別の工夫が求められることが多い。例えば,fooという関数を改ざんし,ここからbarという悪意あるコードを呼び出す場合,barの呼び出しのために書き換えた部分をどこかで代わりに実行する必要がある。そこで,上書きしたコードを実行した後,関数fooの上書きされた次の命令にジャンプを行うトランポリン関数を生成し,実行する(図2)。この手法は,マイクロソフト・リサーチによって研究・開発されておりDetoursとして知られている。同社のWebサイトでは本手法を用いた汎用的なフック・ライブラリが公開されている(http://research.microsoft.com/sn/detours/)。

図2●トランポリン関数を使った実装方法のイメージ
図2●トランポリン関数を使った実装方法のイメージ

フィルタ用のインタフェースを悪用

 フィルタ・ドライバはデバイス・ドライバの一種で,既存のドライバの上位または下位に挿入することでドライバに対する要求をフィルタする。フィルタ・ドライバの仕様は,マイクロソフトによって文書化されておりルートキットによる悪意の利用に限らず,多くのサードパーティ製品で利用されている。最も身近な例ではウイルス対策ソフト製品がある。リアルタイム検知機能を備えたウイルス対策製品は,文字通りリアルタイムにファイルI/Oを監視する必要がある。そのため,NTFSのファイル・システム・ドライバの上位または下位に専用のフィルタ・ドライバを挿入し,I/Oの監視を行っている(図3)。同様にルートキットをフィルタ・ドライバとして実装することでI/O要求をフィルタし,特定ファイルの隠ぺいなどが可能である。

図3●NTFSファイル・システム・ドライバに米シマンテックのフィルタ・ドライバがアタッチされたことをデバイス・ツリーで確認している様子
図3●NTFSファイル・システム・ドライバに米シマンテックのフィルタ・ドライバがアタッチされたことをデバイス・ツリーで確認している様子

 またフィルタ・ドライバは,I/O要求の種類とその処理を関連付けるアドレス・テーブルを内部的に利用しており,こうしたテーブルを改ざんすることで,ドライバに対するI/O要求のフィルタを実現することができる。

出力データやデータ構造を改ざん

 ここまで紹介した手法はいずれも実行パスの変更によりプロセス・リストなどのシステム情報の操作を行うものである。これに対してもう一つ,処理が扱うデータやデータ構造を変更することでシステム情報の操作を行う手法がある。「DKOM(direct kernel object manipulation)」だ。

 例えば,Windowsではプロセスは双方向のリンク・リスト(※リストの各ノードが前方および後方についてのリンクを持つデータ構造)で管理されている。前述のプロセス・リストの取得処理はこのリンク・リストを順に追って各プロセスの情報を取得している。そこで,リンク・リストのリンクを故意に書き換えることで特定のプロセス・エントリをリストから切り離し,隠ぺいすることができる(図4)。

図4●DKOM(irect kernel object manipulation)によるプロセスの隠ぺい
図4●DKOM(irect kernel object manipulation)によるプロセスの隠ぺい
プロセスは先頭と後方で双方向に参照し合うリンク・リストを持つ。プロセス・リストはこのリンク・リストをたどっていくことで作られる。図の場合,fooのリンク先をbazにすればbarを飛ばしたプロセス・リストを作れる。

 「隠ぺいしたプロセスが実行されない(スケジューリングされない)のでは?」と考える読者もいかもしれないが,Windowsではプロセス単位のスケジューリングの他に,スレッド単位でのスケジューリングも行う。Windowsにおいてプロセスは,スレッドのコンテナ(入れもの)でしかなく処理自体はスレッドによって実行される。そのため,隠ぺいしたプロセス(図4ではbar)がスケジューリングされなくとも,プロセス内部のスレッドが実行されるため,当該プロセスは問題なく動作する。

 以上,ルートキットが利用する様々な技術について紹介した。近年,上記以外にも様々な手法が研究されており今後もより多くの手法が生み出されると考えられる。こうした手法については回を改めて紹介したいと思う。


村上純一(むらかみ・じゅんいち)
国内の大手セキュリティ・コンサルティング会社に勤務。セキュリティ・コンサルタント業務やソフトウエアのぜい弱性を発見する業務に携わる。