博智工控漏洞挖掘平台实战-西门子PLC漏洞挖掘
1.准备工作
1.1.靶标介绍
本次实战选取的靶标是德国西门子PLC产品,西门子公司生产的PLC在我国工控行业应用得十分广泛,例如冶金、化工、印刷、交通等领域。西门子(SIEMENS)公司的PLC产品包括S7-200、S7-300、S7-400、S7-1200、S7-1500等。
本次实战选取的西门子PLC产品为:S7-1200。实物图:
通过TIA软件可以搜索到该PLC,查看固件版本号为V 3.0.2。如图:
查看其IP地址为192.168.11.199。如图:
1.2.S7Comm Plus协议介绍
介绍S7Comm-Plus之前,需要介绍一下S7Comm(全称为S7Communication),它是西门子为了在多个PLC之间、SCADA与PLC之间的通信而设计的专属协议。而S7Comm-Plus的诞生是为了解决S7Comm存在的一些安全漏洞。
在早期的S7Comm-PlusV2中,通过引入新的会话ID来防止包重放攻击,该机制存在漏洞,可以被绕过,从而继续实施报文伪造和重放;在S7Comm-PlusV3中,通过引入证书和复杂的加密算法,彻底从协议层面解决了报文伪造和重放的漏洞。
本次实战的靶标对象西门子S7-1200系列采用S7Comm-Plus V2协议。
使用wireshark对S7-1200 PLC与上位机TIA软件的通信进行抓包,可以看到协议中存在一个“SessionId”字段,每次建连通信都使用不同的session id,如果攻击者创建新的会话进行包重放攻击,重放攻击包中的的sessionid无法通过PLC的校验,从而达到抵御重放攻击的目的。
但该协议实际使用中,研究者发现这个”会话id”可以通过与PLC握手的报文中获取到。sessionid失去了原本的设计意义,无法达成抵抗重放攻击的目的。
在初始建连过程里上位机将向PLC发起CreateObject请求,该请求使PLC创建“服务端会话容器对象”(ObjectServerSessionContainer),如图:
PLC创建完会话对象后,将Session Id返回给上位机,在PLC返回的响应报文中,字段ObjectId[1]中的内容就是Sesssion Id。
如图可见,报文中的原始数据是0x878080a03d,wireshark显示的SessionId却是0x7000103d,这中间需要进行一次转换,才能在后续的报文中填入正确的Session Id。
这里使用的转换算法是一种被称为VLQ编码的算法,VLQ指variable lengthquantity,即可变长度的量。该算法特性是无须使用单独的结束字符以及长度字符,仅靠其本身就能表示长度可变的值。在报文传输中它意义是无须设立专门的长度字段,接收方就能正确判断变量的长度。
VLQ是基于7bit组的变长编码,本身很简单,就是利用每个字节的bit来暗示是否有后续字节。
l 0xxxxxxx
l 1xxxxxxx 0xxxxxxx
l 1xxxxxxx 1xxxxxxx 0xxxxxxx
这样设计的好处在于无须将数据的长度写在某处,通过读取每个字节的首位bit位,判断其是否是0,是0则结束读取,是1则表示后续还有数据。
通过该算法得知,只要将0x878080a03d每个字节中的首位为1的bit位去掉,使用剩下的7个bit进行重组,终得到的数据正好是0x7000103d。
博智漏洞挖掘平台内置了VLQ算法,能正确读取会话id,并将解码后的SessionId编入测试用例中,从而突破了PLC的防御机制,使测试用例能够正常进行。
1.3.测试环境搭建
测试所需硬件:
硬件 | 数量 | 说明 |
PC电脑 | 1 | 安装chrome浏览器,用来登陆漏挖web界面 |
博智漏洞挖掘平台 | 1 | 测试主体,利用fuzz技术对被测靶标进行漏洞挖掘 |
PLC S7-1200 | 1 | 被测主体,可通过观测其端口或指示灯判断运行状态 |
普通网线 | 2 | 设备连接 |
博智漏洞挖掘平台允许通过测试网络连接上位机和下位机。本次实战不涉及上位机,仅需使用网线将PLC与漏挖平台的下位机端口,对应漏挖网口ETH0,PLC与漏挖连接如图:
用网线将漏挖的管理口(对应网口MGMT)与PC机连入同一个内网,在PC上能访问管理口IP即可。
2.漏洞挖掘
2.1.网络配置
在PC上使用浏览器登录漏挖管理系统,在系统中找到“环境配置->测试网络配置”,将漏挖系统eth0网口的ip地址配置为PLC同网段地址,本次测试PLC的IP地址是:192.168.11.199,将本端地址设置为192.168.11.1~192.168.11.254中的任意一个即可(除192.168.11.199)。
2.2.端口扫描
在“扫描配置->扫描配置“中扫描PLC端口情况,S7Comm-Plus协议端口固定为102/tcp。端口扫描必须确认102端口已经开放。
2.3.监视器选择
根据被测服务的特点选择相应的监视器,S7Comm-Plus协议端口是TCP协议,TCP监视器是必须打开的,其他的监视器可根据情况自行选择。
2.4.测试用例选择
博智漏洞挖掘平台根据S7Comm-Plus协议规范内置了若干Fuzzing测试用例,本次实战选取”S7CommPlus v2SetVariable语法测试”,该用例将测试设备对SetVariable命令的执行逻辑有无漏洞。
2.5.测试用例执行
执行测试用例之前系统会检测各个监视器状态,确保所有监视器状态正常才会开始发送测试用例数据。
如果测试用执行到所有监视器状态均为正常,则表示未发现漏洞,若监视器异常,则需要对测试用例数据进行分析,以确定是否真实存在漏洞。
当测试进度来到13.02%时,测试监视器出现异常,TCP监视器告警,说明此时监视的102、80、443端口无法建连了。
通过监视详情界面,可以看到所有PLC的所有 TCP端口均无法连通,如图:
2.6.结果分析以及复现
在漏洞测试结果详情页面可以查看漏洞类型为”拒绝服务”,漏洞个数为1个。
漏洞详情页面还展示了触发本次拒绝务漏洞的payload报文:
开头的03 00 00 38是TPKT协议头、02 f0 80是COTP协议头,从7202开始则是S7Comm-Plus协议数据,72表示该协议是S7Comm-Plus协议,02则表示该报文是S7Comm-PlusV2。
通过编写包重放代码,仅将该报文发送给处于正常状态的PLC,观察PLC状态,RUN信号灯从绿色变为黄色并闪烁,error等变为红色并闪烁,表示PLC处于错误状态,观察其102端口,已经无法连通。
正常工作的PLC状态:
发送了拒绝服务漏洞的payload报文之后的PLC状态:
抓取payload流量,使用wireshark分析,可以看到如下信息:
触发漏洞的功能码是SetVariable,触发漏洞的数据位于ObjectQualifier区块,PLCS7-1200在处理该数据块的时候,代码逻辑不严密,导致漏挖平台通过构造特殊数据,可以引起服务崩溃,进而触发DOS攻击。
厂商可以通过复查该部分的代码,结合本次测试用例的payload分析代码逻辑缺陷,从而修复该漏洞。