1. 项目概述:为什么工业网络也需要“听诊器”?
在传统IT领域,Wireshark作为网络协议分析的金标准,几乎是每个网络工程师和安全研究员的必备工具。但当我第一次把Wireshark的网卡指向一个工业控制系统的网络端口时,那种感觉是完全不同的。屏幕上不再是熟悉的HTTP、TCP三次握手,而是滚动着诸如“Modbus/TCP”、“S7comm”、“DNP3”、“IEC 104”这样陌生的协议名称,数据包的内容也充满了看似随机的十六进制数字。那一刻我意识到,工业网络是一个平行于我们日常互联网的“隐秘世界”,而Wireshark,正是我们进入这个世界、理解其运行逻辑、诊断其潜在风险最关键的“听诊器”。
这个项目,或者说这次经验分享,核心就是探讨如何将Wireshark这个强大的通用工具,精准地应用于工业控制系统(ICS)和监控与数据采集(SCADA)这一特殊领域。工业网络协议与IT协议在设计哲学上有着根本区别:IT协议追求高效、灵活和通用性,而工业协议首要目标是确定性、实时性和可靠性。一个Modbus请求/响应延迟几毫秒,可能就意味着生产线的一次停机;一个被篡改的S7comm数据包,可能直接导致物理设备的异常动作。因此,对SCADA协议的分析,绝不仅仅是“看看数据流”,它关乎系统稳定性诊断、通信故障排查、安全威胁发现,甚至是理解整个工业流程的“数据脉搏”。
无论你是刚接触工控的IT运维人员、负责系统集成的工程师,还是关注工业网络安全的研究者,掌握Wireshark在工控场景下的应用,都是一项极具价值的技能。它能让你从“黑盒”猜测,走向“白盒”洞察。接下来,我将结合多年在项目现场踩过的坑和积累的经验,从环境准备、协议解析、实战分析到安全审计,为你拆解这套方法论。
2. 核心思路与准备工作:打造专属工控抓包环境
直接把办公室电脑上的Wireshark连到工厂网络,是鲁莽且危险的行为。工控网络环境敏感,一个错误的配置或广播流量就可能干扰生产。因此,搭建一个非侵入式、安全的抓包环境是第一步,也是最重要的一步。
2.1 网络接入方案选择:镜像端口是唯一正解
在工控现场,绝对禁止将分析终端直接接入控制网络的核心交换机或PLC的普通业务端口。主流且安全的方案只有一种:使用网络交换机的端口镜像(Port Mirroring 或 SPAN)功能。
为什么必须是端口镜像?
- 零干扰:镜像端口只复制流量,不影响原端口的任何数据收发,对生产业务零风险。
- 全流量捕获:你可以将需要监控的PLC、RTU或工程师站的上联端口流量,镜像到你连接Wireshark主机的端口,从而捕获所有进出该设备的数据。
- 隐蔽性:你的分析主机在网络中是“沉默”的,只接收数据,不发送任何数据包(除非你主动进行注入测试,但那必须在独立测试环境进行),避免了因主机ARP请求、DHCP探测等行为对网络产生意外影响。
实操步骤与注意事项:
- 交换机配置:登录工业交换机管理界面,找到端口镜像功能。通常需要设置“源端口”(被监控的设备所连端口)和“目的端口”(你的抓包主机所连端口)。有些交换机还支持基于VLAN或MAC地址的镜像,灵活性更高。
- 抓包主机配置:用于抓包的电脑最好是一台轻量化的笔记本或工控机。务必禁用其无线网卡,防止意外连接到其他网络。同时,将其有线网卡的IP地址设置为与被监控网络同网段的一个未被使用的静态IP,或者更安全的方式是不设置IP地址(在Windows中设置为“自动获取IP”但在没有DHCP服务器的网络中,它实际上无法获得IP),这样它就无法主动发起任何通信。
- 使用专用抓包网卡(可选但推荐):对于高性能或需要精确时间戳的场景,可以考虑使用Endace、Mellanox等厂商的专用抓包网卡,它们能提供更高的吞吐量和更精确的时间戳,避免丢包。
注意:在进行任何镜像配置前,必须与工厂的运营技术(OT)团队进行沟通并获得书面授权。了解网络拓扑,明确镜像端口配置不会影响关键环网或冗余链路。
2.2 Wireshark的工控专项配置
安装好Wireshark后,默认配置是为IT网络优化的。为了更好服务工控分析,需要进行针对性设置。
1. 工控协议解析器(Dissectors)的启用与验证: Wireshark内置了大量工控协议解析器,但默认可能未全部启用。你需要检查并确保它们已激活。
- 路径:
分析->启用的协议。 - 关键协议:在过滤器中输入“modbus”、“s7comm”、“dnp3”、“iec60870”、“cip”、“opcua”等,确保其复选框被勾选。对于像“EtherNet/IP”(其CIP协议运行在TCP/UDP 44818端口)这类协议,需要确保相关解析器已关联到正确端口。
2. 优化显示过滤器和着色规则: 工控流量中可能混杂着设备发现(如LLDP)、网络时间协议(NTP/PTP)以及各种厂商私有协议。创建自定义显示过滤器能快速聚焦。
- 示例过滤器:
modbus:过滤所有Modbus流量。s7comm:过滤西门子S7协议。tcp.port == 502 || udp.port == 502:捕获所有使用502端口(Modbus默认端口)的流量。!arp && !stp && !cdp:排除常见的二层发现和链路协议,让视图更干净。
- 着色规则:可以为关键或异常流量设置醒目颜色。例如,将Modbus异常响应(功能码高位为1)标记为红色,将写操作(如Modbus的06写单个寄存器)标记为黄色。规则路径:
视图->着色规则。
3. 关键首选项设置:
捕获->选项:在“输入”选项卡下,为抓包网卡勾选“在所有接口上使用混杂模式”。虽然在不设IP的情况下可能收不到太多非本机流量,但勾选更保险。编辑->首选项->协议:- DNP3:可以设置“将片段重组为完整的应用层报文”,这对于分析跨多个TCP段的长指令非常有用。
- TCP/UDP:确认“允许子解析器重组TCP流”已启用,这对于理解S7comm等多消息交互的协议至关重要。
3. 核心工控协议解析实战
配置好环境,我们开始直面这些工控协议。理解它们的语法和语义,是分析的基础。
3.1 Modbus/TCP:工控世界的“HTTP”
Modbus因其简单、开源而广泛应用。在TCP/IP网络上,它运行在502端口。
协议结构速览: 一个Modbus/TCP报文 = MBAP头(7字节)+ Modbus PDU。
- MBAP头:包含事务标识符(用于请求响应匹配)、协议标识符(0代表Modbus)、长度字段和单元标识符(从站地址)。
- Modbus PDU:包含功能码和数据。
- 功能码:1字节,决定操作类型。例如:
01读线圈,03读保持寄存器,06写单个寄存器,16写多个寄存器。 - 数据:根据功能码变化,包含寄存器地址、数量、具体数值等。
- 功能码:1字节,决定操作类型。例如:
Wireshark实战分析:
- 捕获一次典型的读写操作。过滤
modbus。 - 选中一个Modbus请求包,在下方协议详情面板逐层展开。Wireshark已经帮你解析好了MBAP头和PDU。重点关注“Function: Read Holding Registers (3)”这样的字段。
- 查看寄存器地址和值:对于读响应或写请求,Wireshark会以十进制和十六进制两种形式显示寄存器地址和读取/写入的值。这是理解数据点的关键。
- 识别异常:如果功能码高位为1(例如,请求是
03,响应是83),说明发生了异常。Wireshark会解析异常码,如01非法功能,02非法数据地址等。这是故障排查的直接证据。
经验心得:
- Modbus协议本身无任何认证或加密。在Wireshark中,你可以清晰地看到写入PLC的设定值,这既是诊断的便利,也赤裸裸地展现了安全风险。
- 寄存器地址的映射关系(例如,40001地址对应PLC内的哪个实际变量)通常需要查阅设备手册或组态软件配置,这是将网络数据包与实际工艺参数关联起来的关键。
3.2 西门子S7comm协议:深度解析PLC的“对话”
S7comm(S7 Communication)是西门子S7系列PLC与上位机(如STEP 7, WinCC)通信的复杂协议。它比Modbus复杂得多,包含了连接管理、数据读写、程序上传下载等多种功能。
协议特点与Wireshark解析:
- 连接建立(COTP/TPKT):S7comm运行在TCP 102端口上,底层先经过TPKT(RFC 1006)和COTP(ISO-on-TCP)协议层,最后才是S7comm。Wireshark能完整解析这个栈。连接建立阶段会有“COTP Connection Request”和“COTP Connection Confirm”的握手过程。
- S7comm PDU类型:
- Job/ACK:简单确认。
- Job/Ack-Data:请求/响应,用于读写数据。
- Userdata:用于PLC状态查询、启动/停止等管理功能。
- 关键字段:
- ROSCTR:PDU类型,如
Job (1),Ack (2),Ack-Data (3)。 - Function:功能码,如
Read Var (0x04),Write Var (0x05),PLC Stop (0x29)。 - Item:读写请求的具体细节,包含变量地址(如
DB10.DBX2.0)、长度和值。
- ROSCTR:PDU类型,如
实战案例:分析一次数据块读取
- 过滤
s7comm。 - 找到一个“S7COMM”协议,ROSCTR为“Job”的请求包。查看其功能(Function)。
- 如果是“Read Var”,展开“Parameter”部分,你会看到“Items”。这里详细列出了请求读取的变量地址,例如
Area: DB memory, Number: 10, Start: 2.0, Length: 1 bit。这表示请求读取DB10.DBX2.0这一个位。 - 找到对应的响应包(ROSCTR为“Ack-Data”),查看“Data”部分,就能看到读取到的值是
0还是1。
注意事项:
- S7comm协议有多个版本(如“S7comm”、“S7comm-plus”),加密和复杂性递增。基础S7comm是明文的,Wireshark可以完美解析。S7comm-plus可能涉及加密,Wireshark只能解析到传输层。
- 理解西门子的存储区概念(I, Q, M, DB, T, C)和地址编码方式是看懂数据的前提。
3.3 DNP3与IEC 60870-5-104:电力行业的“规约”
在电力SCADA中,DNP3(Distributed Network Protocol)和IEC 104应用广泛。它们设计用于主站(Master)和远方终端(RTU)之间,支持自发报告(Unsolicited Reporting),即RTU在状态变化时主动上报,而非仅响应主站轮询。
DNP3协议分析要点:
- 分层结构:DNP3数据链路层(LPDU)负责帧校验和分片,传输层负责分段重组,应用层(APDU)包含实际数据。
- 应用层对象:DNP3使用对象模型,如
Group 30 Var 1代表带时标的单点数字量输入。Wireshark会解析出这些对象标识。 - 功能码:如
Read (0x01),Write (0x02),Select (0x03),Operate (0x04)(用于遥控),Direct Operate (0x05),Immediate Freeze (0x07)等。Select和Operate的“选择-执行”两步操作是DNP3实现安全遥控的典型方式。 - 内部指示字(IIN):在响应报文中,IIN字段指示了设备状态,如“需要时间同步”、“缓冲区溢出”、“设备重启”等,是诊断设备健康状态的重要窗口。
Wireshark操作: 过滤dnp3。展开一个应用层请求,你会看到清晰的“DNP3 Request”和“Function Code”。对于响应,重点关注“IIN”字段和返回的数据对象列表。Wireshark能够将二进制对象值解析为可读的带品质描述符的测量值(如Float: 123.4 (Good))。
4. 高级分析与故障排查实战
掌握了基础协议解析,Wireshark在工控现场才能真正发挥威力。下面分享几个典型的应用场景。
4.1 通信超时与中断故障排查
现象:HMI画面上部分数据点显示####或“通信超时”,但网络物理连通性正常。
排查思路:
- 全局审视:首先,在Wireshark中停止捕获,使用统计功能(
统计->对话),查看TCP或UDP选项卡。找到出问题的设备IP地址,观察其对话的报文数量、字节数,并与正常设备对比。是否存在大量重传(TCP Retransmission)或重复的ACK?这指向网络拥堵或设备响应缓慢。 - 过滤追踪:针对问题设备的IP进行过滤,例如
ip.addr == 192.168.1.10。 - 分析交互时序:Wireshark的“时间”列默认显示的是捕获时间差。你可以通过
视图->时间显示格式->自上一个捕获分组后的秒数来更直观地看报文间隔。重点关注:- 请求与响应间隔:一个Modbus请求发出后,多久才收到响应?如果超过PLC的扫描周期或预设超时时间(常见为1-5秒),就会导致超时。
- TCP连接建立与保持:对于S7comm或IEC 104这类基于长连接的协议,查看是否有异常的TCP重置(RST)或结束(FIN)包。是否存在频繁的TCP重连?这可能是防火墙会话超时设置过短,或PLC/RTU处理能力不足。
- 解码异常响应:仔细查看设备返回的异常响应。一个Modbus异常码
02(非法数据地址)明确告诉你,HMI请求的寄存器地址在PLC中不存在。一个DNP3的IIN标志位可能表明RTU内部有错误。
我曾遇到的一个案例: 一个WinCC站频繁报告与某个S7-300 PLC通信中断。抓包分析发现,TCP连接大约每30分钟就会被PLC主动发送一个RST包断开。进一步过滤发现,在断开前,WinCC会发送一个“PLC Stop”功能的S7comm请求。最终查明,是另一个工程师站的组态软件配置了定时任务,错误地包含了“停止PLC”的指令。没有Wireshark,这个问题就像幽灵一样难以定位。
4.2 数据不一致与“跳变”问题分析
现象:HMI上显示的某个温度值偶尔会突然跳变成一个极大或极小的不合理值,然后又恢复正常。
排查思路:
- 定位数据点:首先确定该温度值对应的协议、地址和数据类型。例如,是Modbus的保持寄存器40010,数据类型为16位有符号整数。
- 精确过滤与搜索:使用Wireshark的显示过滤器结合搜索功能。例如,对于Modbus:
modbus && modbus.func_code == 3 && modbus.reg == 9(因为40010对应寄存器地址偏移9)。然后,在包含该数据包的流中(右键 ->追踪流->TCP流/UDP流),查看历史数据。 - 检查原始数据:在Wireshark的Packet Bytes面板(底部窗口),切换到“Hex Dump”模式,直接查看该寄存器返回的原始字节。对比正常值和异常值。是某个字节位翻转了(如
0x41 0x20变成了0xC1 0x20)?还是字节序弄反了? - 关联分析:观察异常数据出现的时间点,网络中是否有其他大量广播流量(如ARP风暴)、或是否有其他高优先级通信任务正在执行?这可能是由电磁干扰(EMI)导致的数据位错误,或PLC在高压负载启动时电源波动造成的瞬时故障。
经验技巧:
- 利用Wireshark的
工具->Fire/ACL规则功能可以临时创建一个过滤器,只捕获特定数据点的流量,减少干扰。 - 对于模拟量,理解数据格式(如IEEE 754浮点数、有/无符号整数、标度变换)至关重要。Wireshark有时能自动解析,有时需要你根据手册手动换算。
4.3 性能瓶颈分析与优化
现象:系统整体响应变慢,操作指令执行延迟高。
排查思路:
- 统计流量基线:在系统正常时,捕获一段时间的流量(如5分钟),使用
统计->摘要,记录总包数、字节数、平均包速率(pps)和比特率(bps)。 - 对比异常时段:在系统缓慢时,同样捕获流量进行对比。是否是总流量激增?还是特定协议的请求/响应延迟变长?
- 分析协议效率:
- 轮询间隔:对于Modbus等轮询协议,主站发送请求的间隔是否过短?过短的轮询会给PLC造成不必要的处理负担,过长则影响数据刷新率。通过Wireshark的“时间”列可以精确测量轮询周期。
- 报文大小:是否在频繁地使用“读多个寄存器”功能码(如Modbus的0x03)读取大量连续数据?这通常比多次读取单个寄存器更高效。反之,检查是否有大量的小报文、短数据包,导致网络利用率低下(因为每个以太网帧都有固定的帧头开销)。
- TCP窗口与吞吐量:对于S7comm等TCP协议,可以启用Wireshark的“TCP流图”功能(
统计->TCP流图形->时间序列(吞吐量))。查看图形中是否存在吞吐量瓶颈、TCP窗口大小是否受限。
- 识别“噪音”流量:过滤掉主要的SCADA协议(
!modbus && !s7comm && !dnp3),看看还剩下什么流量。是否有大量的NetBIOS、LLMNR广播?是否有未知的多播流量?这些“背景噪音”会消耗交换机和终端设备的处理资源。
5. 工业网络安全审计入门
Wireshark不仅是诊断工具,也是安全审计的利器。在获得授权的前提下,可以对工控网络进行安全评估。
5.1 识别潜在安全风险
- 明文传输:这是工控协议最普遍的风险。直接搜索“包含字符串”功能(
Ctrl+F),尝试搜索“password”、“admin”、“setpoint”等敏感词汇,可能会发现一些明文配置协议或HTTP管理界面泄露的凭证。 - 缺乏认证:观察Modbus、DNP3的写操作(Function Code)。任何主机都可以向PLC发送写寄存器或遥控命令吗?协议层面通常没有身份验证。
- 异常访问模式:
- 扫描与探测:发现来自非授权IP地址的对502、102、44818等工控端口的连接尝试(SYN包)。使用过滤器
tcp.flags.syn==1 and tcp.flags.ack==0 and (tcp.dstport==502 or tcp.dstport==102)。 - 功能码滥用:过滤异常的Modbus功能码,例如试图使用
0x10(写多个寄存器)覆盖大段内存区域,或使用0x2B(设备标识)等诊断功能码进行信息搜集。 - 畸形报文:Wireshark会以黑色背景或“Malformed Packet”标识无法正确解析的报文。这可能是攻击者发送的用于模糊测试(Fuzzing)或导致设备崩溃的恶意数据包。
- 扫描与探测:发现来自非授权IP地址的对502、102、44818等工控端口的连接尝试(SYN包)。使用过滤器
- 网络架构问题:
- IT/OT网络混流:在抓包中发现了来自办公网(如10.0.0.0/8)的IP地址直接与PLC(如192.168.1.0/24)通信,这违背了分区隔离原则。
- 无线接入:发现了802.11(Wi-Fi)协议的数据包,但现场并未部署授权的工业无线网络,这可能是一个非法接入点。
5.2 构建工控安全分析Profile
为了提高效率,可以创建一个专门用于工控安全分析的Wireshark配置文件。
- 新建配置:
编辑->配置文件夹->新建,创建一个名为“ICS_Security”的配置。 - 预置关键过滤器:
tcp.port == 502 or udp.port == 502:Modbustcp.port == 102:S7commtcp.port == 20000:DNP3 over TCPtcp.port == 44818 or udp.port == 44818:EtherNet/IPtcp.port == 2404:IEC 60870-5-104icmp:ICMP协议(常用于网络探测)bootp or dhcp:动态地址分配(在静态IP为主的工控网中出现需警惕)
- 设置着色规则:
- 高危操作:将Modbus的
06(写单个寄存器)、10(写多个寄存器),DNP3的05(直接操作),S7comm的Write Var等功能码的报文设为红色背景。 - 异常响应:将Modbus异常响应、TCP RST包设为紫色背景。
- 广播/多播:将ARP、LLDP等广播流量设为浅灰色,降低其视觉干扰。
- 高危操作:将Modbus的
- 保存并切换:保存配置后,通过左下角配置文件选择器快速切换。这样,在需要安全审查时,可以立即进入一个针对性极强的视图。
6. 常见问题与排查技巧实录
在实际操作中,你会遇到各种各样的问题。这里记录了一些典型场景和解决方法。
问题1:抓不到任何工控协议包,只有ARP和少量TCP包。
- 检查:确认镜像端口配置正确,且流量确实流经该端口(可通过在交换机上查看端口计数器确认)。
- 检查:抓包主机的网卡是否启用了混杂模式?Wireshark捕获接口列表前是否有“(P)”标志?
- 检查:显示过滤器是否误设了过于严格的过滤条件?尝试清空所有过滤器。
- 检查:工控协议解析器是否已启用?尝试在“启用的协议”中搜索并勾选。
- 终极方法:使用最原始的
tcp.port == 502或tcp.port == 102过滤器,如果还抓不到,说明目标流量确实没有到达你的网卡,问题出在网络接入层面。
问题2:Wireshark能识别协议(如显示为MODBUS),但无法解析功能码和寄存器数据,详情面板显示“Malformed Packet”或大量“Unknown”。
- 原因:这通常是协议版本或变种不匹配。例如,有些设备使用Modbus RTU over TCP(在TCP流中直接封装RTU帧,无MBAP头),而Wireshark默认按标准的Modbus/TCP解析。
- 解决:尝试右键点击该数据包 ->
解码为...,在“当前”列中,为对应的TCP或UDP端口选择不同的解析器。例如,对于非标Modbus,可以尝试选择“Modbus”或“None”,然后手动分析十六进制载荷。 - 原因:也可能是私有协议或经过简单封装。需要结合设备通信手册,尝试理解其帧结构,必要时可以编写简单的Lua插件进行解析。
问题3:捕获文件太大,分析卡顿。
- 预防:在开始捕获前,在
捕获->选项->输出中,设置“环状缓冲区”,例如3个文件,每个文件50MB。这样只会保留最新的数据。 - 预防:使用更精确的捕获过滤器(BPF语法)。例如,只抓特定主机对的流量:
host 192.168.1.1 and host 192.168.1.10。或者只抓特定协议:port 502 or port 102。注意:捕获过滤器语法与显示过滤器不同,且一旦设置,未被匹配的流量将直接丢弃,无法恢复。 - 事后:对于已捕获的大文件,先使用
文件->导出特定分组...,根据IP或协议过滤后,导出一个更小的文件进行分析。
问题4:如何确定某个数据包的具体含义?比如,寄存器40025到底对应现场哪个传感器?
- 这是工控协议分析的终极挑战,Wireshark无法直接回答。解决方法:
- 文档:寻找PLC程序文档、HMI组态文档或IO地址分配表。
- 关联操作:在HMI上对某个设备进行操作(如启动一台泵),同时抓包,寻找同一时间点出现的写线圈或写寄存器命令,该命令的地址即对应此设备。
- 趋势分析:观察某个寄存器值的变化趋势(Wireshark可通过
统计->IO图表绘制简单趋势),同时观察现场仪表读数,进行关联匹配。
掌握Wireshark在工控系统中的应用,是一个从“看热闹”到“看门道”的过程。它要求你不仅懂网络,还要懂一点PLC、懂一点工艺、懂一点安全。最初的迷茫和面对十六进制数的无力感是正常的。我的建议是,从一次简单的Modbus通信开始,亲手抓一个包,对照协议手册一个字段一个字段地去核对,直到你能从一串Hex数字中清晰地“看见”那个“读保持寄存器40001-40010”的请求。这个突破一旦发生,整个工业网络在你眼中就将变得透明而有序。剩下的,就是在无数个现场中,用这个“听诊器”去聆听、诊断和守护那些沉默运转的钢铁脉搏。