boofuzz入门与源码简析
boofuzz基本使用
官方手册:https://boofuzz.readthedocs.io/en/stable/index.html
GitHub:https://github.com/jtpereyda/boofuzz
boofuzz分类:协议模糊测试,黑盒,基于生成
boofuzz源码
问题:
- 如何与目标建立连接的?
- socket,端口号,在fuzz过程中如何使用?
- 如何生成测试用例?
- 图结构?
- 如何从崩溃断点处继续测试?
- 如何重新建立连接?端口号?
boofuzz代码结构
blocks
connections
legos
monitors
pgraph
primitives
sessions
utils
web (web端口 localhost:26000 不太核心先不讨论)
以官方文档的示例代码为例:
session = Session(
target=Target(
connection=TCPSocketConnection("127.0.0.1", 8021)))
user = Request("user", children=(
String("key", "USER"),
Delim("space", " "),
String("val", "anonymous"),
Static("end", "\r\n"),
))
session.connect(user)
session.fuzz()
boofuzz的一般步骤:
- 定义session
- 定义协议格式
- session.connect()
- session.fuzz()
定义session
session = Session(
target=Target(
connection=TCPSocketConnection("127.0.0.1", 8021)))
涉及到:sessions,connections两块代码
sessions包含:
- target.py 定义了Target类
- connection 关键变量
- open()
- close()
- send()
- recv() 等方法
self._target_connection = connection
self._target_connection.open()
self._target_connection.close()
self._target_connection.send()
self._target_connection.recv()
connections
itarget_connection.py
base_socket_connection.py
tcp_socket_connection.py
socket_connection.py
connection来自connections的TCPSocketConnection()
TCPSocketConnection()使用了socketimport socket
类继承关系
class ABCMeta
class ITargetConnection
class BaseSocketConnection
class TCPSocketConnection
基于socket做封装
实现了open() close() connect() send() recv()用于和目标建立连接和发送测试用例
sessions
sessions.connect()
用于连接两个request,如果只有一个参数则和root连接
sessions.fuzz()
session.fuzz()
_main_fuzz_loop()
server_init()
_start_target()
_fuzz_current_case()
_pause_if_pause_flag_is_set()
_open_connection_keep_trying()
_pre_send()
_callback_current_node()
open_test_step()
transmit_normal() or transmit_fuzz()
_check_for_passively_detected_failures()
在_main_fuzz_loop()
使用total_mutant_index来表示变异index,在_generate_mutations_indefinitely()中递增。
total_mutant_index小于index_start时跳过,不发送测试用例。
因此可以使用session的index_start
参数来指定从第几个用例开始fuzz(可用于跳过已知的可触发崩溃的测试用例)
至此,可以解决问题1和问题3。
boofuzz如何生成测试用例
先看boofuzz如何将测试用例发送给目标
fuzz()
_main_fuzz_loop(self, fuzz_case_iterator)
#fuzz_case_iterator使用以下函数传入
#_generate_mutations_indefinitely() #用于生成变异的测试用例
#_generate_test_case_from_named_mutations()
_fuzz_current_case()
transmit_fuzz()
send(data) #完成向目标发送测试用例
如何生成测试用例?
具体分析_generate_mutations_indefinitely()如何工作的。
#boofuzz使用yield来写生成测试用例的函数
_generate_mutations_indefinitely()
_generate_n_mutations()
#两个嵌套的for循环
for _iterate_protocol_message_paths()
for _generate_n_mutations_for_path()
################################
_iterate_protocol_message_paths()
_iterate_protocol_message_paths_recursive()
#一个递归函数,实现了深度优先遍历XXX
################################
_generate_n_mutations_for_path()
_generate_n_mutations_for_path_recursive()
#一个递归函数,实现了深度优先遍历XXX
_generate_mutations_for_request()
get_mutation() #此函数的实现在/boocks/request.py中
################################
### /boocks/request.py
### fuzzable_block.py
### fuzzable.py
get_mutation()
mutations() #实现于fuzzable_block.py中
get_mutations() #实现于fuzzable.py中
mutations() #位于fuzzable.py中,是一个抽象方法给子类自己实现
类继承关系:
class Fuzzable
class FzzableBlock
class Requst
class Fuzzable
class Byte
class Bytes
Class String
#...#
#以上这些不同格式的变异字段类分别定义了自己的mutations()函数生成变异
至此boofuzz核心代码结构简单析完毕,可以回答本文的三个问题了。
可以利用boofuzz框架自己设计字段格式类,实现变异方法自定义自己的生成方法。
有问题的同学欢迎留言讨论共同进步(snail1502博客园高强度在线,奥利给)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?