初探BooFuzz
字数 1711 2025-08-05 08:17:20

BooFuzz模糊测试框架深入解析与实战应用

1. BooFuzz框架概述

BooFuzz是Sulley模糊测试框架的一个分支和继承者,在修复了许多错误的同时提升了可扩展性。它是一个功能强大的网络协议模糊测试框架,主要用于发现软件中的安全漏洞。

主要特性

  • 轻松快速的数据生成方式
  • 仪表板支持(故障检测)
  • 失败后的目标重置功能
  • 完善的测试数据记录
  • 在线文档支持
  • 支持任意通信媒介
  • 内置支持串行模糊测试、以太网、IP层和UDP广播
  • 更好的测试数据记录(统一、彻底、清晰)
  • 测试结果通过CSV导出
  • 可扩展的仪器/故障检测
  • 便捷的安装体验

2. 安装与配置

Ubuntu安装

sudo apt-get install python-pip
git clone https://github.com/jtpereyda/boofuzz.git
cd boofuzz
sudo pip install .

Windows安装

git clone https://github.com/jtpereyda/boofuzz.git
pip install .

3. 核心模块分析

Session模块

Session是BooFuzz的核心模块,负责管理整个模糊测试过程:

  • pre_send():发送数据后开始遍历Pgraph结构,并沿途fuzz每个组件
  • connect():声明连接关系
  • fuzz():发送负载并开始模糊测试

状态图(Pgraph)机制

BooFuzz通过构建有状态的图(Pgraph)将协议分解为单个请求,并fuzz所有可能路径:

  1. 以"helo"请求开头
  2. 完成后开始fuzz"mail from"请求(每个测试用例前加上有效的"helo"请求)
  3. 继续fuzz"rcpt to"请求(每个测试用例前加上有效的"helo"和"mail from"请求)
  4. 完成"data"请求后,又转回到从"ehlo"开始

回调函数

可以在图中每个节点定义回调函数,原型如下:

def callback(target, fuzz_data_logger, session, node, edge, *args, **kwargs)

参数说明:

  • target:目标对象
  • fuzz_data_logger:记录测试检查和通过/失败
  • session:指向会话实例的指针
  • node:要发送的节点
  • edge:当前fuzz到node的最后一条路径

静态协议定义

BooFuzz使用层次化的结构定义协议:

  1. Request:表示完整的消息
  2. Blocks:消息中的块
  3. Primitives:构成块/请求的基本元素(字节、字符串、数字、校验和等)

Block和Group机制

  • Block:将独立的primitives组建成有序的块
  • Group:包含特定的primitives,与Block结合后,每次调用Block时会循环取出Group中的数据组成不同的Block

示例:

s_initialize("HTTP VERBS")
s_group("verbs", values=["GET", "HEAD", "POST", "TRACE", "PUT", "DELETE"])
if s_block_start("body", group="verbs"):
    s_delim(" ")
    s_delim("/")
    s_string("index.html")
    s_delim(" ")
    s_string("HTTP")
    s_delim("/")
    s_string("1")
    s_delim(".")
    s_string("1")
    s_block_end()

常用语法

s_initialize('grammar')  # 初始化块请求并命名
s_static("HELLO \r\n")  # 始终发送此信息
s_static("PROCESS")     # 在HELLO \r\n之后立即发送
s_delim("")             # 使用s_delim()原语代替分割符
s_string("AAAA")        # 这是我们的fuzz字符串
s_static("\r\n")        # 告诉服务器"done"

4. 连接与监控

目标定义

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)
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()

监控代理

  1. netmon子模块

    • 捕捉网络双向流量并保存
    • 在发送数据前记录流量,成功后存入磁盘
  2. procmon子模块

    • 检测fuzz过程中发生的故障
    • 错误信息存储在"crash bin"文件中
    • 可在web监控服务中查看详细crash信息
  3. vmcontrol子模块

    • 控制虚拟机(启动、关闭、创建快照等)
    • 在目标崩溃时恢复主机状态

请求样例

session.connect(s_get("user"))
session.connect(s_get("user"), s_get("pass"))
session.connect(s_get("pass"), s_get("stor"))
session.connect(s_get("pass"), s_get("retr"))

