第1章:Python模糊测试框架搭建

各位同学好,我是老周。在电信核心网干了十几年协议测试,今天咱们聊聊怎么搭一套趁手的模糊测试环境。说实话,很多新手一上来就想着跑大型工具,结果环境配三天,跑起来五分钟就崩了——这种事我见得太多了。

这一章,咱们从零开始,把Python环境、Scapy、Boofuzz这些基础工具捋一遍。最后我会带大家写一个最简单的自定义Fuzzer。嗯,别急,一步步来。

1.1 Python环境配置

我个人习惯用Python 3.8到3.10之间的版本。为什么?因为Scapy和Boofuzz在这些版本上最稳定。我曾经在Python 3.11上踩过坑,某些依赖库的二进制包还没跟上,折腾了半天。

建议用虚拟环境隔离项目,别把系统Python搞乱了。

推荐配置:

  • Python 3.9.13(我目前的主力版本)
  • pip 23.0+
  • virtualenv 或 conda 管理环境
# 创建虚拟环境
python -m venv fuzz_env
# 激活(Linux/Mac)
source fuzz_env/bin/activate
# 激活(Windows)
fuzz_env\Scripts\activate

# 升级pip
pip install --upgrade pip

小技巧: 我习惯在项目根目录放一个 requirements.txt,把所有依赖写进去。这样换机器时一行命令就能恢复环境。

1.2 Scapy库安装与基础使用

Scapy是协议模糊测试的瑞士军刀。说白了,它能让你像搭积木一样构造任意协议报文。我当年第一次用Scapy构造SIP消息时,感觉打开了新世界的大门。

安装

pip install scapy

装完验证一下:

python -c "from scapy.all import *; print('Scapy OK')"

基础用法

咱们先构造一个最简单的IP包。你想想看,核心网里跑的全是IP报文,这个基础必须打牢。

from scapy.all import *

# 构造一个IP包
pkt = IP(src="192.168.1.1", dst="10.0.0.1")/TCP(sport=1234, dport=5060)
pkt.show()

# 发送并接收响应
ans = sr1(pkt, timeout=2)
if ans:
    ans.show()

为什么会这样设计?Scapy用 / 操作符把协议层叠起来,非常直观。我在项目中经常用这个特性快速构造畸形报文——比如把IP头的 ihl 字段改成0,看看对端会不会崩溃。

注意: 发送原始报文需要root/管理员权限。我在Windows上吃过这个亏,折腾了半天才发现是权限问题。

1.3 Boofuzz框架入门

Boofuzz是Sulley的继承者,专门做协议模糊测试。我个人觉得它最大的优点是:你只需要定义协议结构,它自动帮你生成变异数据。

安装

pip install boofuzz

一个简单的例子

咱们用Boofuzz测试一个简单的TCP服务。假设目标监听在 127.0.0.1:8888

from boofuzz import *

def test_tcp():
    session = Session(
        target=Target(connection=TCPSocketConnection("127.0.0.1", 8888))
    )
    
    # 定义协议结构
    s_initialize("TestPacket")
    s_static("HELO")          # 固定头部
    s_delim(" ")              # 分隔符
    s_string("FUZZ", fuzzable=True)  # 模糊字段
    s_static("\r\n")          # 结束符
    
    session.connect(s_get("TestPacket"))
    session.fuzz()

if __name__ == "__main__":
    test_tcp()

这段代码里,s_string("FUZZ", fuzzable=True) 告诉Boofuzz:这个字段可以随便改。它会自动生成超长字符串、特殊字符、边界值等测试用例。

核心概念:

  • Session:管理整个测试流程
  • Target:定义被测目标
  • s_initialize:初始化一个协议模板
  • s_static/s_string:定义固定字段和可变字段

1.4 自定义Fuzzer编写基础

有时候现成的框架不够灵活,比如你想针对某个协议字段做特殊变异。这时候就得自己写Fuzzer了。别怕,其实核心逻辑很简单:构造报文 → 发送 → 监控响应。

下面是我写的一个最小化Fuzzer模板,你可以在此基础上扩展。

import socket
import random
from scapy.all import *

class SimpleFuzzer:
    def __init__(self, target_ip, target_port):
        self.target_ip = target_ip
        self.target_port = target_port
        self.sock = None
    
    def connect(self):
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock.settimeout(5)
        self.sock.connect((self.target_ip, self.target_port))
    
    def generate_payload(self):
        """生成随机载荷"""
        length = random.randint(1, 100)
        return bytes([random.randint(0, 255) for _ in range(length)])
    
    def send_payload(self, payload):
        try:
            self.sock.send(payload)
            response = self.sock.recv(1024)
            return response
        except Exception as e:
            print(f"发送失败: {e}")
            return None
    
    def fuzz(self, count=100):
        print(f"开始模糊测试 {self.target_ip}:{self.target_port}")
        for i in range(count):
            payload = self.generate_payload()
            print(f"[{i+1}/{count}] 发送 {len(payload)} 字节")
            resp = self.send_payload(payload)
            if resp:
                print(f"收到响应: {len(resp)} 字节")
            else:
                print("无响应或连接断开")
                # 重新连接
                self.connect()
        self.sock.close()

# 使用示例
if __name__ == "__main__":
    fuzzer = SimpleFuzzer("127.0.0.1", 8888)
    fuzzer.connect()
    fuzzer.fuzz(50)

这段代码虽然简单,但包含了Fuzzer的核心要素:

  • 连接管理:建立和断开socket
  • 载荷生成:随机数据生成器
  • 发送与监控:发送数据并捕获响应
  • 异常处理:连接断开后自动重连

避坑指南: 我曾经犯过一个错误——没有处理连接断开的情况。结果测试跑到一半,程序卡死在 recv() 上。后来我加上了超时和重连机制,才稳定下来。

知识体系总览

下面这张图概括了本章的核心内容。你可以把它当作搭建模糊测试环境的路线图。

Python模糊测试框架搭建 - 知识体系 1. Python环境配置 Python 3.8-3.10 | 虚拟环境 | pip依赖管理 推荐:Python 3.9.13 + virtualenv 2. 核心工具安装与使用 Scapy 协议报文构造/发送/解析 Boofuzz 自动化模糊测试框架 3. 自定义Fuzzer编写 连接管理 | 载荷生成 | 发送监控 | 异常处理 核心循环:构造 → 发送 → 监控 → 重连 4. 实战:电信核心网协议测试 SIP/Diameter/HTTP2 等协议模糊测试

这张图展示了从环境搭建到实战应用的完整路径。每一步都是下一层的基础,缺一不可。我个人建议你按照这个顺序来学习,别跳步。

本章小结:

  • Python环境用虚拟环境隔离,版本选3.9左右最稳
  • Scapy是构造协议报文的神器,/ 操作符要熟练
  • Boofuzz适合自动化测试,定义好协议结构就能跑
  • 自定义Fuzzer的核心是:构造→发送→监控→重连

好了,这一章的内容就到这里。环境搭好了,下一章咱们就开始玩真的——用Scapy构造SIP协议报文,看看核心网设备会有什么反应。


专注资料整理