看网上的评价fuzz好像是挖漏洞的首选工具,就先浅浅学习一下,或许可以找找ctf的应用场景,先从AFL++开始

安装

在安装之前AFL++要求要有llvm和clang,ldd,gcc等编译器

1
2
3
4
5
sudo apt install wget
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 13
sudo apt install clang-13 lld-13 llvm-13

之后更新环境变量

1
2
3
export PATH=/usr/lib/llvm-13/bin:$PATH
echo 'export PATH=/usr/lib/llvm-13/bin:$PATH' >> ~/.bashrc
source ~/.bashrc

记住export只对本shell生效,bashrc只对之后起的shell生效

1
gcc --version

假设输出显示您的GCC版本是9.xx.xx

1
sudo apt install gcc-9-plugin-dev

之后便可以下载依赖然后下载AFL++之后编译

1
2
3
4
5
sudo apt update
$ sudo apt install git make build-essential clang ninja-build pkg-config libglib2.0-dev libpixman-1-dev
$ git clone https://github.91chi.fun/https://github.com/AFLplusplus/AFLplusplus.git
$ cd AFLplusplus
$ make all

这样没有error的话就完成AFL++的基本安装

如果报错就看报错解决,先百度,如果有网上没有的话可以与我讨论,即使我大概率也不会

AFL++的使用

首先是测试,就借用[网上的源码](初探AFL-Fuzz - 先知社区 (aliyun.com))

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#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;
}

有源码的fuzz

首先是编译器的选择官方文档

1
afl-clang-lto ./afl_test.c -o afl_test

对那些可以直接从stdin读取输入的目标程序来说,语法如下:
./afl-fuzz -i testcase_dir -o findings_dir /path/to/program […params…]
对从文件读取输入的目标程序来说,要用“@@”,语法如下:
./afl-fuzz -i testcase_dir -o findings_dir /path/to/program @@

1
afl-fuzz -i fuzz_in -o fuzz_out ./afl_test

image-20240526003227700

这样三个区域要注意的

process time,overall result,findings in depth

主要是total crashes可以看到几个被保留,先知社区那篇AFL便有细讲

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
bamboo@bamboo-virtual-machine:~/test/fuzz_out/default/crashes$ xxd id:000000,sig:11,src:000002,time:525,execs:641,op:havoc,rep:2
00000000: 4646 ff61 6161 FF.aaa //异常
bamboo@bamboo-virtual-machine:~/test/fuzz_out/default/crashes$ xxd id:000001,sig:11,src:000002,time:2133,execs:2603,op:havoc,rep:30
00000000: cfcf cfcf cfcf cfcf cfcf cfcf cfcf cfcf ................
00000010: cfcf cfcf cfcf cfff 80b2 b2b2 b2b2 b2b2 ................
00000020: b2b2 b2b2 b2b2 b2b2 b2b2 b2b2 b2b2 b2b2 ................
00000030: b2b2 b2b2 4db2 b2b2 b2b2 b2b2 b2cf cfcf ....M...........
00000040: cfcf cfcf cfcf ff80 9eb2 b2b2 b2b2 b2cf ................
00000050: cfcf cfcf cfcf cfcf cfcf cfcf cfcf cfcf ................
00000060: d4cf cf80 b2cf 0064 e2cf cfcf cfcf ff80 .......d........
00000070: 9eb2 97b2 b2b2 b2cf cfcf cfcf cfcf cfcf ................
00000080: cfcf cfcf b2b2 b2b2 b2b2 9db2 b2b2 b2e6 ................
00000090: ddff ..
bamboo@bamboo-virtual-machine:~/test/fuzz_out/default/crashes$ xxd id:000002,sig:11,src:000002,time:7445,execs:10000,op:havoc,rep:2
00000000: 256e 6161 %naa //格式化字符串
bamboo@bamboo-virtual-machine:~/test/fuzz_out/default/crashes$ xxd id:000003,sig:11,src:000001,time:11633,execs:15043,op:havoc,rep:63
00000000: 417f 418e 4141 be41 4141 4141 4140 4129 A.A.AA.AAAAAA@A)
00000010: 4141 4180 4120 415a 5a41 6241 4141 4141 AAA.A AZZAbAAAAA
00000020: 4102 4120 415a 5a3b 3241 4141 4141 4141 A.A AZZ;2AAAAAAA
00000030: 4141 4141 4141 4141 4141 7f36 4141 4141 AAAAAAAAAA.6AAAA
00000040: 4141 0200 4140 4129 4141 4180 4120 415a AA..A@A)AAA.A AZ
00000050: 5a41 6241 3041 4141 4102 4120 415a 5a3b ZAbA0AAAA.A AZZ;
00000060: 3241 4140 4141 0241 2041 5a5a 4162 4149 2AA@AA.A AZZAbAI
00000070: 4141 4141 0241 df41 5a5a 4132 4141 4141 AAAA.A.AZZA2AAAA
00000080: 4141 0241 2041 5a64 4141 4100 4041 4100 AA.A AZdAAA.@AA.
00000090: 1b .
bamboo@bamboo-virtual-machine:~/test/fuzz_out/default/crashes$ xxd id:000004,sig:11,src:000001,time:25097,execs:31270,op:havoc,rep:28 //异常2,不过\x00
00000000: 4197 8241 1f87 a4a4 c87f ffc8 c8c8 afaf A..A............
00000010: af8e afaf afaf afaf afaf 98d8 9898 9898 ................
00000020: 98b8 9897 9898 8e98 9898 9898 9898 9898 ................
00000030: 9898 9898 9898 98af afaf afaf afaf c821 ...............!
00000040: 8820 0000 0002 0003 2017 c8c8 1c . ...... ....
  1. id:000001:
    • 这是一个唯一的标识符,用于标识 AFL++ 生成的测试用例。每个新生成的测试用例都会有一个递增的 ID。
  2. sig:11:
    • 这是信号编号,表示程序崩溃时接收到的信号。在这个例子中,11 表示 SIGSEGV(Segmentation Fault),即内存访问违规。
  3. src:000002:
    • 这是生成该测试用例的父测试用例的 ID。它表示此测试用例是从 ID 为 000002 的测试用例变异而来的。
  4. time:2133:
    • 这是 AFL++ 生成该测试用例时的运行时间,单位是毫秒。这里表示 AFL++ 在运行 2133 毫秒后生成了这个测试用例。
  5. execs:2603:
    • 这是 AFL++ 在生成该测试用例时的执行次数。表示 AFL++ 已经执行了 2603 次测试用例。
  6. op:havoc:
    • 这是 AFL++ 用来生成该测试用例的变异操作类型。在这个例子中,havoc 是一种随机变异策略,AFL++ 会对输入进行多种随机变异操作,以发现潜在的漏洞。
  7. rep:30:
    • 这是 AFL++ 在生成该测试用例时重复变异操作的次数。表示该测试用例是在第 30 次变异操作时生成的。

看来里面还是有很多门道的,希望我有一天能参透

无源码的fuzz

无源码的要在qemu上运行,确保事先装好system和static的qemu

1
2
cd qemu_mode
./build_qemu_support.sh
1
gcc -g -o afl_test2 afl_test.c
1
afl-fuzz -i in -o out -Q ./afl_test2

-Q说明是qemu运行

之后尝试一些ctf,iot上的应用(算是留个坑),其实我尝试了go的但是跑的很慢很慢,等我有服务器了再用服务器跑(听说跑fuzz烧硬盘