
Fuzzing de chamadas de sistema do OpenBSD amd64 usando TriforceAFL (ou seja, AFL e QEMU)
Esta é uma coleção de arquivos usados para realizar fuzzing de chamadas de sistema do OpenBSD amd64 usando o TriforceAFL (ou seja, AFL e QEMU). Para usá-lo, você precisará do TriforceAFL (https://github.com/nccgroup/TriforceAFL), da distribuição FlashRD 2.0 (http://www.nmedia.net/flashrd/), de uma máquina OpenBSD para compilar o driver e uma imagem de disco, e de uma máquina Linux como host para executar o fuzzer (outros hosts do fuzzer também podem funcionar; nós só executamos o TriforceAFL em um host Linux, especificamente Debian/Ubuntu).
Faremos tudo como root na máquina OpenBSD, pois esta máquina está sendo usada apenas para inicializar nosso ambiente. Se você já tem uma máquina OpenBSD, sinta-se à vontade para fazer menos disso como root. Se você é um usuário experiente de OpenBSD, muito disso será excessivamente detalhado. De qualquer forma, vamos em frente!
Na 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
Em seguida, você precisará baixar os fontes do OpenBSD e os fontes do kernel e depois descompactá-los:
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 você já tiver um CD de instalação, não é necessário baixar os seguintes arquivos (pois eles estarão em $CDMOUNT/5.9/amd64/*.tgz). Você só precisará definir $DISTDIR apropriadamente. Caso contrário...
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=~
Agora temos as dependências necessárias instaladas e podemos começar a compilar as coisas.
Entre no diretório TriforceOpenBSDFuzzer. Existem diretórios separados contendo os arquivos do OpenBSD (targ) e os arquivos do host do fuzzer (fuzzHost).
Em um host OpenBSD, entre no diretório targ e execute make. Você também deve gerar os arquivos de entrada a partir deste diretório
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
Em seguida, você precisará criar uma imagem de disco com o driver, usando a distribuição FlashRD (http://www.nmedia.net/flashrd/). Em um host OpenBSD (com os fontes em /usr/src e os fontes do kernel em /usr/src/sys da seção anterior), agora faremos várias coisas:
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 ..
Agora você pode criar uma imagem executando estes comandos:
cp $FUZZER/targ/driver obsd/bin/driver
./flashrd obsd
mv flashimg* $FUZZER/flashimg.bin
mv bsd.gdb $FUZZER/bsd.gdb
Salve uma cópia de flashimg.bin e bsd.gdb. Você precisará deles no host do fuzzer.
Você pode querer criar uma segunda imagem para depuração que permita executar um shell interativo. Edite obsd/etc/rc, substitua /bin/driver -v por /bin/sh -i e crie uma segunda imagem. Então salvaremos uma cópia de flashimg-sh.bin e bsd-sh.gdb para depois.
./flashrd obsd
mv flashimg* $FUZZER/flashimg-sh.bin
mv bsd.gdb $FUZZER/bsd-sh.gdb
Agora podemos sair da máquina OpenBSD e retornar ao nosso host de fuzzing (certifique-se de copiar $FUZZER para fora, para que possamos usá-lo no host de fuzzing).
Executamos o fuzzer em um host Linux (deve funcionar em qualquer host onde o TriforceAFL compile e execute, mas YMMV, especialmente em um host não Linux). No host do fuzzer, instale o TriforceAFL em ../TriforceAFL. Copie os arquivos flashimg*.bin e bsd*.gdb para o diretório fuzzhost e descompacte as entradas no diretório 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
Agora estamos prontos para fuzzar! Entre no diretório fuzzHost e inicie o fuzzer com ./runFuzz -M M0.
Observe que o script runFuzz espera um nome de master ou slave, pois ele sempre executa no modo master/slave. Consulte o script runFuzz para obter mais informações de uso.
Para reproduzir casos de teste (como crashes), no host do fuzzer execute:
./runTest inputs/ex1
./runTest outputs/crashes/id*
Você também pode executar o driver fora do ambiente emulado com a opção -t, com registro verboso com -vv e sem realmente realizar as chamadas de sistema com -x. Por exemplo, no host OpenBSD execute:
./driver -tvvx < inputs/ex1
ktrace ./driver -t < inputs/ex1
Às vezes é útil poder inicializar o kernel e executar testes interativamente. Você pode executar ./runSh para inicializar em um shell interativo.
Você provavelmente vai querer adicionar arquivos adicionais (como casos de teste) ao arquivo flashimg-sh.bin para testes. Para isso, no host OpenBSD, copie os arquivos adicionais para flashrd-2.0/obsd/root e reconstrua a imagem flash. Transfira os arquivos de volta para o seu host do fuzzer e execute runSh novamente. Você encontrará os arquivos adicionais no diretório /root. Você também pode adicionar arquivos à imagem flash após criá-la, como root no host OpenBSD:
vnconfig vnd0 ./flashimg.bin
mount /dev/vnd0a /mnt
cp file /mnt
umount /mnt
vnconfig -u vnd0
Os arquivos adicionados aqui aparecerão em /flash quando a imagem for inicializada
Os patches aplicados anteriormente à distribuição flashrd ativarão a depuração e desativarão a otimização ao compilar o kernel. Isso torna a depuração muito mais fácil.
Para depurar o kernel a partir do fuzzHost, faça uma cópia de /usr/src/sys do seu host OpenBSD e copie bsd-sh.gdb para sys/x/x/x/x. Em uma janela, execute ./runSh e, depois que o sistema inicializar, execute
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