Modbus-TCP模糊测试实战解析

Modbus Fuzzing Lab

Github仓库地址

1. 前言

针对Modbus TCP协议中的03功能码-读取保存寄存器开发的模糊测试教学实验平台,是一个非常非常非常简陋的初级版本,用于课程作业

2.Modbus-TCP 协议深度解析

2.1 协议体系结构

2.1.1 OSI 7层模型定位

Modbus-TCP 协议是工业自动化领域的一种应用层报文传输协议,它是将传统的 Modbus 序列通信协议通过 TCP/IP 网络进行封装的产物;Modbus-TCP 严格遵循 OSI 7 层模型,其运行在 TCP/IP 协议栈上,属于应用层协议。

与运行在物理层串口 RS-485/232 的 Modbus-RTU 不同,Modbus-TCP 剥离了 RTU 报文中的循环冗余校验校验字段,因为 TCP 协议与以太网链路层已经提供了完善的差错控制机制;并将 Modbus 的应用数据单元 ADU 封装在标准的 TCP/IP 协议栈中。

2.1.2 Client/Server 通信模型

Modbus-TCP 改变了传统串行通信中的主从概念(Master/Slave),转而采用以太网通用的客户端/服务器模型(Client/Server):

  • 客户端:发起请求,主动建立 TCP 连接,并发送包含功能码和地址的请求报文;在本次实验中,客户端为基于 Python Boofuzz 编写的 fuzz 测试脚本
  • 服务器:Modbus-TCP 服务器默认监听在 502 端口,负责接收请求、解析报文逻辑并返回响应或执行相应的输出控制;在本次实验中,Modbus-TCP 服务器为用 Node.js 编写的模拟器

这种模型的优势在于支持多连接并发,使得一个控制中心可以同时访问数十台甚至上百台 PLC 节点,但也增加了协议解析器在处理高并发畸形报文时的压力

Modbus-TCP 的核心在于 ADU 的构成,由两部分组成:MBAP 报文头与协议数据单元 PDU

2.2 MBAP 报文头格式

Modbus-TCP 协议的 MBAP 报文头固定 7 字节长,一共有 4 个字段:

2.2.1 事务标识符 (Transaction Identifier)

  • 长度:2 字节
  • 作用:用于标识每个 Modbus-TCP 请求和响应事务,允许客户端和服务器能够将请求和响应进行配对,确保请求和响应的正确匹配。每次发起请求时,客户端会设置一个唯一的事务标识符,而服务器在响应时会返回相同的事务标识符。

2.2.2 协议标识符 (Protocol Identifier)

  • 长度:2 字节
  • 作用 :用于标识 Modbus 协议的版本和类型。对于 Modbus-TCP 协议,协议标识符的值通常为 00 00

2.2.3 长度 (Length)

  • 长度:2 字节
  • 作用:指示后续数据的字节数,通常是数据部分的长度。该字段的值包括从 Unit ID 字段开始,直至整个报文的末尾数据的长度。

2.2.4 单元标识符 (Unit ID)

  • 长度:1 字节
  • 作用:单元标识符用于标识 Modbus 设备的具体单元或节点。在 Modbus-TCP 协议中,单元标识符通常用于识别请求数据的目标设备,尤其在多设备环境中,能确保数据被送到正确的目标设备。

2.3 PDU 格式

Modbus-TCP 协议的 PDU 按照字段可分为:

  • 功能码 (Function Data)
    • 长度:1 字节
    • 作用:指示 Modbus 设备执行某个特定的操作。
    • 常见功能码
      • 0x01:读取线圈状态
      • 0x02:读取离散输入状态
      • 0x03:读取保持寄存器
      • 0x04:读取输入寄存器
      • 0x05:强制单个线圈
      • 0x06:强制单个寄存器
      • 0x0F:强制多个线圈
      • 0x10:预置多个寄存器
  • 数据(以 0x03 功能码为例)
    • 对于请求报文
      • 长度:4 字节
      • 内容:起始寄存器地址与寄存器数量各占 2 字节
    • 对于响应报文
      • 长度:不固定
      • 内容
        • 字节数:表示在这之后有多少字节的数据
        • 读取值:寄存器中的值(高位 1 字节,低位 1 字节)

2.4 字节序与数据处理

2.4.1 Modbus-TCP 所使用的字节序

Modbus-TCP 协议严格规定采用大端序进行数据传输;即数据的高位字节存储在低地址内存中,而低位字节存储高地址内存中。

