AFL学习记录(一)——安装、运行
这是一个崭新的分类。学院为我们安排了科研导师,而我选择了研究安全方向的导师组,其实上个学期期中就选好了,但是由于各种原因当时没有直接开始学,到这个学期排课了才开始进行学习。
对于模糊测试我其实比较陌生,之前只看过一篇综述性论文The Art Science and Engineering of Fuzzing A Survey。大概了解到这是一种发现漏洞的方式,总体上感觉非常优雅,因为是高度自动化的。我在做 PWN 的时候,一般不会特别担心发现漏洞点的问题,因为 CTF 比赛比较脱离实战,特别是 PWN,许多漏洞都是非常明显的(当然也不排除非常刁钻的),而且程序的体量普遍较小,一般可以看完、看懂整个逻辑。而实际上的漏洞挖掘,显然的,面对的程序都是至少以兆为单位的,想像 CTF 中完全逆向分析几乎是不可能的,我也是希望能尽量和实战结合,掌握一些现代漏洞挖掘方法,所以对 fuzzing 还是非常感兴趣的。学长要求我学习 AFL(American Fuzzy Lop),这里第一步还是先记录一下安装和运行。
首先安装依赖环境,基本的 gcc g++ 就不多说了,主要需要下面这两个
sudo apt install clang
sudo apt install llvm
然后
wget http://lcamtuf.coredump.cx/afl/releases/afl-2.52b.tgz
tar -zxvf afl-2.52b.tgz
cd afl-2.52b
make
sudo make install
这样在此目录中就可以运行 ./afl-fuzz
了。

当然也可以编译出使用 llvm
模式来编译,这样可以加快 fuzz,使用 afl-clang-fast
来编译就可以了。
先来试一试有源码情况的 fuzz,我自己写的代码漏洞点布置的好像都太明显、危害性太大了,这个模糊器都不给我 fuzz 的机会,所以就到网上找了了代码(来源)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
int vuln(char *str)
{
int len = strlen(str);
if(str[0] == 'A' && len == 66)
{
raise(SIGSEGV);
//如果输入的字符串的首字符为A并且长度为66,则异常退出
}
else if(str[0] == 'F' && len == 6)
{
raise(SIGSEGV);
//如果输入的字符串的首字符为F并且长度为6,则异常退出
}
else
{
printf("it is good!\n");
}
return 0;
}
int main(int argc, char *argv[])
{
char buf[100]={0};
gets(buf);//存在栈溢出漏洞
printf(buf);//存在格式化字符串漏洞
vuln(buf);
return 0;
}
充满了漏洞的程序,然后就是一个简单的流程
- 用 afl 提供的编译器编译代码,对 C 代码而言就是使用
afl-gcc
,编译器会自动插桩之类的,便于 fuzzing - 提供测试数据文件,模糊器会使用文件进行输入并自动进行变异
- 运行模糊器
程序有漏洞的情况下,随机的、恶意的输入都很容易造成 crash(想想 pwn 中精心构造的输入都很容易造成 crash),模糊器会自动记录 crash,我们就可以通过这些 crash 来溯源找到漏洞点。之后就是 pwn 干的事了。
首先编译
./afl-gcc -g -o path/to/store/target/program path/of/source
然后建立一个储存输入的文件夹,比如 testcase
然后就可以用 afl-fuzz
跑了
./afl-fuzz -i /input/path -o /output/path /target/path
用 -i
指定输入文件夹路径,-o
指定结果输出文件夹路径。
运行这个的时候一般会报个错,大概就是核心转储的设置有问题,按照报错的提示来做就行了
sudo su
echo core >/proc/sys/kernel/core_pattern
然后就可以开跑啦

界面还是很炫酷的,由于我的 wsl 无法正常显示这个界面,所以我只好忍痛到 VMware 上做这个了,不过用 VMware,性能似乎有一定上升,这个软件还是很强大的。
今天就到这了,别的东西之后继续学习。