
Winstrument is a framework of modular scripts to aid in instrumenting Windows software using Frida for reverse engineering and attack surface analysis.
Winstrumentは、リバースエンジニアリングおよび攻撃対象領域の分析のために、Fridaを使用してWindowsソフトウェアをインストルメントするためのモジュール式スクリプトのフレームワークです。
このプロジェクトはPython 3.7をサポートしています。 Pythonとpipがすでにインストールされていることを前提に、次のようにします:
pip install winstrument
次にプログラムを実行するには、次のコマンドを実行します:
winstrument
このツールは現在実験的なものであり、フリーズしたり、その他の安定性の問題が発生する場合があります。
Windows 10の新規インストールなど、場合によっては、FridaをインストールするときにpipでSSLエラーが発生することがあります。この場合は、下記のトラブルシューティングを参照してください。
winstrument REPLを実行するには、winstrumentを実行するだけです。
以下は、registryモジュールを使用してnotepad.exeをインストルメントする簡単な例です。利用可能なCLIコマンドの詳細については、下記のCLIセクションを参照してください。
PS C:\winstrument> winstrument
> set target C:\Windows\System32\notepad.exe
> use registry
> run
Spawned 1144
instrumented process with pid: 1144 and path: C:\Windows\System32\notepad.exe
<User closes notepad from GUI>
detached from 1144 for reason process-terminated
> show registry
module time target function hkey subkey value
-------- ----------------- ------------------------------- ---------------- ------------------ --------------------------------------------------------------------------- ---------------------------------
registry 2019-08-19 07:03:07 C:\Windows\System32\notepad.exe RegGetValueW 0x2f4 SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize AppsUseLightTheme
<...>
上記の例では、ユーザーはターゲットプロセス(この場合はnotepad.exe)を指定します。次に、プログラムによって行われるレジストリ関連のシステムコールを列挙するregistryモジュールを使用することを指定します。プロセスが終了すると(ユーザーがメモ帳を閉じると)、保存された出力はshow registryを使用して表示できます。
メインのPythonファイルwinstrument.pyは、Fridaデバイスを初期化し、ターゲットプロセスのインスタンスを起動します。
cmdline.pyは、cmd2を使用したコマンドラインインターフェースを提供します。これは、Winstrumentがコマンドラインから直接実行される場合のメインスクリプトのエントリポイントです。コマンドについては、以下で説明します。
次に、有効な各モジュールを順に処理し、それをインスタンス化して、そのモジュールのload_scripts()メソッドを呼び出してプロセスをインストルメントします。
最後に、ターゲットからデタッチされると、各モジュールのget_output()とon_finish()を呼び出します。
モジュールは、modules/ディレクトリ内の.pyファイルに含まれています。モジュールは、注入するコード、その注入されたコードのメッセージ処理、および出力を定義するbase_module.BaseInstrumentationのサブクラスで構成されます。
モジュールAPIの詳細は、下記の「モジュール」セクションで定義されています。
各モジュールは、説明などのメタデータをmodules/metadata.tomlに保存します。セクションの見出しには、モジュール名(大文字と小文字を区別しない)を使用する必要があります。
例えば、dllsモジュールに対応するセクションは次のとおりです:
[DLLS]
description = """Hooks LoadLibrary-family system calls and outputs DLL loads where part of the search path might be
writable by the current user or a low-privileged user group."""
プログラムは設定を%APPDATA%/winstrument内のsettings.tomlに保存します。
モジュールのほとんどすべてがターゲットプロセスにJavaScriptを注入するため、modules/js/ディレクトリには、モジュールによって読み込まれ注入されるFrida JavaScriptスニペットが含まれています。
これらのファイルはモジュールと同じ名前を持つ必要があります。つまり、モジュールdlls.pyはjs/dlls.jsのJSを使用します。
上記のように、各モジュールはbase_module.pyのBaseInstrumentationをサブクラス化します。
各モジュールは、その名前(拡張子を除いたpythonファイルとjsファイルの名前)をmodulenameという静的クラス属性として定義する必要があります。
モジュールは、BaseInstrumentationの次のメソッドを使用またはオーバーライドできます:
__init__(self,*args,**kwargs) - モジュール固有の初期化コードに加えて、このコンストラクタはsuper().__init__(*args,**kwargs)を呼び出す必要があります。load_script(self) - このメソッドは通常、オーバーライドする必要はありません。BaseInstrumentationの実装でほとんどのユースケースに十分対応できるためです。Fridaイベントにフックするには、代わりにregister_callbacks()をオーバーライドしてください。load_scriptは、インストルメントするJavaScriptファイルを読み込み、Fridaのsession.create_scriptを呼び出し、必要なコールバックを追加してから、スクリプトオブジェクトのload()メソッドを呼び出してインストルメントするために使用します。register_callbacks(self) - スクリプトをターゲットプロセスに読み込む前にBaseInstrumentation.load_scriptによって呼び出されます。_session.on('message')などのイベントを登録するために使用されます。BaseInstrumentationバージョンでは、デフォルトでon_message用のフックが追加されます。write_message(message) - JSONライクなメッセージをdictとして受け取り、それをsqliteデータベースに書き込み、後で出力できるように保存します。Winstrumentシェルは次のコマンドを提供します:
list - 利用可能なモジュールと読み込まれたモジュールをすべて表示しますload <modulename>/use <modulename> - 指定された名前のモジュールを有効にしますunload <modulename> - 指定された名前のモジュールを無効にしますset [setting [value]] - 引数なしで、すべての設定とその値を表示します。引数が1つの場合は、settingの値を表示します。引数が2つの場合は、settingをvalueに設定します。設定は複数回の実行にわたって保持されます。show [modulename [format]] - 指定されたformatでmodulenameから保存された入力を表示します。引数なしで実行すると、フォーマッタの一覧が表示されます。info <modulename> - 指定された名前のモジュールの説明を出力します。run - インストルメンテーションを開始します。これは主にWindowsの新規インストールで発生するようです。Fridaのsetup.pyは、https://files.pythonhosted.org から.eggファイルを取得しようとします。場合によっては、そのドメインのSSL証明書が検証されないため、これが失敗します。これは、WindowsがルートCAを読み込む方法の副作用のようです。WindowsはデフォルトのインストールではすべてのルートCAを同梱していないようで、Webサイトが訪問されたときに必要に応じてルートCAを取得することを好みます。その結果、files.pythonhosted.orgのSSL証明書に署名したルートCAがシステムのトラストストアにない可能性があります。
この問題を解決するには、EdgeまたはChromeで https://files.pythonhosted.org に手動でアクセスして、WindowsにルートCAをトラストストアに追加させてから、もう一度pip installを試してください。
Firefoxでページにアクセスしても機能しないことに注意してください。Firefoxはシステムストアではなく独自のトラストストアを使用するためです。
WinstrumentはGPLv3の下でライセンスされています。詳細については、LICENSEファイルを参照してください。
post_load(self) - スクリプトがターゲットプロセス内に読み込まれた後にBaseInstrumentation.load_scriptによって呼び出されます。これは、例えば、スクリプトによってエクスポートされたrpcメソッドを呼び出すために使用できます。get_output(self) - ターゲットがデタッチされたときにメインスクリプトによって呼び出されます。このメソッドは、各エントリが1つのMoudleMessageオブジェクト(data/module_message.pyから)であるリストを返す必要があります。通常はオーバーライドする必要はありません。on_message(self,message,data) - 注入されたJSのsendによってトリガーされるfrida messageイベントを処理するためのコールバックon_finish(self) - ターゲットがデタッチされたときにメインスクリプトによって呼び出されるコールバック。必要なクリーンアップ操作をここで実行します。qquitexit