
Фаззинг системных вызовов OpenBSD amd64 с использованием TriforceAFL (т.е. AFL и QEMU)
Это набор файлов для фаззинга системных вызовов OpenBSD amd64 с использованием TriforceAFL (т.е. AFL и QEMU). Для использования вам понадобятся TriforceAFL (https://github.com/nccgroup/TriforceAFL), дистрибутив FlashRD 2.0 (http://www.nmedia.net/flashrd/), машина с OpenBSD для сборки драйвера и образа диска, а также машина с Linux в качестве хоста для запуска фаззера (другие хост-системы для фаззера тоже могут подойти, но мы запускали TriforceAFL только на Linux, а именно Debian/Ubuntu).
Мы будем выполнять всё от имени root на машине с OpenBSD, поскольку эта машина используется только для начальной настройки окружения. Если у вас уже есть машина с OpenBSD, можете делать меньше операций от root. Если вы опытный пользователь OpenBSD, многое здесь покажется излишне подробным. В любом случае, поехали!
На машине с 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
Далее нужно загрузить исходники OpenBSD и исходники ядра, а затем распаковать их:
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;
Если у вас уже есть установочный CD, следующие файлы скачивать не нужно (они находятся в $CDMOUNT/5.9/amd64/*.tgz). Вам лишь нужно будет задать $DISTDIR соответствующим образом. В противном случае...
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=~
Теперь необходимые зависимости установлены, и можно приступать к сборке.
Перейдите в каталог TriforceOpenBSDFuzzer. В нём есть отдельные каталоги с файлами для OpenBSD (targ) и файлами для хост-системы фаззера (fuzzHost).
На машине с OpenBSD перейдите в каталог targ и выполните make.
Также стоит собрать входные файлы из этого каталога:
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
Далее нужно создать образ диска с драйвером, используя дистрибутив FlashRD (http://www.nmedia.net/flashrd/). На машине с OpenBSD (с исходниками в /usr/src и исходниками ядра в /usr/src/sys из предыдущего раздела) мы сделаем следующее:
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 ..
Теперь можно создать образ, выполнив следующие команды:
cp $FUZZER/targ/driver obsd/bin/driver
./flashrd obsd
mv flashimg* $FUZZER/flashimg.bin
mv bsd.gdb $FUZZER/bsd.gdb
Сохраните копии flashimg.bin и bsd.gdb. Они понадобятся вам на хост-системе фаззера.
Возможно, вы захотите создать второй образ для отладки, который позволяет запустить интерактивную оболочку. Отредактируйте obsd/etc/rc и замените /bin/driver -v на /bin/sh -i, затем создайте второй образ. Позже мы сохраним копии flashimg-sh.bin и bsd-sh.gdb.
./flashrd obsd
mv flashimg* $FUZZER/flashimg-sh.bin
mv bsd.gdb $FUZZER/bsd-sh.gdb
Теперь можно покинуть машину с OpenBSD и вернуться к хост-системе фаззера (не забудьте скопировать $FUZZER, чтобы использовать его на хост-системе).
Мы запускаем фаззер на Linux-хосте (он должен работать на любой системе, где собирается и запускается TriforceAFL, но результат может отличаться, особенно не на Linux). На хост-системе установите TriforceAFL в ../TriforceAFL. Скопируйте flashimg*.bin и bsd*.gdb в каталог fuzzhost и распакуйте входные данные в каталог 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
Теперь мы готовы к фаззингу! Перейдите в каталог fuzzHost и запустите фаззер командой ./runFuzz -M M0.
Обратите внимание, что сценарий runFuzz ожидает имя мастера или слейва, поскольку он всегда работает в режиме master/slave. Дополнительную информацию об использовании см. в сценарии runFuzz.
Для воспроизведения тестовых случаев (например, сбоев) на хост-системе фаззера выполните:
./runTest inputs/ex1
./runTest outputs/crashes/id*
Вы также можете запустить драйвер вне эмулируемого окружения с опцией -t, с подробным журналированием с помощью -vv и без фактического выполнения системных вызовов с помощью -x. Например, на машине с OpenBSD выполните:
./driver -tvvx < inputs/ex1
ktrace ./driver -t < inputs/ex1
Иногда бывает полезно загрузить ядро и интерактивно запускать тесты. Вы можете выполнить ./runSh, чтобы загрузиться в интерактивную оболочку.
Вероятно, вы захотите добавить дополнительные файлы (например, тестовые случаи) в файл flashimg-sh.bin для тестирования. Для этого на машине с OpenBSD скопируйте дополнительные файлы в flashrd-2.0/obsd/root и пересоберите flash-образ. Перенесите файлы обратно на хост-систему фаззера и снова выполните runSh. Дополнительные файлы вы найдёте в каталоге /root. Вы также можете добавлять файлы в flash-образ после его создания, будучи root на машине с OpenBSD:
vnconfig vnd0 ./flashimg.bin
mount /dev/vnd0a /mnt
cp file /mnt
umount /mnt
vnconfig -u vnd0
Файлы, добавленные таким образом, появятся в /flash при загрузке образа.
Патчи, применённые ранее к дистрибутиву flashrd, включают отладку и отключают оптимизацию при сборке ядра. Это значительно упрощает отладку.
Чтобы отлаживать ядро с хост-системы fuzzHost, сделайте копию /usr/src/sys с вашей машины OpenBSD и скопируйте bsd-sh.gdb в sys/x/x/x/x. В одном окне выполните ./runSh, а после загрузки системы выполните:
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