diff --git a/覃业斌-AFL++示例运行.md b/覃业斌-AFL++示例运行.md new file mode 100644 index 0000000..29a0b7e --- /dev/null +++ b/覃业斌-AFL++示例运行.md @@ -0,0 +1,184 @@ +# 一、功能介绍 + +AFL++是一个社区驱动的开源模糊测试工具,它是在原始的American Fuzzy Lop (AFL)的基础上发展起来的。AFL++集成了多种模糊测试技术,提供了一个可扩展的平台,允许研究人员和开发者轻松地添加新的模糊测试策略和技术。它的特点包括: + +1. **种子调度**:AFL++采用了AFLFast的调度算法,包括多种策略如 `fast`, `coe`, `explore`, `quad`, `lin`, `exploit`等,以及新增的 `mmopt`和 `rare`策略,以优化测试用例的选择和执行。 +2. **变异器**:AFL++在原有的 `havoc`和 `deterministic`变异器基础上增加了多种变异方式,包括自定义变异器API、Input-To-State变异器和MOpt Mutator,这些变异器可以提高模糊测试的效率和效果。 +3. **插桩支持**:AFL++支持多种插桩方式,包括LLVM、GCC、QEMU、Unicornafl和QBDI,以适应不同的测试需求和环境。 +4. **绕过障碍**:AFL++集成了如LAF-Intel和RedQueen等技术,这些技术可以帮助模糊测试工具绕过程序中的一些常见障碍,如复杂的字符串和校验和检查。 +5. **结构化输入变异**:AFL++支持对结构化输入进行变异,如AFLSmart,它可以利用输入模型来减少生成输入的空间,从而更有效地探索程序中的深层路径。 +6. **Custom Mutator API**:AFL++提供了自定义变异器API,允许用户根据自己的需要开发新的变异策略,这对于学术研究和特定场景的测试非常有用。 + +AFL++的目标是提供一个稳定的基础,使得未来的模糊测试研究可以在此基础上进行,同时也为现有的模糊测试技术提供一个集成的平台。它与原始的AFL相比,做了大量的改进和优化,以适应快速发展的模糊测试领域。 + +[AFL++项目地址](https://github.com/AFLplusplus/AFLplusplus/releases) + +# 二、编译安装 + +项目推荐使用docker直接pull下来,但由于网络问题,本次示例采用在linux虚拟机上编译安装 + +```shell +git clone https://github.com/AFLplusplus/AFLplusplus # 克隆项目 +sudo apt-get install -y build-essential python3-dev automake cmake git flex bison libglib2.0-dev libpixman-1-dev python3-setuptools cargo libgtk-3-dev #安装依赖环境 +# 如果安装依赖环境出现问题,先安装下面的llvm +sudo apt-get install -y lld-14 llvm-14 llvm-14-dev clang-14 || sudo apt-get install -y lld llvm llvm-dev clang +sudo apt-get install -y gcc-$(gcc --version|head -n1|sed 's/\..*//'|sed 's/.* //')-plugin-dev libstdc++-$(gcc --version|head -n1|sed 's/\..*//'|sed 's/.* //')-dev +#编译 +git clone https://github.com/AFLplusplus/AFLplusplus +cd AFLplusplus +make distrib +sudo make install +``` + +安装完成后可以在使用afl-fuzz命令测试是否安装成功 +![1](image/1.png) + +# 三、运行示例 + +### (一) 目标程序的源码 + +一个栈溢出案例,代码如下,当输入为abcd时会出现崩溃 + +```c +//test.c +#include +#include + +void vulnerable_function(char *input) +{ + char buffer[4]; // 定义一个长度为4的字符数组 + + // 复制用户输入到buffer中 + strcpy(buffer, input); + + printf("输入内容: %s\n", buffer); +} + +int main() +{ + char user_input[100]; + + printf("请输入一串字符(以回车结束):"); + fgets(user_input, sizeof(user_input), stdin); + + // 移除换行符 + user_input[strcspn(user_input, "\n")] = 0; + + // 检查前四个字符是否是'a', 'b', 'c', 'd' + if (user_input[0] == 'a' ){ + if( user_input[1] == 'b' ) { + if (user_input[2] == 'c'){ + if (user_input[3] == 'd'){ + vulnerable_function(user_input); + } + } + } + } + + return 0; +} +``` + +### (二)模糊测试以及准备工作 + +在模糊测试前先要进行**源码编译插桩**和**创建语料库** + +1. 源码编译插桩:**使用 afl++ 自带的插桩编译器**:afl-gcc + ![2](image/1.png) +2. 准备语料库:作为程序输入的原始材料,必须有才可以运行,原始材料越好漏洞发现的越快 + +```shell + ➜ afl echo "abc" >> ./input/seed1 +``` + +3. 开启模糊测试:指定必要的目标文件夹就可以开启模糊测试了 + +```shell +➜ afl afl-fuzz -i input/ -o output/ ./test +afl-fuzz++4.22a based on afl by Michal Zalewski and a large online community +[+] AFL++ is maintained by Marc "van Hauser" Heuse, Dominik Maier, Andrea Fioraldi and Heiko "hexcoder" Eißfeldt +[+] AFL++ is open source, get it at https://github.com/AFLplusplus/AFLplusplus +[+] NOTE: AFL++ >= v3 has changed defaults and behaviours - see README.md +[+] No -M/-S set, autoconfiguring for "-S default" +[*] Getting to work... +[+] Using exploration-based constant power schedule (EXPLORE) +[+] Enabled testcache with 50 MB +[+] Generating fuzz data with a length of min=1 max=1048576 +[*] Checking core_pattern... +[!] WARNING: Could not check CPU scaling governor +[+] You have 16 CPU cores and 2 runnable tasks (utilization: 12%). +[+] Try parallel jobs - see /usr/local/share/doc/afl/fuzzing_in_depth.md#c-using-multiple-cores +[*] Setting up output directories... +[+] Output directory exists but deemed OK to reuse. +[*] Deleting old session data... +[+] Output dir cleanup successful. +[*] Checking CPU core loadout... +[+] Found a free CPU core, try binding to #0. +[*] Validating target binary... +[*] Scanning 'input/'... +[*] Creating hard links for all input files... +[+] Loaded a total of 1 seeds. +[*] Spinning up the fork server... +[!] WARNING: Old fork server model is used by the target, this still works though. +[+] All right - old fork server is up. +[*] No auto-generated dictionary tokens to reuse. +[*] Attempting dry run with 'id:000000,time:0,execs:0,orig:seed1'... + len = 4, map size = 5, exec speed = 157 us, hash = ad4e684fcf34ff0e +[+] All test cases processed. +[+] Here are some useful stats: + + Test case count : 1 favored, 0 variable, 0 ignored, 1 total + Bitmap range : 5 to 5 bits (average: 5.00 bits) + Exec timing : 157 to 157 us (average: 157 us) + +[*] No -t option specified, so I'll use an exec timeout of 20 ms. +[+] All set and ready to roll! + + american fuzzy lop ++4.22a {default} (./test) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 0 hrs, 0 min, 1 sec │ cycles done : 15 │ +│ last new find : 0 days, 0 hrs, 0 min, 1 sec │ corpus count : 4 │ +│last saved crash : 0 days, 0 hrs, 0 min, 1 sec │saved crashes : 1 │ +│ last saved hang : none seen yet │ saved hangs : 0 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 3.19 (75.0%) │ map density : 0.01% / 0.01% │ +│ runs timed out : 0 (0.00%) │ count coverage : 1.00 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : havoc │ favored items : 4 (100.00%) │ +│ stage execs : 85/100 (85.00%) │ new edges on : 4 (100.00%) │ +│ total execs : 10.2k │ total crashes : 5 (1 saved) │ +│ exec speed : 8074/sec │ total tmouts : 0 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 0/32, 0/31, 0/29 │ levels : 2 │ +│ byte flips : 0/4, 0/3, 0/1 │ pending : 0 │ +│ arithmetics : 0/238, 0/25, 0/0 │ pend fav : 0 │ +│ known ints : 0/23, 0/84, 0/46 │ own finds : 3 │ +│ dictionary : 0/0, 0/0, 0/0, 0/0 │ imported : 0 │ +│havoc/splice : 1/9650, 0/0 │ stability : 100.00% │ +│py/custom/rq : unused, unused, unused, unused ├───────────────────────┘ +│ trim/eff : n/a, 25.00% │ [cpu000: 12%] +└─ strategy: explore ────────── state: started :-) ──┘^C + ++++ Testing aborted by user +++ +[*] Writing output//default/fastresume.bin ... +[+] Written fastresume.bin with 295308 bytes! +[+] We're done here. Have a nice day! +``` + +4. `afl-fuzz`: 这是 AFL++ 的核心工具,用于执行模糊测试。AFL++ 是一个强大的模糊测试工具,它通过自动化生成输入数据来测试目标程序,从而发现潜在的安全漏洞或程序崩溃。 +5. `-i input/`: 这个选项指定了 AFL++ 用来开始模糊测试的初始输入种子文件的目录。在这里,`input/` 是包含初始输入数据的目录。AFL++ 会基于这些初始输入生成变异后的测试数据。 +6. `-o output/`: 这个选项指定了 AFL++ 将输出模糊测试结果的目录。`output/` 目录将包含测试过程中生成的各种数据,比如发现的崩溃或挂起的输入、统计信息等。 +7. `./test`: 这是要测试的目标程序。在这个例子中,`./test` 是你要使用 AFL++ 进行模糊测试的可执行文件。AFL++ 会向这个程序提供变异后的输入,观察它的行为(例如,是否会崩溃或触发其他异常行为)。 + +### (三)验证漏洞 + +崩溃的输入样本会被保存在output目录下的crashes目录,查看一下,与原先对源码分析的结果一样,也成功使程序崩溃,示例完成 + +```shell +➜ afl cat output/default/crashes/id:000000,sig:06,src:000000,time:101,execs:789,op:havoc,rep:2 +abcdcccccccccccccccccccccccc +➜ afl ./test +请输入一串字符(以回车结束):abcdcccccccccccccccccccccccc +*** buffer overflow detected ***: terminated +[1] 1456167 IOT instruction ./test +```