一、 省流版
$ wget http://panda.moyix.net/~moyix/lava_corpus.tar.xz
$ xz -d lava_corpus.tar.xz # 此步将tar.xz格式解压缩成tar格式,不保留原压缩文件,如果要保留原压缩文件,加上-k
$ tar -xvf lava_corpus.tar
$ sudo apt install libacl1-dev # 安装libacl1-dev
# 进入到 lava_corpus/LAVA-M/base64/coreutils-8.24-lava-safe 文件夹下 ubuntu20以后会遇到的奇怪的bug
# 将lib文件夹下的所有 .c 文件中的IO_ftrylockfile替换为IO_EOF_SEEN
$ sed -i 's/IO_ftrylockfile/IO_EOF_SEEN/' lib/*.c
$ echo "#define _IO_IN_BACKUP 0x100" >> lib/stdio-impl.h
# 在 lava_corpus/LAVA-M/base64/coreutils-8.24-lava-safe/lib/mountlist.c 的头部加入: #include <sys/sysmacros.h>
# 进入到 lava_corpus/LAVA-M/base64 文件夹下
$ export CC=afl-gcc
$ export CXX=afl-g++
$ ./validate.sh # 运行脚本安装,这一步需要在普通用户权限下执行
$ afl-fuzz -m none -t 5000 -i fuzzer_input/ -o outputs coreutils-8.24-lava-safe/lava-install/bin/base64 -d @@
二、详细版
https://www.jianshu.com/p/63e99530d744
https://www.jianshu.com/p/31a048ccb2ad
由于root模式下LAVA-M的自动化脚本不可用,最好在普通用户权限下运行,遇到权限不足的,切换到root修改文件的权限。
提前安装需要的包
$ sudo apt install libacl1-dev # 安装libacl1-dev
下载压缩包
$ wget http://panda.moyix.net/~moyix/lava_corpus.tar.xz
解压
# .tar.xz文件可以分两步解压缩
$ xz -d lava_corpus.tar.xz # 此步将tar.xz格式解压缩成tar格式,不保留原压缩文件,如果要保留原压缩文件,加上-k
$ tar -xvf lava_corpus.tar
此时如果直接进入到 lava_corpus/LAVA-M/base64/ 运行如下 ./validate.sh
命令,结果应该如下:
Building buggy base64...
Checking if buggy base64 succeeds on non-trigger input...
Success: base64 -d inputs/utmp.b64 returned 127
Validating bugs...
Validated 0 / 44 bugs
You can see validated.txt for the exit code of each buggy version.
于是我就将 validate.sh 中的命令拆开,一步一步执行,遇到了Ubuntu20上的一些奇怪bug。
$ ./configure --prefix=`pwd`/lava-install LIBS="-lacl" &> /dev/null
$ make` # 这一步会报错,报错内容如下
lib/freadseek.c:68:3: error: #error "Please port gnulib freadseek.c to your platform! Look at the definition of getc, getc_unlocked on your system, then report this to bug-gnulib."
68 | #error "Please port gnulib freadseek.c to your platform! Look at the definition of getc, getc_unlocked on your system, then report this to bug-gnulib."
| ^~~~~
# 解决方法 将lib文件夹下的所有 .c 文件中的IO_ftrylockfile替换为IO_EOF_SEEN
$ sed -i 's/IO_ftrylockfile/IO_EOF_SEEN/' lib/*.c
$ make #再次make还会报错,报错内容如下
lib/fflush.c:43:20: error: '_IO_IN_BACKUP' undeclared (first use in this function)
43 | if (fp->_flags & _IO_IN_BACKUP)
# 解决方法
$ echo "#define _IO_IN_BACKUP 0x100" >> lib/stdio-impl.h
$ make #再次make还会报错,报错内容如下
.../lava_corpus/LAVA-M/base64/coreutils-8.24-lava-safe/lib/mountlist.c:526: undefined reference to `makedev'
collect2: error: ld returned 1 exit status
# 解决方法
# 在 lava_corpus/LAVA-M/base64/coreutils-8.24-lava-safe/lib/mountlist.c 的头部加入: #include <sys/sysmacros.h>
$ make # 这次成功
$ make install
编译安装部分就完成了。剩下的bug校验部分可以直接用validate.sh 文件中的后半部分内容,直接执行 validate.sh 应该也行。创建 my_validate.sh 文件,内容如下。
#!/bin/bash
PROG="base64"
PROGOPT="-d"
INPUT_PATTERN="inputs/utmp-fuzzed-%s.b64"
INPUT_CLEAN="inputs/utmp.b64"
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."
运行 ./my_validate.sh
命令, 结果如下
Checking if buggy base64 succeeds on non-trigger input...
Success: base64 -d inputs/utmp.b64 returned 0
Validating bugs...
Validated 44 / 44 bugs
You can see validated.txt for the exit code of each buggy version.
得到 validated.txt 文件,第一列为每个 bug 的编号。第二列为返回结果,值为0表示程序正常返回,即bug注入失败,非0表示注入成功。
至此就完成了base64的安装与检验,其余三个程序照此即可。