第1回ローレイヤー勉強会いってきた
Windowsカーネルハックというネタでしゃべってきたのでその資料をアップ(llbenkyo1_win.cab)。よく知っている人には「それはどうなのよ」というところがあると思うので、その辺は突っ込んでもらえるとうれしいです。
以下にデモごとの主要な動作・コンセプト等を列記します。このデモは実行すると青画面になる可能性が高いので悪しからず。
loader00 CreateService + StartServiceによるドライバのロード/アンロードツール loader01 NtSetSystemInformation(SystemLoadAndCallImage, ...) によるロードツール loader02 一見sysファイルがない状態から、内蔵のカーネルモジュールを密かに展開してロードする (読み込まれたカーネルモジュールによりこのプロセスは隠蔽される) レジストリでカーネルモジュールに必要な値を渡したり、 カーネルモジュールのロードが完了したらディスク上から削除するなどしている example00 DbgPrintを使用してDebugViewにデバッグ出力 example01 特権命令(ここではrdmsr)を使用する example02 writemsrでsysenterフック ただしDriverEntryが実行されたプロセッサのものだけフックしているので、 アンロード関数がDriverEntryとは別のプロセッサで実行されると死ぬ example03 すべてのプロセッサでのsysenterフック版 カーネルデバッガを接続しているとなぜか死ぬ。たぶん出力データが多すぎる。 example04 KeServiceDescriptorTable(システムサービスへのアドレスの配列)を列挙 example05 KeServiceDescriptorTableのアドレスを交換して任意の関数に置き換える ここではプロセスの生成・終了に関する関数をフックする example06 関数の先頭2byte+とその後方5byteを書き換えて任意のコードを実行させる(detourフック) ここではNTFSアクセスチェックの実装である SeAccessCheck と ファイル名のマッチング処理の実装である FsRtlIsNameInExpression が対象 本来はすべてのプロセッサの一時ロックのうえでフックするのが安全(gain exclusivity) example07 関数が参照するデータ構造体を直接書き換えることで、関数の結果にも影響を与える(DKOM) EPROCESSとMODULE_ENTRYのリンクリストを操作してプロセスとカーネルモジュールを隠蔽 これも本来はすべてのプロセッサの一時ロックを必要とする brute_force プロセスIDやスレッドIDをインクリメントしながらopenすることで 隠蔽されたプロセスを検出する(結果の差異による検出例) 特に面白いこともないので、ここでは検出までは実装していない HookDetector ポインタの変更によるフックの検出 HookDetector.sys を読み込ませてから -std -stds などの引数を渡してチェックする >loader00 HookDetector.sys >HookDetector.exe -std <- フックされてない >loader00 example05.sys >HookDetector.exe -std <- フックされてる 途中で放棄したソースの再利用なので完全に魔窟 xp_080526.txt xp_080527.txt とあるセキュリティツールをインストールする前後のKeServiceDescriptorTableの状態
Windowsの仕組みやAPIを理解するにあたっては以下の書籍がおすすめです。
- APIで学ぶWindows徹底理解(「価格に比して」内容が良い)
- Advanced Windows
- インサイド Windows
- Rootkits: Subverting the Windows Kernel
インサイドWindowsの上巻はこの中でも特にオススメです。1月にVista対応の新版(英語)が出るはずなのでそれ待ちもあり。
また、話のネタは2005年ぐらいまでにすべてまとめられていたりしていて、特に目新しいものではないです。きっちり勉強したい方は上記Rootkits: Subverting the Windows Kernelを買うと良いです。