Kaliでradare2を使ってマルウェアPEを解剖する — アセンブリ抽出を完全にマスター

“コードを実行することなく、私たちはその中に隠された意図を読み取ることができる。”

静的解析の最初の関門を、radare2で開いてみましょう。


この記事で扱うこと

  • マルウェアPEファイルを実行せずにアセンブリを抽出する安全な方法
  • rabin2でPEヘッダー・インポート・文字列を素早く収集する事前偵察技術
  • r2の主要コマンド(aaa, afl, pdf)で関数単位の逆アセンブルを行う
  • 抽出したアセンブリをきれいな.asmテキストファイルとして保存するバッチ(ヘッドレス)技術
  • アナリストが必ず守るべき隔離環境と安全規則

なぜradare2なのか

マルウェア解析を初めて行う際、ほとんどの人はIDA ProやGhidraを思い浮かべます。どちらも素晴らしいツールですが、重くGUI中心であるため、「素早く一つの関数だけを覗きたい」という状況には過剰な面があります。

radare2(略してr2)はその反対側に位置します。ターミナルベースの軽量で高速なリバースエンジニアリングフレームワークで、Kali Linuxに標準搭載されているため、別途インストールなしですぐに利用できます。何よりもスクリプトで自動化しやすいため、数十個のサンプルから特定の関数のアセンブリだけを一括抽出する作業に強力です。

核心はこれです。r2による逆アセンブルは静的解析です。つまり、マルウェアを絶対に実行せず、ファイル内部の機械語を人間が読めるアセンブリに翻訳するだけです。解析自体でシステムが感染する危険がないという意味です。


主要概念の整理

PEファイルとは

PE(Portable Executable) はWindowsの実行ファイルフォーマットです。.exe、.dll、.sysがすべてPE形式であり、内部にはコードが格納された.textセクション、データが格納された.data、インポートテーブル、エントリポイントアドレスなどが構造化されています。マルウェアのほとんどがWindowsを標的とするため、PE解析はアナリストの基本スキルです。

逆アセンブル(Disassembly)

コンパイルされたバイナリの中には、人間が読みにくい機械語(machine code) が含まれています。これをmov、push、callのようなアセンブリ命令に逆翻訳する過程が逆アセンブルです。radare2はこの作業をコマンド一行で実行します。

radare2ツールセット

  • r2 — 対話型メインコンソール。解析と逆アセンブルの中心
  • rabin2 — PE/ELFなどのバイナリのメタ情報(ヘッダー、インポート、文字列)を抽出するツール
  • r2スクリプティング — -cオプションでコマンドを事前に挿入して自動実行

実習:アセンブリ抽出の段階別コマンド

ステップ0 — 隔離環境とサンプル整合性の確認

解析は必ずインターネットから分離された隔離VM(スナップショット復元可能)で実施します。まず、サンプルの正体とハッシュを記録しておきます。

bash

# ファイルタイプ確認 — PE実行ファイルであるか検証
file sample.exe

# ハッシュ記録 — 後で脅威インテリジェンス(VirusTotalなど)で検索するため
sha256sum sample.exe

ハッシュは解析レポートの識別子となるため、最初に記録する習慣をつけるのが良いでしょう。

ステップ1 — rabin2で事前偵察

コンソールに入る前に、rabin2で全体像を把握します。実行せずにヘッダーだけを読み込むため、非常に安全です。

# バイナリ基本情報(アーキテクチャ、ビット、コンパイラ、エントリ)
rabin2 -I sample.exe

# PEヘッダーフィールド詳細
rabin2 -H sample.exe

# インポート関数リスト — 悪性挙動推定の核心的な手がかり
rabin2 -i sample.exe

# エクスポート関数(DLL解析時に有用)
rabin2 -E sample.exe

# エントリポイントアドレス
rabin2 -e sample.exe

# 文字列抽出 — URL、コマンド、レジストリキーなどが明らかになる
rabin2 -z sample.exe

rabin2 -i で表示されるインポートは特に重要です。CreateRemoteThread、VirtualAllocEx、WinHttpOpenのようなAPIが見られる場合、コードインジェクションや外部通信を疑うことができます。

ステップ2 — r2でロードして自動解析

次に、メインコンソールに入ります。-Aオプションはロードと同時に全体解析(aaa)を実行します。

# -A : ロードと同時にaaa(自動解析)を実行
r2 -A sample.exe

-Aなしで開いた場合は、コンソール内で直接解析を実行します。

[0x00401000]> aaa

aaa(analyze all)は、関数境界、呼び出し関係、文字列参照を自動的に識別するr2の主要解析コマンドです。大きなサンプルでは時間がかかる場合があるので、しばらくお待ちください。

ステップ3 — 関数リストの確認

解析が完了したら、識別された関数をリストアップします。

[0x00401000]> afl

