0x10 AFL简介
模糊测试(Fuzzing)在安全界广为流传,被用来进行漏洞挖掘。通过向目标系统提供非预期的输入并监视异常记过来发现软件的漏洞。
0x11 AFL
AFL(American Fuzzy Lop)是由安全研究员Michał Zalewski(@lcamtuf)开发的一款基于覆盖引导(Coverage-guided)的模糊测试工具,它通过记录输入样本的代码覆盖率,从而调整输入样本以提高覆盖率,增加发现漏洞的概率。其工作流程大致如下:
- 从源码编译程序时进行插桩,以记录代码覆盖率(Code Coverage);
- 选择一些输入文件,作为初始测试集加入输入队列(queue);
- 将队列中的文件按一定的策略进行“突变”;
- 如果经过变异文件更新了覆盖范围,则将其保留添加到队列中;
- 上述过程会一直循环进行,期间触发了crash的文件会被记录下来。
AFL同时支持两种Fuzz模式:
- 有源码模式
- 无源码模式(afl-qemu)
有源码的方式依赖于对源码的重新编译,从而进行插桩,通过类似 afl-gcc -fno-stack-protector -z execstack vuln1.c -o vuln1
的命令(-fno-stack-protector
该选项会禁止stack canary
保护
-z execstack
允许堆栈可执行),对代码重新编译,就可以使用如下命令进行fuzz测试了。
afl-fuzz -i ./testcases/ -o ./results/ ./vuln1
AFL的无源码模式的fuzz依赖于qemu虚拟化。使用apt方式安装的afl没有afl-qemu-trace(不支持使用QEMU模式),所以我们需要下载afl的源码自己编译。
AFL的安装并不难,但是其中会遇到很多问题,需要耐心排查。笔者先后在 ubuntu16.0.4、ubuntu18.0.4、Kali
以及fedora
上安装了AFL及其qemu模式,从分析构建脚本出发,解决了其中的很多问题。(目前只有Debian系列的Linux发行版对AFL的支持较为友好)。
0x12 AFLplusplus
推荐使用 AFLplusplus。该分支版本最初由Michal“ lcamtuf” Zalewski开发。自afl官方发布版以来进行了许多改进(自2017年11月以来未进行任何功能改进)。
项目地址 https://github.com/vanhauser-thc/AFLplusplus.git
afl ++除其他更改外,还具有更高的llvm_mode性能,支持llvm最高版本11,QEMU 3.1,更快的速度和QEMU的崩溃修复,更好的支持* BSD和Android系统等等。
此外,还集成了诸多功能和修补程序(懒得翻译了,将就着看吧):
- AFLfast’s power schedules by Marcel Böhme: https://github.com/mboehme/aflfast
- The new excellent MOpt mutator: https://github.com/puppet-meteor/MOpt-AFL
- InsTrim, a very effective CFG llvm_mode instrumentation implementation for large targets: https://github.com/csienslab/instrim
- C. Holler’s afl-fuzz Python mutator module and llvm_mode whitelist support: https://github.com/choller/afl
- Custom mutator by a library (instead of Python) by kyakdan
- unicorn_mode which allows fuzzing of binaries from completely different platforms (integration provided by domenukk)
- laf-intel or CompCov support for llvm_mode, qemu_mode and unicorn_mode
- NeverZero patch for afl-gcc, llvm_mode, qemu_mode and unicorn_mode which prevents a wrapping map value to zero, increases coverage
- Persistent mode and deferred forkserver for qemu_mode
- Win32 PE binary-only fuzzing with QEMU and Wine
- Radamsa mutator (enable with -R to add or -RR to run it exclusivly).
- qbdi_mode: fuzz android native libraries via QBDI framework
- The new CmpLog instrumentation for LLVM and QEMU inspired by Redqueen
补丁文件中包含了更多功能
Feature/Instrumentation | afl-gcc | llvm_mode | gcc_plugin | qemu_mode | unicorn_mode |
---|---|---|---|---|---|
NeverZero | x | x(1) | (2) | x | x |
Persistent mode | x | x | x86[_64]/arm[64] | x | |
laf-intel / CompCov | x | x86[_64]/arm[64] | x86[_64]/arm | ||
CmpLog | x x86[_64]/arm[64] | ||||
Whitelist | x | x | (x)(3) | ||
InsTrim | x |
下载完成之后,输入make distrib
以及 sudo make install
即可安装。但是在这期间可能会出现很多问题,多数是依赖的问题。
0x20 深入分析AFL安装中出现的问题
如果你下载的是标准的 afl 或者 afl-unicorn,一般的安装过程是
cd /path/to/afl-unicorn
make # 编译 afl
sudo make install
cd unicorn_mode # 如果你想安装qemu,就去qemu-mode文件夹下运行相应的脚本
sudo ./build_unicorn_support.sh
而对于AFLplusplus,一般的安装过程是,首先下载AFLplusplus
git clone https://github.com/vanhauser-thc/AFLplusplus.git
然后进入到该目录,并编译即可
make distrib
sudo make install
接下来,你可能会遇到如下问题,一般而言,安装 qemu / unicorn模式(如果只是安装afl本身,是不会出现问题的),提示python、automake、bison等依赖库未安装,使用 apt-get install
这样的命令即可。但是也会有很多意外情况,以下重点讲解根据提示信息,直接安装仍然无效的情况。
0x21 Ubuntu16.04 32位系统(其它系统也会遇到如下问题)
1.安装软件包,提示没有libtool库
libtool 是一个通用库支持脚本(/usr/bin/libtool),将使用动态库的复杂性隐藏在统一、可移植的接口中。可以在不同平台上创建并调用动态库,我们可以认为libtool是gcc的一个抽象,也就是说,它包装了gcc或者其他的任何编译器,用户无需知道细节, 只要告诉libtool说我需要要编译哪些库即可。
sudo apt-get install libtool-bin
使用上述命令安装即可,这里需要注意的是,要安装libtool-bin,而不是libtool,不然会报错。
2.安装软件包,提示找不到glib2
通过查看qemu_mode/build_qemu_support.sh
源码,发现其需要 /usr/include/glib-2.0/ 或者 /usr/local/include/glib-2.0/有关库;
可以通过安装libgtk2.0-dev库解决问题
sudo apt-get install libgtk2.0-dev
如果还不行,找到glib-2.0.pc文件所在的文件夹,比如,/usr/lib/x86_64-linux-gnu/pkgconfig,将文件夹添加进PKG_CONFIG_PATH环境变量当中
export $PKG_CONFIG_PATH=/usr/lib/x86_64-linux-gnu/pkgconfig
3.继续重新安装,发现这次提示的不是缺少啥,而是编译文件出错
recipe for target ‘accel/tcg/cpu-exec.o’ failed。这是由于qemu针对的是上层路径文件更新,可以直接注释 qemu_mode/build_qemu_support.sh
该文件的patch
# patch -p1 <../patches/cpu-exec.diff || exit 1
4.仍然提示错误,提示link失败
这是由于上层patch对qemu的源码进行了修改,导致部分外部变量没有导入,注释掉相关patch即可
#patch -p1 <../patches/elfload.diff || exit 1
#patch -p1 <../patches/cpu-exec.diff || exit 1
#patch -p1 <../patches/syscall.diff || exit 1
注意:不同环境下,提示错误可能有所不同,根据提示的undefined,选择注释不同的patch
5.继续make distrib,afl-qemu-trace
失败
是由于指令位数跟qemu模拟的架构不兼容造成的,可以忽略此测试错误,也可以指定32位程序使用32位的架构
CPU_TARGET=i386 ./build_qemu_support.sh
0x22 对于Ubuntu18.04 64位系统,你还可能在一开始就遇到如下问题
1.提示cc并不在系统路径中
这里的cc就是指gcc,新版本Ubuntu默认没有安装gcc,因此,是提示该版本系统路径没有安装gcc,安装一下即可。同样的道理,可能也会提示没有安装python,这里是指python2,安装一下即可。
2.提示未安装 python-setuptools
如果我们直接使用 apt install
安装,会发现,仍然提示我们,没有安装setuptools,这里,查看build_unicorn_support.sh
的源码,看看到底需要什么。
从源码中,我们可以看到,程序编译时,真正需要的是easy_install,而setuptools就包含了easy_install,由于ubuntu中同时包含python2和python3,我们最好直接使用 pip install setuptools
的方式解决问题。
Tips:如果你安装的不是 aflplusplus,而是原版的 afl-unicorn,可能会一直报错,如下所示
After I run "sudo ./build_unicorn_support.sh" under unicorn_mode directory, you got this error:
[*] Performing basic sanity checks...
[-] Error: Python setup-tools not found. Run 'sudo apt-get install python-setuptools'.
原因:根据更改日志 easy_install
已从python-setuptools
包中删除,因此一种解决方案是,使用低版本的 pip;第二种解决方案如下
# 新建该命令
sudo gedit /usr/bin/easy_install
# 在该文件中写入如下命令
`python /usr/lib/python2.7/dist-packages/easy_install.py pip`
# 修改该文件的权限
sudo chmod 755 /usr/bin/easy_install
3.git下载某些资源过慢
可以尝试修改脚本的源码,这里举个例子,在 git unicornafl文件时,网速居然是0!如下图所示
为了提高效率,手动修改 unicorn_mode/build_unicorn_support.sh
文件,注释掉 rm -rvf uniconafl
以及 git clone https:...
(上图出现了失误,第二个框画错了,请无视)。手动下载 unicornafl,解压到下面的文件夹即可。
如果出现以下画面,则说明 make distrib
成功
最后输入 make install
,安装成功。输入 afl-fuzz -Q -m none -i in -o out test @@
即可对无源码的 test 二进制文件进行 fuzz 测试。
0x30 总结
下载 afl
,使用源码编译的方式安装,可能会出现很多问题,需要耐心排查。根据环境的不同,遇到的问题也不尽相同。本文重点讲解那些难以用常规方法解决的问题,并且分析了出现这些问题的原因,希望对大家能够有所帮助。
2020/2/14 首发
2020/2/21 更新:添加 qemu_mode 安装 libgtk2.0-dev库 仍然不行的问题
2020/3/05 更新:修正部分错误,更改标题