一篇文章看不懂,如何使用AFL Fuzz Apache
2021-05-29

原文地址

intro

笔者发现了Apache数组越界漏洞 CVE-2017-7668,漏洞的详情写在了笔者的博客中。博客中介绍了如何使用AFL来测试httpd服务。
和Dominic先生交流之后,决定在这里再记录一下整个过程。
文中涉及,代码审计、honggfuzz使用、radamsa使用、AFL工具使用

Goal

偶然遇到AFL,尝试后发现AFL只能测试stdin的输入。对于来自网络的输入则无能为力。
于是我尝试对Apache进行测试,希望能找到测试Httpd Server端的办法
总体思路有二:1、对于Apache Command Line添加新的参数 2、使用AFL的持久化Fuzzing

Steup part 1

我的服务器是Debian GNU/Linux 8 64bit,它的内核是4.9.0-0.bpo.2-rt-amd64.
无须严格使用上述配置,能编译AFL就行。
在开始正式的编译源码、安装程序、fuzz测试之前,我建议您创建一个适合你的文件夹目录,来存放测试中使用的文件。
这里给大家介绍我的文件目录格式,仅作参考:

  • Victims – For the target programs that we are about to fuzz
  • Fuzzers – AFL, honggfuzz, radamsa, etc. go here
  • Testcases – The samples we are going to feed the fuzzer to throw against our Victim
  • Sessions – For storing the fuzzing sessions
  • Compilers – To store compilers such as clang-4.0 and binaries needed to compile

Compiling and Installing AFL

执行以下命令即可

sudo apt install build-essential
wget http://lcamtuf.coredump.cx/afl/releases/afl-latest.tgz
tar xzf afl-latest.tgz
cd afl*
make && sudo make install && echo-e "\n[+] AFL ready to fuzz at $(which afl-fuzz)"

编译之后,可以添加环境变量,来更方便的调用AFL

Compiling and installing Apache

首先下载Apache及其依赖。在本次案例中,我把apache放到了~/Fuzzing/Victims/apache_afl/目录下
在编译Apache之前,还需要安装Apache portable Runtime. APR和nghttp2

sudo apt install pkg-config
sudo apt install libssl-dev

Fuzzing Apache with AFL through an input file

as we all know, AFL使用种子文件作为命令行参数的初始测试范围。

afl-fuzz -i testcases/-o session_1/--./victim -v -f @@

然而Apache没有命令行参数输入

Patching Apache

为了让Apache能接收命令行传入的参数,需要修改Apache的main.c源码文件。修改后的源文件可在这里下载.
然后在apache源码根目录下执行命令

patch -p0 -i apatching_apache_for_AFL_fuzzing.diff

这个补丁的思路是,在Apache进程中创建一个线程以修改web渲染线程的参数,这样就能让左右结构发生在同一个进程当中,从而实现AFL的代码解析。

Fuzzing Apache

现在我们就可以Fuzz Apache相关代码了。
我们使用如下命令来编译Apache:

CC="afl-clang" CXX="afl-clang++" PREFIX="/usr/local/apache_afl_blogpost/"./compile_dependencies_with_flags.sh

在启动Apache时,我们需要添加三个参数

-X -m none -t 5000

Setup part 2

使用AFL的持久化测试方法

Compiling afl-clang-fast

还记得之前下载的clang和llvm吗,超方便的。我们可以直接在他们的文件夹下面编译AFL。为了实现可持续化的Fuzz我们只需要额外编译一个AFL的实验性功能。
可以只fuzz一部分代码,而不是执行全部代码。

Patching Apache for Persistence

在这之前,还是需要改一下Apache的源码。修改后的源码链接

Fuzzing Apache with AFL on Persistent mode

同上文中介绍的该参数的方法一样,我们需要在启动Apache时,我们需要添加三个参数

-X -m none -t 5000

Conclusions

本文介绍了如何通过使用 unshared function 来高效的fuzz程序。
这个办法相对honggfuzz而言还是慢了点。可能是因为Apache实现中包含多线程的原因。
测试中发现的crash也都能复现,效果棒棒。
很感谢Apache安全团队在研究中给予的帮助,很高兴和你们合作。
加油,奥利给