工控安全入门Modbus协议渗透测试与流量分析实战

admin 2026-02-17 20:09:30 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文介绍了工控安全中Modbus协议的原理与渗透测试。详解了主从架构、寄存器类型及常用功能码,并解析了协议帧结构。重点阐述了使用Nmap和Smod工具对PLC设备进行发现、枚举及模糊测试的流程,最后通过CTF实战演示了从流量包中提取寄存器数据并解析Flag的过程,为工控安全入门提供了实践参考。 综合评分: 89 文章分类: 渗透测试,IoT安全,CTF,安全工具


cover_image

工控安全入门Modbus协议渗透测试与流量分析实战

Gh0xE9

2026年2月11日 13:43 福建

历史存货

离散量输入:主要用来读取单个位的数据,如IO的状态; 线圈:开关输出信号,主要用来写入单个位的数据,与离散量构成组成对位的操作; 输入寄存器:主要用来读取16位,也就是两个字节的数据; 保持寄存器:主要用来写入16位的数据。 PLC:可编程逻辑控制器,是一种采用一类可编程的存储器,用于其内部存储程序,执行逻辑运算、顺序控制、定时、计数与算术操作等面向用户的指令,并通过数字或模拟式输入/输出控制各种类型的机械或生产过程。

协议原理

Modbus使用一种简单的 Masterand/Slave主从协议(客户机/服务器协议)进行通信。

主从协议是指只有主机(客户机)向从机(服务器)发送请求,从机(服务器)才会对主机(客户机)的请求作出回应,返回报文。

(最多247个,地址范围为1-247,0节点是广播地址)。每个slave设备都具有一个唯一的地址。总线上只能有一个Master节点。 客户机作为主站,向服务器发送请求;服务器(从站)接到请求后,对请求进行分析并作出应答。其中使用的通信帧被称为应用数据单元(Application Data Unit,ADU),它包括通信地址段、功能代码段、数据段和校验段,其中,功能代码段和数据段组合称为协议数据单元(Protocol Data Unit or Protocol Description Unit),PDU。如下图:

image-20260203200251887

协议原理

Modbus传输模式可分为 ASCII和RTU两种模式,同一网络中所有设备必须保持统一,要么是ASCII,要么统一为RTU模式,两者不可共存。相对来说RTU模式传输效率较高,

  • • ASCII模式下,消息以冒号字符开始,以回车换行字符结束。
  • • RTU模式下,消息发送和接收至少间隔3.5字符时间的停顿间隔作为标志。

寄存器介绍

所有数据都存在寄存器中,寄存器可指物理寄存器,也可是一块内存区域。Modbus根据数据类型及各自读写特性,将寄存器分为了4个部分,分别如下。

image-20260203200347027

Modbus地址、功能码、数据域

Modbus消息帧的地址,在ASCII模式下包含2个字符,在RTU模式下包含1个字符。单个设备地址实际范围是在1-247值之间。0为广播地址、248-255为保留地址。 功能码由1个字节构成,因此取值范围1-255。常用功能码如下:

  • • 01:读线圈状态
  • • 02:读输入状态
  • • 03:读保持寄存器
  • • 04:读输入寄存器
  • • 05:强制单线圈
  • • 06:预制单寄存器
  • • 15:强制多线圈
  • • 17:报告从设备ID
  • • 22:屏蔽写寄存器
  • • 23:读/写寄存器

数据内容与功能码紧密相关,存放功能码需要操作的具体数据,数据域以字节为单位,长度可变,对于有些功能码此域可为空。

协议解析

ModbusTCP通常使用端口502作为接收报文端口ModbusTCP包含一个应用报文头,该头占用7个字节。Modbus TCP/IP协议最大数据帧长度为260字节。

读取线圈输出状态(别人的)

发送报文

下图为query请求报文,Modbus传输内容为 “05 91 00 00 00 06 ff 01 00 00 00 0a”。

image-20260203200504258

