安装
AFL 下载地址
http://lcamtuf.coredump.cx/afl/
安装方式
1 | wget http://lcamtuf.coredump.cx/afl/releases/afl-latest.tgz |
安装后保存在 /usr/local/bin
中
在执行的过程中会遇到一些错误,但都给出了提示,如:
1 | echo core > /proc/sys/kernel/core_pattern |
学习
基础使用
1 | afl-gcc 和afl-g++ 分别对应的是gcc 和g++ 的封装 可以编译文件,并在源文件中添加特殊指令用于 afl fuzz 编译插装 |
处理流程图 来自 上面链接
使用方法为
如果有源码 ,使用 afl-gcc
进行编译插装
afl-fuzz -i ./testcases/-o ./results ./vuln1
-i 指定 输入的数据目录
-o 指定输出的结果目录
fuzz 简单事例
我们编写一个 存在漏洞的 程序
1 |
|
存在 gets 的栈溢出漏洞。
利用 afl-gcc 编译。并不需要 cananry 保护
afl-gcc -fno-stack-protector -z execstack test.c -o test1
然后是创建 fuzz 用的测试用例。
创建 input 目录
然后返回左面创建 res 目录
然后切到root用户,修改core_pattern
文件内容为core
:
echo core > /proc/sys/kernel/core_pattern
然后运行
afl-fuzz -i ./input/ -o ./res/ ./test1
uniq crashes
,如果它的值不为0,表明已经有输入导致了程序崩溃,在results/crashes文件夹里存有相应文件
里面保存的就是程序逻辑中 不同程序路径下的输入内容
比如这里就 是可以输入 root root
queue
目录下保存了 不同的输入 内容
测试crashes 数据
cat ./res/crashes/id\:000001\,sig\:11\,src\:000004\,op\:ext_AO\,pos\:0 | ./test1
窗口解读
- Process timing:Fuzzer运行时长、以及距离最近发现的路径、崩溃和挂起经过了多长时间。
- Overall results:Fuzzer当前状态的概述。
- Cycle progress:我们输入队列的距离。
- Map coverage:目标二进制文件中的插桩代码所观察到覆盖范围的细节。
- Stage progress:Fuzzer现在正在执行的文件变异策略、执行次数和执行速度。
- Findings in depth:有关我们找到的执行路径,异常和挂起数量的信息。
- Fuzzing strategy yields:关于突变策略产生的最新行为和结果的详细信息。
- Path geometry:有关Fuzzer找到的执行路径的信息。
- CPU load:CPU利用率
语料库
初始输入数据(也叫种子文件)作为Fuzzing的起点,这些输入甚至可以是毫无意义的数据,AFL可以通过启发式算法自动确定文件格式结构。
需要保证
- 是有效输入
- 尽量小的体积
AFL 算法
1) 把用户提供的初始测试用例加载到队列(queue)中;
2) 从队列中获取下一个测试输入文件;
3) 在保持程序行为的前提下,尝试修剪(trim)测试用例(体积)到最小;
4) 使用传统的模糊测试策略中的各种已有的研究方法,重复变异文件;
5) 如果生成的变异结果能够驱动新的状态转换(通过插桩记录),则把这一测试用例加入到队列中;
6) 调到第2步。
对二进制程序插桩
操作 利用 qemu 插装 黑盒
1 | cd qemu_mode |