5. 实战案例:Fuzzing Vulnserver

Vulnserver简介

Vulnserver是一个多线程的基于Windows的TCP服务器,监听端口9999,允许用户运行多个容易受到缓冲区溢出攻击的命令。

基础fuzz脚本

from boofuzz import *

def main():
    port = 9999
    host = '10.211.55.17'
    protocol = 'tcp'
    
    session = Session(
        target=Target(
            connection=SocketConnection(host, port, proto=protocol),
        ),
    )
    
    s_initialize("trun")
    s_string("TRUN", fuzzable=False)
    s_delim(" ", fuzzable=False)
    s_string("FUZZ")
    s_static("\r\n")
    
    session.connect(s_get("trun"))
    session.fuzz()

if __name__ == "__main__":
    main()

增强功能

1. 添加回调函数

session.connect(s_get("trun"), callback=get_banner)

def get_banner(target, my_logger, session, *args, **kwargs):
    banner_template = "Welcome to Vulnerable Server! Enter HELP for help."
    try:
        banner = target.recv(10000)
    except:
        print("Unable to connect. Target is down. Exiting.")
        exit(1)
    
    my_logger.log_check('Receiving banner..')
    if banner_template in banner:
        my_logger.log_pass('banner received')
    else:
        my_logger.log_fail('No banner received')
        print("No banner received, exiting..")
        exit(1)

2. 日志记录

csv_log = open('fuzz_results.csv', 'wb')
my_logger = [FuzzLoggerCsv(file_handle=csv_log)]
fuzz_loggers = my_logger

3. 进程监控

procmon = pedrpc.Client(host, 26002)
procmon_options = {
    "proc_name": "vulnserver.exe",
    "stop_commands": ['wmic process where (name="vulnserver") delete'],
    "start_commands": ['vulnserver.exe'],
}

完整fuzz脚本

from boofuzz import *
from sys import exit

def get_banner(target, my_logger, session, *args, **kwargs):
    banner_template = "Welcome to Vulnerable Server! Enter HELP for help."
    try:
        banner = target.recv(10000)
    except:
        print("Unable to connect. Target is down. Exiting.")
        exit(1)
    
    my_logger.log_check('Receiving banner..')
    if banner_template in banner:
        my_logger.log_pass('banner received')
    else:
        my_logger.log_fail('No banner received')
        print("No banner received, exiting..")
        exit(1)

def main():
    port = 9999
    host = '127.0.0.1'
    protocol = 'tcp'
    
    s_initialize("Vulnserver")
    s_group("verbs", values=["TRUN", "GMON", "KSTET"])
    if s_block_start("test", group="verbs"):
        s_delim(" ")
        s_string("AAA")
        s_string("\r\n")
        s_block_end("test")
    
    csv_log = open('fuzz_results.csv', 'wb')
    my_logger = [FuzzLoggerCsv(file_handle=csv_log)]
    
    session = Session(
        target=Target(
            connection=SocketConnection(host, port, proto=protocol),
            procmon=pedrpc.Client(host, 26002),
            procmon_options={
                "proc_name": "vulnserver.exe",
                "stop_commands": ['wmic process where (name="vulnserver") delete'],
                "start_commands": ['vulnserver.exe'],
            }
        ),
        fuzz_loggers=my_logger,
        crash_threshold_element=1,  # Crash多少次后停止
    )
    
    session.connect(s_get("Vulnserver"), callback=get_banner)
    session.fuzz()

if __name__ == "__main__":
    main()

6. 监控与分析

Web界面

访问http://127.0.0.1:26000可以观察fuzz测试进度,显示完整性和导致崩溃的输入文件。

结果分析

  • 查看fuzz_results.csv文件获取payload信息
  • 分析崩溃时的寄存器状态(如EIP被41414141覆盖)
  • 使用记录的payload进行复现和利用

7. 最佳实践

  1. 协议建模:准确建模目标协议的状态转换
  2. 监控配置:合理配置netmon、procmon和vmcontrol
  3. 回调函数:使用回调函数增强测试逻辑
  4. 日志记录:充分利用CSV日志和Web界面
  5. 崩溃阈值:设置合理的crash_threshold_element
  6. 测试范围:使用s_group覆盖所有可能的命令和参数

