
TriforceAFL(すなわちAFLとQEMU)を使用したOpenBSD amd64のシステムコールファジング
これは、TriforceAFL(すなわちAFLとQEMU)を使ってOpenBSD amd64のシステムコールファジングを実行するためのファイル群です。これを使用するには、TriforceAFL (https://github.com/nccgroup/TriforceAFL)、FlashRD 2.0ディストリビューション (http://www.nmedia.net/flashrd/)、ドライバとディスクイメージをビルドするためのOpenBSDマシン、そしてファザーを実行するホストとしてのLinuxマシンが必要です(他のファザーホストでも動作する可能性はありますが、私たちはLinuxホスト、具体的にはDebian/UbuntuでのみTriforceAFLを実行しています)。
このOpenBSDボックスは環境をブートストラップするためだけに使われるので、私たちはOpenBSDボックス上ではすべてrootとして実行します。既存の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 のコピーを保存してください。ファザーホスト上で必要になります。
デバッグ用に、対話型シェルを実行できる2つ目のイメージを作成するとよいでしょう。obsd/etc/rc を編集し、/bin/driver -v を /bin/sh -i に置き換えて、2つ目のイメージを作成します。その後、後で使うために 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ホストではうまくいかないかもしれません(YMMV))。ファザーホストで、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 スクリプトは常にマスター/スレーブモードで実行されるため、マスター名またはスレーブ名が必要です。詳しい使い方については 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 にコピーし、フラッシュイメージを再ビルドします。その後、ファイルをファザーホストに転送し、runSh を再度実行します。追加したファイルは /root ディレクトリにあります。また、イメージ作成後に OpenBSDホスト上でrootとしてファイルを追加することもできます:
vnconfig vnd0 ./flashimg.bin
mount /dev/vnd0a /mnt
cp file /mnt
umount /mnt
vnconfig -u vnd0
ここで追加されたファイルは、イメージ起動時に /flash に表示されます。
先ほどflashrdディストリビューションに適用したパッチにより、カーネルビルド時にデバッグが有効になり、最適化が無効になります。これによりデバッグがはるかに容易になります。
fuzzHostからカーネルをデバッグするには、OpenBSDホストから /usr/src/sys のコピーを作成し、bsd-sh.gdb を sys/x/x/x/x にコピーします。1つのウィンドウで ./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