工控协议端口速查表
Charmersix

一、Modbus 系列

端口协议说明
502Modbus TCP标准Modbus端口,最常见
8011Modbus TCP变体
502-505Modbus备用端口

二、西门子 S7 协议

端口协议说明
102S7Comm西门子PLC专用
102-103S7Comm经典端口

三、IEC 104 协议(电力系统)

端口协议说明
2404IEC 60870-5-104电力调度常用
2404-2405IEC 104备用

四、DNP3 协议

端口协议说明
20000DNP3 TCP分布式网络协议
20000-20002DNP3变体

五、Ethernet/IP (CIP)

端口协议说明
44818EtherNet/IPRockwell/Allen-Bradley
2222CIP通用工业协议

六、OPC 系列

端口协议说明
135OPC DA传统OPC(基于DCOM)
4840OPC UA新一代OPC
5353OPC UA Discovery服务发现

七、Profinet

端口协议说明
102Profinet与S7Comm共用
34962-34964ProfinetRT通信

八、其他常见工控协议

端口协议说明
161/162SNMP设备管理
9600MMS制造报文规范
4000-4005BACnet楼宇自动化
47808BACnet/IP楼宇自动化IP版
1911FoxboroFoxboro I/A系列
12345Generic通用测试端口
5500-5600EtherCAT实时以太网
5000-5005SynchrophasorPMU数据

九、最常见 TOP 5:

端口协议应用场景
502Modbus通用PLC、逆变器
102S7Comm西门子PLC
2404IEC104电力调度、变电站
44818EIPAllen-Bradley PLC
135OPC工业数据采集

十、Wireshark 快速筛选技巧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 按协议筛选
modbus
s7comm
iec104
dnp3
cip
opcua

# 按端口筛选
tcp.port == 502
tcp.port == 102
tcp.port == 2404
udp.port == 20000

# 组合筛选(控制命令)
tcp.port == 502 && modbus.func_code == 6
tcp.dstport == 102 && s7comm

十一、Modbus 功能码速查

常见功能码

功能码名称方向
0x01读线圈客户端→服务器
0x02读离散输入客户端→服务器
0x03读保持寄存器客户端→服务器
0x04读输入寄存器客户端→服务器
0x05写单个线圈客户端→服务器
0x06写单个寄存器客户端→服务器
0x0F写多个线圈客户端→服务器
0x10写多个寄存器客户端→服务器

要点

  1. 关注写操作(功能码 0x05, 0x06, 0x0F, 0x10)

    • 读操作一般不是答案
    • 写操作才是控制命令
  2. 数据包方向

    • 客户端 → 服务器:控制命令
    • 服务器 → 客户端:响应
  3. 值的含义

    • 不要凭经验判断
    • 按时间顺序 + 题目描述 来判断

十二、实战建议

1. 流量包分析步骤

1
2
3
4
5
6
7
8
9
10
11
12
13
14
第1步:初步观察
├── Statistics → Protocol Hierarchy(协议统计)
├── Statistics → Conversations(会话统计)
└── 查看端口通信频率

第2步:筛选关键数据
├── 按端口筛选常见工控端口
├── 按协议筛选(modbus、s7comm等)
└── 关注写操作(功能码 0x05/0x06/0x0F/0x10)

第3步:定位关键包
├── 按时间排序
├── 对比前后状态变化
└── 结合题目描述判断

2. 异常模式识别

异常类型特征
恶意控制短时间内大量写命令
非法访问陌生IP发送控制命令
异时操作非正常工作时间有控制命令
状态翻转设备状态频繁切换

十三、Python 解析示例

1
2
3
4
5
6
7
8
9
10
11
# 筛选 Modbus 写命令
def find_modbus_writes(packets):
writes = []
for pkt in packets:
if pkt.get('dst_port') == 502: # 或 8011
payload = pkt.get('payload', [])
if len(payload) >= 2:
func_code = payload[1]
if func_code in [0x05, 0x06, 0x0F, 0x10]:
writes.append(pkt)
return writes
 Comments