概述:西门子PLC使用私有协议进行通信,端口为102。西门子PLC协议有3个版本,S7Comm协议,早期S7CommPlus协议和最新的S7CommPlus协议。S7-200、S7-300、S7-400系列的PLC采用早期的西门子私有协议S7comm进行通信,S7-1200系列v3.0版本之前的通信协议采用早期S7Comm-Plus协议,S7-1200系列v4.0版本、S7-1500系列采用了最新的S7Comm-Plus协议,最新的S7Comm-Plus协议引入了会话ID来防止重放攻击,且对关键流量有加密处理,该部分的内容从2017年以来就有多名研究员进行了阐述,网络上相关的文章也比较多。但对S7Comm-Plus协议在工控环境下使用最多的业务流量分析较为缺乏,本文以工控常见业务场景为例,分析Wincc V7.4作为上位机对PLC数据区的访问操作,现实场景中工控流量占比最大的也是上位机的SCADA环境对下位机PLC数据区的一些读写操作,而非组态软件对PLC的启停、下装上载操作,只有在调试运维过程中才会使用组态软件。
1
环境配置
整个协议分析的基本环境配置如下:Win7 x64虚拟机:
PLC:S7-1200,6ES7214-1AG40-0XB0
Firmware: V4.2.3
Software:Wincc V7.4
S7Comm-Plus Wiresharkdissector plugin: V0.0.8
配置环境搭建的框架图如下所示,通过交换机连接SCADA上位机与S7-1214C的PLC,wireshark安装在连接镜像端口的PC机中,wireshark中导入S7Comm-Plus的解析插件。
2
对数据区的读变量操作
本文所述的数据区特指S7系列PLC中的DB块、M区(I区、Q区与M区类似)。Wincc对PLC的读变量操作,首先需要组态Wincc V7.4在画面中建立输出控件,关联上PLC的对应地址变量,运行系统后在控件中就可读取对应变量的值,如下所示:
组态读取MD92地址处的变量值,读取变量的操作码Opcode为0X31,Function为CreateObject(0x04ca),寻找第7个Attribute属性中ID Number字段SubscriptionReferenceList。
展开SubscriptionReferenceList的详细描述,在SubscriptionList下包含了具体的访问区域与详细地址信息,Accessbase-area区域显示M区(0x52),Blob startoffset为92,表示M区中的访问地址,读取字节数Blob bytecount为2,表示读取两个字节长度。
组态读取DB59999.DBW6地址处的变量值(wincc对于DB块进行读取操作必须不加入优化,DB块中的变量必须有确定分配的地址),读取变量的操作码Opcode为0X31,Function为CreateObject(0x04ca),寻找第7个Attribute属性中ID Number字段SubscriptionReferenceList。
展开SubscriptionReferenceList的详细描述,在SubscriptionList下包含了具体的访问区域与详细地址信息,Accessbase-areaa区域经过算法解析后得到0x8a0eea5f,表示DB59999(原始数据帧中字节为0x88 d0 bb d4 5f),Blob startoffset为6,表示DB5999中的访问地址,读取字节数Blob bytecount为2,表示读取两个字节长度。
备注:VLQ相关编码算法可参考S7Comm-plus wireshark插件的源码,源码地址https://sourceforge.net/p/s7commwireshark/code/HEAD/tree/trunk/src/
3
对数据区的写变量操作
Wincc对PLC的写值操作一般会在画面中建立输入控件,关联上PLC的对应地址变量,在控件中写值,按enter键后写入成功,如下所示:
在MD92写入变量过程中抓取到请求数据帧
写入变量的操作码Opcode为0X31,Function为SetMultiVariables(0x0542),Access base-areaa字段显示为M区(0x52),写入地址Blob startoffset为92,写入字节数Blob bytecount为4,写入的值为value:0x0001046a。
在DB59999.DBW6地址处写入变量过程中抓取到请求数据帧,(Wincc写DB块必须保证DB块不优化,有自己的实际地址)
写入变量的操作码Opcode为0X31,Function为SetMultiVariables(0x0542),Access base-areaa字段显示为DB59999(0x8a0eea5f),写入地址Blob startoffset为6,写入字节数Blob bytecount为2,写入的值为value:0x8235。
4
流量中关键点提取
从以上的分析中可以总结如下表格,不论是工业防火墙还是审计系统,均需要将关键字段识别并加入至白名单中,在S7Comm-plus协议的流量中,识别表格中的关键信息就能命中各种业务操作,比如读M区变量、写Q区变量等。但是想和实际工艺场景结合,比如命中流量中对污水处理加药间加药量阀门的操作需要做进一步的工作。
读DB块 | 读M区 | 读I区 | 读Q区 | |
---|---|---|---|---|
Opcode | Request(0X31) | |||
Function | CreateObject(0x04ca) | |||
ID Number | SubscriptionReferenceList | |||
Base-area | 0x8a0e | 0x52 | 0x50 | 0x51 |
写DB块 | 写M区 | —— | 写Q区 |
Opcode | Request(0X31) | |||
---|---|---|---|---|
Function | SetMultiVariables(0x0542) | |||
Base-area | 0x8a0e | 0x52 | —— | 0x51 |
5
总结
本文以Wincc V7.4作为上位机,调用S7Comm-plus的驱动访问S7-1200系列PLC,具体访问了PLC的DB块、M区等,在访问过程中通过wireshark抓取对应报文,并做了简单分析,并通过表格形式总结出S7Comm-plus访问西门子系列PLC常用数据区的关键字段,在工业安全产品中要解析或者捕获流量是需要命中这些字段,通过这些字段关联到对应的操作区域。但如果想再次区分流量中对M区的哪个地址写入了什么数据还需要深入解析后续的value字段。如若需要和工艺流程联动,还需要将工程点表和安全产品中的命中规则联动和融合,这样才能更接近工业现场。