AFL(一)源码fuzz
0x0 概述
American Fuzz Lop简称 AFL
,号称是当前最高级的Fuzzing测试工具之一,由lcamtuf所开发的开源模糊测试工具。
AFL同时支持两种Fuzz模式:
有源码模式:使用AFL来进行有源码fuzz基本上是依赖于AFL中的代码插桩。
无源码模式(afl-qemu):AFL的无源码模式的fuzz依赖于qemu虚拟化。
使用有源码模式需要使用afl-clang或afl-clang++来编译工程代码,然后以文件(尽量 <1K)为输入,然后启动afl-fuzz程序,将testcase(seed) 喂给程序代码,然后程序接收此次输入执行程序,如果发现新的路径则保存此testcase到一个queue中,afl-fuzz继续编译testcase,因此程序每次接收不同的输入,如果程序崩溃,则记录crash。
与其他基于插桩技术的fuzzers相比,afl-fuzz具有较低的性能消耗,有各种高效的fuzzing策略和tricks最小化技巧, 不需要先行复杂的配置,能无缝处理复杂的现实中的程序。
AFL
,号称是当前最高级的Fuzzing测试工具之一,由lcamtuf所开发的开源模糊测试工具。
有源码模式:使用AFL来进行有源码fuzz基本上是依赖于AFL中的代码插桩。
无源码模式(afl-qemu):AFL的无源码模式的fuzz依赖于qemu虚拟化。
0x1 安装
0x11 包管理器安装
macOS:
$ brew install afl-fuzz
Linux:
$ apt install afl
$ brew install afl-fuzz
$ apt install afl
0x12 源码编译安装
如果需要较新版本的AFL,也可通过AFL的官网下载源码自行编译:
$ wget http://lcamtuf.coredump.cx/afl/releases/afl-latest.tgz
$ tar xvf afl-latest.tgz
$ make
$ sudo make install
$ wget http://lcamtuf.coredump.cx/afl/releases/afl-latest.tgz
$ tar xvf afl-latest.tgz
$ make
$ sudo make install
0x2 使用有源码模式
0x21 AFL Fuzzing步骤
- 使用afl-gcc编译项目代码,将编译脚本中的
CC=afl-gcc
/CXX=afl-g++
;
- 新建两个文件夹,如
fuzz_in
/fuzz_out
,文件夹名随意;
- 将初始化testcase放到fuzz_in目录下;
- 执行
afl-fuzz -i fuzz_in -o fuzz_out ./xxx @@
,xxx为可执行程序名,@@表示从文件中读入
- 观察fuzzing结果,如有crash,定位问题。
CC=afl-gcc
/CXX=afl-g++
;fuzz_in
/fuzz_out
,文件夹名随意;afl-fuzz -i fuzz_in -o fuzz_out ./xxx @@
,xxx为可执行程序名,@@表示从文件中读入0x22 fuzz测试示例
0x221 示例代码afl_test.c
:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
int vuln(char *Data) {
int num = rand() % 100 + 1;
printf("Data is generated, num is %d\n", num);
if(Data[0] == 'C' && num == 25)
{
raise(SIGSEGV);
}
else if(Data[0] == 'F' && num == 90)
{
raise(SIGSEGV);
}
else{
printf("it is good!\n");
}
return 0;
}
int main(int argc, char *argv[])
{
char buf[40]={0};
FILE *input = NULL;
input = fopen(argv[1], "r");
if(input != 0)
{
fscanf(input, "%s", &buf);
printf("buf is %s\n", buf);
vuln(buf);
fclose(input);
}
else
{
printf("bad file!");
}
return 0;
}
如果输入的数据第一个字母是’C’并且num=25 或者第一个字母是’F’并且num=90,那么程序异常退出。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
int vuln(char *Data) {
int num = rand() % 100 + 1;
printf("Data is generated, num is %d\n", num);
if(Data[0] == 'C' && num == 25)
{
raise(SIGSEGV);
}
else if(Data[0] == 'F' && num == 90)
{
raise(SIGSEGV);
}
else{
printf("it is good!\n");
}
return 0;
}
int main(int argc, char *argv[])
{
char buf[40]={0};
FILE *input = NULL;
input = fopen(argv[1], "r");
if(input != 0)
{
fscanf(input, "%s", &buf);
printf("buf is %s\n", buf);
vuln(buf);
fclose(input);
}
else
{
printf("bad file!");
}
return 0;
}
如果输入的数据第一个字母是’C’并且num=25 或者第一个字母是’F’并且num=90,那么程序异常退出。
0x222 编译
$ afl-clang -g -o afl_test afl_test.c
$ afl-clang -g -o afl_test afl_test.c
0x223 准备环境
- 新建输入、输出文件夹:
$ mkdir fuzz_in fuzz_out
- 准备初始化testcase, 将testcase内容随意写成aaa:
$ echo aaa > fuzz_in/testcase
另外官网提供了部分测试集,里面有大量的各种格式的且经过修剪处理的测试用例
$ mkdir fuzz_in fuzz_out
$ echo aaa > fuzz_in/testcase
另外官网提供了部分测试集,里面有大量的各种格式的且经过修剪处理的测试用例0x224 开始Fuzz
使用如下指令即可开始fuzz
$ afl-fuzz -i fuzz_in -o fuzz_out ./afl_test @@
启动afl-fuzz中往往会报错,表示某些环境变量没有配置或者配置错误,如:
afl-fuzz 2.52b by <[email protected]>
[+] You have 4 CPU cores and 4 runnable tasks (utilization: 100%).
[-] Whoops, your system is configured to forward crash notifications to an
external crash reporting utility. This will cause issues due to the
extended delay between the fuzzed binary malfunctioning and this fact
being relayed to the fuzzer via the standard waitpid() API.
To avoid having crashes misinterpreted as timeouts, please run the
following commands:
SL=/System/Library; PL=com.apple.ReportCrash
launchctl unload -w ${SL}/LaunchAgents/${PL}.plist
sudo launchctl unload -w ${SL}/LaunchDaemons/${PL}.Root.plist
[-] PROGRAM ABORT : Crash reporter detected
Location : check_crash_handling(), afl-fuzz.c:7247
按照提示配置即可:
$ SL=/System/Library; PL=com.apple.ReportCrash
$ launchctl unload -w ${SL}/LaunchAgents/${PL}.plist
$ sudo launchctl unload -w ${SL}/LaunchDaemons/${PL}.Root.plist
重新执行fuzz,运行成功如下
$ afl-fuzz -i fuzz_in -o fuzz_out ./afl_test @@
$ afl-fuzz -i fuzz_in -o fuzz_out ./afl_test @@
afl-fuzz 2.52b by <[email protected]>
[+] You have 4 CPU cores and 4 runnable tasks (utilization: 100%).
[-] Whoops, your system is configured to forward crash notifications to an
external crash reporting utility. This will cause issues due to the
extended delay between the fuzzed binary malfunctioning and this fact
being relayed to the fuzzer via the standard waitpid() API.
To avoid having crashes misinterpreted as timeouts, please run the
following commands:
SL=/System/Library; PL=com.apple.ReportCrash
launchctl unload -w ${SL}/LaunchAgents/${PL}.plist
sudo launchctl unload -w ${SL}/LaunchDaemons/${PL}.Root.plist
[-] PROGRAM ABORT : Crash reporter detected
Location : check_crash_handling(), afl-fuzz.c:7247
$ SL=/System/Library; PL=com.apple.ReportCrash
$ launchctl unload -w ${SL}/LaunchAgents/${PL}.plist
$ sudo launchctl unload -w ${SL}/LaunchDaemons/${PL}.Root.plist
$ afl-fuzz -i fuzz_in -o fuzz_out ./afl_test @@
0x225 重现crash
$ ./afl_test fuzz_out/crashes/id:000001,sig:06,src:000001,op:havoc,rep:16
然后调试分析即可
$ ./afl_test fuzz_out/crashes/id:000001,sig:06,src:000001,op:havoc,rep:16
0x23 fuzz开源软件
0x231 编译fuzz目标
libpng是开源的png解析库
$ wget https://nchc.dl.sourceforge.net/project/libpng/libpng16/1.6.36/libpng-1.6.36.tar.xz
$ tar xvf libpng-1.6.36.tar.xz
$ cd libpng-1.6.36
$ ./autogen.sh
$ CC=afl-clang CXX=afl-g++ ./configure --enable-static
$ make -j4
--enable-static
: 用于生成静态库,fuzz开源库时会需要
$ wget https://nchc.dl.sourceforge.net/project/libpng/libpng16/1.6.36/libpng-1.6.36.tar.xz
$ tar xvf libpng-1.6.36.tar.xz
$ cd libpng-1.6.36
$ ./autogen.sh
$ CC=afl-clang CXX=afl-g++ ./configure --enable-static
$ make -j4
--enable-static
: 用于生成静态库,fuzz开源库时会需要0x232 准备环境
获取官网提供的测试集作为输入
$ mkdir fuzz_in fuzz_out
$ cd fuzz_in
$ wget http://lcamtuf.coredump.cx/afl/demo/afl_testcases.tgz
$ tar xvf afl_testcases.tgz
$ mkdir fuzz_in fuzz_out
$ cd fuzz_in
$ wget http://lcamtuf.coredump.cx/afl/demo/afl_testcases.tgz
$ tar xvf afl_testcases.tgz
0x233 开始fuzz
$ afl-fuzz -i ../fuzz_in/png/full/images -o ../fuzz_out ../.libs/pngimage @@
其中,../fuzz_in/png/full/images
为afl官网提供的测试集,里面有大量的各种格式的且经过修剪处理的测试用例,../.libs/pngimage
是编译出来的被测试程序,@@代表测试输入样本,即../fuzz_in/png/full/images
目录下的.png文件,在实际执行时@@会被替换成实际的测试样本。
之后就等待crash了
$ afl-fuzz -i ../fuzz_in/png/full/images -o ../fuzz_out ../.libs/pngimage @@
../fuzz_in/png/full/images
为afl官网提供的测试集,里面有大量的各种格式的且经过修剪处理的测试用例,../.libs/pngimage
是编译出来的被测试程序,@@代表测试输入样本,即../fuzz_in/png/full/images
目录下的.png文件,在实际执行时@@会被替换成实际的测试样本。
梓源大佬最近更新很频繁啊。
回复删除运行./autogen.sh的时候会报错:
回复删除autogen.sh is intended only to generate 'configure' on systems
that do not have it. You have a complete 'configure', if you
need to change Makefile.am or configure.ac you also need to
run configure with the --enable-maintainer-mode option.
尝试了先./configure --enable-maintainer-mode再./autogen.sh,报同样错;
尝试./configure --enable-maintainer-mode ./autogen.sh和./configure ./autogen.sh --enable-maintainer-mode,报如下错:
configure: WARNING: you should use --build, --host, --target
configure: WARNING: invalid host type: ./autogen.sh
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... ./install-sh -c -d
checking for gawk... no
checking for mawk... no
checking for nawk... no
checking for awk... awk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking whether to enable maintainer-specific portions of Makefiles... yes
checking for ./autogen.sh-gcc... no
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking whether gcc understands -c and -o together... yes
checking whether make supports the include directive... yes (GNU style)
checking dependency style of gcc... gcc3
checking dependency style of gcc... gcc3
checking build system type... Invalid configuration `./autogen.sh': machine `./autogen.sh' not recognized
configure: error: /bin/sh ./config.sub ./autogen.sh failed
请问解决办法?