Boofuzz介绍
官方文档
https://github.com/jtpereyda/boofuzz
FUZZ案例脚本
boofuzz/examples at master · jtpereyda/boofuzz · GitHub
boofuzz/request_definitions at master · jtpereyda/boofuzz · GitHub
api文档
boofuzz: Network Protocol Fuzzing for Humans — boofuzz 0.4.1 documentation
Boofuzz是一个基于著名的Sulley模糊测试框架的分支和继承者。除了修复了许多bug,Boofuzz还致力于扩展性。其目标是:fuzz everything。
关于Sulley
https://github.com/Bit9/sulley
Sulley 是一款开源模糊测试工具的佼佼者,但是已经不再维护了。
Boofuzz特点
和 Sulley 一样,boofuzz 包含了所有关键的模糊测试元素:
- 易于快速生成数据。
- 插桩 - 即故障检测。
- 故障后目标重置。
- 记录测试数据。
与 Sulley 不同,boofuzz 还具有:
- 在线文档。
- 支持任意通信介质。
- 内置支持串行模糊测试、以太网和 IP 层、UDP 广播。
- 更好的测试数据记录 - 一致、全面、清晰。
- 测试结果 CSV 导出。
- 可扩展的插桩/故障检测。
- 安装体验更加简单!
- 错误更少。
Boofuzz安装
Windows安装
git clone https://github.com/jtpereyda/boofuzz.git
cd boofuzz
pip install .
其他系统安装方式参考官方文档:Installing boofuzz — boofuzz 0.4.1 documentation
Boofuzz使用
Boofuzz API
Session — boofuzz 0.4.1 documentation
api模块
- Session
- Target
- Connections
- Monitors
- Logging
- Protocol Definition
由于官方API文档对此的描述非常详细,一般是需要的时候再来找对应的api使用即可,鉴于刚开始使用过于繁杂,我们拿一个官方提供的脚本来解析对应的基础功能来快速入门。
下面一个是通过对FTP协议的默认端口进行FUZZ的脚本;
#!/usr/bin/env python3
"""Demo FTP fuzzer as a standalone script."""from boofuzz import *def main():"""This example is a very simple FTP fuzzer. It uses no process monitory(procmon) and assumes that the FTP server is already running."""session = Session(target=Target(connection=TCPSocketConnection("127.0.0.1", 21)))define_proto(session=session)session.fuzz()def define_proto(session):# disable Black formatting to keep custom indentation# fmt: offuser = Request("user", children=(String(name="key", default_value="USER"),Delim(name="space", default_value=" "),String(name="val", default_value="anonymous"),Static(name="end", default_value="\r\n"),))passw = Request("pass", children=(String(name="key", default_value="PASS"),Delim(name="space", default_value=" "),String(name="val", default_value="james"),Static(name="end", default_value="\r\n"),))stor = Request("stor", children=(String(name="key", default_value="STOR"),Delim(name="space", default_value=" "),String(name="val", default_value="AAAA"),Static(name="end", default_value="\r\n"),))retr = Request("retr", children=(String(name="key", default_value="RETR"),Delim(name="space", default_value=" "),String(name="val", default_value="AAAA"),Static(name="end", default_value="\r\n"),))# fmt: onsession.connect(user)session.connect(user, passw)session.connect(passw, stor)session.connect(passw, retr)def define_proto_static(session):"""Same protocol, using the static definition style."""s_initialize("user")s_string("USER")s_delim(" ")s_string("anonymous")s_static("\r\n")s_initialize("pass")s_string("PASS")s_delim(" ")s_string("james")s_static("\r\n")s_initialize("stor")s_string("STOR")s_delim(" ")s_string("AAAA")s_static("\r\n")s_initialize("retr")s_string("RETR")s_delim(" ")s_string("AAAA")s_static("\r\n")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"))if __name__ == "__main__":main()
BooFuzz快速指引
实例化Session
对象
Session对象是模糊测试会话的中心。创建Session对象时,需要传递一个Target对象,该对象本身将接收一个Connection对象。例如:
session = Session(target=Target(connection=TCPSocketConnection("127.0.0.1", 80)),)
连接对象实现 ITargetConnection。可用选项包括:
- TCPSocketConnection
- UDPSocketConnection
- SSLSocketConnection
- RawL2SocketConnection
- RawL3SocketConnection
- SocketConnection (depreciated)
- SerialConnection
每一个都有对应的协议,具体用法可以参考官方说明;
有了Session对象后,接下来需要定义协议中的消息;
定义消息(Request)
user = Request("user", children=(String(name="key", default_value="USER"),Delim(name="space", default_value=" "),String(name="val", default_value="anonymous"),Static(name="end", default_value="\r\n"),))passw = Request("pass", children=(String(name="key", default_value="PASS"),Delim(name="space", default_value=" "),String(name="val", default_value="james"),Static(name="end", default_value="\r\n"),))stor = Request("stor", children=(String(name="key", default_value="STOR"),Delim(name="space", default_value=" "),String(name="val", default_value="AAAA"),Static(name="end", default_value="\r\n"),))retr = Request("retr", children=(String(name="key", default_value="RETR"),Delim(name="space", default_value=" "),String(name="val", default_value="AAAA"),Static(name="end", default_value="\r\n"),))
"""
这里的代码是跟上面一样的作用,只是换一种取值方式
"""
#s_initialize 初始化一个新的块请求。此调用后生成的所有块/原语都适用于命名请求。s_initialize("user")
#s_string 将字符串压入当前块堆栈。s_string("USER")
#s_delim 将分隔符压入当前块堆栈。s_delim(" ")s_string("anonymous")
#s_static 将静态值压入当前块堆栈。s_static("\r\n")
一旦定义了信息,将使用刚刚创建的Session对象将它们连接成一个图形:
#s_get 返回具有指定名称的请求,如果未指定名称,则返回当前请求。使用它可以从全局函数样式请求操作切换到直接对象操作。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"))
根据上面构建的顺序,当模糊化时,boofuzz将在模糊化passw之前发送user,在模糊化stor或retr之前发送user和passw。
Fuzz
通过下面代码既可以开始模糊测试;
session.fuzz()
查看结果
注意,此时你只有一个非常基本的模糊测试器。如何让它更加强大取决于你。存储每次运行的日志数据将保存在当前工作目录中的boofuzz-results目录中的SQLite数据库中。你可以随时使用这些数据库重新打开Web界面。
$ boo open <run-*.db>
官方提供了很多案例模板,且网上关于boofuzz的使用介绍很多,也比较成熟,在各个领域都有,可以通过官方提供的案例也看得出来,然后覆盖的面也非常的全,目前也就只有ble、zigbee这种无线电通信协议的覆盖不了。
参考
初探BooFuzz - 先知社区
IoT 设备网络协议模糊测试工具boofuzz实战_江下枫的博客-CSDN博客