亡霊を暴く:PEB解析とDKOMによる「プロセス隠蔽」の深淵
現場でインシデントレスポンスに当たっていると、OSの「嘘」を見抜く瞬間が最もスリリングだ。タスクマネージャーや tasklist コマンドが何も語らない時、多くの運用者は「クリーンだ」と判断する。だが、我々DFIRの人間にとって、そこは「侵入者が最も深い場所に潜んでいる」というサインに過ぎない。
今日は、Windowsの心臓部であるプロセス環境ブロック(PEB)を巡る攻防と、DKOM(Direct Kernel Object Manipulation)による隠蔽をどう突き崩すかについて語ろう。
1. なぜ「リスト」は信用できないのか
Windowsにおいて、プロセスが列挙される仕組みは一つではない。標準的なツールが参照するのは、主にカーネル内の EPROCESS オブジェクトが持つ二重連結リスト ActiveProcessLinks だ。
攻撃者はこの ActiveProcessLinks を書き換え、自身のプロセスノードをリストから切り離す(Unlinkする)。これにより、API経由でプロセスリストを要求するツールからは姿が消える。しかし、カーネルがCPUに命令を実行させるためには、そのプロセスがスケジュールされなければならない。ここが最大の矛盾であり、我々の勝機だ。
2. PEB:プロセスが隠し持つ「秘密の地図」
PEBは各プロセスに一つ割り当てられるユーザーモード側のデータ構造だ。ここにはロードされたモジュール情報、環境変数、そしてヒープ情報などが格納されている。
隠蔽されたプロセスを見つけ出す際、我々は ActiveProcessLinks だけでなく、PEBに格納されている LDR_DATA_TABLE_ENTRY を精査する。攻撃者がプロセスを隠しても、PEB内のモジュールリストまで完璧に同期して改ざんするのは至難の業だ。ここに、彼らが残した「足跡」が残る。
3. DKOM検知の現実解:メモリダンプからの深掘り
Volatilityなどのフレームワークを使う際、単純に pslist を叩いて満足してはならない。pslist は ActiveProcessLinks を辿るだけだからだ。我々が使うべきは psscan だ。
psscan はメモリ全体をスキャンし、EPROCESS 構造体の特徴的なシグネチャ(プールタグ)を直接探しに行く。リストに載っていないが、メモリ上に確かに存在するオブジェクトを見つけ出す、泥臭いが確実な手法だ。
検知のためのPython (Volatility 3 API) の概念的実装
以下は、特定のプロセスが ActiveProcessLinks から切り離されていないかをチェックするロジックの断片だ。
# ボラティリティのデータ構造を走査し、隠蔽を検知するコンセプトコード
import volatility.framework.interfaces.objects as objects
def detect_hidden_process(context, layer_name, symbol_table):
# EPROCESSのリストをカーネルから直接取得
procs = context.modules[symbol_table].object_types.EPROCESS
# ActiveProcessLinksを辿って見えるプロセス群
visible_procs = {p.UniqueProcessId: p for p in procs.ActiveProcessLinks}
# メモリ上の全EPROCESSオブジェクトをスキャン
all_procs = scan_for_eprocess(context, layer_name)
for proc in all_procs:
if proc.UniqueProcessId not in visible_procs:
print(f"[!] 隠蔽の可能性を発見: PID {proc.UniqueProcessId}")
# ここでPEBを解析し、実行イメージのパスを確認する
verify_peb_integrity(proc)
def verify_peb_integrity(proc):
# プロセスのPEB構造体にアクセス
peb = proc.Peb
if not peb:
return
# PEB内のモジュールリストを解析し、正規のプロセス名か確認する処理
# ...
4. 監査の観点:アーキテクトが準備すべき「検知の層」
これからの防御技術は、単なるEDRの導入にとどまらない。アーキテクトが設計すべきは、メモリ整合性の継続的監視だ。
- カーネルモード・コールスタックのプロファイリング:
ZwQuerySystemInformation等のAPIがフックされていないか、あるいは「不自然なリターン先」を持つスレッドが存在しないかを監視する。 - ページテーブルの改ざん検知: DKOMは単なるリスト操作だけでなく、ページテーブルを書き換えてメモリ権限を昇格させる場合がある。ハードウェアレベルの仮想化支援機能(Intel VT-x/EPT)を活用したハイパーバイザ型のメモリ保護が今後のスタンダードになる。
- 生成AIガードレイルとの統合: 攻撃者が生成AIを使用して悪意あるコードを難読化・生成する場合、プロンプトインジェクションの検知だけでなく、その後の「メモリ上の挙動(Unusual Memory Allocation)」をSIEMと連動させ、自動的にメモリダンプをトリガーするパイプラインを構築しておくべきだ。
最後に:泥臭さを愛する者たちへ
デジタルフォレンジックにおいて「完璧なツール」は存在しない。攻撃者がOSの仕様の裏を突いてくるなら、我々はOSの仕様そのものを再定義するレベルで理解しなければならない。
PEBの解析は、始まりに過ぎない。隠蔽されたプロセスの裏には、隠蔽されたネットワーク接続があり、隠蔽されたファイルハンドルがある。それら全てを繋ぎ合わせた時、初めて攻撃者の全体像が浮かび上がる。
「見えない」ものは「存在しない」のではなく、「見ようとしていない」だけだ。次回の調査では、pslist を閉じて、バイナリの海へダイブしてみてほしい。そこには、教科書には載っていない真実が沈んでいる。
コメント