
Questo fuzzer sperimentale è destinato al fuzzing in-memory delle API.
v1.4 Copyright (C) 2020 Andrea Fioraldi [email protected]
Rilasciato sotto la Licenza Apache v2.0
Questo fuzzer sperimentale è pensato per essere usato per il fuzzing in-memory di API.
Il design è fortemente ispirato e basato su AFL/AFL++.
Al momento il mutatore è piuttosto semplice, solo gli stadi havoc e splice di AFL.
Ho testato solo gli esempi in tests/, questo è un progetto WIP ma è noto che funziona almeno su GNU/Linux x86_64 e Android x86_64.
Hai bisogno di Frida >= 12.8.1 per eseguirlo (pip3 install -U frida) e frida-tools per compilare l'harness.
La libreria fuzz deve essere importata in un harness personalizzato e poi compilata con frida-compile per generare l'agente che frida-fuzzer inietterà nell'app target.
La maggior parte della logica del fuzzer è nell'agente.
Un harness ha il seguente formato:
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 è obbligatorio. Se non specifichi fuzz.target_module, tutto il codice eseguito verrà instrumentato.
Puoi anche impostare fuzz.manual_loop_start = true per dire al fuzzer che chiamerai fuzz.fuzzing_loop() in un callback e quindi non deve chiamarlo per te (ad esempio per avviare il fuzzing quando viene cliccato un pulsante nell'app Android).
Il callback fuzz.init_callback può essere impostato per eseguire codice quando il fuzzer è pronto per iniziare. Vedi tests/test_java.js per un esempio.
fuzz.dictionary è un dizionario classico del fuzzer, un array in cui puoi aggiungere elementi (i tipi accettati sono Array, ArrayBuffer, Uint8Array, String) che vengono utilizzati come valori aggiuntivi nel mutatore. Vedi tests/test_libxml2.js per un esempio.
frida-fuzzer accetta i seguenti argomenti:
Se non specifichi la cartella di output, viene creata una cartella temporanea in /tmp.
Se non specifichi la cartella con il seme iniziale, viene utilizzato un seme non informato 0000 come seme di partenza.
Se stai facendo fuzzing di un'applicazione locale, potresti voler eseguire system-config prima di frida-fuzzer per regolare i parametri del tuo sistema e velocizzare le cose.
Eseguendo ./frida-fuzzer -spawn ./tests/test_linux64 vedrai qualcosa come la seguente schermata di stato sul tuo terminale:

Puoi anche facilmente aggiungere uno stage personalizzato in fuzz/fuzzer.js e aggiungerlo alla lista degli stage in fuzz/index.js.
Per personalizzare il fuzzer, modifica fuzz/config.js.
Le variabili che potresti voler cambiare sono MAP_SIZE (Se il codice che stai fuzzando è piccolo puoi ridurlo e guadagnare un po' di velocità), MAX_FILE (la dimensione massima dell'input generato) e QUEUE_CACHE_MAX_SIZE (aumenta la dimensione della cache della coda per più velocità, specialmente su Android).
Fuzziamo la libreria condivisa nativa nell'app Android di esempio in tests.
Assicurati di avere i permessi di root sul tuo dispositivo virtuale:
host$ adb root
Scarica il frida-server Android x86_64 dalla pagina di rilascio del repository e copialo sul dispositivo in /data/local/tmp (usa adb push).
Avvia una shell ed esegui il frida-server:
device# cd /data/local/tmp
device# ./frida-server
Ora installa l'app di test tests/app-debug.apk usando il drag & drop nella finestra dell'emulatore.
Poi, apri l'app.
Compila lo script dell'agente con frida-compile:
host$ frida-compile -x tests/test_ndk_x64.js -o fuzzer-agent.js
Apri l'app nell'emulatore.
Fuzza la funzione test_func della libreria libnative-lib.so fornita con l'app di test con il comando:
host$ ./frida-fuzzer -U -o output_folder/ com.example.ndktest1
I testcase interessanti e i crash vengono entrambi salvati in output_folder.
Buon divertimento.

Ehi community OSS, ci sono molti TODO se qualcuno vuole contribuire.
Se hai dubbi su una di queste funzionalità, sentiti libero di scrivermi in DM su Twitter.
Per proposte di funzionalità, c'è la sezione Issues.
| -i FOLDER | Cartella con i semi iniziali |
| -o FOLDER | Cartella di output con semi e crash intermedi |
| -U | Connetti via USB |
| -spawn | Avvia e collega invece di semplicemente collegare |
| -script SCRIPT | Nome del file script (predefinito è fuzzer-agent.js) |