从源码的角度学习 boofuzz 函数的使用
字数 3215 2025-08-22 18:37:14

Boofuzz 源码分析与使用详解

1. Boofuzz 概述

Boofuzz 是一款流行的网络黑盒模糊测试工具,主要用于生成网络协议数据包进行模糊测试。与基于变异的模糊测试不同,Boofuzz 采用基于生成的测试方法,这意味着:

  • 不需要收集目标程序的反馈信息(如代码覆盖率)
  • 测试用例生成是独立的,新用例与旧用例无直接关系
  • 属于纯黑盒测试方法

2. Boofuzz 基本组成结构

Boofuzz 测试用例由三个核心元素构成:

2.1 Request(请求)

  • 代表一个完整的测试用例(数据包)
  • 使用 self.stack 列表存储所有 Block 和 Primitive
  • 使用 self.block_stack 存储当前"打开"的 Block
  • 使用 self.names 字典存储所有 Block 和 Primitive(key 为 qualified_name)

2.2 Block(块)

  • 表示多个字段的集合
  • 用于对字段组进行统一操作(如计算长度、校验和等)
  • 可以嵌套包含其他 Block 或 Primitive

2.3 Primitive(原语)

  • 代表数据包中的最小字段单元
  • 是测试用例生成的基本单位
  • 有多种类型,每种类型有不同的生成策略

三者关系:Request > Block > Primitive

3. Primitive 类型及生成策略

3.1 BitField

  • 参数
    • width:bit 位宽度(默认8)
    • max_num:最大值(默认None)
    • full_range:是否使用全量数据(默认False)
  • 生成策略
    • 全量数据:生成0到指定width能表示的最大值
    • 非全量:使用特殊边界值
  • 快捷函数
    • s_byte/s_char(8位)
    • s_word/s_short(16位)
    • s_dword/s_int/s_long(32位)
    • s_qword/s_double(64位)

3.2 Bytes

  • 参数
    • size:字节数(None表示任意长度)
    • padding:填充字节(默认\x00)
    • max_len:最大长度(size为None时使用)
  • 生成策略
    • 使用特殊值测试溢出
    • 重复默认值
    • 特殊值替换原始值每个位置
    • 根据size和max_len限制长度

3.3 Delim

  • 生成策略
    • 重复默认值
    • 使用特殊值

3.4 Float

  • 参数
    • s_format:格式化字符串(默认".1f")
    • f_min:最小值(默认0.0)
    • f_max:最大值(默认100.0)
    • max_mutations:最大生成次数(默认1000)
  • 生成策略
    • 使用默认值
    • 从f_min到f_max随机取值

3.5 FromFile

  • 参数
    • filename:文件通配符(如*.txt)
    • max_len:最大长度(默认0)
  • 生成策略
    • 使用文件内容
    • 根据max_len过滤

3.6 Mirror

  • 参数
    • primitive_name:目标原语名称
  • 生成策略
    • 与目标原语保持一致

3.7 RandomData

  • 参数
    • min_length:最小长度(默认0)
    • max_length:最大长度(默认1)
    • max_mutations:最大生成次数(默认25)
    • step:长度变化步长(默认None)
  • 生成策略
    • 根据长度随机生成0-255字节

3.8 String

  • 参数
    • size:长度(None表示随机)
    • padding:填充字节(默认\x00)
    • encoding:编码方式(默认ascii)
    • max_size:最大长度
  • 生成策略
    • 使用特殊值测试命令注入
    • 重复默认值(2、10、100次)
    • 使用边界长度
    • 特殊长度插入\x00
    • 根据max_len和size限制长度
  • 快捷函数
    • s_cstring:字符串后加\x00

3.9 Group & Simple

  • Group参数
    • values:取值列表
    • encoding:编码方式(默认ascii)
  • Simple参数
    • fuzz_values:取值列表
  • 生成策略
    • 从列表中顺序取值
  • 区别
    • Group用于bytes,Simple用于字符串

3.10 Static

  • 固定值,不参与模糊测试
  • 快捷函数
    • s_static
    • s_raw
    • s_unknown
    • s_dunno

3.11 绑定Block的原语

Checksum

  • 参数
    • block_name:绑定Block名称
    • algorithm:算法(crc32, crc32c, adler32, md5, sha1, ipv4, udp)
    • length:自定义算法时需要
    • endian:大小端
    • ipv4_src_block_name:udp算法需要
    • ipv4_dst_block_name:udp算法需要
  • 功能:计算指定Block的校验和

Repeat

  • 参数
    • block_name:绑定Block名称
    • min_reps:最小重复次数
    • max_reps:最大重复次数
    • step:变化步长(默认1)
  • 功能:重复指定Block

