エグゼクティブ サマリー
多くの場合、IDA を使用した静的リバースエンジニアリングには問題があります。実行時に計算される値があるため、特定の基本ブロックの動作を把握するのが困難なのです。一方、マルウェアをデバッグして動的に分析しようとすると、多くの場合マルウェアはそれに気づき、動作を変えてしまいます。そこで Cisco Talos が開発したのが、Dynamic Data Resolver(DDR)です。IDA 用の新しいプラグインで、マルウェアを簡単にリバースエンジニアリングできます。
機能
コード フロー トレース
(どの基本ブロックが何回実行されたかを約 20 色に分けて表示)
図 1API コールに関する検索可能なログの作成
(特定の命令(call、jxx など)が API アドレスにアクセスした回数を含む)
図 2
文字列を検索可能なログの作成
図 3
動的な値の解決と自動コメント付与
図 4
技術的な詳細
アーキテクチャと使用方法
図 5 に示すように、DDR のアーキテクチャはクライアント/サーバ型で、DDR IDA プラグインと DDR サーバは Python スクリプトです。DynamoRIO クライアントは C 言語で記述された DLL であり、DynamoRIO ツールの drrun.exe によって実行されます。この DLL は、インストルメンテーション手法を利用して、マルウェア サンプルの実行時に分析とモニタを行います。フロントエンドになるのが IDA プラグインです。通常はすべてのプロセスがプラグインを介して制御されます。DynamoRIO クライアントのバックエンドで分析が終了すると、結果がプラグインに返されます。ユーザがデータを簡単に読み取ったり、サードパーティ製 Python スクリプトで解析したりできるように、データは JSON 形式になっています。
プラグインとサーバは理論的には同じ PC 上で実行できますが、マルウェア サンプルを実行する場合には、プラグインとサーバは別のマシンで稼働させることを強くお勧めします。
ほとんどの環境では、以下に説明する手順でプラグインをインストールすれば、IDA の [DDR/トレース(DDR/Trace)] メニューから分析を開始できます。ただし、エアギャップを設けた、Python を使用できないシステムでマルウェアを実行したり、プラグイン メニューでサポートされていないアドレス空間を分析したりする場合は、分析を手動で行うことも可能です。DLL はコマンド ラインで実行できます。サンプルのアーキテクチャに応じて、構文は次のようになります。
<DYNRIO_DIR>\bin<ARCH>\drrun.exe -c "<PATH_TO_DLL>\ddr<ARCH>.dll" -s <START_ADDR> -e <END_ADDR> -c <NUM_INSTR_TO_EXECUTE> -f "<JSON_FILE_TO_LOG_TO>" -- <MALWARE-SAMPLE> e.g. C:\DYNRIO_DIR\bin64\drrun.exe -c "C:\ddr\ddr64.dll" -s 0x140001000 -e 0x140002200 -c 10000 - f "C:\ddrlog\sample_log64.json" -- sample64.exe C:\DYNRIO_DIR\bin32\drrun.exe -c "C:\ddr\ddr32.dll" -s 0x00401000 -e 0x00402000 -c 10000 -f "C:\ddrlog\sample_log32.json" -- sample32.exe
After the analysis is done, you will need to load the <JSON_FILE_TO_LOG_TO>, ex. sample_log32.json, via the File/Load file/Load DynRio File menu in IDA.
しかし通常はこれも不要です。DDR では、[IDA逆アセンブルビュー(IDA Disassembler View)] のコンテキスト メニューを右クリックすると、すべての機能にアクセスできます。ただし DDR 機能を実行するには、最初にサンプルを分析するか、前述のように JSON ファイルを手動でロードする必要があります。手動でプロセスを実施する以外に、DDR には分析を行う方法がいくつか用意されています。それらの分析機能は、すべて図 6 に示す [トレース(Trace)] メニューから選択できます。
図 6
フルトレース オプションでは、非常に多くのランタイム情報が収集されます。フルトレースは簡易トレースに比べて大幅に時間がかかり、メモリ消費も多くなります。簡易トレースで行うのはコード カバレッジ トレースだけです。つまり、ランタイムに実行される命令と、call、jmp、ret など、制御フローに関連する命令の基本情報がログに記録されます。可能な限り多くの命令をログに記録し、サンプルの動作の概要を把握する場合には、一般的に簡易トレースを選択します。たとえば、実行された回数に基づいてできるだけ多くの基本ブロックをハイライトしたり、サンプルで使用された API コールの概要を把握したりする場合などです。ログに記録する命令の数は、[ログに記録する命令数の設定(Config/Set number of instructions to log)] メニューで値を大きくすることができます。平均的な PC で簡易トレースを行う場合、通常はこの値を 200.000 に設定します。デフォルトは 20.000 で、フルトレースに適しています。サンプルの開始シーケンスに注目する場合(例:[セグメントにフルトレースを実施(Run full trace for segment)])や、暗号化ルーチンなど特定の基本ブロックを分析していて、すべての命令とそのオペラントの詳細が必要な場合(例:[基本ブロックにフルトレースを実施(Run full trace for basic block)])、通常はフルトレースを実行します。この分析に要する時間は 30 秒を超えないようにします。超える場合は、DDR_plugin.py スクリプトの MAX_API_TIMEOUT の設定値を大きくする必要があります。さらにトレースに時間を要する場合は、前述の手動による分析を行うこともできます。
すべての DDR 機能で使用されるのは、最後に実行した分析/トレースの JSON ファイルであることに注意してください。たとえば、簡易トレースを実行した後に、[ソース オペラントの値を取得する(Get values for source operant)] を実行してレジスタ値を解決しようとしても、データが見つからない可能性があります(call や jmp など、前述の制御フロー命令である場合を除く)。初めて DDR を使用する場合は、生成された JSON ファイルを確認して、トレースの種類に応じてログに記録されるデータの違いを理解するとよいでしょう。
トレースは、サンプルが置かれているディレクトリにキャッシュ/保存されます。フルパスは IDA のログ ウィンドウでも確認できます。そのため、JSON ファイルに記録されているが、その時点でロードされていない情報が必要な場合は、該当するトレース メニュー オプションを再度選択すると、キャッシュ/保存されているファイルがロードされます。ファイルのロードと解析には通常それほど時間はかからないため、分析を実際に再実行しなくても、各種の分析結果を簡単に確認できます。実際に特定の分析を再実行する場合は、[トレース(Trace)] メニューからキャッシュ/保存済みのファイルをすべて削除するか、サンプルがあるディレクトリから該当するファイルを手動で削除します。
次のビデオでは、各種の DDR 機能とワークフローの例を紹介しています。
免責条項
このアルファ バージョンは、将来的に改善できるバグがいくつか含まれている可能性があることを前提にリリースされています。それでも Talos では、このツールを早い段階でコミュニティに公開した方が役に立つと考えています。問題、バグ レポート、機能に対するリクエストの送付先については、ソース コードをご確認ください。問題が発生した場合は、作成者までお問い合わせください。
インストール
このプラグインは、Windows x64 用 IDA Version 7.2 向けに設計されていますが、基本的には 7.1 でも動作します。
最初に、こちら から DDR リポジトリを複製またはダウンロードしてください。
必要な Python モジュールと DynamoRIO フレームワークをインストールします。詳細については以下の付録をご覧ください。
次に現在のローカル設定に基づいて、「DDR_server.py」スクリプトの変数を設定する必要があります。また、ローカルのファイアウォールがプラグインとサーバ間のトラフィックをブロックしていないことを確認します。DDR_server.py スクリプトを開始します。既存の証明書ファイルが見つからない場合は、自己署名証明書/鍵のペアと API 鍵ファイルが生成され、DDR_server.py スクリプトの <CONFDIR> 変数に設定されているディレクトリに書き込まれます。この証明書を使用するか、独自の証明書/鍵ファイルをこのディレクトリに配置します。次に証明書ファイル(例:ddr_server.crt)をアナリストのマシン(IDA/DDR_plugin.py)にコピーして、DDR_plugin.py の CA_CERT 変数がそのファイルをポイントするように設定します。さらに、現在のセットアップに基づいて、API 鍵とその他の変数も設定します。以下に、確認すべき主な変数を示します。
DDR_plugin.py
# hostddr_server.py が実行されるホストの IP アドレス
WEBSERVER = “192.168.100.122”
# DDRserver.py が使用する TCP ポート
WEBSERVER_PORT = “5000”
# API 鍵。ddr_server.py の開始メッセージを確認します。
# ddr_server.py スクリプトで生成されます。
DDR_WEBAPI_KEY = “KT5LUFCHHSO12986OPZTWEFS”
# DDR_server.py スクリプトによって生成された証明書または手動で作成した証明書(SSL 接続に使用)があるローカル ディレクトリ。この場所に証明書ファイルを必ずコピーします。
CA_CERT = r”C:\Users\User Name\Documents\idaplugin\ddr_server.crt”
# 証明書の確認の有無を設定します。False にするのは危険なので、テスト時のみとします。
VERIFY_CERT = True
# ddr_server.py マシンのディレクトリ。サーバ スクリプトから分析対象のサンプルを検索できるサーバのローカル ディレクトリ。このディレクトリが存在し、サンプルがコピーされていることを確認してください。このプラグインの今後のバージョンでは、ファイルが自動的にコピーされるようになる予定です。
SERVER_LOCAL_SAMPLE_DIR = r”C:\Users\User Name\Documents\DDR_samples”
DDR_server.py
# 最初に自己署名証明書を生成し、
# ローカル ネットワークを設定するためのパラメータ
CERT_FILE = “ddr_server.crt”
KEY_FILE = “ddr_server.key”
APIKEY_FILE = “ddr_apikey.txt”
MY_IPADDR = “192.168.100.122” # マルウェア ホストの IP アドレス
MY_PORT = “5000”
MY_FQDN = “malwarehost.local” # マルウェア ホストの FQDN
# API 鍵ファイル、証明書ファイルなどに関する設定ファイルを保存/ロードするディレクトリ。
CONFDIR = r”C:\malware\tools\DDR_Talos\IDAplugin”
# x32/x64 ddrun.exe および対応する DynRIO クライアント DDR.dll のある場所。
CFG_DYNRIO_DRRUN_X32 = r”C:\tools\DynamoRIO-Windows-7.0.0-RC1\bin32\drrun.exe
CFG_DYNRIO_CLIENTDLL_X32 = r”C:\malware\tools\DDR_Talos\IDAplugin\ddr32.dll”
CFG_DYNRIO_DRRUN_X64 = r”C:\tools\DynamoRIO-Windows-7.0.0-RC1\bin64\drrun.exe”
CFG_DYNRIO_CLIENTDLL_X64 = r”C:\malware\tools\DDR_Talos\IDAplugin\ddr64.dll
注意
設定しているディレクトリが存在することを確認してください。存在しない場合でも、アルファ バージョンではディレクトリは作成されません。プログラムではエラー メッセージが表示されるだけです。
また、IDA で分析しようとするマルウェア サンプルを、DDR_plugin.py スクリプトの SERVER_LOCAL_SAMPLE_DIR 変数で設定したディレクトリにコピーしておく必要があります。これは次のバージョンで自動化される予定です。
付録
Python の要件
- Python27-x64
ddr_plugin.py/IDA マシン(アナリストの PC)
- リクエスト
(http://docs.python-requests.org)
例:
C:\python27-x64\Scripts>pip install -U requests
複数のバージョンの Python を使用している場合は、以下について、IDA で使用しているものと同じバージョン用のパッケージをインストールする必要があります。
ddr_server.py マシン(マルウェアのホスト)
- Flask
(http://flask.pocoo.org/) - PyOpenSSL
(https://pyopenssl.org/en/stable/)
例:
pip install -U Flask
pip install -U pyOpenSSL
その他の要件
ddr_server.py マシン(マルウェアのホスト)
– DynamoRIO フレームワーク(https://www.dynamorio.org/ )
DynamoRIO ホームページにあるバイナリ インストーラを使用します。
テスト環境
ddr_plugin.py/IDA(アナリストの PC – Windows 10 64 ビット)
IDA バージョン 7.2.181105 Windows x64
C:\Python27-x64\Scripts\pip.exe freeze
certifi==2017.7.27.1
chardet==3.0.4
first-plugin-ida==0.1.1
idna==2.6
requests==2.18.4
requests-kerberos==0.11.0
urllib3==1.22
winkerberos==0.7.0
yara==1.7.7
ddr_server.py マシン(マルウェアのホスト – Windows 7 64 ビット)
C:\Python27-x64\Scripts\pip.exe freeze
asn1crypto==0.24.0
certifi==2018.11.29
cffi==1.11.5
chardet==3.0.4
Click==7.0
cryptography==2.4.2
enum34==1.1.6
Flask==1.0.2
idna==2.7
ipaddress==1.0.22
itsdangerous==1.1.0
Jinja2==2.10
MarkupSafe==1.1.0
pycparser==2.19
pyOpenSSL==18.0.0
requests==2.20.1
six==1.11.0
urllib3==1.24.1
Werkzeug==0.14.1
yara-python==3.6.3
DynamoRIO のインストール
DynamoRIO バージョン:7.0.0-RC1
インストール ディレクトリ:C:\tools\DynamoRIO-Windows-7.0.0-RC1
本稿は 2019年1月16日に Talos Group のブログに投稿された「Dynamic Data Resolver (DDR) – IDA Plugin」の抄訳です。