SIMATIC S7-300-400中间人攻击
时间:2021-09-07 作者:安帝科技
>0x01 协议简介
S7Comm全称S7 Communication ,是西门子为了多个PLC之间、SCADA与PLC之间的通信而设计的专属协议。在西门子S7-300 / 400系列、S7-200系列、S7-200 Smart系列上应用。S7-1200和S7-1500系列采用带有加密签名的S7 CommPlus协议。S7的通讯大致分为4个过程,分别是:1.TCP三次握手;2.COTP握手:COTP部分分为两种,COTP连接包和COTP功能包,COTP握手阶段使用的是COTP连接包,S7数据传输阶段使用的是COTP功能包;3.S7COMM建联:S7COMM作为COTP的有效载荷,主要包含三部分:Header、Parameter、Data,建联阶段S7COMM只包含Header和Parameter两个字段。S7 Communication协议与西门子S7 Communication Plus不同,该协议并没有采用会话ID,整个通信过程是不受任何保护的,中间人可以通过截断、重放、伪造对其进行攻击。虽然S7 Commplus也被曝出具有相关漏洞,但S7Comm更加不安全。其攻击原理如图1-1所示。
>0x02 产品简介
1994年4月,西门子S7系列诞生,它具有更国际化、更高性能等级、安装空间更小、更良好的WINDOWS用户界面等优势,其机型就包括S7-300、400。
S7-300模块化结构、易于实现分布式的配置以及性价比高、电磁兼容性强、抗震动冲击性能好,使其在广泛的工业控制领域中,成为一种既经济又切合实际的解决方案。S7-400系列plc中功能分级的CPU以及种类齐全的模板,总能为其自动化任务找到最佳的解决方案,实现分布式系统和扩展通讯能力都很简便,组成系统灵活自如,用户友好性强,操作简单,免风扇设计。随着应用的扩大,系统扩展无任何问题。SIMATIC S7-300和SIMATICS7-400被广泛应用于汽车工业、立体仓库、纺织机械、包装机械等领域。虽较新的SIMATICS-1500拥有更强的性能,但由于工业控制系统设备的使用周期通常是15-20年,至今仍有不少的SIMATIC S7-300或SIMATIC S7-400在工作。
>0x03 实验环境
Windows 10/KALI 2019.1/Snap7 Server Demo/Snap7 Client Demo
>0x04 环境搭建及攻击复现
本次复现采用的是PLC S7的模拟器Snap7,与实体S7攻击流程相同。该模拟器分为客户端和服务端。复现流程如下:
命令行输入ipconfig查看本机IP地址。本次实验环境IP地址为192.168.88.129.
打开Snap7 Server Demo,并在左上角Local Address输入本机IP192.168.88.129
点击Start启动服务端,可以看到服务端已经启动。
打开Snap7 Client Demo,输入本机IP192.168.88.129。
点击客户端Connect后可以看到服务端显示连接成功。
进入kali,打开isf,使用对应模块。
输入show options查看选项。
设置攻击目标为192.168.88.129。
输入run运行,可以看到isf回显stop plc。
返回查看服务端,可以看到CPU发送了停止PLC的请求,攻击成功。
>0x05 攻击分析
此次攻击其实就是一次中间人攻击,查看exp也可以发现中间人通过伪造发送了一个停止PLC的请求,PLC收到请求后停止工作。
S7-300和S7-400采用的S7 Communication协议进行通信,该协议主要通过COTP、TPKT、TCP、IP进行一层一层的封装。
本次漏洞分析主要进行拆解STOP请求包的协议,图5-2为S7 300和S7 400的OSI模型中所采用的协议。而图5-3则是从应用层的S7 communication到传输层的TCP的封装流程,本次分析主要针对其中的前三层。S7 Comm包括了头部、参数块和数据块,如果只是下达一些指令而不传输数据的话,数据块为空。COTP对S7的封装则是在其基础上新增一个头部和参数块。TPKT则是在COTP的基础上再增加一个COTP 头部,最后再将其封入TCP中。
如图5-4为STOP指令的TPKT协议包,TPKT头部主要包含三个参数,分别为版本、保留值和TPKT、COTP、S7 Comm三层协议的总长度值,如图5-5所示。
如图5-6所示是STOP指令的TPKT协议包中的TPKT Header部分,在十六进制中,两位十六进制数占1字节(8位二进制、8bit),第0字节的0x03为TPKT的版本信息,第1字节的0x00为TPKT头部的保留值,是固定的。而TPKT协议包总长度占2字节,也就是紧随其后的0x0021,该协议包总共66位十六进制数,33字节,也就是总长度所表示的0x0021。
COTP有两种类型,一种是连接包(握手包),是用于建立连接的,其主要包括1字节的COTP协议数据包后续部分长度值、1字节的PDU类型、2字节的目的地址、2字节的源地址、1字节的是否为拓展格式和是否为没有明确的流控、以及不限制字节参数块。还有一种就是功能包,如图5-6所示,其包括1字节的COTP协议数据包后续部分长度值、1字节的PDU类型和1字节的PDU类型。可以通过看COTP Header的第一个字节确定是连接包还是功能包,COTP的第0字节为0x02则为功能包,大于0x02则为连接包,因为0x02所表示的长度不包括0x02本身,且只表示COTP Header内后续部分的长度,功能包后续部分刚好为2字节,而连接包大于2字节。我们可以确定STOP指令的COTP是功能包。第1字节的PDU类型,0xf0代表这是一个数据,不同的PDU类型表示的不同,主要包括加急数据、加急数据确认、用户数据、拒绝、数据确认、连接的请求与确认、断开的请求与确认。第2字节的0x80为是否为拓展格式和是否为没有明确的流控,都采用Boolean类型。
S7Comm的Header结构如图5-9所示。第0字节的0x32表示协议ID,通常为0x32。第1字节的0x01表示PDU请求类型为作业请求(作业请求包括读/写存储器,读/写块,启动/停止设备,设置通信),其他PDU类型还包括确认响应、确认数据响应、原始协议拓展,很明显STOP就属于作业请求,所以PDU类型为0x01。第2-3字节为冗余数据,通常为0x0000。第4-5字节为协议数据单元参考,这个值通常通过请求事件来增加,这里将其设置为0x0600。第6-7字节为参数块的总长度,STOP请求的参数块总长度为0x0010,该值表示S7 Header之后的参数块长度,不包括Header的6-9字节,所以从0x0029开始计算,到结束刚好16字节,也就是0x0010。该STOP指令的协议包后续数据均为参数块。第8-9字节0x0000表示数据块的长度,这里也就是表示没有数据块,该S7 Comm协议包不包含数据块。
如图5-11所示,建立通信的作业请求的S7的参数块主要包括功能ID、未知块、参数块、PI Service字符串长度、PI Service。不同的功能块所用的功能ID不一样,该STOP协议包的第1字节0x29表示这是一个停止PLC的数据包。第6字节0x09表示后续PI Service的长度,共9字节。之后的0x505f50524f4752414d表示PI Service名,可通过解码获得结果,PI Service为P_PROGRAM,该进程表示设置设备的运行状态。