見えない敵を暴く:DKOMによるプロセス隠蔽とメモリフォレンジックの真髄
現場でインシデント対応をしていると、「psコマンドにもタスクマネージャにも現れないのに、明らかにネットワークトラフィックが異常」という不気味な相談を受けることがよくある。これは、攻撃者がOSのAPIを欺く「ルートキット」を導入し、カーネルレベルで自身の存在を消し去っている証拠だ。
今回は、彼らが多用する DKOM(Direct Kernel Object Manipulation) という古典的かつ強力な手法と、それをメモリフォレンジックでどう暴くか、そして現代のエンジニアがどう防御すべきかを解説する。
—
1. DKOMの正体:OSの「目」を盗むトリック
Windowsを例に挙げると、OSは実行中のプロセスを EPROCESS というカーネル構造体のリンクリスト(ActiveProcessLinks)で管理している。OSが「今、何が動いているか」を表示する際、このリストを辿るわけだ。
攻撃者はカーネルドライバをロードし、このリンクリストの「ポインタ」を直接書き換える。例えば、AプロセスとCプロセスの間にあるBプロセス(悪意あるもの)をリストから切り離し、Aから直接Cへ繋ぐように書き換える。すると、OSの管理ツールはBプロセスが存在しないものとして処理してしまう。
しかし、CPUのスケジューラは別だ。 CPUはプロセスを動かすために、ActiveProcessLinks ではなく、別のキュー(スレッドスケジューリングキュー)を参照する。メモリダンプを解析すると、「リストにはいないのに、CPU時間を消費し続けているプロセス」という致命的な不整合が浮かび上がる。これが、我々フォレンジック担当者が敵を特定する「決定的な瞬間」だ。
—
2. 「見えないプロセス」を検知するための視点
メモリダンプを取得し、Volatility等のツールで解析する場合、以下の手順で不整合を探る。
1. pslistの実行: ActiveProcessLinks を辿る標準的な列挙。
2. psscanの実行: カーネルメモリ内の EPROCESS オブジェクトを直接スキャン。
3. 差分比較: pslist には表示されないが psscan でヒットするオブジェクトを探す。
もし、psscan で見つかったプロセスの親が services.exe や explorer.exe であり、かつ署名のないドライバがロードされていれば、十中八九そのシステムは侵害されている。
—
3. 防御の要:カーネルを汚染させないための設計
DKOMはカーネルモードでの実行権限が必要だ。つまり、「いかにしてカーネルに悪意あるコードを注入させないか」が全ての鍵になる。
3.1. ドライバ署名の強制(Windows/Linux共通)
攻撃者は、自作の悪意あるドライバをロードするために「ドライバ署名の強制」を無効化しようとする。これを防ぐには、グループポリシーや管理ツールで厳格に設定する必要がある。
3.2. EDRの導入と「カーネル保護」の有効化
現代のEDRは、カーネルの重要な構造体に対する書き込みをフックしている。以下は、クラウド環境やオンプレミスで適用すべき、攻撃者のカーネルアクセスを防ぐためのポリシー設定例だ。
# Nginx/WAFでの防御(Webアプリ経由の脆弱性悪用を防ぐ)
# カーネルへの侵入経路となる「リモートコード実行」を阻止するための設定例
location / {
# 不審なシステムコマンドの実行をブロック
if ($arg_cmd ~* "(powershell|cmd|/bin/sh|nc|netcat)") {
return 403;
}
# ヘッダーによる攻撃遮断(XSS/SQLi対策)
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options DENY;
}
3.3. クラウドIAMによる特権管理
クラウド上のインスタンスであれば、メタデータサービスへのアクセスを制限し、IAMロールの権限を最小限に絞る。攻撃者が管理者権限を奪取しても、カーネル操作を伴うドライバのインストールができないようにする。
{
// IAMポリシー例:インスタンスのプロファイル管理権限を剥奪する
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": [
"iam:PutRolePolicy",
"iam:CreateInstanceProfile"
],
"Resource": "*"
}
]
}
—
4. まとめ:システムは常に「疑う」ことから始まる
カーネルオブジェクトの改竄は、単なるWebアプリの脆弱性よりも一段階深い、OSの根幹を揺るがす攻撃だ。開発者や運用者が意識すべきは、「アプリケーションが乗っ取られた時、どこまで権限が拡大されるか」という境界線だ。
- 検証: 定期的にメモリダンプを採取し、自動化されたスクリプトで
pslistとpsscanの差分を監視する。 - 防御: カーネル空間への書き込み権限を極限まで絞り、署名のないコードの実行を物理的に拒絶する。
「ログには何も残っていない」という報告は、往々にして「ログを消せるほど深く潜り込まれている」ことの裏返しだ。システムの不整合を察知する嗅覚は、机上の空論ではなく、こうした技術的裏付けから養われる。
現場で戦うエンジニア諸君、攻撃者の足跡は必ずどこかに残る。メモリという名の「真実の空間」を読み解くスキルを磨き続けてほしい。
コメント