05 91(十六进制) 为传输标识,即1425(十进制);
00 00为协议标识;
00 06为字节长度;
ff为单位标识符,即255(十进制);
01为功能码,占1个字节;
00 为Modbus起始地址高位;
00 为Modbus起始地址低位;
00 为寄存器高位;
0a为寄存器低位。
下图为query后的响应报文,Modbus传输内容为 “05 91 00 00 00 05 ff 01 02 01 00”。

响应报文

05 91(十六进制) 为传输标识,即1425(十进制);
00 00为协议标识;
00 05为字节长度;
ff为单位标识符,即255(十进制);
01为功能码,占1个字节;
02为数据域字节数;
01 00 为数据字段。响应报文的数据字段中,每个线圈占用1位(bit),01=0000 0001,00=0000 0000。1=ON,0=OFF。如果最后的数据字节不能填满8个线圈的状态(1个字节),则由0填充。

读取线圈输出状态(自己的)

功能码为:01

发送报文

image-20260203200544018

  • • 22 F3 – 传输标志(8947)
  • • 00 00 – 协议标识
  • • 00 06 – 字节长度
  • • 01 – 功能码,占一个字节
  • • 00 – 为Modbus起始地址高位;
  • • 00 – 为Modbus起始地址低位;
  • • 00 – 为寄存器高位;
  • • 0a – 为寄存器低位。

image-20260203200631020

响应报文

image-20260203200659517

  • • 22 F3 – 传输标志(8947)
  • • 00 00 – 协议标识
  • • 00 04 – 字节长度
  • • 01 – 为单位标识符,即255(十进制)
  • • 01 – 为功能码,占1个字节;
  • • 01 – 为数据域字节数;
  • • 01 03 为数据字段。响应报文的数据字段中,每个线圈占用1位(bit),01=0000 0001,00=0000 0000。1=ON,0=OFF。如果最后的数据字节不能填满8个线圈的状态(1个字节),则由0填充。

读取离散量输入值

功能码为:02

发送报文

Modbus流量为:39 f3 00 00 00 06 01 02 00 00 00 03

image-20260203201147610

  • • 39 F3 – 传输标志(14835)
  • • 00 00 – 协议表示
  • • 00 06 – 字节长度
  • • 01 – 单位标识符
  • • 02 – Modbus起始地址高位
  • • 00 – Modbus起始地址地位
  • • 00 – 为寄存器高位
  • • 03 – 为寄存器地位

响应报文

Modbus流量为:39 f3 00 00 00 04 01 02 01 03

image-20260203201210759

  • • 39 F3 – 传输标志
  • • 00 00 – 协议标识
  • • 00 06 – 字节长度
  • • 01 – 单位标识符
  • • 02 – 功能码
  • • 00 – 字节数
  • • 00 00 03 – 数据字段

读取输入寄存器值

功能码为:04

请求报文

下图为query请求报文,Modbus传输内容为 “07 45 00 00 00 06 ff 04 01 8f 00 02″。下图请求报文大体含义为:需读取输入寄存器地址30144-30145,共计2个寄存器内容。即读取Modbus协议地址143至144的内容。

image-20260203201232294

  • • 07 – 45(十六进制) 为传输标识,即1861(十进制);
  • • 00 – 00为协议标识;
  • • 00 – 06为字节长度;
  • • FF – 为单位标识符,即255(十进制);
  • • 04 – 为功能码;
  • • 01 – 为Modbus起始地址高位;
  • • 8F – 为Modbus起始地址低位,起始地址为143。
  • • 00 – 为寄存器高位;
  • • 02 – 为寄存器低位,读取数量为2。

下图为query后的响应报文,Modbus传输内容为 07 45 00 00 00 07 ff 04 04 b6 00 47 7f

image-20260203201315161

  • • 07 45 – (十六进制) 为传输标识,即1861(十进制);
  • • 00 00 – 为协议标识;
  • • 00 07 – 为字节长度;
  • • FF – 为单位标识符,即255(十进制);
  • • 04 – 为功能码;
  • • 04 – 为数据域字节数。
  • • B6 00 47 7F为数据字段。响应报文的数据字段中,每个线圈占用1位(bit),b6=1011 0110,00=0000 0000,47=1000 0111,7f=1111111。1=ON,0=OFF。如果最后的数据字节不能填满8个线圈的状态(1个字节),则由0填充。

