投稿者:Xabier Ugarte Pedrero
Talos では、脅威の調査・インテリジェンス能力の向上に継続的に努めています。そのため、分析用の一般的なツールを活用するだけでなく、イノベーションや、新しい課題を克服するための独自技術の開発にも力を入れています。また、Talos では従来からオープンソース プロジェクトをサポートしており、さまざまなオープンソース プロジェクトを運営しています。たとえば FIRST や BASS などで、これらのツールはワークフローの一部としても使用されています。
このブログ投稿では、Python スクリプトで操作できる Talos のリバース エンジニアリング サンドボックス、PyREBox について紹介します。QEMU を基盤としている PyREBox は、さまざまな視点からの動的分析とデバッグ機能を実現し、リバースエンジニアリングを支援します。PyREBox を使用することで、シンプルな Python スクリプトにより実行中の QEMU VM を検査し、メモリとレジスタを変更し、解析できます。QEMU(システム全体のエミュレータとして機能している場合)は、システム全体(CPU、メモリ、デバイスなど)をエミュレートします。仮想マシンのイントロスペクション(VMI)技術を使用することで、実行時にメモリから情報を透過的に取得でき、ゲスト OS を一切変更せずに済みます。
DECAF、PANDA、S2E、または AVATAR など、複数の学術プロジェクトでは、以前からリバース エンジニアリング タスクに対して QEMU ベースのインストルメンテーションが使用されています。これらのプロジェクトでは、プラグインを C/C++ で作成でき、動的なテイント解析、シンボリック実行、さらには実行トレースの記録と再生のような高度な機能を実装しています。PyREBox では、設計を簡素化し、脅威分析用システムの利便性を向上させる狙いがあります。
目標
- システム全体をエミュレーションするプラットフォームにより、エミュレートされたゲスト システムをシンプルなインターフェイスで検査可能(システム イベントの詳細な解析を実現)。
- Volatility を基にした仮想マシンのイントロスペクション(VMI)。ゲストに対するエージェントやドライバのインストールが不要。
- IPython ベースのシェル インターフェイス。
- 最大のエコシステムの 1 つである Python ベースのスクリプティング エンジンにより、広範囲のセキュリティ ツールを活用可能。
- クリーンな設計と QEMU からの分離。QEMU を基盤とした多くのプロジェクトは QEMU がアップグレードされても進化しておらず、新しい機能、最適化、そしてセキュリティ更新を利用する機会を逸しています。この問題に対処するために、PyREBox は独立したモジュールとして実装されます。QEMU とともにコンパイルできるため、変更のセットが最小限で済みます。
- 各種アーキテクチャのサポート現在、PyREBox は 32/64 ビット アーキテクチャの Windows 専用ですが、PyREBox は ARM、MIPS、PowerPC などの OS にも対応できるように設計されています。攻撃を受けやすいデバイス(そして他のアーキテクチャや OS)が増加するにつれ、ARM やMIPS などのシステムをサポートする意義も大きくなります。他のアーキテクチャや OS にも順次対応する予定です。
PyREBox の仕組み
PyREBox は QEMU と組み合わせて構築されており、最小限の変更でシステムにおける特定のイベントをモニタできます。QEMU は、各種のアーキテクチャのコードを、仮想 CPU で稼働する中間言語へと変換可能な「Tiny Code Generator(TCG)」エンジンを基盤としています。この中間言語は QEMU が実行されるターゲット アーキテクチャにコンパイルされます。PyREBox では、こうして変換されたコードを解析できます。これにより、実行時にコールバックを動的に登録できます。PyREBox が必要なパラメータは、Python で判読可能なオブジェクトにすべて変換されます。Python 関数は、該当システムで特定のイベントがトリガーされた場合に実行されます。
また、PyREBox は仮想マシンの検査で Volatility を利用するため、システム(エミュレートされたマシン)の物理構成図と、OS の論理構成図(プロセス数、モジュール数、シンボル数など)との間にある意味上の差異を解消できます。頻繁に呼び出す必要があるいくつかの C/C++ ルーチンも PyREBox に実装されています。これは、Python のランタイム環境を妨げる頻度を下げ、効率を高めることが目的です。このアプローチにより、実行プロセスや、実行プロセスによってロード/エクスポートされたシンボルを、エミュレートされたシステムにエージェントやドライバを挿入せずに検査できます。
つまり、ゲストの状況を物理レベルで検査できます。さらに重要なの点は、実行中のプロセスを常に把握できること、分析対象をいくつかの特定プロセスに集約できること、そして任意のレベル(ユーザまたはカーネル スペース)で任意のプロセスにブレークポイントを密かに挿入できることです。
PyREBox のメリット
PyREBox は、2 つのメイン インターフェイスを備えています。1 つ目のインターフェイスでは、QEMU でゲスト システムを実行しながらシェルを開始し、実行中の VM を各種コマンドにより検査できます。このシェルは IPython に基づいており、IPython の API を基盤として Python コードのスニペットを記述し、Python の式を使用して PyREBox コマンド パラメータを表現できます。2 つ目のインターフェイスでは、システム上で特定イベントを対象としたコールバックを登録できる Python スクリプトを記述できます。
IPYTHON シェル
PyREBox シェルは、QEMU のモニタで sh コマンドを入力するだけで簡単に起動できます。これにより、IPython シェルが即座に起動します。このシェルは、コマンド履歴に加えて定義済みの変数も記録します。たとえば、値を保存しておくことで、別の実行時(シェルの再始動時)に同じ値を復元できます。PyREBox では、オートコンプリート、コマンド履歴、複数行の編集、コマンド ヘルプの自動生成など、IPython で利用可能な機能をすべて使用できます。
PyREBox では、密かにシステム(または特定のプロセス)をデバッグできます。デバッグ対象のシステムに留まる(ブレークポイントを挿入するためにデバッグ プロセスのメモリも変更する)従来のデバッガとは異なり、PyREBox は検査対象のシステム内部に入ることは一切なく、ゲスト上にドライバやコンポーネントをインストールする必要もありません。
PyREBoxでは、実行中の VM 状態を検査し、変更するための包括的なコマンド セットが用意されています。コマンドの一覧を取得するには、list_commands と入力します。
VM を実行中の任意の時点で、vol コマンド、およびそれに対応する Volatility コマンドを入力することで、任意の Volatility プラグインを実行できます。 使用可能な Volatility プラグインの一覧を取得するには、list_vol_commands と入力します。このリストは自動的に生成されるため、PyREBox の volatility/ パスにインストールしたすべての Volatility プラグインも表示されます。
最後に、スクリプトには独自のコマンドを定義することもできます。コマンドの定義は、「do_」から始まる名前の関数を作成するだけで完了します。この後の作業は PyREBox 上で自動化されています。
コマンドよりも複雑な表現が必要な場合は、API を利用して Python スニペットを作成することもできます。
API の詳細については、シェルで help(api) と入力することで確認できます。
スクリプティング
PyREBox を使用すると、コールバック関数を登録できるスクリプトを動的にロードできます。これらの関数は、以下のような特定のイベントが発生すると呼び出されます。
- 指示または基本ブロック、あるいはその両方の実行
- メモリの読み取りまたは書き込み
- プロセスの作成または終了
- コンテキストの切り替え
- TLB ミス
- ネットワーク インターフェイスおよびキーボードのイベント
このフレームワークは DECAF などのプロジェクトを参考にしています。そのため、DECAF でサポートされているコールバック タイプの多くがサポートされています。
PyREBox は Volatility と統合されているため、Python スクリプトで、メモリ調査用の Volatility プラグインをすべて利用できます。よく使用されているリバース エンジニアリング ツールの多くは Python を実装しており、少なくとも Python バインディングを使用しています。Talos のアプローチにより、これらのツールをすべてのスクリプトに統合できます。
このスクリプティング インターフェイスにより、カスタム コマンドを定義することもできます。スクリプトでは、特定のプロトタイプの後に関数を宣言するだけで、(スクリプトがロードされた後にシェルから利用できる)新しいコマンドを作成できます。つまり、Python でシンプルなラッパーを記述するだけで、スクリプティング エンジンだけでなく IPython シェルにも、あらゆる Python ツールを統合できます。
スクリプトは、特定のイベントが発生するか、特定の条件が満たされた場合に、ユーザに代わってシェルを起動することもできます。ユーザはイベントをモニタし、記録できます。条件が満たされた場合は、start_shell() を呼び出すだけで、いつでも VM を停止させ、特定ポイントでシェルを始動できます。
以下のスニペットは、スクリプトが PyREBox にロードされた時点で、プロセスの作成時にコールバックを登録する、シンプルなスクリプトです。新しいプロセスが作成されるたびに、PyREBox シェルが始動します。また、my_command という名前のカスタム コマンドも実装されます。このコマンドは、custom my_command と入力することで、PyREBox シェルから呼び出せます。
#!/usr/bin/python import sys import api from ipython_shell import start_shell from api import CallbackManager #Callback manager cm = None #Printer pyrebox_print = None if __name__ == "__main__": #This message will be displayed when the script is loaded in memory print "[*] Loading python module %s" % (__file__) def new_proc(pid,pgd,name): ''' Process creation callback. Receives 3 parameters: :param pid: The pid of the process :type pid: int :param pgd: The PGD of the process :type pgd: int :param name: The name of the process :type name: str ''' global pyrebox_print global cm #Print a message. pyrebox_print("New process created! pid: %x, pgd: %x, name: %s" % (pid,pgd,name)) #Start a PyREBox shell exactly when a new process is created start_shell() def initialize_callbacks(module_hdl,printer): ''' Initilize callbacks for this module. ''' global cm global pyrebox_print #Initialize printer function pyrebox_print = printer pyrebox_print("[*] Initializing callbacks") #Initialize the callback manager cm = CallbackManager(module_hdl) #Register a process creation callback new_proc_cb = cm.add_callback(CallbackManager.CREATEPROC_CB,new_proc) pyrebox_print("[*] Initialized callbacks") def clean(): ''' Clean up everything. ''' global cm print "[*] Cleaning module" #This call will unregister all existing callbacks cm.clean() print "[*] Cleaned module" def do_my_command(line): ''' Short description of the custom command. Long description of the custom command ''' global pyrebox_print global cm #Implementation of the command functionality pyrebox_print("This is a custom command")
Finally, given that python callbacks can introduce a performance penalty (especially on frequent events such as instructions executed), it is also possible to create triggers.トリガーはネイティブコード プラグイン(C/C++ で作成)です。これは実行時に、Python のコールバックが実行される直前で任意のイベントに動的に挿入できます。これにより、Python コードにヒットするイベント数を制限し、ネイティブ コード内の値を事前に計算できます。
使用可能な機能についての詳細情報は、プロジェクトの関連資料を参照してください。
まとめ
PyREBox は、リバース エンジニアリングに非常に便利なツールです。PyREBox は Python と Volatility が統合されており、マルウェアまたはエクスプロイト/脆弱性分析から、ファームウェア分析に至るまで多用途で活用できます。他のアーキテクチャやオープン システムにも順次対応予定です。PyREBox は、すでに Python に実装されている多数のセキュリティ ツールと簡単に統合できます。こうしたフレームワーク設計により、あらゆる Python ライブラリと連動する新しいシェル コマンドを簡単に作成できます。これは、シンプルなラッパー スクリプトを記述する上で重要です。
PyREBox は社内開発されたツールですが、コミュニティに貢献し、新しいスクリプトによる機能強化を狙ってオープンソース化されています。
本稿は 2017年7月17日に Talos Group のブログに投稿された「PyREBox, a Python Scriptable Reverse Engineering Sandbox」の抄訳です。