【テクニカル・上級編】 Windowsメモリダンプにおけるプロセス環境ブロック(PEB)の解析と隠蔽検知 – インシデントレスポンス & フォレンジック(DFIR)防御ガイド

亡霊を暴く: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 を閉じて、バイナリの海へダイブしてみてほしい。そこには、教科書には載っていない真実が沈んでいる。

コメント

タイトルとURLをコピーしました