带你走进 S7COMM 与 MODBUS 工控协议
字数 2935 2025-08-24 20:49:22
S7COMM与MODBUS工控协议深度解析
1. S7COMM协议详解
1.1 协议概述
S7COMM全称S7 Communication,是西门子专有协议,主要用于:
- 西门子S7-300/400系列PLC之间的通信
- PLC编程
- PLC之间的数据交换
协议封装在TPKT和ISO-COTP协议中,包含三部分:
- Header(头部)
- Parameter(参数)
- Data(数据)
1.2 协议头部结构
Header包含8个字段,共14字节:
| 字节范围 | 字段名 | 描述 |
|---|---|---|
| 0-1 | Protocol Id | 协议ID,通常为0x32 |
| 1-2 | ROSCTR (PDU type) | PDU类型,常见值: 0x01: JOB(作业请求) 0x02: ACK(确认响应) 0x03: ACK_DATA(确认数据响应) 0x07: USERDATA(扩展协议) |
| 2-4 | Redundancy Identification | 冗余数据,通常为0x0000 |
| 4-6 | Protocol Data Unit Reference | 协议数据单元参考,随请求事件增加 |
| 6-8 | Parameter length | 参数总长度 |
| 8-10 | Data length | 数据长度,读取PLC内部数据时为0x0000 |
| 10-12 | Error class | 错误类型 |
| 12-14 | Error code | 错误码 |
1.3 常见功能码
当PDU类型是JOB和ACK_DATA时,常见功能码:
| 十六进制值 | 含义 |
|---|---|
| 0x00 | CPU服务 |
| 0xf0 | 建立通信 |
| 0x04 | 读取值 |
| 0x05 | 写入值 |
| 0x1a | 请求下载 |
| 0x1b | 下载块 |
| 0x1c | 下载结束 |
| 0x1d | 开始上传 |
| 0x1e | 上传 |
| 0x1f | 上传结束 |
| 0x28 | 程序调用服务 |
| 0x29 | 关闭PLC |
1.4 关键功能详解
1.4.1 建立通信(0xf0)
在每个会话开始时发送,用于协商ACK队列大小和最大PDU长度。
Parameter结构:
- 0-1字节:功能码(0xf0)
- 1-2字节:保留(0x00)
- 2-4字节:Max AmQ calling
- 4-6字节:Max AmQ called
- 6-8字节:PDU长度
1.4.2 读取值(0x04)
通过指定变量存储区域、地址和大小执行读取操作。
Parameter结构:
- 0-1字节:功能码(0x04)
- 1-2字节:Item计数
- 2-14字节:Item[1]
- 后续:Item[n]
Item结构:
- 0-1字节:变量规范(通常0x12)
- 1-2字节:地址规范长度
- 2-3字节:Syntax Id(地址规范格式类型)
- 3-4字节:传输大小
- 4-6字节:数据长度
- 6-8字节:DB编号
- 8-9字节:区域
- 9-12字节:地址
常见区域值:
- 0x80:直接外设访问
- 0x81:输入(I)
- 0x82:输出(Q)
- 0x83:标志(M)
- 0x84:数据块(DB)
- 0x85:背景数据块(DI)
- 0x86:局部变量(L)
- 0x87:全局变量(V)
- 0x1c:S7计数器(C)
- 0x1d:S7定时器(T)
1.4.3 写入值(0x05)
结构与读取类似,但包含要写入的数据。
1.4.4 下载流程
- Request download (0x1a)
- Download block (0x1b)
- Download ended (0x1c)
1.4.5 上传流程
- Start upload (0x1d)
- Upload (0x1e)
- End upload (0x1f)
1.4.6 程序调用服务(0x28)
用于PLC修改执行/内存状态,如启动/停止控制程序。
1.4.7 PLC停止(0x29)
关闭PLC操作。
2. MODBUS协议详解
2.1 协议概述
MODBUS是Modicon公司推出的协议,后由施耐德电气收购并发展。2004年成为中国国家标准。
MODBUS特点:
- 应用层消息传递协议(OSI第7层)
- 客户端/服务器通信模式
- 请求/回复协议
- 通过功能码指定服务
2.2 常用功能码
八种最常用功能码:
| 功能码 | 描述 |
|---|---|
| 1 | 读取线圈状态 |
| 2 | 读取输入状态 |
| 3 | 读取保持寄存器 |
| 4 | 读取输入寄存器 |
| 5 | 写入单个线圈 |
| 6 | 写入单个寄存器 |
| 15 | 写入多个线圈 |
| 16 | 写入多个寄存器 |
2.3 特殊功能码
- 20/21:General Reference Register(大多数设备不支持)
2.4 寄存器类型
- 状态寄存器(0x0000~0x0009):监视用
- 控制寄存器(0x000A~0x0014):控制用
- 状态线圈(0x0000~0x0009):监视用
- 控制线圈(0x000A~0x0014):控制用
- 附加寄存器(0x1000~0x1063):提交FLAG用
3. 实例分析
3.1 S7COMM协议分析实例
分析异常流量包中的flag:
- 筛选S7协议流量
- 分析PDU类型频率
- 发现异常字符串"NESSUS"即为flag
3.2 MODBUS协议分析实例
- 修复被篡改的pcap文件头
- 筛选MODBUS协议
- 分析功能码3(读取保持寄存器)的流量
- 提取寄存器1的变化数据
- 转换为ASCII码得到flag
3.3 工控系统操作实例
实例1:调节阀门开度
- 将线圈15设为true解锁
- 将控制寄存器0x00B设为3(维护模式)
- 在地址16写入大于60的值
- 恢复工作模式
- 从附加寄存器获取flag
实例2:报警日志分析
- 打开报警使能开关(线圈13设为true)
- 读取状态寄存器0x100~0x163的报警日志
- 分析时间戳数据得到flag
4. 附录
4.1 S7COMM错误码
完整错误码表见原文,包含:
- 0x0000:无错误
- 0x0110:块号无效
- 0x0111:请求长度无效
- 0x0112:参数无效
- ...(共100+种错误码)
4.2 PI服务名称
- _INSE:激活PLC模块
- _DELE:删除模块
- P_PROGRAM:PLC启动/停止
- _MODU:Copy Ram to Rom
- _GARB:压缩PLC内存
- ...(共40+种服务)
4.3 MODBUS缩写
- ADU:应用数据单元
- HDLC:高级数据链路控制
- MBAP:MODBUS应用协议
- PDU:协议数据单元
- ...(共10+种缩写)
5. 总结
- S7COMM协议复杂,没有官方文档,需通过实践学习
- MODBUS协议标准化程度高,有官方文档参考
- 工控安全学习需要实际设备环境支持
- 两种协议在工业控制系统中广泛应用,理解其原理对工控安全至关重要