Sulley fuzzer learning---2
字数 1782 2025-08-20 18:17:48
Sulley Fuzzer 学习指南 - 第二部分:高级使用与实战
1. Sessions 会话管理
1.1 请求连接与图形化表示
Sulley 的核心优势之一是能够将多个请求(request)连接成协议图(protocol graph),实现深度模糊测试:
from sulley import *
# 定义多个请求
s_initialize("helo")
s_static("helo")
s_initialize("ehlo")
s_static("ehlo")
s_initialize("mail from")
s_static("mail from")
s_initialize("rcpt to")
s_static("rcpt to")
s_initialize("data")
s_static("data")
# 创建会话并连接请求
sess = sessions.session()
sess.connect(s_get("helo"))
sess.connect(s_get("ehlo"))
sess.connect(s_get("helo"), s_get("mail from"))
sess.connect(s_get("ehlo"), s_get("mail from"))
sess.connect(s_get("mail from"), s_get("rcpt to"))
sess.connect(s_get("rcpt to"), s_get("data"))
# 生成图形化表示
fh = open("session_test.udg", "w+")
fh.write(sess.render_graph_udraw())
fh.close()
1.2 会话执行流程
Sulley 从根节点开始遍历图结构:
- 从"helo"请求开始模糊测试
- 完成后,开始模糊测试"mail from"请求,每个测试用例前加上有效的"helo"请求
- 接着模糊测试"rcpt to"请求,前面加上有效的"helo"和"mail from"请求
- 最后处理"data"请求
- 完成后转回从"ehlo"开始
1.3 会话配置参数
实例化 session 时可配置的参数:
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| session_filename | string | None | 持久化数据的文件名 |
| skip | integer | 0 | 要跳过的测试用例数 |
| sleep_time | float | 1.0 | 测试用例间的休眠时间(秒) |
| log_level | integer | 2 | 日志级别(数字越大日志越多) |
| proto | string | "tcp" | 通信协议 |
| timeout | float | 5.0 | send()/recv()超时时间(秒) |
| restart_interval | integer | 0 | 每N个测试用例后重启目标(0表示禁用) |
| crash_threshold | integer | 3 | 节点耗尽前允许的最大崩溃次数 |
1.4 边缘回调
可以在协议图的边缘注册回调函数,原型如下:
def callback(node, edge, last_recv, sock):
# node: 要发送的节点
# edge: 当前fuzz到node的最后一条路径
# last_recv: 最后一次socket传输返回的数据
# sock: 实时socket
注册回调示例:
sess.connect(s_get("helo"), s_get("mail from"), callback=my_callback)
2. Targets 和 Agents
2.1 目标配置
target = sessions.target("10.0.0.1", 5168)
target.netmon = pedrpc.client("10.0.0.1", 26001) # 网络监控
target.procmon = pedrpc.client("10.0.0.1", 26002) # 进程监控
target.vmcontrol = pedrpc.client("127.0.0.1", 26003) # VMWare控制
# 进程监控选项
target.procmon_options = {
"proc_name": "SpntSvc.exe",
"stop_commands": ['net stop "trend serverprotect"'],
"start_commands": ['net start "trend serverprotect"'],
}
sess.add_target(target)
sess.fuzz()
2.2 网络监控代理 (network_monitor.py)
功能:
- 监控网络通信并记录为PCAP文件
- 硬编码绑定到TCP端口26001
- 通过PedRPC协议与Sulley通信
命令行参数:
USAGE: network_monitor.py
<-d|--device DEVICE #> 设备号(见下方列表)
[-f|--filter PCAP FILTER] BPF过滤字符串
[-p|--log_path PATH] PCAP日志目录
[-l|--log_level LEVEL] 日志级别(默认1,数字越大越详细)
2.3 进程监控代理 (process_monitor.py)
功能:
- 检测fuzz过程中发生的故障
- 硬编码绑定到TCP端口26002
- 通过PedRPC协议与Sulley通信
命令行参数:
USAGE: process_monitor.py
<-c|--crash_bin FILENAME> 序列化crash bin类的文件名
[-p|--proc_name NAME] 要查找和附加的进程名
[-i|--ignore_pid PID] 搜索目标进程时忽略的PID
[-l|--log_level LEVEL] 日志级别(默认1,数字越大越详细)
2.4 VMWare控制代理 (vmcontrol.py)
功能:
- 控制虚拟机操作(启动、停止、挂起、重置)
- 管理快照(获取、删除、恢复)
- 硬编码绑定到TCP端口26003
命令行参数:
USAGE: vmcontrol.py
<-x|--vmx FILENAME> VMX文件路径
<-r|--vmrun FILENAME> vmrun.exe路径
[-s|--snapshot NAME> 快照名称
[-l|--log_level LEVEL] 日志级别(默认1,数字越大越详细)
3. Web监控界面
Sulley Session类内置Web服务:
- 硬编码绑定到端口26000
- 调用fuzz()方法后自动启动
- 功能:
- 显示fuzz进度
- 暂停/恢复fuzzer
- 查看崩溃详情
4. 事后分析工具
4.1 崩溃浏览工具 (crashbin_explorer.py)
USAGE: crashbin_explorer.py <xxx.crashbin>
[-t|--test #] 转储特定测试用例的崩溃概要
[-g|--graph name] 生成所有崩溃路径的图形,保存为'name'.udg
示例输出:
[3] ntdll.dll:7c910f29 mov ecx,[ecx] from thread 664 caused access violation
1415, 1416, 1417,
[2] ntdll.dll:7c910e03 mov [edx],eax from thread 664 caused access violation
3780, 9215,
[24] rendezvous.dll:4900c4f1 rep movsd from thread 664 caused access violation
1418, 1419, 1420, 1421, 1422, 1423, 1424, 1425, 3443, 3781, 3782, 3783, 3784, 3785, 3786, 3787,
[1] ntdll.dll:7c911639 mov cl,[eax+0x5] from thread 664 caused access violation
3442,
4.2 PCAP清理工具 (pcap_cleaner.py)
USAGE: pcap_cleaner.py <xxx.crashbin> <path to pcaps>
功能:删除不包含崩溃信息的PCAP文件
5. 实战案例分析
5.1 Trillian Jabber协议解析器漏洞
漏洞分析:
-
在plugins\rendezvous.dll中,处理接收消息的逻辑:
4900C470 str_len: 4900C470 mov cl, [eax] ; *eax = message+1 4900C472 inc eax 4900C473 test cl, cl 4900C475 jnz short str_len 4900C477 sub eax, edx 4900C479 add eax, 128 ; strlen(message+1) + 128 4900C47E push eax 4900C47F call _malloc -
计算消息长度并分配堆缓冲区(长度+128)
-
通过expatxml.xmlComposeString()处理字符串,将&,>,<编码为&,>,<
-
初始长度计算未考虑字符串扩展,导致后续内存操作可能触发内存损坏
崩溃表现:
- 多个崩溃点实际上源于同一逻辑错误
- 通过图形化分析可以快速识别问题根源
6. 最佳实践
-
协议图设计:
- 充分理解协议状态转换
- 覆盖所有可能的协议路径
- 示例中"ehlo"路径暴露了"helo"路径未发现的漏洞
-
监控配置:
- 同时使用网络和进程监控
- 利用VM快照快速恢复测试环境
-
分析流程:
- 首先使用crashbin_explorer分类崩溃
- 对关键崩溃点进行详细分析
- 使用图形化工具识别问题模式
- 清理无关的PCAP文件节省存储空间
-
复杂漏洞识别:
- 注意字符串扩展等边界条件
- 跟踪内存分配与实际使用情况
- 分析多个崩溃点间的关联性