针对Modbus进行渗透测试

在对PLC设备进行一系列渗透测试操作之前,我们先对网段PLC设备进行一次扫描,了解有哪些设备。虽然Smod框架里面也有扫描脚本,但并没有Nmap里面的Scripts脚本效率高,当然也可以用PLCScan(通过先检测端口TCP/502,若开放会调用其他函数来进行更深层次的扫描检测的工具)。这里我选择Nmap里的三个模块:

  • • modbus-discover.nse(nmap自带)识别并发现Modbus PLCS设备及版本
  • • modicon-info.nse(需添加)识别并列举Schneider Electric Modicon PLC
  • • modbus-enum.nse (需添加)识别并枚举使用Modbus的设备

image-20260203201338545

Smod渗透测试

仓库地址 https://github.com/Joshua1909/smod

1、 暴力破解PLC的UID 2、 网络嗅探进行ARP地址欺骗 3、 枚举Modbus PLC的功能 4、 模糊读写单一或多个线圈功能 5、 模糊读写单一或多个输入寄存器功能 6、 测试读写单一或多个保持寄存器功能 7、 测试单个PLC 所有功能 8、 对单个或多个线圈写值进行Dos攻击 9、 对单个或多个寄存器写值进行Dos攻击 10、对ARP地址欺骗进行Dos攻击

实战例题

这里举例一道以前给某省大学生网络安全竞赛出的类似题目,直接上Writeup了,现在做法五花八门,没必要详细写了

在线靶场 https://platform.cyclens.tech/challenge/37

打开流量包,过滤 Modbus 流量,发现寄存器写入了奇怪的东西

image-20260203201733350

将筛选后的流量包导出为 flag_des.pcapng,写个脚本跑一下就好了

#!/usr/bin/python
# coding=utf-8
import pyshark,sys
captures = pyshark.FileCapture('./flag_des.pcapng')
print(captures[1].modbus.regval_uint16)
i = 0
while True:
    try:
        print(captures[i].modbus.regval_uint16,end=", ")
        i += 1
    except:
        sys.exit(0)
# 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 5, 4, 1, 7, 8, 5, 121, 124, 6, 7, 2, 523, 32, 443, 66, 46, 23, 5, 56, 32, 5, 57, 45, 3, 37, 45, 52, 56, 23, 25, 47, 43, 1, 16, 45, 5, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 99, 54, 49, 54, 55, 55, 98, 51, 49, 51, 52, 51, 50, 51, 52, 51, 48, 51, 49, 51, 53, 51, 57, 50, 100, 51, 55, 54, 54, 51, 51, 51, 54, 50, 100, 51, 52, 54, 51, 51, 51, 51, 54, 50, 100, 54, 50, 51, 52, 51, 54, 54, 49, 50, 100, 51, 55, 51, 52, 54, 49, 51, 54, 54, 49, 51, 54, 54, 52, 54, 53, 54, 52, 51, 56, 51, 52, 54, 49, 55, 100,
flag = [54, 54, 54, 99, 54, 49, 54, 55, 55, 98, 51, 49, 51, 52, 51, 50, 51, 52, 51, 48, 51, 49, 51, 53, 51, 57, 50, 100, 51, 55, 54, 54, 51, 51, 51, 54, 50, 100, 51, 52, 54, 51, 51, 51, 51, 54, 50, 100, 54, 50, 51, 52, 51, 54, 54, 49, 50, 100, 51, 55, 51, 52, 54, 49, 51, 54, 54, 49, 51, 54, 54, 52, 54, 53, 54, 52, 51, 56, 51, 52, 54, 49, 55, 100]
for i in flag:
    print(chr(i), end="")

将十六进制解码下就出 flag

image-20260203201810338

flag{14240159-7f36-4c36-b46a-74a6a6ded84a}

image-20260203201824123


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:Gh0xE9 《工控安全入门Modbus协议渗透测试与流量分析实战》

评论:0   参与:  0