
Dieser experimentelle Fuzzer soll für das API-In-Memory-Fuzzing verwendet werden.
v1.4 Copyright (C) 2020 Andrea Fioraldi [email protected]
Veröffentlicht unter der Apache License v2.0
Dieser experimentelle Fuzzer ist für das In-Memory-Fuzzing von APIs gedacht.
Das Design ist stark von AFL/AFL++ inspiriert und basiert darauf.
Derzeit ist der Mutator recht einfach, nur die Havoc- und Splice-Stufen von AFL.
Ich habe nur die Beispiele unter tests/ getestet. Dies ist ein WIP-Projekt, aber es ist bekannt, dass es zumindest unter GNU/Linux x86_64 und Android x86_64 funktioniert.
Sie benötigen Frida >= 12.8.1, um dies auszuführen (pip3 install -U frida) und frida-tools, um die Harness zu kompilieren.
Die fuzz-Bibliothek muss in eine benutzerdefinierte Harness importiert und dann mit frida-compile kompiliert werden, um das Agenten-Skript zu erzeugen, das frida-fuzzer in die Ziel-App injiziert.
Der Großteil der Logik des Fuzzers befindet sich im Agenten.
Eine Harness hat das folgende Format:
var fuzz = require("./fuzz");
var TARGET_MODULE = "test_linux64";
var TARGET_FUNCTION = DebugSymbol.fromName("target_func").address;;
var RET_TYPE = "void";
var ARGS_TYPES = ['pointer', 'int'];
var func_handle = new NativeFunction(TARGET_FUNCTION, RET_TYPE, ARGS_TYPES, { traps: '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 ist obligatorisch. Wenn Sie fuzz.target_module nicht angeben, wird der gesamte ausgeführte Code instrumentiert.
Sie können auch fuzz.manual_loop_start = true setzen, um dem Fuzzer mitzuteilen, dass Sie fuzz.fuzzing_loop() in einem Callback aufrufen werden, sodass er ihn nicht für Sie aufrufen muss (z.B. um das Fuzzing zu starten, wenn in der Android-App eine Schaltfläche geklickt wird).
Der Callback fuzz.init_callback kann gesetzt werden, um Code auszuführen, wenn der Fuzzer bereit ist zu beginnen. Siehe tests/test_java.js für ein Beispiel.
fuzz.dictionary ist ein klassisches Fuzzer-Wörterbuch, ein Array, in das Sie Elemente hinzufügen können (akzeptierte Typen sind Array, ArrayBuffer, Uint8Array, String), die als zusätzliche Werte im Mutator verwendet werden. Siehe tests/test_libxml2.js für ein Beispiel.
frida-fuzzer akzeptiert die folgenden Argumente:
Wenn Sie keinen Ausgabeordner angeben, wird ein temporärer Ordner unter /tmp erstellt.
Wenn Sie keinen Ordner mit dem anfänglichen Seed angeben, wird ein uninformierter Seed 0000 als Startseed verwendet.
Wenn Sie eine lokale Anwendung fuzzen, sollten Sie vor frida-fuzzer das Kommando system-config ausführen, um die Parameter Ihres Systems anzupassen und die Dinge zu beschleunigen.
Wenn Sie ./frida-fuzzer -spawn ./tests/test_linux64 ausführen, sehen Sie auf Ihrem Terminal einen Statusbildschirm wie den folgenden:

Sie können auch ganz einfach eine benutzerdefinierte Stufe in fuzz/fuzzer.js hinzufügen und sie in fuzz/index.js zur Liste der Stufen hinzufügen.
Um den Fuzzer anzupassen, bearbeiten Sie fuzz/config.js.
Die Variablen, die Sie möglicherweise ändern möchten, sind MAP_SIZE (Wenn der Code, den Sie fuzzen, klein ist, können Sie ihn verkleinern und etwas Geschwindigkeit gewinnen), MAX_FILE (die maximale Größe der generierten Eingabe) und QUEUE_CACHE_MAX_SIZE (erhöhen Sie die Größe des Warteschlangen-Caches für mehr Geschwindigkeit, insbesondere auf Android).
Lassen Sie uns die native Shared Library in der Beispiel-Android-App in tests fuzzen.
Stellen Sie sicher, dass Sie Root-Zugriff auf Ihrem virtuellen Gerät haben:
host$ adb root
Laden Sie den Android x86_64 frida-server von der Release-Seite des Repos herunter und kopieren Sie ihn auf das Gerät unter /data/local/tmp (verwenden Sie adb push).
Starten Sie eine Shell und führen Sie den frida-server aus:
device# cd /data/local/tmp
device# ./frida-server
Installieren Sie nun die Test-App tests/app-debug.apk per Drag & Drop in das Emulatorfenster.
Öffnen Sie dann die App.
Kompilieren Sie das Agenten-Skript mit frida-compile:
host$ frida-compile -x tests/test_ndk_x64.js -o fuzzer-agent.js
Öffnen Sie die App im Emulator.
Fuzzen Sie die test_func-Funktion der libnative-lib.so-Bibliothek, die mit der Test-App ausgeliefert wird, mit dem folgenden Befehl:
host$ ./frida-fuzzer -U -o output_folder/ com.example.ndktest1
Interessante Testfälle und Abstürze werden beide im output_folder gespeichert.
Viel Spaß.

Hey OSS-Community, es gibt viele TODOs, falls jemand einen Beitrag leisten möchte.
Wenn Sie Zweifel zu einem dieser Features haben, können Sie mich gerne auf Twitter anschreiben.
Für Feature-Vorschläge gibt es den Issues-Bereich.
| -i ORDNER | Ordner mit anfänglichen Seeds |
| -o ORDNER | Ausgabeordner mit Zwischenseeds und Abstürzen |
| -U | Mit USB verbinden |
| -spawn | Spawnen und anhängen anstatt nur anhängen |
| -script SKRIPT | Skriptdateiname (Standard ist fuzzer-agent.js) |