
Fuzzer binario coverage-guided per Windows, macOS, Linux e Android
Copyright 2020 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Jackalope è un fuzzer personalizzabile, distribuito e guidato dalla copertura in grado di lavorare con binari black-box.
Sebbene esistano molti buoni fuzzer guidati dalla copertura che funzionano su target per cui è disponibile il codice sorgente, ce ne sono relativamente pochi che funzionano su binari black box, in particolare sui sistemi operativi Windows e macOS, e quelli che esistono sono principalmente basati su codebase non molto facili da personalizzare. Gli obiettivi iniziali di Jackalope sono:
Jackalope può essere utilizzato in modo autonomo, ma è più potente quando usato come libreria, dove gli utenti possono inserire componenti personalizzati che sostituirebbero il comportamento predefinito. Per impostazione predefinita, Jackalope viene fornito con:
Jackalope può essere eseguito in parallelo
-nthreads-start_server) e facendo connettere i fuzzer sulle macchine worker a questo server (flag da riga di comando -server). Il server raccoglie e distribuisce quindi campioni, crash e copertura tra i worker.Jackalope attualmente non include strategie di mutazione avanzate. Viene invece fornito con un insieme di mutatori generici, che funzioneranno per molti target, tuttavia gli utenti sono incoraggiati a scrivere mutatori e strategie di mutazione personalizzati in base ai target che desiderano sottoporre a fuzzing.
Attualmente, il fuzzing di binari black-box è supportato sui sistemi operativi Windows, macOS, Linux e Android.
Su Linux, Jackalope è anche in grado di funzionare con Sanitizer Coverage (è richiesto il codice sorgente del target). Questa modalità è documentata in un documento separato.
Prerequisito: Python 3
Apri un terminale e configura il tuo ambiente di build se necessario. Su Windows, invece di aprire un prompt dei comandi generico, dovrai aprire il prompt dei comandi di Visual Studio per la piattaforma per cui stai compilando, oppure eseguire vcvars64.bat / vcvars32.bat.
Naviga nella directory contenente il codice sorgente.
Esegui i seguenti comandi:
cd Jackalope
git clone --recurse-submodules [email protected]:googleprojectzero/TinyInst.git
(alternately: git clone --recurse-submodules https://github.com/googleprojectzero/TinyInst.git)
mkdir build
cd build
cmake <generator arguments> ..
cmake --build . --config Release
Gli argomenti del generatore dipendono dal tuo ambiente. Su macOS vorrai usare -G Xcode, mentre ad esempio su Windows con Visual Studio 2019 e per una build a 64 bit useresti -G "Visual Studio 16 2019" -A x64. Su Linux non sono richiesti argomenti del generatore. Quando si esegue la cross-compilazione per Android sono necessari argomenti cmake aggiuntivi, gli stessi descritti nelle istruzioni di build di TinyInst per Android. Se stai eseguendo il fuzzing di Android su una VM che supporta la memoria condivisa tramite /dev/shm, -DANDROID_TARGET=VM abilita la consegna dei campioni tramite memoria condivisa.
Per compilare per l'esecuzione su binari arm64e su macOS, vedi qui.
Ricevi l'errore No CMAKE_C_COMPILER could be found su macOS? Prova ad aggiornare cmake. Assicurati inoltre che Xcode sia installato e che tu lo abbia eseguito almeno una volta (installa alcuni componenti alla prima esecuzione).
Utilizzo:
./fuzzer <fuzzer arguments> <instrumentation and other components arguments> -- <target command line>
Sono supportati i seguenti argomenti da riga di comando:
-in - Directory di input (directory contenente il set di campioni iniziale). Se la directory di input è "-", il fuzzer tenta di ripristinare la sessione precedente (come usare il flag -restore).
-out - Directory di output
-t - Timeout del campione in ms
-t1 - Timeout per l'inizializzazione del target (ad esempio prima di raggiungere il metodo target se definito). Il valore predefinito è il timeout del campione.
-nthreads - Numero di thread del fuzzer. Il valore predefinito è 1.
-delivery <file|shmem> - Meccanismo di consegna dei campioni da usare. Se file, ogni campione viene scritto come file e "@@" negli argomenti del target viene sostituito con un percorso al file. Se shmem, il fuzzer crea invece memoria condivisa e sostituisce "@@" negli argomenti del target con il nome della memoria condivisa. In questo caso è responsabilità del target aprire la memoria condivisa ed estrarre il campione. Il valore predefinito è file.
-file_extension - Quando si usa la consegna dei campioni tramite file, aggiunge l'estensione specificata al nome del file. Utile se il target si aspetta che i file di input abbiano una certa estensione.
-restore o -resume - Ripristina e riprende una sessione di fuzzing precedente. Sia il processo fuzzer che quello server supportano il ripristino.
-server - Specifica il server di copertura da usare.
-start_server - Esegue un processo server invece di un processo di fuzzing.
-crash_retry - Numero di tentativi per riprodurre un crash. Il valore predefinito è 10. I crash che non si riproducono entro questo numero di tentativi o che non si riproducono quando eseguiti senza strumentazione vengono contrassegnati come flaky.
-coverage_retry - Numero di tentativi per riprodurre una nuova copertura. La copertura che non può essere riprodotta in modo affidabile entro questo numero di tentativi è considerata flaky. I campioni che contengono solo copertura flaky non vengono salvati.
-clean_target_on_coverage - Riavvia il target quando si riproduce la copertura. Il valore predefinito è true.
-minimize_samples - Tenta di minimizzare i nuovi campioni prima di salvarli nel corpus. Il valore predefinito è true.
-iterations_per_round - Numero di volte in cui mutare ed eseguire un campione dal corpus prima di passare al campione successivo. Il valore predefinito è 1000. Potresti considerare di diminuire questo valore per target molto lenti.
-deterministic_mutations - Usa mutazioni deterministiche in aggiunta a quelle non deterministiche. Il valore predefinito è true a meno che non venga usato il flag -server.