EtherNet/IP协议解析:CIP基础、抓包审计与工控安全防护

EtherNet/IP协议解析:CIP基础、抓包审计与工控安全防护 在工控安全现场待久了你迟早会撞上EtherNet/IP习惯上也有人写成Ethernet/IP。不管是在汽车零部件厂评估一条PLC产线还是排查HMI和PLC之间通信时好时坏的问题EtherNet/IP报文都会高频出现在你的抓包里。它是ODVA维护的工业以太网协议在罗克韦尔自动化AB体系里几乎是默认标配很多日系、欧系设备也支持它。很多刚转入工控安全的人一听到CIP协议栈、对象模型就头大其实它没想象中那么玄乎底子是标准以太网上面跑的是面向对象的CIP协议通信方式主要就两种——显式消息和隐式消息。理解这两条主线再去看攻击面、审计点、防护手段思路就顺了。这篇文章就按我实际做项目时的思路从协议原理、风险场景、抓包审计、落地防护到常见坑位系统梳理一遍。1. 先搞清楚EtherNet/IP到底是个什么协议1.1 工业以太网里的三大流派工控网络里说到工业以太网经常被拿出来对比的通常是三个PROFINET、EtherCAT、EtherNet/IP。它们都用标准以太网做物理层但上层协议差异很大。PROFINET是西门子体系的地盘设备发现靠DCP实时通信走的是RT/IRT那套EtherCAT是倍福带起来的主站发一帧报文从站“在飞行中”读取和插入数据靠分布式时钟保证同步EtherNet/IP则走了另一条路——把上层CIP协议完整搬到TCP/IP之上HMI、PLC、IO模块、变频器、机器人控制器之间全用标准的以太网报文交互。这三个流派的安全侧重点完全不同。PROFINET要关注DCP协议、LLDP、实时通道EtherCAT要注意主从拓扑和过程数据被篡改的可能EtherNet/IP要盯的是44818端口上的CIP命令、2222端口上的周期性IO数据以及CIP对象模型暴露出的资产信息。如果你服务的客户里外资工厂、汽车产线、物流仓储比较多EtherNet/IP的出镜率会非常高。国内很多汽车焊装线、总装线底层就是AB的PLC加EtherNet/IP网络所以做资产梳理、做风险排查这个东西绕不过去。1.2 EtherNet/IP 标准以太网 CIPEtherNet/IP的关键在于“IP”不是指Internet Protocol而是Industrial Protocol全称是EtherNet/Industrial Protocol。它把CIPCommon Industrial Protocol通用工业协议作为应用层承载在标准TCP/UDP之上。CIP最早并不是为以太网设计的它源自DeviceNet、ControlNet那套体系后来被移植到以太网上形成了EtherNet/IP。打个比方TCP/IP就像城市道路EtherNet/IP是道路上的标准厢式货车CIP则是车厢里的标准化货架。做安全的人关心的是货车能不能被冒充货架上的东西能不能被人偷看或篡改CIP的设备模型很统一任何设备都是“对象”的集合每个对象有类、实例、属性、服务。这种设计带来一个安全上的事实——只要掌握了CIP读写规则就可以跨厂商对设备做操作不区分是AB还是第三方设备。这也意味着网络里一旦混入一个恶意节点它对整个厂区EtherNet/IP设备的“理解成本”非常低。1.3 为什么安全人员必须啃协议细节很多做传统IT安全的同事刚接触工控网络习惯用“扫端口看版本”的方式做评估这在EtherNet/IP场景里远远不够。等保2.0的工控扩展要求、IEC 62443的落地检查都会明确提到“应对工业控制协议进行深度分析”和“对非授权指令进行检测”。你不能只会看“44818端口开着”就完了你得能回答这个端口上跑的是什么服务、谁在访问、是否建立了会话、有没有出现Set类的写指令、IO报文周期是否正常。而且EtherNet/IP的漏洞利用、异常检测、白名单规则编写全都建立在协议细节之上。防火墙如果不认CIP就只能按IP端口做黑白名单很多攻击流量照样能混过去。所以下面我会花不少篇幅讲协议本身这不是学院派掉书袋是做审计和防护的基本功。2. 协议核心CIP对象模型与两种消息2.1 “设备对象的集合”这个模型CIP把每个设备都抽象成多个对象。对象由类Class、实例Instance、属性Attribute三层结构描述外部通过“服务”Service对属性进行读取或写入。比如一个简单的IO模块它会有Identity对象设备身份信息、Assembly对象IO数据集合、Connection Manager对象连接管理等。每个对象都有固定的类ID比如Identity对象类ID 0x01存放厂商ID、设备类型、产品代码、序列号、固件版本Message Router对象类ID 0x02负责消息路由Assembly对象类ID 0x04应用数据的主要载体Connection Manager对象类ID 0x06负责显式和隐式连接的生命周期管理在抓包里你会看到“路径”这个概念它是CIP用来定位对象的。例如路径0x20 0x04 0x24 0x69 0x30 0x03代表“类ID 4、实例ID 105、属性ID 3”的一个对象属性。类ID、实例ID、属性ID都是数值化的这给安全检测带来便利因为防火墙可以做字段级过滤只允许读属性、禁止写属性在技术上是可行的。2.2 显式消息TCP 44818上的请求与响应显式消息用于非实时通信比如工程站读取PLC程序、诊断设备状态、读写标签数据。它跑在TCP 44818端口是典型的请求/响应模型。流程大致是客户端先发RegisterSession注册会话报文服务端返回会话句柄后续再通过SendRRData把CIP命令打包发送。Wireshark里能看到完整的封装头Encapsulation Header和CIP数据段。显式消息里经常出现的服务码有0x0EGet_Attribute_Single读取单属性、0x10Set_Attribute_Single写单属性、0x4CRead Tag读取标签、0x4DWrite Tag写标签、0x01Get_Attribute_List读属性列表等。安全审计时我建议重点关注Set/Write类服务码因为它们直接改变设备行为。举个例子一个HMI正常巡检时只读IO数据如果抓包发现某个IP频繁向PLC发Write Tag指令那就值得查一查是不是有异常行为。2.3 隐式消息UDP 2222上的周期性IO隐式消息是EtherNet/IP的实时通道用于PLC与IO模块、HMI与PLC之间周期性交换过程数据。它走UDP 2222端口通常是一个预先建立的连接由Connection Manager负责协商RPIRequested Packet Interval请求包间隔。数据格式是固定的不带请求/响应语义强调的是低延迟和可预测性。正因为这种流量“周期性”非常明显所以在安全监控里很容易建模。但隐式消息也有自己的风险点报文是明文且没有认证机制。攻击者只要进入网络就能监听IO数据甚至伪造源IP向PLC发预编译好的隐式报文直接改写设定值或让执行机构动作。而且这类报文的长度和内容相对固定普通防火墙很难识别“这个值合理不合理”只能靠业务侧规则来做深度检测。3. 风险视角攻击者会从哪些点下手3.1 明文通信等于信息裸奔EtherNet/IP从设计之初就把功能放在首位没有为安全性留太多余地。CIP报文里的设备身份信息、程序标签名、工艺参数全都以明文形式在网络上传输。这意味着只要有人能接入网络无论是物理插网线、连了生产WiFi还是攻破了一台边缘设备他就能通过抓包获得整个产线的“底细”比如PLC型号、固件版本、标签命名规则。这些信息会进一步帮助攻击者精准选择漏洞、构造恶意指令。在一次产线排查中我见过类似情况工程站到PLC的通信被镜像到一个临时排查口上抓了一小时包不仅看到了IO周期数据连某台设备的序列号和固件都清清楚楚。如果这些流量落到恶意分子手里他们不需要物理接触设备就能完成摸底。3.2 无认证写操作离“搞停机”只差一条指令EtherNet/IP的大多数设备不会校验“谁在给我发指令”。只要网络可达、CIP会话建立成功任何节点都可以发起写请求。常见的破坏行为包括向PLC发送Set指令修改设定值、向设备发送Reset指令重启、通过Download指令下载恶意配置。更麻烦的是很多老固件的PLC即使设置了程序保护口令口令校验也只存在于上层组态软件CIP层面的写操作未必会被拦截。所以我在做安全加固时跟前端运维同事强调最多的一句话是不要指望PLC自身能挡住恶意写操作必须在网络层把“谁有权限写”这件事管起来。这也是为什么防火墙的CIP深度解析、白名单机制在工控场景里比什么都重要。3.3 资产枚举等于给攻击者画了张地图EtherNet/IP有一个非常方便的能力向网段内发送ListIdentity广播所有支持CIP的设备都会返回自己的身份信息。类似地ListServices可以列举设备支持的服务。这个机制本来是方便工程软件自动发现设备的但对攻击者来说这就是现成的资产测绘工具。扫一遍广播域设备型号、厂商ID、固件版本全拿到手再对照漏洞库打哪里、怎么打思路很清晰。作为防守方我建议定期做同样的资产盘点用攻击者的视角检查网络里到底有哪些EtherNet/IP设备、存不存在未收录的“黑户”设备。下面第4节我会给一个可复现的盘点方法。3.4 拒绝服务比数据窃密更致命在传统IT里数据泄露是头号担心但在工控里最怕的是“业务不可用”。EtherNet/IP设备在资源上通常很有限连接表、会话数都有上限。攻击者可以快速建立大量TCP连接或者发大量UDP报文冲击设备的CIP协议栈让PLC的通信处理器过载导致正常的HMI轮询超时、IO丢包甚至CPU停机。这类攻击无需漏洞只要协议本身支持大量连接就能实现所以防御上必须靠网络层的连接数限制、流量限速和异常会话检测。4. 实操从抓包到资产盘点一次完整的安全审计4.1 抓包位置和准备工作做EtherNet/IP审计之前先确定抓包位置这个很关键。最常见的做法是交换机镜像口把核心交换机上连PLC、HMI、工程站的端口流量镜像到审计笔记本。如果现场有工业防火墙或分流器也可以从它的镜像口取流。还有一个必须注意的点抓包时机。生产高峰期的流量最真实但也最容易影响业务建议先在低峰期做一轮摸底再在运维窗口做深度抓包。准备工具方面Wireshark是主力另外准备一台装了Scapy的Linux笔记本用于主动资产发现。如果条件允许还可以带一台工业交换机做小范围测试环境避免在真实产线上做太多实验。无论哪种方式都建议先把抓包文件命名、时间戳、对应的PLC柜号和交换机端口记录清楚不然事后复盘会一头雾水。4.2 Wireshark快速定位EtherNet/IP流量打开抓包文件后可以直接在过滤栏输入tcp.port 44818看显式消息udp.port 2222看隐式消息ethernetip或cip按协议解析层过滤Wireshark对CIP的支持已经比较完善会自动把封装头、CIP路径解析成可读结构。我最常用的操作是先按IP排序看哪些设备在互相通信然后取一条RegisterSession报文展开封装头确认会话建立过程再随机看几条CIP请求找到服务码和路径判断这条连接是在读数据还是在写数据。如果你想快速从一份大抓包文件里提取所有CIP设备身份可以直接用统计功能里的“Protocol Hierarchy”或“Conversations”把EtherNet/IP流量和端到端会话两层信息结合起来看。这样既能知道“谁在和谁说话”又能知道“传输层用了什么端口”。4.3 用Scapy做CIP设备盘点主动发现CIP设备最常用的是ListIdentity广播。下面这段脚本可以往目标网段发一个ListIdentity请求并打印返回设备的IP和身份信息。注意这是在你自己有授权的网络里做资产梳理用的千万别对着没授权的生产网乱扫。from scapy.all import * import struct def build_list_identity(): # EtherNet/IP封装头共20字节小端序 # 命令0x0063表示ListIdentity长度0会话、状态、上下文、选项全为0 return struct.pack(HHI8xI, 0x0063, 0, 0, 0) def parse_identity(data): if len(data) 2: return None item_count struct.unpack(H, data[:2])[0] offset 2 for _ in range(item_count): if offset 4 len(data): break type_id, length struct.unpack(HH, data[offset:offset4]) offset 4 if type_id 0x00B1: # CIP Identity数据项 if offset length len(data): break vendor_id, dev_type, prod_code, rev struct.unpack(HHHH, data[offset:offset8]) status, serial struct.unpack(HI, data[offset8:offset14]) name_len data[offset14] name data[offset15:offset15name_len].decode(utf-8, replace) return vendor_id, dev_type, prod_code, rev, status, serial, name offset length return None def scan(target_cidr): # 需要替换成自己的网卡和网段 pkt Ether(dstff:ff:ff:ff:ff:ff) / IP(dsttarget_cidr) / \ UDP(sport44818, dport44818) / Raw(loadbuild_list_identity()) ans, _ srp(pkt, timeout3, ifaceeth0, verbose0) for sent, recv in ans: if recv.haslayer(Raw): result parse_identity(recv[Raw].load) if result: vendor_id, dev_type, prod_code, rev, status, serial, name result print(f{recv[IP].src}: vendor{vendor_id}, type{dev_type}, fprod{prod_code}, rev{rev}, name{name}) if __name__ __main__: scan(10.10.20.255)注意目标地址这里写的是广播地址实际扫描时可以直接填网段广播地址也可以对设备逐个单独发。响应解析部分做了简化如果遇到结构特殊的设备建议用Wireshark打开对应报文做交叉验证。我在真实项目里发现部分老设备不会响应广播ListIdentity只会回复定向请求这时候就需要结合供应商工具进行补充盘点。4.4 输出一份能推动整改的审计报告资产盘点不是终点最终要落到报告上。我常用的表格字段包括设备IP、MAC地址、厂商、设备类型、序列号、固件版本、开放端口、发现时间、风险等级。风险等级我一般这样定义生产网络直接暴露、存在可写CIP服务但无访问控制、固件版本存在已知漏洞、不在资产台账中的“黑户设备”等。风险等级高的设备对应到整改建议时不能只说“抓紧升级”要给出具体的处置路径比如先做网络隔离、限制源IP再排计划升级固件。报告里最好附上几份关键抓包截图尤其是异常CIP请求和未识别会话的截图方便网络和自动化团队定位问题。审计的目的不是“抓谁的小辫子”而是让所有相关方看到当前状态推动改进。5. 落地防护从架构到设备一层层加上去5.1 用IEC 62443的区域与通道思路隔离EtherNet/IP做EtherNet/IP防护我最推荐的顶层框架是IEC 62443国内也有对应的工控信息安全标准转化。这个标准里的“区域与通道”概念非常实用把功能相近、安全级别相近的资产放在同一个区域里区域之间用通道连接通道上做访问控制。比如一条产线里PLC、HMI、IO模块、机器人控制器可以放在“产线控制区”工程站放在“工程维护区”上层MES、ERP放在“企业IT区”。EtherNet/IP通信只允许在控制区和维护区内部发生跨区访问必须经过工业防火墙并且只放行业务必需的协议和端口。这样做的好处是即使某台HMI被攻破攻击者也不能直接横向跳到其他产线更碰不到企业IT系统。相比“一台防火墙挡在全厂门口”的粗放做法区域划分能把爆炸半径压到最小。5.2 协议白名单允许读禁止写针对EtherNet/IP光有IP端口白名单是不够的要做CIP协议层的深度白名单。现在主流的工业防火墙基本都能解析CIP识别服务码、类ID、实例ID。我实际部署时喜欢做一套“业务基线”工程站对PLC允许读标签、在线监控、上传下载但下载操作要求严格审批并通过临时策略放行HMI对PLC只允许读IO数据、写报警确认类标签禁止修改设定值PLC对IO模块只允许隐式消息UDP 2222端口按既定RPI周期通信其他设备之间默认拒绝这套白名单建议先在监控模式下运行一两周把业务流量基线抓全、看明白之后再切成强制模式。否则一上来就阻断很容易把正常业务搞挂。5.3 流量监控抓异常不只看告警监控EtherNet/IP流量建议重点关注几类异常新增设备网络里出现从未见过的IP/MAC尤其是尝试发ListIdentity或RegisterSession的设备连接数量突增某个IP突然建立大量TCP连接到PLC可能是扫描或DoS的前兆写操作异常在非业务时段出现大量Write Tag、Set Attribute等操作IO周期变化流量周期性突然变化可能意味着IO连接被篡改或设备状态异常非标路径的CIP访问访问了业务基线上不存在的类ID或实例ID这些检测如果靠人工看日志会累死建议把镜像流量接到工控IDS或SIEM里用规则做自动化告警。我自己的经验是阈值刚开始别设太紧先磨合一两周再逐步收敛避免被正常业务误报淹没。5.4 设备侧加固和CIP Security的现状设备层面的加固同样不能落下。能关的端口就关能改的默认口令就改CPU的运行/编程模式切换权限要收口工程软件的升级补丁要及时打。对于EtherNet/IP有些新设备开始支持CIP Security基于TLS/DTLS对CIP通信加密和认证但坦白说现网设备普及率还不高老设备更多要靠网络侧防护来兜底。所以新项目选型时可以优先考虑支持CIP Security的设备存量设备则通过区域隔离和协议白名单来降低风险。另外一定要做好配置备份。PLC程序和网络配置文件定期备份到离线位置避免设备故障或遭受攻击后无法快速恢复。备份本身也是安全事件应急响应的基础条件。6. 常见问题与避坑指南6.1 常见问题速查表现象可能原因排查与处置抓包看不到44818端口流量抓包位置不对、流量被VLAN隔离、设备修改了端口检查交换机镜像配置用IPMAC维度做会话统计PLC能ping通但CIP连接建立失败CPU处于停止状态、连接数耗尽、固件限制查看CPU状态重启工程软件必要时重启PLC通信模块防火墙放行44818/2222后HMI仍连不上PLC只放了单方向策略隐式消息回包被拦同时放行PLC到HMI的UDP 2222回程并保证组播可达ListIdentity只返回少量设备设备关闭广播响应、跨VLAN、老固件机制不同改为定向发送结合供应商工具做补充发现DPI设备偶尔丢包HMI时断时续深度检测对CIP报文处理开销大或多个会话被误判调整DPI规则业务流量单独放行避免“一刀切”设备出现写操作但无告警监控规则只查了端口没查服务码在规则里增加CIP服务码和路径匹配6.2 我踩过的一些坑先在运维窗口做主动扫描这件事我强调多少遍都不过分。有一回我在一个项目上做ListIdentity广播因为目标网段里接了上百台设备广播风暴和响应报文瞬时冲击了一段时间结果某台老PLC的通信模块直接报错产线上HMI开始闪烁。后来我们改成了逐台定向扫描、限制发包速率才彻底消停。做资产盘点一定要“温柔”尤其是对上了岁数的设备宁慢勿快。另一个坑是抓包记录写得不够细。早期我抓完包回到办公室看着一堆pcap文件经常想不起来这是哪个车间、哪个交换机端口、什么时间段。后来我养成习惯抓包前先在记事本里写三行——时间、地点、交换机端口抓完包马上复制一份到带日期的目录里。这个习惯帮我省了很多返工时间。还有一个容易被忽略的问题调试用的临时抓包口、临时放行策略活动结束后没有及时拆除。这些临时通道往往会变成安全的缺口。现在我每次项目收尾都会列一个“临时措施清单”逐项确认关闭和回收避免留下尾巴。最后想说的是EtherNet/IP本身并不复杂复杂的是它身处生产环境任何误操作都会直接影响业务。做安全的人要敬畏这一点先保住业务再谈安全先看清基线再做封禁。这样你在车间里才会被老师傅信任后面推进工作也会顺利很多。