AFL学习记录(四)——使用 LAVA-M/BASE64 测试集进行表现测试

Posted on May 6, 2021

这个测试本来我应该在一个月前完成,但是由于各种各样的原因拖到了现在哈哈哈。

之前一直因为无法完成插桩编译,所以只能用 qemu 模式来整,这个模式就会慢很多了,我用了 6 个线程跑了两个多小时什么都没跑出来,遂放弃。今天灵光一闪,自己手动编译了一下,不知道为什么就完成了插桩编译。然后也发现了之前跑不出结果的原因——没加 -d 参数(哈哈哈也是很呆了)。这里简单记录一下测试过程。

插桩编译

这里我使用 Google 维护的 AFL 并使用 LLVM 模式进行测试。

首先安装 libacl

sudo apt-get install libacl1-dev

然后下载测试集 wget http://panda.moyix.net/~moyix/lava_corpus.tar.xz,然后解压

进入 lava_corpus/LAVA-M/base64/coreutils-8.24-lava-safe 目录,依次执行如下指令

CC=afl-clang-fast CXX=afl-clang-fast++ ./configure --prefix=`pwd`/lava-install LIBS="-lacl"

注意这里使用 pwd 可能会报错,如果报错手动换成当前目录路径就可以了。

然后 make

make -j $(nproc)

这里的 $(nproc) 是你的机器的线程数,多线程编译可以加快编译速度。

再安装

make install

在 make 和 make install 的过程中可能会出现各种依赖错误,仔细看报错信息都可以解决。

检测

编译好后可以使用在 lava_corpus/LAVA-M/base64/ 目录中的 validate.sh 检测编译出的程序是否被插入 bug,注意要先把该脚本中的编译代码注释掉,如下

#!/bin/bash

PROG="base64"
PROGOPT="-d"
INPUT_PATTERN="inputs/utmp-fuzzed-%s.b64"
INPUT_CLEAN="inputs/utmp.b64"

#echo "Building buggy ${PROG}..."
#
#cd coreutils-8.24-lava-safe
#make clean &> /dev/null
#./configure --prefix=`pwd`/lava-install LIBS="-lacl" &> /dev/null
#make -j $(nproc) &> /dev/null
#make install &> /dev/null
#cd ..

echo "Checking if buggy ${PROG} succeeds on non-trigger input..."
./coreutils-8.24-lava-safe/lava-install/bin/${PROG} ${PROGOPT} ${INPUT_CLEAN} &> /dev/null 
rv=$?
if [ $rv -lt 128 ]; then
    echo "Success: ${PROG} ${PROGOPT} ${INPUT_CLEAN} returned $rv"
else
    echo "ERROR: ${PROG} ${PROGOPT} ${INPUT_CLEAN} returned $rv"
fi

echo "Validating bugs..."
cat validated_bugs | while read line ; do
    INPUT_FUZZ=$(printf "$INPUT_PATTERN" $line)
    { ./coreutils-8.24-lava-safe/lava-install/bin/${PROG} ${PROGOPT} ${INPUT_FUZZ} ; } &> /dev/null
    echo $line $?
done > validated.txt

awk 'BEGIN {valid = 0} $2 > 128 { valid += 1 } END { print "Validated", valid, "/", NR, "bugs" }' validated.txt

echo "You can see validated.txt for the exit code of each buggy version."

我跑了一下发现只有 43 个 bug,少一个问题也不是很大。

fuzzing

然后用 afl-fuzz 测试就可以了。

afl-fuzz -i ./fuzzer_input -o fuzzer_output ./base64 -d @@

一定要注意这里的 -d,不写这个的话是基本上是跑不出来的(确定有的 bug 是在 -d 模式下的)。

结果

使用一个线程进行了一个多小时的测试,总共仅跑出了 5 个 unique crash,其中还有一个实际是重复的。最后发现了 1,774,792,804 四个漏洞。