メモリに潜む「影」を暴く:プロセスインジェクション検知の現場から
こんにちは。SOCで日々、攻撃者の足跡を追っているチーフアナリストです。
さて、今日語るのは「プロセスインジェクション」についてだ。EDRのアラートでよく目にするこの単語、ただの流行り言葉じゃない。攻撃者はディスクにファイルの実体を残さない「ファイルレス攻撃」を好む。彼らにとって、メモリは隠れ蓑であり、聖域だ。
DLLインジェクションやProcess Hollowing(プロセスの差し替え)を許してしまうと、正規のプロセス(例えば explorer.exe や svchost.exe)の顔をして、やりたい放題される。今日は、この「メモリ上の悪意」をどう見抜き、システムレベルでどう防ぐか、現場の視点で切り込む。
—
なぜプロセスインジェクションが恐ろしいのか
攻撃者は、わざわざマルウェアをインストールしてログを残すような真似はしない。彼らが狙うのは、すでに動作している「信頼されたプロセス」のメモリ空間だ。
VirtualAllocEx でメモリを確保し、WriteProcessMemory で悪意のあるシェルコードを書き込み、CreateRemoteThread で実行させる。これが典型的なDLLインジェクションの流れだ。これが行われると、どんなにディスク上のスキャンを厳密にしても、攻撃者の存在は「プロセスリスト」には現れない。
現場で見る「違和感」
メモリフォレンジックを行う際、我々が真っ先に注目するのは「VAD(Virtual Address Descriptor)ツリーの不整合」だ。
- 実行権限(
PAGE_EXECUTE_READWRITE)が不自然に付与されたメモリ領域 - ディスク上のファイルとマッピングされていない実行可能領域
これを見つけた時が、狩りの始まりだ。
—
防御の最前線:開発と運用で何ができるか
正直に言おう。「これを入れれば100%防げる」という銀の弾丸はない。しかし、攻撃者のコストを跳ね上げ、検知の網を広げることは可能だ。
1. OSレベルでの防御(設定)
Windows環境であれば、まずは「攻撃対象領域の縮小(ASR)」ルールを適用するのが鉄則だ。特に「信頼されていないプロセスによるプロセス間注入」をブロックする設定は必須である。
PowerShellでのASRルール有効化(抜粋)
# プロセスインジェクションを試みるAPI呼び出しをブロックする
Add-MpPreference -AttackSurfaceReductionRules_Ids "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" -AttackSurfaceReductionRules_Actions Enabled
2. アプリケーションコード側での防御(Pythonの例)
Webアプリやバックエンドの処理で、OSコマンドを叩くような危険な実装をしていないか? 攻撃者はそこから権限昇格を狙い、インジェクションに繋げる。以下は、ユーザー入力をそのまま実行させないためのセキュアな設計の雛形だ。
import subprocess
import shlex
def execute_safe_command(user_input):
"""
ユーザー入力を受け取り、外部コマンドを安全に実行する
シェルインジェクションを防ぐため、リスト形式で引数を分解する
"""
# ユーザー入力をホワイトリストで検証(例:英数字のみ許可)
if not user_input.isalnum():
raise ValueError("無効な入力値です")
# shlex.splitを使用し、コマンドライン引数を安全に解析する
# 悪意ある記号(;や&など)が混入していても、個別の引数として扱われる
command = ["/usr/bin/some_binary", "--target", user_input]
try:
result = subprocess.run(command, capture_output=True, text=True, check=True)
return result.stdout
except subprocess.CalledProcessError as e:
# エラーログには詳細を出すが、ユーザーには汎用的なメッセージのみ返す
print(f"Error executing command: {e}")
return "Internal Server Error"
3. WAFでのフィルタリング設定
WAF(例えばNginx + ModSecurityなど)では、リクエスト内に埋め込まれた不審なバイナリや、エンコードされたペイロードを弾く設定が重要だ。
Nginx / ModSecurity 設定例
# リクエストボディ内のBase64エンコードされたMZヘッダー(DLL/EXEの兆候)を検知する
SecRule REQUEST_BODY "@rx [TVqQAAMAAAAEAAAA]" \
"id:100001,phase:2,deny,status:403,msg:'Potential DLL/EXE injection payload detected'"
—
最後に:フォレンジックの心得
プロセスインジェクションを調査する際、我々アナリストはツール(VolatilityやRekall)でメモリダンプを解析するが、諸君に覚えておいてほしいのは「ツールはあくまで補助輪」だということだ。
「なぜこのプロセスが、このタイミングでネットワークソケットを開いたのか?」「なぜこのスレッドは、本来のロジックとは無関係なスタックトレースを持っているのか?」
そうした疑問を持ち続けることが、インシデントを早期収束させる鍵になる。セキュリティは技術の積み重ねだが、最後は人間が持つ「違和感への嗅覚」が勝敗を分ける。
今の開発環境に「怪しいプロセス」が潜んでいないか、一度ログを深く掘り下げてみてほしい。何か見つけたら、いつでも相談してくれ。
コメント