afl(analyze function list)は、各関数のアドレス、サイズ、名前を表形式で表示します。特定の名前だけを見たい場合は、r2内蔵のgrep(~)を使用します。

[0x00401000]> afl~main
[0x00401000]> afl~entry

ステップ4 — アセンブリの逆アセンブル

いよいよ核心です。関数単位でアセンブリを出力します。

# エントリポイント関数全体を逆アセンブル
[0x00401000]> pdf @ entry0

# 現在位置に移動後、関数を出力
[0x00401000]> s entry0
[0x00401000]> pdf

# 特定の関数を逆アセンブル(aflで確認した名前を使用)
[0x00401000]> pdf @ sym.malicious_routine

# 特定のアドレスから50個の命令のみを出力
[0x00401000]> pd 50 @ 0x00401230

pdf(print disassembly function)は関数全体を、pd Nは指定した数の命令だけを逆アセンブルします。両者の違いを覚えておけば、状況に応じて使い分けることができます。

ステップ5 — 視覚的(Visual)モードでフローを見る

命令の羅列ではなく、グラフで制御フローを見たい場合はビジュアルモードを使用します。

# ビジュアル逆アセンブルモード(qで終了、pで画面切り替え)
[0x00401000]> V

# 関数制御フローグラフ
[0x00401000]> VV

VVのグラフビューは、分岐や繰り返し構造を一目で把握できるようにするため、複雑なパッキング解除ルーチンを理解する際に特に役立ちます。

ステップ6 — アセンブリをファイルに抽出(自動化)

アナリストの真の武器は自動化です。コンソールに入らずとも、-q -cオプションでコマンドを注入し、結果をテキストファイルとして抽出できます。

# エントリ関数のみをきれいなテキストで保存(カラーコード除去)
r2 -q -c "e scr.color=0; aaa; pdf @ entry0" sample.exe > entry0.asm

# すべての関数を一括で逆アセンブル — @@f は関数単位の繰り返し実行
r2 -q -c "e scr.color=0; aaa; pdf @@f" sample.exe > all_functions.asm

# 関数リストのみをテキストで
r2 -q -c "aaa; afl" sample.exe > functions.txt

ここでe scr.color=0はターミナルのカラーコードをオフにする設定です。これを省略するとファイルにANSIエスケープ文字が混ざって汚くなるので、必ず含めてください。@@fはr2の繰り返し演算子で、識別されたすべての関数に対してpdfを順次実行するという意味です。

より読みやすい出力を希望する場合は、追加設定を調整します。

# 左側のフローラインとhexバイトを隠して純粋なアセンブリのみを抽出
r2 -q -c "e scr.color=0; e asm.lines=false; e asm.bytes=false; aaa; pdf @@f" sample.exe > clean.asm

このように抽出した.asmファイルは、grepで特定のAPI呼び出しを検索したり、複数の亜種間のコード類似性を比較する解析資料としてすぐに活用できます。


⚠️ 注意事項とよくある間違い

  • 絶対にホストで直接扱わないでください。 解析はスナップショットが可能な隔離VMでのみ行い、ネットワークは遮断します。r2自体は実行しませんが、誤ってサンプルをダブルクリックする事故はいつでも起こりえます。
  • パッキングされたサンプルは逆アセンブルが無意味な場合があります。 UPXなどでパッキングされている場合、表示されるコードはアンパッキングスタブだけです。rabin2 -Iの結果のエントロピーが異常に高かったり、セクション名がUPX0のようであれば、まずアンパッキングを検討してください。
  • カラーコードの削除を忘れないでください。 e scr.color=0なしでファイルに抽出すると、^[[31mのような制御文字が混ざります。
  • aaaがすべての関数を捕捉できない場合があります。 難読化されたコードでは、自動解析が関数境界を見逃すことがあります。この場合、疑わしいアドレスでaf(関数定義)を手動で呼び出した後、pdfを実行してください。
  • 法的・倫理的境界を守ってください。 正当な権限のあるサンプルと環境でのみ解析します。解析目的は防御と検出能力の強化にあります。

✅ まとめ

今日扱った流れを一句で要約するとこうなります。隔離環境準備 → rabin2で偵察 → r2 -Aで解析 → aflで関数識別 → pdfでアセンブリ抽出 → -q -cで自動保存。

radare2は最初はコマンドが馴染みにくいかもしれませんが、i(info)、a(analyze)、p(print)、s(seek)という4つのカテゴリでコマンド体系が構成されていることを知れば、すぐに慣れるでしょう。静的解析でアセンブリを読み解く感覚が身につけば、動的解析(デバッグ)や振る舞い解析へ移行する道もはるかにスムーズになります。

次のステップの推奨

  • r2のデバッガーモード(r2 -d)で動的解析入門
  • pdcまたはr2decプラグインで擬似Cコードの逆コンパイルを試す
  • Cutter(radare2 GUI)でグラフ解析を併用
  • YARAルール作成と連携した亜種検出の自動化


Comments

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です