Size

  • 参数
    • block_name:绑定Block名称
    • offset:起始偏移(默认0)
    • length:描述长度的字节数(默认4)
    • endian:大小端
    • output_format:输出格式(bytes或ascii)
    • inclusive:是否包含自身
  • 功能:计算指定Block的长度
  • 快捷函数
    • s_size
    • s_sizer

4. 核心函数详解

4.1 Request 操作函数

s_initialize

  • 定义一个新的Request
  • 存储在全局字典blocks.REQUEST
  • 设置blocks.CURRENT为当前Request

s_switch

  • 切换当前使用的Request
  • 修改blocks.CURRENT

s_get

  • 根据name从blocks.REQUEST获取Request
  • name为None时返回blocks.CURRENT

s_update

  • 参数
    • name:qualified_name
    • value:替换值
  • 功能:替换指定Primitive的default_value

4.2 Block 操作函数

s_block_start & s_block_end

  • 管理self.block_stack
  • 用于生成context_path和qualified_name

s_block

  • 定义Block
  • 支持with语法(自动调用start/end)
  • 重要参数
    • group:绑定其他Primitive实现联动变化

s_align

  • 参数
    • modulus:对齐字节数
    • pattern:填充字节
  • 功能:使Block按指定字节对齐
  • 支持with语法

4.3 其他实用函数

s_binary

  • 将16进制字符串转换为字节
  • 定义为Static原语

s_lego

  • 未文档化,不建议使用

s_hexdump

  • 返回字符串的16进制表示

5. 使用示例

HTTP请求示例

s_initialize(name="Request")
with s_block("Request-Line"):
    s_group("Method", ["GET", "HEAD", "POST", "PUT", "DELETE", "CONNECT", "OPTIONS", "TRACE"])
    s_delim(" ", name="space-1")
    s_string("/index.html", name="Request-URI")
    s_delim(" ", name="space-2")
    s_string("HTTP/1.1", name="HTTP-Version")
    s_static("\r\n", name="Request-Line-CRLF")
    
s_string("Host:", name="Host-Line")
s_delim(" ", name="space-3")
s_string("example.com", name="Host-Line-Value")
s_static("\r\n", name="Host-Line-CRLF")

s_static("Content-Length:", name="Content-Length-Header")
s_delim(" ", name="space-4")
s_size("Body-Content", output_format="ascii", name="Content-Length-Value")
s_static("\r\n", "Content-Length-CRLF")
s_static("\r\n", "Request-CRLF")

with s_block("Body-Content"):
    s_string("Body content ...", name="Body-Content-Value")

Block绑定Group示例

s_initialize("example")
s_simple("simple_field1", fuzz_values=["a", "b"])
s_group("group_field1", values=[b"\x01", b"\x02"])

with s_block("block1", group="group_field1"):
    s_bit_field(0xff, width=8, name="bit_field1")
    s_simple("simple_field2", fuzz_values=["x", "y"])

6. 总结

Boofuzz 提供了丰富的原语类型和灵活的测试用例构建方式,通过Request-Block-Primitive的三层结构,可以方便地描述各种网络协议数据包。关键点包括:

  1. 理解基于生成的模糊测试与基于变异的区别
  2. 掌握三种核心元素的关系和使用方法
  3. 熟悉各种Primitive的生成策略和参数
  4. 善用Block的group参数实现联动变化
  5. 合理使用校验和、长度计算等绑定Block的原语

通过深入理解这些概念和函数,可以更有效地使用Boofuzz进行网络协议模糊测试。

