
Fuzzing delle system call di OpenBSD amd64 tramite TriforceAFL (cioè AFL e QEMU)
Questa è una raccolta di file utilizzata per eseguire il fuzzing delle system call su OpenBSD amd64 usando TriforceAFL (cioè AFL e QEMU). Per usarla avrai bisogno di TriforceAFL (https://github.com/nccgroup/TriforceAFL), della distribuzione FlashRD 2.0 (http://www.nmedia.net/flashrd/), di una macchina OpenBSD per compilare il driver e un'immagine disco, e di una macchina Linux come host per eseguire il fuzzer (altri host per il fuzzer potrebbero funzionare, ma abbiamo eseguito TriforceAFL solo da un host Linux, in particolare Debian/Ubuntu).
Faremo tutto come root sulla macchina OpenBSD, poiché questa macchina viene usata solo per preparare il nostro ambiente. Se hai già una macchina OpenBSD, sentiti libero di fare meno di queste operazioni come root. Se sei un utente OpenBSD esperto, molto di questo sarà fin troppo dettagliato. Comunque, andiamo avanti!
Sulla macchina OpenBSD:
export PKG_PATH=http://mirrors.sonic.net/pub/OpenBSD/$(uname -r)/packages/$(uname -m)/
pkg_add git
pkg_add python # pick python 2.7
Quindi dovrai scaricare i sorgenti di OpenBSD e i sorgenti del kernel, e poi decomprimerli:
cd ~
ftp http://mirrors.sonic.net/pub/OpenBSD/5.9/src.tar.gz
ftp http://mirrors.sonic.net/pub/OpenBSD/5.9/sys.tar.gz
cd /usr/src; tar -xzpf $HOME/src.tar.gz; tar -xzpf $HOME/sys.tar.gz;
Se hai già un CD di installazione, non è necessario scaricare i seguenti file (dato che si troveranno in $CDMOUNT/5.9/amd64/*.tgz). Dovrai solo impostare $DISTDIR di conseguenza. Altrimenti...
cd ~
ftp http://mirrors.sonic.net/pub/OpenBSD/5.9/amd64/base59.tgz
ftp http://mirrors.sonic.net/pub/OpenBSD/5.9/amd64/man59.tgz
ftp http://mirrors.sonic.net/pub/OpenBSD/5.9/amd64/comp59.tgz
ftp http://mirrors.sonic.net/pub/OpenBSD/5.9/amd64/game59.tgz
export DISTDIR=~
Ora abbiamo installato le dipendenze necessarie e possiamo iniziare a compilare.
Entra nella directory TriforceOpenBSDFuzzer. Ci sono directory separate che contengono i file OpenBSD (targ) e i file per l'host del fuzzer (fuzzHost).
Su un host OpenBSD, entra nella directory targ ed esegui make.
Dovresti anche generare i file di input da questa directory
mkdir inputs
./gen.py # build simple tests
./genTempl.py templ.txt # build most syscall tests
./gen2.py # build complex syscall tests
tar -czf ../inputs.tgz inputs
Successivamente dovrai creare un'immagine disco con il driver, utilizzando la distribuzione FlashRD (http://www.nmedia.net/flashrd/). Su un host OpenBSD (con i sorgenti in /usr/src e i sorgenti del kernel in /usr/src/sys come nella sezione precedente), faremo ora diverse cose:
cd ~ #make sure this is on your /home parition, you will need significant disk space for this
ftp http://www.nmedia.net/flashrd/flashrd-2.0.tar.gz
tar xzf flashrd-2.0.tar.gz
cd flashrd-2.0
patch -p1 < $FUZZER/image-diff.txt #set $FUZZER to where you cloned TriforceOpenBSDFuzzer
mkdir obsd
cd obsd
tar xzpf $DISTDIR/base59.tgz
tar xzpf $DISTDIR/man59.tgz
tar xzpf $DISTDIR/comp59.tgz
tar xzpf $DISTDIR/game59.tgz
tar xzpf /var/sysmerge/etc.tgz
cp $FUZZER/image-etc-rc etc/rc
cp $FUZZER/targ/inputs/ex1 root/ex1
cd ..
Ora puoi creare un'immagine eseguendo questi comandi:
cp $FUZZER/targ/driver obsd/bin/driver
./flashrd obsd
mv flashimg* $FUZZER/flashimg.bin
mv bsd.gdb $FUZZER/bsd.gdb
Salva una copia di flashimg.bin e bsd.gdb. Ti serviranno sull'host del fuzzer.
Potresti voler creare una seconda immagine per il debug che ti permetta di eseguire una shell interattiva. Modifica obsd/etc/rc e sostituisci /bin/driver -v con /bin/sh -i, poi crea una seconda immagine. Quindi salveremo una copia di flashimg-sh.bin e bsd-sh.gdb per dopo.
./flashrd obsd
mv flashimg* $FUZZER/flashimg-sh.bin
mv bsd.gdb $FUZZER/bsd-sh.gdb
Ora possiamo lasciare la macchina OpenBSD e tornare al nostro host di fuzzing (assicurati di copiare $FUZZER, così possiamo usarlo sull'host di fuzzing).
Eseguiamo il fuzzer su un host Linux (dovrebbe funzionare su qualsiasi host dove TriforceAFL compila ed esegue, ma i risultati possono variare, specialmente su un host non Linux). Sull'host del fuzzer, installa TriforceAFL in ../TriforceAFL. Copia i file flashimg*.bin e bsd*.gdb nella directory fuzzhost e decomprimi gli input nella directory fuzzHost:
cd TriforceOpenBSDFuzzer # this should now have the files we made on the BSD host in it
cp flashimg* fuzzHost/
cp bsd* fuzzHost/
cd fuzzhost
tar xzf ../inputs.tgz
Ora siamo pronti a fuzzare! Entra nella directory fuzzHost e avvia il fuzzer con ./runFuzz -M M0.
Nota che lo script runFuzz si aspetta un nome master o slave, poiché esegue sempre in modalità master/slave. Consulta lo script runFuzz per maggiori informazioni sull'uso.
Per riprodurre i casi di test (come i crash), sull'host del fuzzer esegui:
./runTest inputs/ex1
./runTest outputs/crashes/id*
Puoi anche eseguire il driver fuori dall'ambiente emulato con l'opzione -t, con log dettagliati con -vv e senza eseguire effettivamente le system call con -x. Ad esempio, sull'host OpenBSD esegui:
./driver -tvvx < inputs/ex1
ktrace ./driver -t < inputs/ex1
A volte è utile poter avviare il kernel ed eseguire test in modo interattivo. Puoi eseguire ./runSh per avviare una shell interattiva.
Probabilmente vorrai aggiungere file aggiuntivi (come casi di test) al file flashimg-sh.bin per i test. Per fare questo, sull'host OpenBSD copia i file aggiuntivi in flashrd-2.0/obsd/root e ricostruisci l'immagine flash. Trasferisci i file di nuovo al tuo host di fuzzing ed esegui di nuovo runSh. Troverai i file aggiuntivi nella directory /root. Puoi anche aggiungere file all'immagine flash dopo averla creata, come root sull'host OpenBSD:
vnconfig vnd0 ./flashimg.bin
mount /dev/vnd0a /mnt
cp file /mnt
umount /mnt
vnconfig -u vnd0
I file aggiunti qui appariranno in /flash quando l'immagine viene avviata
Le patch applicate in precedenza alla distribuzione flashrd abiliteranno il debug e disabiliteranno l'ottimizzazione durante la compilazione del kernel. Questo rende il debug molto più semplice.
Per eseguire il debug del kernel dal fuzzHost, fai una copia di /usr/src/sys dal tuo host OpenBSD e copia bsd-sh.gdb in sys/x/x/x/x. In una finestra esegui ./runSh e, dopo che il sistema è stato avviato, esegui
cd sys
mkdir -p x/x/x/x
cd x/x/x/x
cp $FUZZER/bsd-sh.gdb .
gdb -ex "target remote :1234" ./bsd-sh.gdb