v1.4 著作権 (C) 2020 アンドレア フィオラルディ [email protected]
Apache License v2.0 に基づいてリリースされました
この実験的なファザーは、API のメモリ内ファジングに使用することを目的としています。
デザインは非常にインスピレーションを受けており、AFL/AFL++ に基づいています。
ATM ミューテーターは非常に単純で、AFL のハボック ステージとスプライス ステージだけです。
私は、tests/ の下にある例のみをテストしました。これは WIP プロジェクトですが、少なくとも GNU/Linux x86_64 および Android x86_64 で動作することが知られています。
これを実行するには Frida >= 12.8.1 ( pip3 install -U frida
)、ハーネスをコンパイルするには frida-tools が必要です。
fuzz
ライブラリをカスタム ハーネスにインポートし、 frida-compile
でコンパイルして、 frida-fuzzer
がターゲット アプリに挿入するエージェントを生成する必要があります。
ファザーのロジックの大部分はエージェント内にあります。
ハーネスの形式は次のとおりです。
var fuzz = require("./fuzz");var TARGET_MODULE = "test_linux64";var TARGET_FUNCTION = DebugSymbol.fromName("target_func").address;;var RET_TYPE = "void";var ARGS_TYPES = ['ポインタ', ' int'];var func_handle = 新しい NativeFunction(TARGET_FUNCTION, RET_TYPE, ARGS_TYPES, { トラップ: 'all' });fuzz.target_module = TARGET_MODULE;var payload_mem = Memory.alloc(fuzz.config.MAX_FILE);fuzz.fuzzer_test_one_input = function (/* Uint8Array */ payload) { Memory.writeByteArray (payload_mem、payload、payload.length); func_handle(payload_mem, payload.length);}
fuzz.fuzzer_test_one_input
は必須です。 fuzz.target_module
を指定しない場合、実行されるすべてのコードがインストルメントされます。
また、 fuzz.manual_loop_start = true
と設定すると、コールバックでfuzz.fuzzing_loop()
呼び出すため、ユーザーの代わりに呼び出してはいけないことをファザーに伝えることもできます (たとえば、Android アプリでボタンがクリックされたときにファジングを開始する場合など)。
コールバックfuzz.init_callback
ファザーを開始する準備ができたときにコードを実行するように設定できます。例については、 tests/test_java.js
を参照してください。
fuzz.dictionary
は古典的なファザー辞書で、ミューテーターの追加値として使用される項目 (受け入れられるタイプは Array、ArrayBuffer、Uint8Array、String) を追加できる配列です。例については、 tests/test_libxml2.js
を参照してください。
frida-fuzzer
次の引数を受け入れます。
-i フォルダー | 初期シードが含まれるフォルダー |
-o フォルダー | 中間シードとクラッシュを含む出力フォルダー |
-U | USBに接続する |
-スポーン | 単にアタッチするのではなく、スポーンしてアタッチする |
-script スクリプト | スクリプトファイル名 (デフォルトは fuzzer-agent.js) |
出力フォルダーを指定しない場合、/tmp の下に一時フォルダーが作成されます。初期シードを含むフォルダーを指定しない場合は、通知されていないシード0000
が開始シードとして使用されます。
ローカル アプリケーションをファジングしている場合は、システムのパラメータを調整して高速化するために、 frida-fuzzer
の前にsystem-config
実行するとよいでしょう。
./frida-fuzzer -spawn ./tests/test_linux64
を実行すると、ターミナルに次のようなステータス画面が表示されます。
また、 fuzz/fuzzer.js
にカスタム ステージを簡単に追加し、 fuzz/index.js
のステージ リストに追加することもできます。
ファザーをカスタマイズするには、 fuzz/config.js
を編集します。変更する必要がある可能性のある変数は、MAP_SIZE (ファジングしているコードが小さい場合は、コードを減らして速度を少し向上させることができます)、MAX_FILE (生成される入力の最大サイズ)、および QUEUE_CACHE_MAX_SIZE (キュー キャッシュ サイズを増やす) です。特に Android では速度が向上します)。
tests
のサンプル Android アプリのネイティブ共有ライブラリをファジングしてみましょう。
仮想デバイスに root があることを確認してください。
host$ adb root
リポジトリ リリース ページから Android x86_64 frida-server をダウンロードし、デバイスの /data/local/tmp にコピーします (adb Push を使用します)。
シェルを起動し、frida-server を実行します。
device# cd /data/local/tmp device# ./frida-server
次に、エミュレータ ウィンドウにドラッグ アンド ドロップして、テスト アプリtests/app-debug.apk
インストールします。
次に、アプリを開きます。
frida-compile を使用してエージェント スクリプトをコンパイルします。
host$ frida-compile -x tests/test_ndk_x64.js -o fuzzer-agent.js
エミュレータでアプリを開きます。
次のコマンドを使用して、テスト アプリに付属のlibnative-lib.so
ライブラリのtest_func
関数をファジングします。
host$ ./frida-fuzzer -U -o output_folder/ com.example.ndktest1
興味深いテストケースとクラッシュは両方とも、output_folder に保存されます。
楽しむ。
OSS コミュニティの皆さん、貢献したい人には TODO がたくさんあります。
Java コードのファジング (frida-java-bridge で追加の公開メソッドを待機しています。簡単に完了するはずです)
スプライスステージ (キュー内の 2 つのテストケースをマージし、それに大混乱を適用します)
辞書をサポート (したがって大混乱も修正)
種子の選択
arm64 用のインライン計装
パフォーマンススコアリング (AFL のスケジュールを調べる)
構造ミューテーター (JSON で記述された文法に基づいてバイトを変更)
CompareCoverage (ファジングの障害を回避するためのサブ命令プロファイリング)
frida-fuzzer を C で frida-core で書き直して、モバイルデバイス上ですべてのものを実行できるようにします
この機能について疑問がある場合は、お気軽に Twitter で私に DM してください。
機能の提案については、「問題」セクションがあります。