Afl实验报告

一、对c++程序进行afl

1.环境准备:

下载好afl,并准备两个文件夹用于存放输入的测试例子和输出的crash

准备afl插桩程序

写一个简单的C++程序afl_test.c,主要包含两个函数:main和vuln

main函数是程序的入口点,首先创建了一个字符数组buf,然后使用gets函数从标准输入读取字符串到buf。使用不安全的gets()函数,它不会去检查边界,这会导致缓冲区溢出。这里存在一个栈溢出漏洞,因为gets函数不会检查输入的长度,如果输入的字符串超过buf的大小,就会导致栈溢出。然后,使用printf函数打印buf,这里存在一个格式化字符串漏洞,因为printf函数会将buf中的内容当作格式字符串来处理,如果buf中包含%字符,就可能导致未预期的行为。最后,调用vuln函数处理buf。

vuln函数接受一个字符串作为参数。首先,计算字符串的长度。然后,检查字符串的第一个字符和长度。如果第一个字符是’A’并且长度是66,或者第一个字符是’F’并且长度是6,就会调用raise函数发送SIGSEGV信号,导致程序异常退出。否则,打印”It is good!“。

使用afl的gcc将afl_test.c进行编译,编译完成后出现了新文件afl_test

在AFL编译文件时候afl-gcc会在规定位置插入桩代码,可以理解为一个个的探针(但是没有暂停功能),在后续fuzz的过程中会根据这些桩代码进行路径探索,测试等。

在fuzz_in中还需要创建一个testcase文件,写入aaa。

然后启动afl-fuzz程序,将testcase(输入的测试文件)作为程序的输入执行程序,afl会在这个testcase的基础上进行自动变异输入,使得程序产生crash,产生了crash就会被记录起来。

3.开始Fuzz

4.输出crash分析

crashes文件夹里面是产生crash的样例,hangs里面是产生超时的样例,queue里面是每个不同执行路径的测试用例。

首先回顾测试程序中会导致退出的三种情形:首字符为A且长度为66;首字符为F且长度为6;栈溢出漏洞

用xxd查看第一个crash样例的完整内容,符合栈溢出导致的程序退出情况:

用xxd查看第二个crash样例的完整内容,符合首字符是F且长度为6导致程序退出的情况:

用xxd查看第三个crash样例的完整内容,符合栈溢出导致的程序退出情况:

二、对cpython库进行afl

1.配置cpython环境

下载cpython库,并将编译器指定为 afl-gcc,然后再进行编译:

apt-get update

sudo apt-get install -y build-essential libncursesw5-dev libreadline-dev libssl-dev libgdbm-dev libc6-dev libsqlite3-dev tk-dev libbz2-dev zlib1g-dev libffi-dev

git clone https://gitee\.com/mirrors/cpython\.git

cd cpython

./configure CC=”afl-gcc” CXX=”afl-g++“

make

2.开始fuzz

在fuzz_in文件夹下出创建testcase输入语料aaaaa,然后开始fuzz:

3.输出结果分析

CPython 是最常用的 Python 实现,它是官方用 C 编写的 python 实现,所以crash几乎发现不了也很正常,但还是在fuzz一整天(24小时)内发现了6个超时案例,对输出文件夹fuzz_out下的hangs文件夹中的输出例子进行分析,hangs文件夹放超时的例子,共有80个:

依次用xxd命令查看完整内容,以第一个例子为典型看出,仅仅18个字符就可以造成官方实现的cpython库超时:

三、Afl界面分析以及遇到的问题

1.process timing

展示了当前fuzzer的运行时间、最近一次发现新执行路径的时间、最近一次崩溃的时间、最近一次超时的时间。

值得注意的是第2项,最近一次发现新路径的时间。如果由于目标二进制文件或者命令行参数出错,那么其执行路径应该是一直不变的,所以如果从fuzzing开始一直没有发现新的执行路径,那么就要考虑是否有二进制或者命令行参数错误的问题了。对于此状况,AFL也会智能地进行提醒odd check synax

我在测试dwebp库时遇到了这样的情况,这表明afl没有找到测试输入路径,解决方法是需要在输入fuzz指令时指定输入的测试路径,并加上-f参数指令强制覆盖结果内容。

2.overall results

这里包括运行的总周期数、总路径数、崩溃次数、超时次数。

其中,总周期数可以用来作为何时停止fuzzing的参考。随着不断地fuzzing,周期数会不断增大,其颜色也会由洋红色,逐步变为黄色、蓝色、绿色。一般来说,当其变为绿色时,代表可执行的内容已经很少了,继续fuzzing下去也不会有什么新的发现了。此时,我们便可以通过Ctrl-C,中止当前的fuzzing

3.stage progress

这里包括正在测试的fuzzing策略、进度、目标的执行总次数、目标的执行速度

执行速度可以直观地反映当前跑的快不快,如果速度过慢,比如低于500次每秒,那么测试时间就会变得非常漫长。如果发生了这种情况,那么我们需要进一步调整优化我们的fuzzing

在运行时发现,afl进行时会占用一个cpu内核,由于虚拟机在安装时设置使用两个内核,所以普通的afl最多只能同时进行两个afl测试

Comments

⬆︎TOP