afl+preeny实现对交互应用的fuzz
字数 1211 2025-08-24 16:48:16
AFL+Preeny实现对交互应用的Fuzz测试教程
1. 概述
本教程详细介绍了如何使用AFL(American Fuzzy Lop)结合Preeny工具对交互式应用程序(如wget)进行模糊测试(Fuzz)。通过这种方法,我们可以发现程序中的潜在漏洞,如本教程中发现的CVE-2017-13089。
2. 环境准备
2.1 测试目标 - wget
版本: 1.19.1
下载与编译:
wget https://ftp.gnu.org/gnu/wget/wget-1.19.1.tar.gz
tar zxvf wget-1.19.1.tar.gz
cd wget-1.19.1
CXX=afl-clang-fast++ CC=afl-clang-fast ./configure --prefix=/home/mortywget
AFL_USE_ASAN=1 make
make install
验证安装:
./wget --version
# 应输出: GNU Wget 1.19.1 built on linux-gnu.
2.2 Fuzz工具 - AFL
使用AFL的快速模式(afl-clang-fast)进行编译,并启用ASAN(Address Sanitizer)检测内存错误。
2.3 交互功能实现 - Preeny
项目地址: https://github.com/zardus/preeny
Preeny通过LD_PRELOAD机制重写交互函数,将socket交互转换为标准输入输出,便于AFL进行Fuzz。
验证Preeny安装:
LD_PRELOAD="/root/preeny/x86_64-linux-gnu/desock.so" wget localhost:6666 -q -O result < <(echo "success")
more result # 应显示"success"
3. Fuzz过程
3.1 准备Payload
创建测试HTTP响应文件(如in/a):
HTTP/1.1 401 Not Authorized
Content-Type: text/plain; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
test
3.2 初始Fuzz测试
nc -lp 6666 < in/a & ./wget localhost:6666 -F -O /dev/null
发现问题: wget接收响应后不会立即断开连接,导致Fuzz效率低下。
3.3 调试与修改源码
使用gdb定位问题:
gdb ./wget
r localhost:6666
bt # 查看调用栈
发现程序卡在select_fd()函数处。修改http.c文件,在以下位置添加exit(0)强制断开连接:
- 错误处理分支:
case HERR: case HEOF: case CONSOCKERR:
case CONERROR: case READERR: case WRITEFAILED:
case RANGEERR: case FOPEN_EXCL_ERR: case GATEWAYTIMEOUT:
exit(0); // 手动添加
printwhat (count, opt.ntry);
continue;
- 401未授权处理:
if (keep_alive && !head_only
&& skip_short_body (sock, contlen, chunked_transfer_encoding))
exit(0); // 手动添加
else
exit(0); // 手动添加
- chunked编码处理:
ret = fd_read (fd, dlbuf, MIN (contlen, SKIP_SIZE), -1);
exit(0); // 手动添加
if (ret <= 0)
重新编译后测试确认修改生效。
3.4 执行Fuzz
使用修改后的wget进行Fuzz,很快发现crash。
4. 漏洞分析
4.1 Crash分析
触发Payload:
HTTP/1.1 401 Not AutzednUcion:TF-8
Transfer-Encoding: chunked
Connection: ke
-0xFFFFFD00P/1.1 401 N1.1 401 Not AutzednUcion:TF-8
...
ASAN报告:
==30736==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fffffffcf01
WRITE of size 689 at 0x7fffffffcf01 thread T0
漏洞位置: http.c中的skip_short_body()函数发生栈溢出。
4.2 漏洞确认
该漏洞被确认为CVE-2017-13089,相关详细信息:
https://www.cvedetails.com/cve/CVE-2017-13089/
5. 关键点总结
- Preeny的作用: 通过
desock.so将网络交互转为标准I/O,使AFL能够Fuzz网络应用 - 源码修改必要性: 对于不自动退出的交互程序,需修改源码强制退出以提高Fuzz效率
- ASAN的重要性: 启用ASAN能有效检测内存错误,如本案例中的栈溢出
- Payload设计: 针对协议特点设计异常响应,如非标准状态码、畸形chunked编码等
- 调试技巧: 使用gdb定位程序卡住位置,针对性修改源码
6. 扩展应用
此方法可应用于其他交互式网络程序的Fuzz测试,关键步骤包括:
- 使用Preeny处理网络交互
- 分析并修改程序不合理的阻塞行为
- 设计针对协议特点的测试用例
- 结合ASAN等检测工具分析结果
通过系统化的Fuzz测试,可以有效发现程序中的各类边界条件错误和安全漏洞。