Boofuzz 源码分析与使用详解 1. Boofuzz 概述 Boofuzz 是一款流行的网络黑盒模糊测试工具,主要用于生成网络协议数据包进行模糊测试。与基于变异的模糊测试不同,Boofuzz 采用基于生成的测试方法,这意味着: 不需要收集目标程序的反馈信息(如代码覆盖率) 测试用例生成是独立的,新用例与旧用例无直接关系 属于纯黑盒测试方法 2. Boofuzz 基本组成结构 Boofuzz 测试用例由三个核心元素构成: 2.1 Request(请求) 代表一个完整的测试用例(数据包) 使用 self.stack 列表存储所有 Block 和 Primitive 使用 self.block_stack 存储当前"打开"的 Block 使用 self.names 字典存储所有 Block 和 Primitive(key 为 qualified_ name) 2.2 Block(块) 表示多个字段的集合 用于对字段组进行统一操作(如计算长度、校验和等) 可以嵌套包含其他 Block 或 Primitive 2.3 Primitive(原语) 代表数据包中的最小字段单元 是测试用例生成的基本单位 有多种类型,每种类型有不同的生成策略 三者关系:Request > Block > Primitive 3. Primitive 类型及生成策略 3.1 BitField 参数 : width :bit 位宽度(默认8) max_num :最大值(默认None) full_range :是否使用全量数据(默认False) 生成策略 : 全量数据:生成0到指定width能表示的最大值 非全量:使用特殊边界值 快捷函数 : s_byte / s_char (8位) s_word / s_short (16位) s_dword / s_int / s_long (32位) s_qword / s_double (64位) 3.2 Bytes 参数 : size :字节数(None表示任意长度) padding :填充字节(默认\x00) max_len :最大长度(size为None时使用) 生成策略 : 使用特殊值测试溢出 重复默认值 特殊值替换原始值每个位置 根据size和max_ len限制长度 3.3 Delim 生成策略 : 重复默认值 使用特殊值 3.4 Float 参数 : s_format :格式化字符串(默认".1f") f_min :最小值(默认0.0) f_max :最大值(默认100.0) max_mutations :最大生成次数(默认1000) 生成策略 : 使用默认值 从f_ min到f_ max随机取值 3.5 FromFile 参数 : filename :文件通配符(如* .txt) max_len :最大长度(默认0) 生成策略 : 使用文件内容 根据max_ len过滤 3.6 Mirror 参数 : primitive_name :目标原语名称 生成策略 : 与目标原语保持一致 3.7 RandomData 参数 : min_length :最小长度(默认0) max_length :最大长度(默认1) max_mutations :最大生成次数(默认25) step :长度变化步长(默认None) 生成策略 : 根据长度随机生成0-255字节 3.8 String 参数 : size :长度(None表示随机) padding :填充字节(默认\x00) encoding :编码方式(默认ascii) max_size :最大长度 生成策略 : 使用特殊值测试命令注入 重复默认值(2、10、100次) 使用边界长度 特殊长度插入\x00 根据max_ len和size限制长度 快捷函数 : s_cstring :字符串后加\x00 3.9 Group & Simple Group参数 : values :取值列表 encoding :编码方式(默认ascii) Simple参数 : fuzz_values :取值列表 生成策略 : 从列表中顺序取值 区别 : Group用于bytes,Simple用于字符串 3.10 Static 固定值,不参与模糊测试 快捷函数 : s_static s_raw s_unknown s_dunno 3.11 绑定Block的原语 Checksum 参数 : block_name :绑定Block名称 algorithm :算法(crc32, crc32c, adler32, md5, sha1, ipv4, udp) length :自定义算法时需要 endian :大小端 ipv4_src_block_name :udp算法需要 ipv4_dst_block_name :udp算法需要 功能 :计算指定Block的校验和 Repeat 参数 : block_name :绑定Block名称 min_reps :最小重复次数 max_reps :最大重复次数 step :变化步长(默认1) 功能 :重复指定Block Size 参数 : block_name :绑定Block名称 offset :起始偏移(默认0) length :描述长度的字节数(默认4) endian :大小端 output_format :输出格式(bytes或ascii) inclusive :是否包含自身 功能 :计算指定Block的长度 快捷函数 : s_size s_sizer 4. 核心函数详解 4.1 Request 操作函数 s_ initialize 定义一个新的Request 存储在全局字典 blocks.REQUEST 中 设置 blocks.CURRENT 为当前Request s_ switch 切换当前使用的Request 修改 blocks.CURRENT s_ get 根据name从 blocks.REQUEST 获取Request name为None时返回 blocks.CURRENT s_ update 参数 : name :qualified_ name value :替换值 功能 :替换指定Primitive的default_ value 4.2 Block 操作函数 s_ block_ start & s_ block_ end 管理 self.block_stack 用于生成context_ path和qualified_ name s_ block 定义Block 支持with语法(自动调用start/end) 重要参数 : group :绑定其他Primitive实现联动变化 s_ align 参数 : modulus :对齐字节数 pattern :填充字节 功能 :使Block按指定字节对齐 支持with语法 4.3 其他实用函数 s_ binary 将16进制字符串转换为字节 定义为Static原语 s_ lego 未文档化,不建议使用 s_ hexdump 返回字符串的16进制表示 5. 使用示例 HTTP请求示例 Block绑定Group示例 6. 总结 Boofuzz 提供了丰富的原语类型和灵活的测试用例构建方式,通过Request-Block-Primitive的三层结构,可以方便地描述各种网络协议数据包。关键点包括: 理解基于生成的模糊测试与基于变异的区别 掌握三种核心元素的关系和使用方法 熟悉各种Primitive的生成策略和参数 善用Block的group参数实现联动变化 合理使用校验和、长度计算等绑定Block的原语 通过深入理解这些概念和函数,可以更有效地使用Boofuzz进行网络协议模糊测试。