Node.js 模拟器端的处理 :在模拟器实现代码中,利用 Node.js 原生的 Buffer 对象进行二进制解析。代码中使用 readUInt16BE() 方法,其中 "BE" 后缀明确代表大端序读取。

实现逻辑const declaredLen = data.readUInt16BE(4); 该行代码确保了从报文第 5、6 字节中正确提取出 Length 字段的数值。

Python Boofuzz 端的处理 :在 fuzzer.py 建模中,通过 s_word 原语定义 16 位字段,使用 endian='>' 参数来指定大端序

3. 模糊测试技术原理

3.1 模糊测试技术概述

模糊测试(Fuzzing)是一种自动化的软件漏洞挖掘技术,其核心思想是向目标系统输入大量精心构造的、非预期的畸形数据,并实时监控目标系统的运行状态(如崩溃、挂起或异常响应),从而发现潜在的安全性缺陷。

在工控安全领域,模糊测试被广泛用于协议栈的健壮性审计。相比于传统的静态代码审计和渗透测试,模糊测试具有自动化程度高、黑盒测试有效以及能够发现深层逻辑漏洞的优势。

3.2 模糊测试分类

按照数据的生成方式,可分为:

  • 生成式:根据协议标准从零构造报文。本实验采用此种方式,通过 Boofuzz 建立协议模型。
  • 变异式:在捕获的合法报文基础上进行位翻转或数据截断。

按照对目标的知识掌握程度,可分为:

  • 黑盒模糊测试:不了解目标内部实现,仅关注输入与输出。本实验对从站模拟器进行的是此类测试。
  • 灰盒/白盒模糊测试:利用代码覆盖率反馈引导变异,如 AFL 框架。

4. 基于模糊测试的Modbus-TCP协议健壮性检测系统

技术架构:

  • 前端:HTML5+js
  • 后端:Node.js
  • 模糊测试:python3.9+Boofuzz

部署

Node.js 环境

  1. 安装Node.js:建议使用version >= 18.x,实验使用v22.14.0
  2. 初始化依赖:
    在项目根目录下执行:
shell 复制代码
npm init -y
npm install express socket.io
  1. 启动服务:
shell 复制代码
node monitor.js

此时服务将运行在http://localhost:3000

Python 环境

Boofuzz的Github地址

shell 复制代码
git clone https://github.com/jtpereyda/boofuzz.git
  • 创建conda虚拟环境
    推荐:使用miniconda,占用空间小且完全够用
shell 复制代码
conda create --name <conda_envs_name> python=3.9 -y
  • 安装必要的库
python 复制代码
# reqiurements.txt
argparse
boofuzz
shell 复制代码
pip install -r requirements.txt
  • 运行

    • 提供运行参数:
    shell 复制代码
      --mode:[
        "length", # 针对MBAP头的Length字段
        "func", # 针对功能码字段
        "payload", #针对超长载荷
        "format", 
        "bound", # 针对边界值
        "all" # 全部fuzzing
    ]
    --sleep: 发送数据包的时间间隔,便于观察数据包
    --ip: 目标ip
    --port: 目标端口
shell 复制代码
python fuzzing.py --mode length --ip 127.0.0.1 --port 5020 --sleep 2 
相关推荐
Alex Cafu2 小时前
Linux网络编程1(OSI模型与TCP/IP协议栈)
linux·c语言·网络·tcp/ip
汽车通信软件大头兵2 小时前
Autosar KeyM模块
网络·安全·汽车·uds·isolar
AC赳赳老秦2 小时前
行业数据 benchmark 对比:DeepSeek上传数据生成竞品差距分析报告
开发语言·网络·人工智能·python·matplotlib·涛思数据·deepseek
zhglhy2 小时前
ckman创建集群报错 数据校验失败: invaild ip range
服务器·网络·tcp/ip
糕......2 小时前
Java异常处理完全指南:从概念到自定义异常
java·开发语言·网络·学习
乾元2 小时前
生成对抗样本在网络安全中的工程化解读——AI 误报、误判与对抗的真实边界
运维·网络·人工智能·python·安全·web安全
stars-he2 小时前
FPGA学习笔记(7)以太网UDP数据报文发送电路设计(一)
笔记·网络协议·学习·fpga开发·udp
仙俊红2 小时前
计算机网络知识总结01
网络·计算机网络·智能路由器
Tandy12356_3 小时前
手写TCP/IP协议栈——实现ping响应不可达
c语言·网络·c++·网络协议·tcp/ip·计算机网络