
Fuzzing de llamadas al sistema de OpenBSD amd64 usando TriforceAFL (es decir, AFL y QEMU)
Esta es una colección de archivos utilizados para realizar fuzzing de llamadas al sistema en OpenBSD amd64 usando TriforceAFL (es decir, AFL y QEMU). Para usarlo necesitarás TriforceAFL (https://github.com/nccgroup/TriforceAFL), la distribución FlashRD 2.0 (http://www.nmedia.net/flashrd/), una máquina OpenBSD para compilar el driver y una imagen de disco, y una máquina Linux como host para ejecutar el fuzzer (otros hosts de fuzzing pueden funcionar también, pero solo hemos ejecutado TriforceAFL desde un host Linux, concretamente Debian/Ubuntu).
Lo haremos todo como root en la máquina OpenBSD, ya que esta máquina se usa solo para preparar nuestro entorno. Si ya tienes una máquina OpenBSD, no dudes en hacer menos de esto como root. Si eres un usuario experimentado de OpenBSD, gran parte de esto será excesivamente detallado. En fin, ¡adelante!
En la máquina 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
A continuación, necesitarás descargar las fuentes de OpenBSD y las fuentes del kernel, y luego descomprimirlas:
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;
Si ya tienes un CD de instalación, no es necesario descargar los siguientes archivos (ya que estarán en $CDMOUNT/5.9/amd64/*.tgz). Solo necesitarás establecer $DISTDIR adecuadamente. De lo contrario...
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=~
Ahora tenemos las dependencias necesarias instaladas y podemos empezar a compilar cosas.
Entra en el directorio TriforceOpenBSDFuzzer. Hay directorios separados que contienen los archivos de OpenBSD (targ) y los archivos del host del fuzzer (fuzzHost).
En un host OpenBSD, entra en el directorio targ y ejecuta make.
También deberías generar los archivos de entrada desde este directorio
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
A continuación, necesitarás crear una imagen de disco con el driver, usando la distribución FlashRD (http://www.nmedia.net/flashrd/). En un host OpenBSD (con las fuentes en /usr/src y las fuentes del kernel en /usr/src/sys de la sección anterior), haremos ahora varias cosas:
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 ..
Ahora puedes crear una imagen ejecutando estos comandos:
cp $FUZZER/targ/driver obsd/bin/driver
./flashrd obsd
mv flashimg* $FUZZER/flashimg.bin
mv bsd.gdb $FUZZER/bsd.gdb
Guarda una copia de flashimg.bin y bsd.gdb. Los necesitarás en el host del fuzzer.
Puede que quieras crear una segunda imagen para depurar que te permita ejecutar un shell interactivo. Edita obsd/etc/rc y reemplaza /bin/driver -v por /bin/sh -i, y crea una segunda imagen. Luego guardaremos una copia de flashimg-sh.bin y bsd-sh.gdb para más tarde.
./flashrd obsd
mv flashimg* $FUZZER/flashimg-sh.bin
mv bsd.gdb $FUZZER/bsd-sh.gdb
Ahora podemos dejar la máquina OpenBSD y volver a nuestro host de fuzzing (asegúrate de copiar $FUZZER para poder usarlo en el host de fuzzing).
Ejecutamos el fuzzer en un host Linux (debería funcionar en cualquier host donde TriforceAFL compile y se ejecute, pero los resultados pueden variar, especialmente en un host que no sea Linux).
En el host del fuzzer, instala TriforceAFL en ../TriforceAFL.
Copia flashimg*.bin y bsd*.gdb al directorio fuzzhost, y descomprime las entradas en el directorio 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
¡Ahora estamos listos para hacer fuzzing! Entra en el directorio fuzzHost y arranca el fuzzer con ./runFuzz -M M0.
Ten en cuenta que el script runFuzz espera un nombre de master o slave, ya que siempre se ejecuta en modo master/slave. Consulta el script runFuzz para más información sobre su uso.
Para reproducir casos de prueba (como los crashes), en el host del fuzzer ejecuta:
./runTest inputs/ex1
./runTest outputs/crashes/id*
También puedes ejecutar el driver fuera del entorno emulado con la opción -t, con registro verbose con -vv y sin realizar realmente las llamadas al sistema con -x. Por ejemplo, en el host OpenBSD ejecuta:
./driver -tvvx < inputs/ex1
ktrace ./driver -t < inputs/ex1
A veces es útil poder arrancar el kernel y ejecutar pruebas de forma interactiva. Puedes ejecutar ./runSh para arrancar un shell interactivo.
Probablemente quieras añadir archivos adicionales (como casos de prueba) al archivo flashimg-sh.bin para las pruebas. Para ello, en el host OpenBSD copia los archivos adicionales a flashrd-2.0/obsd/root y reconstruye la imagen flash. Transfiere los archivos de vuelta a tu host del fuzzer y ejecuta runSh de nuevo. Encontrarás los archivos adicionales en el directorio /root. También puedes añadir archivos a la imagen flash después de crearla, como root en el host OpenBSD:
vnconfig vnd0 ./flashimg.bin
mount /dev/vnd0a /mnt
cp file /mnt
umount /mnt
vnconfig -u vnd0
Los archivos añadidos aquí aparecerán en /flash cuando se arranque la imagen
Los parches aplicados anteriormente a la distribución flashrd habilitarán la depuración y desactivarán la optimización al compilar el kernel. Esto hace que la depuración sea mucho más sencilla.
Para depurar el kernel desde el fuzzHost, haz una copia de /usr/src/sys desde tu host OpenBSD y copia bsd-sh.gdb a sys/x/x/x/x. En una ventana ejecuta ./runSh y, después de que el sistema haya arrancado, ejecuta
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