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的一般步骤:

  1. 定义session
  2. 定义协议格式
  3. session.connect()
  4. 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博客园高强度在线,奥利给)

posted @   snail1502  阅读(670)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示