8. 参考资源

  1. Vulnserver利用参考
  2. BooFuzz相关技术文章
  3. Sulley框架介绍
  4. Fuzzing技术指南
BooFuzz模糊测试框架深入解析与实战应用 1. BooFuzz框架概述 BooFuzz是Sulley模糊测试框架的一个分支和继承者,在修复了许多错误的同时提升了可扩展性。它是一个功能强大的网络协议模糊测试框架,主要用于发现软件中的安全漏洞。 主要特性 轻松快速的数据生成方式 仪表板支持(故障检测) 失败后的目标重置功能 完善的测试数据记录 在线文档支持 支持任意通信媒介 内置支持串行模糊测试、以太网、IP层和UDP广播 更好的测试数据记录(统一、彻底、清晰) 测试结果通过CSV导出 可扩展的仪器/故障检测 便捷的安装体验 2. 安装与配置 Ubuntu安装 Windows安装 3. 核心模块分析 Session模块 Session 是BooFuzz的核心模块,负责管理整个模糊测试过程: pre_send() :发送数据后开始遍历Pgraph结构,并沿途fuzz每个组件 connect() :声明连接关系 fuzz() :发送负载并开始模糊测试 状态图(Pgraph)机制 BooFuzz通过构建有状态的图(Pgraph)将协议分解为单个请求,并fuzz所有可能路径: 以"helo"请求开头 完成后开始fuzz"mail from"请求(每个测试用例前加上有效的"helo"请求) 继续fuzz"rcpt to"请求(每个测试用例前加上有效的"helo"和"mail from"请求) 完成"data"请求后,又转回到从"ehlo"开始 回调函数 可以在图中每个节点定义回调函数,原型如下: 参数说明: target :目标对象 fuzz_data_logger :记录测试检查和通过/失败 session :指向会话实例的指针 node :要发送的节点 edge :当前fuzz到node的最后一条路径 静态协议定义 BooFuzz使用层次化的结构定义协议: Request :表示完整的消息 Blocks :消息中的块 Primitives :构成块/请求的基本元素(字节、字符串、数字、校验和等) Block和Group机制 Block :将独立的primitives组建成有序的块 Group :包含特定的primitives,与Block结合后,每次调用Block时会循环取出Group中的数据组成不同的Block 示例: 常用语法 4. 连接与监控 目标定义 监控代理 netmon子模块 : 捕捉网络双向流量并保存 在发送数据前记录流量,成功后存入磁盘 procmon子模块 : 检测fuzz过程中发生的故障 错误信息存储在"crash bin"文件中 可在web监控服务中查看详细crash信息 vmcontrol子模块 : 控制虚拟机(启动、关闭、创建快照等) 在目标崩溃时恢复主机状态 请求样例 5. 实战案例:Fuzzing Vulnserver Vulnserver简介 Vulnserver是一个多线程的基于Windows的TCP服务器,监听端口9999,允许用户运行多个容易受到缓冲区溢出攻击的命令。 基础fuzz脚本 增强功能 1. 添加回调函数 2. 日志记录 3. 进程监控 完整fuzz脚本 6. 监控与分析 Web界面 访问 http://127.0.0.1:26000 可以观察fuzz测试进度,显示完整性和导致崩溃的输入文件。 结果分析 查看 fuzz_results.csv 文件获取payload信息 分析崩溃时的寄存器状态(如EIP被41414141覆盖) 使用记录的payload进行复现和利用 7. 最佳实践 协议建模 :准确建模目标协议的状态转换 监控配置 :合理配置netmon、procmon和vmcontrol 回调函数 :使用回调函数增强测试逻辑 日志记录 :充分利用CSV日志和Web界面 崩溃阈值 :设置合理的crash_ threshold_ element 测试范围 :使用s_ group覆盖所有可能的命令和参数 8. 参考资源 Vulnserver利用参考 BooFuzz相关技术文章 Sulley框架介绍 Fuzzing技术指南