- Jesse Hertz firstname.lastname@example.org
- Tim Newsham email@example.com
This is a collection of files used to perform system call fuzzing of OpenBSD amd64 using TriforceAFL (i.e. AFL and QEMU). To use it you will need TriforceAFL (https://github.com/nccgroup/TriforceAFL), the FlashRD 2.0 distribution (http://www.nmedia.net/flashrd/), an OpenBSD box to build the driver and a disk image, and a Linux box as host to run the fuzzer (other fuzzer hosts may work as well, we've only run TriforceAFL from a Linux host, specifically Debian/Ubuntu).
We'll be doing everything as root on the OpenBSD box, as this box is being used just to boostrap our environment. If you have an existing OpenBSD box, feel free to do less of this as root. If you're an experienced OpenBSD user, a lot of this will be overly verbose. Anyway, onwards!
On the OpenBSD box:
export PKG_PATH=http://mirrors.sonic.net/pub/OpenBSD/$(uname -r)/packages/$(uname -m)/ pkg_add git pkg_add python # pick python 2.7
Next you'll need to pull down the OpenBSD sources, and the kernel sources, and then unpack them:
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;
If you already have an install CD, no need to pull down the following files (as they'll be in $CDMOUNT/5.9/amd64/*.tgz). You'll only need to set $DISTDIR appropriately. Otherwise...
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=~
We now have the necessary dependencies installed, and can start building stuff.
Enter the TriforceOpenBSDFuzzer directory. There are separate directories containing the OpenBSD files (
the fuzzer host files (
Building Driver and Inputs
On an OpenBSD host, enter the
targ directory and run
You should also build input files from this 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
Building Disk Image
Next you will need to build a disk image with the driver, using the FlashRD distribution (http://www.nmedia.net/flashrd/). On an OpenBSD host (with sources in /usr/src and kernel sources in /usr/src/sys from the above section), we'll now do several things:
- extract flashrd-2.0
- patch flashrd
- create an obsd directory, and fill it with stuff!
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 ..
You can now create an image by running these commands :
cp $FUZZER/targ/driver obsd/bin/driver ./flashrd obsd mv flashimg* $FUZZER/flashimg.bin mv bsd.gdb $FUZZER/bsd.gdb
Save a copy of flashimg.bin and bsd.gdb. You will need them on the fuzzer host.
You may wish to create a second image for debugging that allows
you to run an interactive shell. Edit
/bin/driver -v with
/bin/sh -i and create a second image.
Then we'll save a copy of flashimg-sh.bin and bsd-sh.gdb for later.
./flashrd obsd mv flashimg* $FUZZER/flashimg-sh.bin mv bsd.gdb $FUZZER/bsd-sh.gdb
We can now leave the OpenBSD box, and return to our fuzz host (make sure to copy $FUZZER out, so we can use it on the fuzz host).
We run the fuzzer on a Linux host (it should work on any host
where TriforceAFL builds and runs, but YMMV, especially on a non-linux host).
On the fuzzer host, install TriforceAFL to ../TriforceAFL.
bsd*.gdb to the
and unpack the inputs into the fuzzHost directory:
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
Now we're ready to fuzz! Enter the
and start the fuzzer with
./runFuzz -M M0.
Note that the
runFuzz script expects a master or slave name, as
it always runs in master/slave mode. See the
runFuzz script for
more usage information.
To reproduce test cases (such as crashes), on the fuzzer host run:
./runTest inputs/ex1 ./runTest outputs/crashes/id*
You can also run the driver out of the emulated environment
-t option, with verbose logging with
and without actually performing the system calls with
For example, on the OpenBSD host run:
./driver -tvvx < inputs/ex1 ktrace ./driver -t < inputs/ex1
It is sometimes useful to be able to boot the kernel and interactively
run tests. You can run
./runSh to boot
into an interactive shell.
You will likely want to add additional files (such as test cases)
flashimg-sh.bin file for testing. To do this, on the
OpenBSD host copy the additional files to
and rebuild the flash image. Transfer the files back to your
fuzzer host and execute
runSh again. You will find the additional
files in the
/root directory. You can also add files to the flash
image after creating it, as root on the OpenBSD host:
vnconfig vnd0 ./flashimg.bin mount /dev/vnd0a /mnt cp file /mnt umount /mnt vnconfig -u vnd0
Files added here will appear in
/flash when the image is booted
The patches applied earlier to the flashrd distribution will enable debugging and disable optimization when building the kernel. This makes debugging much easier.
To debug the kernel from the fuzzHost, make a copy of /usr/src/sys
from your OpenBSD host, and copy
In one window run
./runSh and after the system has booted run
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