【実務・中級編】 メモリ上のハンドル分析による隠蔽ファイルの特定 – インシデントレスポンス & フォレンジック(DFIR)防御ガイド

霧の中の足跡を追う:メモリフォレンジックで暴く「隠蔽ファイル」の真実

現場でインシデント対応をしていると、よく「ログには何も残っていないのに、サーバーの挙動がおかしい」という相談を受ける。攻撃者は賢い。彼らは侵入後、足跡を消すためにログを改ざんし、ツールを削除し、さらには「ファイルレス」に近い形でOSの深淵に潜り込む。

だが、どれほど巧妙にエクスプローラーからファイルを隠そうとも、「プロセスがそのファイルにアクセスしている」という事実だけは、メモリ上のハンドル(Handle)に刻まれる。 今日は、泥臭いフォレンジックの現場で僕が最も信頼している「ハンドル分析」の極意を伝授しよう。

—

なぜ攻撃者は「ハンドル」を握られるのか

攻撃者がWebシェルをアップロードし、その後実行ファイルを削除(セルフデリート)したとする。普通の管理者がファイルシステムを見ても、そこにはもう何もない。しかし、メモリ上では、そのプロセスがまだその「削除されたはずのファイル」へのハンドル(参照)を握り続けていることが多々ある。

これが、攻撃者が残した「消しきれなかった爪痕」だ。

攻撃者のPoC:隠蔽のロジック

攻撃者はしばしば、DeleteFile を呼んだ後もプロセスを終了させないことで、ファイルシステムのメタデータから姿を消す。あるいは、名前付きパイプ(Named Pipe)を利用して、外部からの命令をメモリ経由で受け取る。これらは、通常の ls や dir コマンドでは一生見つけることができない。

—

現場で使う「ハンドル」の追跡術

メモリフォレンジックにおいて、プロセスがどんなリソースを掴んでいるかを調べるには、Windowsなら handle.exe (Sysinternals) や Volatility が必須武器だ。

例えば、怪しいプロセスID 1234 が何をしているか探る際、以下のコマンドで「ファイル」や「パイプ」を抽出する。

# Volatilityでプロセスが保持するハンドルを抽出する例
python3 vol.py -f memory.dmp windows.handles --pid 1234

ここで、File オブジェクトや Pipe オブジェクトがどこを指しているかを特定する。もし、/tmp/ や C:\Windows\Temp\ にある不可解なバイナリや、不審な名前のパイプ(例: \pipe\mssec_hollow 等)が見つかったら、それがゲームセットの合図だ。

—

「隠蔽」を許さないためのセキュアな設計・実装

攻撃者は、システムに備わっている「不完全な分離」を突いてくる。これを防ぐには、そもそも彼らがハンドルを操作する余地を奪う必要がある。

1. PHP/Webアプリにおけるファイルアクセスの厳格化

Webアプリが不用意に system() や exec() でシェルを呼び出し、一時ファイルを作成することは、ハンドルを奪われる最大の要因だ。

修正前:
system("sh " . $user_input_file); // 危険!ファイルパスを直接操作させるのは自殺行為。

修正後(セキュアな実装):

<?php
/**
 * ファイル操作を最小化し、パスのトラバーサルを防止する
 */
function execute_safe_process($filename) {
    // 許可されたディレクトリ以外へのアクセスをブロック
    $base_dir = '/var/www/data/uploads/';
    $real_path = realpath($base_dir . basename($filename));

    if ($real_path && strpos($real_path, $base_dir) === 0 && file_exists($real_path)) {
        // パスを直接渡さず、ストリームで処理する等の工夫をする
        // シェル実行を避け、組み込み関数を利用する
        return file_get_contents($real_path);
    }
    throw new Exception("不正なアクセスを検知しました");
}

2. Nginxによるパイプ・ソケットの保護

攻撃者は名前付きパイプをバックドアとして使う。不要なソケット通信やパイプの開放をWAFやサーバー設定で制限しよう。

# Nginx設定: 特定のパスへのアクセスを厳格化
location /internal-api/ {
    # 内部ネットワークからのアクセスのみ許可
    allow 10.0.0.0/8;
    deny all;
    
    # 攻撃者がパイプ経由でコマンドを送り込むのを防ぐ
    add_header X-Content-Type-Options nosniff;
    add_header X-Frame-Options DENY;
}

3. クラウドIAMによる特権の剥奪

もしコンテナやEC2が侵害されても、ハンドル操作を最小化するために「実行権限」を奪う。

  • IAMポリシーの鉄則: s3:* を許可するのではなく、s3:GetObject のように「特定のアクション」かつ「特定のプレフィックス」に限定する。
  • Linuxなら: no-new-privileges フラグをコンテナに立てることで、攻撃者が特権昇格のためにハンドルを悪用するのを困難にできる。

—

最後に:エンジニアが持つべき「視点」

メモリフォレンジックは、単なる解析技術ではない。「OSは嘘をつくことがある」という疑念を持つこと、それが優れたエンジニアの第一歩だ。

もしサーバーの挙動が少しでも変だと感じたら、すぐにプロセスリストを眺めるだけでなく、「そのプロセスが何と繋がっているのか(ハンドル)」に注目してほしい。そこに隠れているファイルやパイプこそが、攻撃者の尻尾である可能性が高いからだ。

何か違和感があったら、まずはメモリをダンプし、落ち着いて紐解いていく。その冷静な判断が、組織を大規模な侵害から守る唯一の術になる。現場からは以上だ。

コメント

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