メモリは嘘をつかない:Volatility 3で暴く侵入者の痕跡
現場でインシデント対応をしていると、よく「ログを消された」「侵入経路がわからない」という悲鳴を聞く。だが、物理メモリ(RAM)は裏切らない。ディスク上のログは改ざんできても、実行中のプロセスやメモリ上に展開された難読化ペイロードは、電源が落ちない限りそこに刻まれているからだ。
今日は、フォレンジックの標準ツール「Volatility 3」を使い、エンジニアが自力で「何が起きたか」を特定するための戦術を解説する。
—
1. Volatility 3のアーキテクチャと解析の「勘所」
Volatility 3は、以前のバージョン(Volatility 2)とは設計思想が全く異なる。最大の変更点は「シンボルテーブル(Intermediate Symbol File: ISF)」の扱いだ。解析対象のOSカーネル情報をJSON形式のシンボルファイルとして読み込むことで、複雑なオフセット計算を効率化している。
現場で最も多いミスは、「間違ったプロファイル(シンボル)を使用すること」だ。OSのビルド番号一つでメモリ構造は変わる。解析を始める前に、まずは windows.info プラグインで、対象のOSバージョンとビルド番号を特定する。これが全ての出発点だ。
—
2. 実践:インシデント調査の標準フロー
メモリダンプ(.raw または .mem)を取得したら、以下の順序で「異常」を炙り出す。
1. プロセスの親子関係を確認 (windows.pstree):cmd.exe や powershell.exe が w3wp.exe(IIS)や php-fpm から起動されていないか?これがWebシェル経由の侵入の典型的な兆候だ。
2. ネットワーク接続の抽出 (windows.netscan):不自然な外部IPとのコネクションはないか?C2サーバーへのビーコン通信をここで叩く。
3. ロード済みモジュールの確認 (windows.dlllist):プロセスが読み込んでいるDLLの中で、パスがおかしいものや、署名検証に失敗するものがないか。
—
3. 攻撃者が狙う盲点:Webシェルとメモリ常駐
攻撃者は、Webアプリケーションの脆弱性を突き、メモリ上にのみ存在する「ファイルレスマルウェア」を送り込むことが多い。例えば、PHPの eval() 実行を狙ったWebシェルは、一度起動すればディスクにファイルを残さず、プロセス空間に潜伏する。
防御するためのセキュアなPHP実装
Webシェルを許す最大の原因は、アップロードされたファイルの実行権限と、動的コード実行を許可してしまう構成にある。
<?php
// 【推奨】外部からの入力でファイルパスを直接作成しない
$filename = basename($_FILES['userfile']['name']);
$upload_dir = '/var/www/uploads/';
// 1. 拡張子をホワイトリストで制限
$allowed_exts = ['jpg', 'png', 'pdf'];
$ext = pathinfo($filename, PATHINFO_EXTENSION);
if (!in_array($ext, $allowed_exts)) {
die("不正なファイル形式です。");
}
// 2. ファイルの中身をスキャン(簡易的なマジックバイト確認)
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $_FILES['userfile']['tmp_name']);
if ($mime !== 'image/jpeg') {
die("ファイルの内容が不正です。");
}
// 3. 実行権限のないディレクトリに保存
move_uploaded_file($_FILES['userfile']['tmp_name'], $upload_dir . bin2hex(random_bytes(16)) . '.' . $ext);
?>
—
4. インフラレベルでの封じ込め:Nginx & WAF設定
メモリフォレンジックで攻撃の足跡を見つけたら、即座に攻撃元を遮断し、再発防止策を打つ必要がある。NginxでのWebシェル対策の鉄則は、特定のディレクトリでのスクリプト実行を「物理的に禁止」することだ。
# /uploads ディレクトリでのPHP実行を禁止する設定
location /uploads/ {
# 外部からのアクセスは許可するが、PHPエンジンをバイパスさせる
location ~ \.php$ {
deny all;
}
}
# 悪意あるリクエストを遮断するWAF的設定(Nginxのmapディレクティブ)
map $query_string $is_malicious {
default 0;
"~*(base64|eval|system|shell_exec)" 1; # 典型的なWebシェル攻撃コード
}
server {
if ($is_malicious) {
return 403;
}
}
—
5. 最後に:エンジニアへの提言
メモリ解析は「答え合わせ」の作業ではない。ダンプを取得した瞬間の攻撃者の息遣いを感じ、彼らが次に何をしようとしていたのか、その論理的思考を追跡するプロセスだ。
もしサーバーが異常なCPU負荷を示したり、特定のプロセスが不審な通信を行っていたら、焦って再起動してはいけない。再起動は証拠の消失を意味する。 まずはメモリをダンプし、Volatilityで解析する。この「泥臭い」調査の積み重ねこそが、あなたのシステムを真に堅牢なものにする唯一の道だ。
次のインシデントが発生した時、君のPCにあるVolatilityが、頼れる武器になることを期待している。
コメント