恶意扫描Modbus怎么办?从协议弱点到实战排查与加固
上周接到一个朋友的电话说他们车间里一台老旧PLC的IP在某个夜班时段被几十个陌生地址轮番连接每次都是连上502端口发几条指令就断开循环了一整晚。监控大屏上没有报错产线也没停要不是做安全巡检时翻了交换机流量根本发现不了。这种悄无声息的“恶意扫描Modbus”事件近两年在工控现场越来越常见。它不像病毒破坏那样动静大但恰恰是这种隐蔽性让大多数OT运维人员毫无防备。这篇东西不是讲攻防案例的猎奇故事而是围绕“恶意扫描Modbus”这个具体场景把协议为什么弱、扫描长什么样、现场怎么排查定位、以及有哪些真正能落地的加固手段完整捋一遍。内容更适合工厂自动化、系统集成和工控安全方向的工程师参考也能让刚接触OT安全的人快速建立一个可操作的知识框架。1. 恶意扫描为什么总盯着Modbus先看清协议的老底子1.1 Modbus的“简单”是把双刃剑Modbus从1979年问世到现在依然是工控现场部署量最大的工业协议之一。它之所以能活这么久核心就是一个“简单”报文结构固定请求/响应的主从模型清晰不分家的功能码设计读线圈、读寄存器、写线圈、写寄存器都靠几个数字搞定主站和从站的实现门槛极低几十行代码就能跑起来。正是这种简单让Modbus在PLC、DCS、仪器仪表、传感器、水处理、电力监控等行业里遍地都是。但简单也意味着“裸露”——协议本身没有会话管理、没有身份认证、没有数据加密。一个能接入生产网络的设备只要知道从站地址和寄存器地址就能直接读取或改写数据。举个例子Modbus TCP通信默认就是502端口。主站发一个“03功能码”读取保持寄存器请求从站直接回一包数据整个过程不校验“你是谁”也不检查“你有没有权限”。这和HTTP的“无状态”有点像但HTTP起码还有SSL/TLS这种补丁Modbus这一层补了很久普及率仍然很低。1.2 “三无”状态无认证、无加密、无审计我用“三无协议”来概括Modbus的安全底子很多老工程师听了都点头无认证从站不验证请求方的身份只要网络可达任何人都能发起读写请求无加密明文传输寄存器地址、数据值、功能码全部裸奔抓包软件直接能看到生产数据无审计协议本身不记录“谁访问过、读了哪些数据、改了什么”事后追溯只能靠外围方案。这三个特征叠加在一起意味着恶意扫描者只要在网络里找到一个可访问的Modbus从站就能像读公共公告栏一样翻寄存器数据如果碰上某些寄存器对应“启动”“停止”这类控制位情况就更严重。可不要觉得这是危言耸听——现实中确实有通过改写保持寄存器导致设备误动作的案例虽然不是大规模破坏但停工损失、设备损害是实实在在的。1.3 扫描和正常轮询的本质区别运维人员常犯的误解是“我们的PLC每隔几秒就轮询一次多几个连接有什么好担心的”这里要分清楚正常轮询和恶意扫描有质的区别正常轮询是固定主站、固定周期、固定功能码、固定寄存器区间流量模式非常规律恶意扫描往往是随机源地址、短连接、快速探测多个从站地址或功能码目的是“摸清家底”。用一个生活化的类比正常轮询就像小区物业每天定时巡查几栋楼路线和楼层固定恶意扫描则像一个小偷半夜挨家挨户拧门把手看看哪家门没锁哪个窗户能推开。两者看起来都是“在楼道里走动”但意图完全不同留在门禁日志里的痕迹也完全不同。2. 恶意扫描的常见套路与流量特征怎么把它从正常通信里揪出来2.1 扫描者的典型行动路径虽然不同工具实现方式不同但针对Modbus的扫描逻辑大体分几步主机发现先探测网段内哪些IP存活常见手段是ICMP ping或TCP端口探测端口识别对存活主机扫描502端口确认哪些是Modbus TCP服务从站探测同一个IP上尝试多个从站地址Unit ID1-255找出该设备下挂的所有从站功能码枚举尝试01、02、03、04、05、06、15、16等功能码摸清哪些操作被支持寄存器读取对支持的功能码发起批量读取请求尝试获取生产数据或配置信息。整个过程可以用自动化脚本在几分钟内跑完对通信双方来说产生的流量在绝对值上并不大。尤其是第3、4步一两个请求就能完成抓包经验不足的人很容易把它误判为“偶发的网络错误”。2.2 抓包时的关键识别特征在Wireshark里过滤tcp.port 502然后盯住几个模式大量短连接来自同一源IP在短时间内反复建立TCP连接、发送请求、断开每个连接只交互一两包数据UNIT ID遍历连接内请求报文中的Unit ID在连续变化如从1跳到2再到3这是扫描器在枚举从站地址不规律的功能码正常主站通常只用固定功能码扫描流量里可能连续出现多个不同功能码比如03后紧跟16请求频率异常远高于业务轮询周期的请求频率比如每秒几十次明显超出实际控制需求目的端口高度集中全网段扫描时目标端口只集中在502而不是随机的多个端口。如果看到这些特征别急着下结论先把抓包文件保存好同时记录时间戳和涉及的IP地址这是后续溯源的基础。2.3 误判陷阱这些“异常”其实很正常识别扫描不能只看单个特征还得结合业务背景。我见过好几个误报警案例配置了下位机但没启用的PLC调试阶段工程师反复用Modbus Poll之类的工具连接每次功能码和寄存器区间都不同流量看起来像扫描其实是厂商调试组态软件自动发现设备某些上位机或网关在启动时会主动扫描整个网段的设备用于自动生成点表这种猝发的自发现流量也很容易被当成恶意行为老式仪表主动上报某些串口服务器或RTU会把多个仪表的请求转成TCP从IP看是同一主站但Unit ID频繁切换乍一看也像扫描。排查这类问题最有效的办法是“先问业务再看流量”先确认该时段有没有调试任务、有没有新接入设备、有没有第三方维保厂商在场。80%的“可疑扫描”都能在业务侧得到解释。3. 实战排查发现恶意扫描后的处置流程与工具用法3.1 第一反应别拔线先取证很多同事遇到疑似扫描第一件事就是拔网线、断PLC的物理连接。这样做虽然能“止血”但坏处也明显扫描源一旦发现目标掉线可能会换下一个网段继续探测而你已经失去了取证时机。更好的做法是保持通信立刻开启端口镜像在交换机上找到连接疑似被扫描设备的端口配置端口镜像到一台抓包主机多位置抓包有条件的话在核心交换机、接入交换机分别抓包定位扫描源在哪个区域同步留存设备日志如果PLC、防火墙、工业交换机支持日志导出这段时间的登录记录、异常报文记录确认业务影响范围同一台PLC下挂的设备有没有异常动作是否影响产线当前和后续运行。这里强调一点取证阶段的记录比当场处置更重要。因为恶意扫描的意图可能是探测、可能是踩点也可能是更大规模攻击的前奏。没有记录后续想溯源、汇报、改进防护都会缺依据。3.2 Wireshark排查的快速上手流程假设你已经镜像到了包含502端口流量的pcap文件按下面步骤操作会高效很多第一步统计会话找“话痨”IP使用菜单“统计 - 对话”或命令行tshark -r capture.pcap -q -z conv,tcp按数据包数量排序找出在网络里短时间发送大量TCP连接请求的IP地址。正常主站和从站之间的会话往往是长连接会话数少、单个会话内报文多恶意扫描恰恰相反会话数多、单个会话只有少数几个报文。第二步过滤Modbus报文按功能码分类tshark -r capture.pcap -Y modbus modbus.func_code -T fields -e ip.src -e ip.dst -e modbus.func_code -e modbus.unit_id快速列出所有Modbus请求/响应看有没有单独一个源IP“雨露均沾”地访问多个Unit ID或者连续使用多个不同功能码的情况。第三步还原扫描节奏定位时间窗口tshark -r capture.pcap -Y tcp.port 502 -T fields -e frame.time -e ip.src -e tcp.flags -e modbus.func_code把时间列出来观察扫描是集中在某个时间段还是全天持续。集中式爆发大概率是外部或内部工具触发的全天低频率反复探测则更像是在做资产测绘。第四步追踪TCP流看封装的真实内容在Wireshark图形界面里选中某条可疑TCP流右键“追踪TCP流”直接看5个关键点事务标识符是否连续、Unit ID是否是遍历规律、功能码是否频繁变化、请求的数据地址区间是否杂乱、报文间隔是否与业务节奏匹配。3.3 一次真实的扫描追踪记录去年夏天处理过一个案例现象是某工厂能源管理系统里一台老型号的电力仪表频繁掉线。原先怀疑是串口服务器不稳定换了两台设备都没解决。后来抓包发现有一个网段的IP10.10.20.50每隔3分钟就发起一次针对网段10.10.10.x的Modbus TCP扫描每次连接尝试访问0x03功能码、读取30001到30010地址区间但只发两三包就断开。从IP地址段看10.10.20.0这个网段属于新改造的办公楼网络和车间生产网只隔了一台三层交换机没有做严格的访问控制。排查后发现是办公楼里某测试网关设备被人用默认密码登录过塞进了一个Modbus地址扫描脚本每三分钟执行一次。由于这个脚本的请求方式和正常仪表的轮询撞了车导致仪表程序里的通信超时逻辑被反复触发最终表现为“周期性掉线”。这类案例的典型教训是OT网和办公网的隔离如果只是“路由可达”而没有“协议过滤”即使VLAN分开了Modbus报文还是会穿过三层交换机横冲直撞。很多防护设备对跨网段的ICMP或普通TCP可能报警但对Modbus这类工控协议反而缺乏认知因为通用防火墙根本不看功能码。4. 加固方案从网络边界到PLC侧层层设卡4.1 网络分区与访问控制先做减法不管现场多复杂第一步永远是“让该通的通不该通的一段都不通”。具体做这几件事梳理出所有Modbus通信的主站、从站清单画一张实际的通信关系拓扑图而不是凭老工程师的记忆在核心交换机、工业防火墙上下发白名单策略只允许已知主站IP访问已知从站IP的502端口对串口转以太网的网关设备把Modbus TCP映射到特定端口默认关闭远程访问在办公网和生产网之间部署工业防火墙或工业网闸协议层级做Modbus深度解析而不只是ACL。网络分区的核心原则是“最小权限”。生产网里从来不应该出现办公网段主动访问PLC的场景所以直接把办公网访问生产网的所有Modbus报文阻断在原理上不会影响任何业务。别怕“误杀”大多数“谁都能访问”的工控网络本来就是历史遗留不是业务刚需。4.2 PLC与上位机的白名单设置技巧白名单分两个层面IP白名单和Modbus功能码白名单。IP白名单大家都懂难点在功能码白名单。很多PLC支持通过程序或硬件配置限制允许的Modbus功能码范围。以三菱FX5U做Modbus TCP主站为例搜索热词里提到过这也是现场很常见的配置需求在GX Works3里配置分配内部软元件作为通信缓冲区指定起始地址和寄存器数量设置允许的读写功能码如只允许03读保持寄存器和06写单寄存器限定对方站点的IP地址范围其他IP一律拒绝建立连接。再比如西门子S7-200 SMART大家常争论“PLC200能不能实现Modbus TCP”。实际上老款S7-200非SMART只支持PPI协议要实现Modbus TCP通常得加CP243-1以太网模块或者用协议转换网关把Modbus RTU转成Modbus TCPS7-200 SMART则可以直接在库指令里调用Modbus TCP通信但需要明确指定连接参数和访问区间。很多人在这一步栽跟头是因为只配置了端口和IP没配置“允许的从站地址范围”导致PLC成了网段内“谁都连得上、谁都能读”的裸设备。配置白名单时留个心别把PLC的IP绑定到业务网段之外的管理VLAN里。有些工程师为了安全把PLC划到独立VLAN结果上位机跨VLAN通信时走的是三层路由原本的二层隔离优势反而丢失了。正确做法是PLC保持业务VLAN边界上做过滤而不是把PLC自身网络结构搞得花里胡哨。4.3 深度包检测与联动告警如果只靠防火墙做IP端口过滤面对功能码级别的恶意行为依然无能为力。所以在资金和技术条件允许的情况下建议在关键路径上引入支持Modbus深度包检测DPI的设备或软件解析功能码对读、写功能码建立基线写操作05、06、15、16的频次和源地址必须严格受限建立寄存器操作基线对常被读写的寄存器区间做学习一旦出现陌生区间访问就告警检测异常从站遍历连续多个Unit ID的请求直接标记为扫描行为。告警不一定要自动阻断。工控现场最怕误阻断影响生产所以前期可以“只告警、不干预”连续观察一到两周确认告警规则准确率足够高后再逐步把高危行为如对写寄存器的未知源访问升级为自动阻断。这个“先观测、后自动”的节奏比一上来就全自动拦截稳妥得多。4.4 老设备“不能加密”的替代方案现场总有那么几台2005年甚至更早的PLC、仪表协议层面根本做不了加密认证。针对这类老设备我的经验是“别指望设备变强但可以在设备前面加岗哨”在设备前端串一台协议转换网关或工业安全网关对外统一使用网关的IP和端口对内网关用Modbus RTU或私有协议和老设备通信网关负责校验来源IP、过滤异常功能码、限制Unit ID范围老设备本身不需要任何改动把网关的所有日志转发到SIEM或集中日志平台作为审计追溯的证据源。这种做法相当于给一个“不设防的院子”装上了门禁系统老房子不用拆院门的安全等级提升了。代价是多一个设备、多一份维护但在没有预算替换全套PLC的情况下这是投入产出比最高的选择。5. 常见问题与排查技巧实录5.1 为什么用了工业防火墙扫描还是漏掉了先检查防火墙有没有开“Modbus协议解析”能力而不仅仅是“端口放行”。很多场景只是把502端口从防火墙放通防火墙压根没看报文内容扫描流量全都合法穿过去了。正确的配置是在防火墙策略中启用Modbus深度解析设置允许的功能码白名单这样才能拦截“用03功能码遍历从站”之类的扫描行为。另一个常见原因是“串口服务器的TCP透传”绕过了DPI。设备厂商为了兼容老系统喜欢设置串口服务器把Modbus RTU报文原封不动地封装成TCP这时候防火墙壁解析到的可能只是“TCP载荷中的透明数据”看不到标准Modbus头。解决办法是把串口服务器的应用层解析功能打开或者换用专门支持Modbus网关模式的设备。5.2 扫描告警误报率太高运维被搞烦了怎么办高误报率的根源通常是基线不准。可以先做一段时间的流量学习把正常的通信关系、功能码分布、请求周期摸清楚再在基线上配置异常检测。如果告警每天几十条、全是误报团队很快就会“狼来了”真正的事件反而被忽略。缩小误报面的技巧区分“读”和“写”读操作告警阈值可以放宽写操作和从站遍历行为阈值收紧按时间窗口聚合单次异常请求不作为告警连续多次或失败次数达到阈值才触发把已知的外部维保IP加白名单并在白名单备注“厂商调试窗口”避免一竿子打死。5.3 关于国产DCS上位与Modbus安全的一点观察搜热词时看到“国产DCS登顶全球第一”这个话题结合工控安全来看国产DCS的快速扩张确实让更多现场开始认真对待通信安全问题。很多国产DCS支持Modbus TCP、Modbus RTU作为南向通信协议但在默认配置里通信白名单和功能码限制往往不是强制开启的需要工程师手动配置。所以每次去现场做过等保预检或安全评估我都会反复建议对方不要以为“国产系统自带安全”任何系统默认配置都是为了跑通业务不是为了防入侵。安全是要在业务跑通之后单独规划和投入的。5.4 Linux环境下自建Modbus Slave做蜜罐的思路如果现场排查和加固都做完了还想提高主动发现能力可以在被重点保护的网段里放一台Linux主机用libmodbus或pymodbus启动一个Modbus Slave服务监听502端口平时不参与任何实际业务。所有尝试连接这台“蜜罐”的IP基本都是可疑对象。把它接入告警系统或写个简单的日志监控脚本扫描行为一发生就能立刻收到消息。蜜罐的价值不在于“被动等攻击”而在于让整个网络具备“有人摸门就能听到声音”的能力。对预算有限的中小工厂来说这甚至可能是性价比最高的主动防御手段之一。我在实验室里实测过用pymodbus搭一个模拟从站配好寄存器读写映射整个搭建过程半小时不到日常监控只需要盯日志文件的变化。6. 长期维护安全不是一次性工程恶意扫描Modbus不是一个“杀一次就完事”的问题。攻击者手段会变现场设备也会不断增改所以安全措施需要跟着网络变化滚动更新。我建议每季度做一次小巡检检查防火墙白名单是否过期、PLC的IP白名单是否还有冗余、蜜罐日志有没有可疑连接记录、上位机软件有没有弱口令。每年做一次大排查重新画一次通信拓扑核对Modbus主从关系的最新状态审计所有第三方设备的远程维护通道。这套动作不需要多高的资金投入也不需要厂商驻场但效果非常直接。说到底工控安全的门槛不在技术复杂度而在“有没有人真的拿它当回事”。只要有人坚持每周看一眼流量告警、每月翻一次防火墙日志恶意扫描想越过你就没那么容易。最后说一点个人经验我在现场处理过这么多起Modbus相关事件发现大多数问题的根源不是攻击者多高明而是生产网络里充满了“三不管”节点——不知道谁接的线、不知道谁开的端口、不知道谁设置的默认密码。把网络里每个设备的通信需求都弄明白比买再贵的防火墙都有用。你治不住自家的乱账再好的防护系统也只是在烂地基上盖房子。