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

 今回と次回は,カーネル・モード・ルートキットについて,その実装を詳しく見ていきたい。最初に,アプリケーションやOSの正常な処理の流れ(実行パス)に自身の処理を挿入して,情報を改ざん・隠ぺいする方法について考えてみる。

 まず,システム上のプロセスの一覧を取得する方法を考えよう。Windowsでは,EnumProcess APIを利用することで実現できる。プロセス・リストはOSが管理しているため,EnumProcess APIはカーネル・モードでの処理を通じて最終的にOSのプロセス・リストを取得する。EnumProcess APIによるプロセス・リスト取得処理の実行パスを図1に示す。

図1●EnumProcess APIによるプロセス・リスト取得処理の実行パス
図1●EnumProcess APIによるプロセス・リスト取得処理の実行パス

 プロセス・リストを取得したいプログラム(図1ではfoo)はpsapi.dllに実装されているEnumProcess APIを呼び出す。次にEnumProcess APIは内部でntdll.dllに実装されているNtQuerySystemInformaton APIを呼び出す。NtQuerySystemInformation APIは,INT命令によってソフトウエア割り込みを発生させる。CPUがこの割り込みをトラップし,プロセスの動作モードをユーザー・モードからカーネル・モードに切り替える。CPUはIDT(Interrupt Descriptor Table)に基づいて例外ハンドラであるKiSystemService関数に制御を移す。

 IDTはOSの起動時に初期化されるテーブル(表)の一種で,一般保護例外やゼロ除算例外といったCPUがハンドリングすべき例外と,その例外ハンドラのアドレスなどを管理している。KiSystemService関数は,同様にSDT(Service Descriptor Table)からSSDT(System Service Descriptor Table)を参照することでNtQuerySystemInformation APIの実処理を行う関数を呼び出す。SDT,SSDTは名称の通り呼び出されたAPIの実処理を行う関数に関連するアドレスなどの情報を管理しているテーブルである。

 ここでは,IDT,SDT,SSDTといったテーブルに注目してほしい。これらのテーブルは,いずれも実行パス上の次の処理のアドレスを解決するために参照される点が共通している。つまり,これらのテーブルに格納されているデータを改ざんできれば,実行パスの変更を実現することができる。

 そこで,デバイス・ドライバとして実装されたルートキットは,カーネル空間にロードされた後,これらのテーブルのデータを改ざんして実行パス上に自身の処理を追加し,システム情報の操作を行おうとする(図2)。

図2●SSDTの改ざんによる実行パスの変更
図2●SSDTの改ざんによる実行パスの変更

 またWindows XP(32ビット版)以降では,処理の高速化のためにINT命令によるソフトウエア割り込みの代わりに,SYSENTER命令を利用している。これは,ユーザー・モードからカーネル・モードに高速に切り替えるための方法で,切り替え時に必要になる情報をあらかじめプロセッサのモデル固有レジスタにセットしておく。SYSENTERを利用した場合も,前述のモデル固有レジスタの情報を改ざんすることで同様のフック(横取り)を実現することが可能である。


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