0x00 概述
Sinec H1是第一个基于以太网的工业协议,可提供传输层功能。该协议由西门子推出,目的是使用现有标准并丰富工业通信协议的相关细节,主要用于控制系统之间的数据传输。它具有大带宽特点,非常适合传输大量数据。基于ISO / IEC 8073标准,定义了不同的传输方法。
当PLC之间进行通讯时,采用在OSI第4层上的对等数据传输模式,称为传输层连接;
当上位机与PLC之间通讯时,在OSI的第7层上进行TF (Technology Function)通信。
TF(Technology Function)通信服务通常在监控上位机和PLC之间使用,以进行数据采集和控制,在典型的H1网络中,可以使用具有该功能的上位机连接一个或多个PLC。上位机系统必须具有以下功能:可在PLC中读取和写入数据。
虽然该协议推出时间较早,但是其用法简单传输数据量大,现在依然存在于大多数工业现场,尤其是和上位机SCADA进行数据交换时应用广泛。各个厂家在SCADA的通信驱动中集成了该协议,但有的命名为Siemens S7驱动而未提及Sinec H1相关内容。
具有Sinec H1 传输通信接口板的Simatic S5和S7系列PLC,例如CP1430,CP143,CP535,CP443-1均支持Sinec H1协议,编址方式为TSAP节点、访问块、word形式、数据长度。
0x01 协议分析
分析Sinec H1协议的测试环境如下图:
关于该协议的信息在网上极少,无公开的报文设计类文档,因此无从知晓数据帧格式。面对这种情况。有如下突破的思路:
A.获取到支持该协议的CP板卡的固件,逆向固件获取处理该协议的相关流程信息;
B.获取支持该协议的上位机驱动文件,通过逆向驱动文件获取处理该协议的相关细节;
A思路尝试。选取CP443-1通信扩展模块尝试下载其固件,访问西门子官网搜索CP443-1的firmware,如下页面:
点击下载后,出现了不美妙的一幕。
显示为限制出口的软件,需要再次注册,即使再次注册最终也是没能成功下载到该软件,因此此路不通,暂时放弃。
转战B路线,在测试环境中找到了上位机SCADA与下位机CP443-1模块利用H1协议通信的驱动程序,命名为s7drv。遂将此文件拷贝出,利用IDA进行分析,如下图:
逆向出的文件很清爽,有完整的文件命名,便于阅读理解。依照main函数找到main_loop,再次深入其中找到处理协议的相关函数Polling_Data,在其中看到轮询数据的处理BUF内存入的数据格式,构造出格式后通过send_to_lan发送至网内。
追踪send_to_lan函数,查看是否还有其余处理程序调用该函数。得到如下图示:
得知有6个函数块调用该发送函数,猜测功能分别为:
序号 | 函数名 | 功能 |
1 | SendMsgManage() | 分发信息管理模式,下发给PLC该任务后,PLC作出对应处理 |
2 | Polling_Data() | 轮询PLC内的数据 |
3 | Polling_Status() | 轮询PLC的定义状态 |
4 | Polling_WRFlag() | 轮询预定义的写入标志 |
5 | Read_Record() | 读取预先定义的记录信息 |
6 | Read_String() | 读取预先定义的字符信息 |
针对于6个不同功能的操作函数,梳理其对应的数据结构如下图:
绿底色的数据结构为固定值,可以推测为标志符、长度之类,青底色的结构可以看作是对应函数操作的功能码,其余无填充色的部分均为随着应用场景变化的部分。
在查找资料过程中发现了Wireshark中对于该协议可解析,且可以获取到对应插件的源码,因此对照源码再次梳理以上数据结构。
在block_type_vals[]字段中定义了以下4中类型:
在value_string opcode_vals[]中定义了4中类型:
在value_string org_vals[]中定义了多种类型,对应访问PLC中的各种不同类型的数据块及其片区。
根据以上较为明显的定义,阅读解析协议的插件代码并对照以上逆向分析出的数据结构,得到如下数据帧结构,不同底色的数据内容可划分为一个类别,按照类别理解每个块的功能结构。
至此推测分析该协议的数据帧格式步骤已完成,接下来通过抓取现场数据报文验证分析过程是否准确,抓取一段时间过滤后的报文如下图所示。
可看到Wireshark解析报文info标记为S5,解析内容均为读操作(包含响应与请求),选取几个报文精细分解。
该报文中访问DB38号块,访问地址为0000,长度为0001,结合逆向结果可知该报文在实际的应用场景中为轮询WRFlag状态,响应帧见下:
整个帧结构为响应帧,在操作类型和第2个子块类型中均为读操作的响应帧结构。附带的响应数据为0。
以下该数据帧结构为读取DB36号块,偏移为0,长度为751的请求帧结构。对照逆向的代码,在该应用场景下为轮询PLC内部数据的操作。
到此我们通过逆向SCADA内部的西门子H1驱动结合Wireshark插件源码,给出了报文格式,再根据现场抓取的报文结合分析了数据格式及其现场应用的实际意义与功能。但仍有以下问题:
1.Sinec H1为通用协议,支持的操作较多,但在驱动内部仅出现了几个类型的操作?
2.在驱动内部仅能看到固定值的操作DB块号,36/38/39/40,其余的功能数据内存块或者编号呢?
根据经验推测:该SCADA的驱动为厂商定制开发,结合Sinec H1协议支持的功能只保留对以上提及DB块的特定操作,减少工程组态的工作量,也可以在针对特定行业开发固定工程模板,提高工程效率。
0x02 模糊测试
目前网络上流行的各类工控协议FUZZ入门测试均以Modbus为例,本文的Sinec H1协议经过分析其结构简单,同样适合初学者上手操作。因此本文从入门普及的角度,对该协议做以简单FUZZ测试解析。
本文选取的FUZZ框架为boofuzz(其余广泛流传的文章中均以sulley、Peach为例),boofuzz的详细信息下载地址https://github.com/jtpereyda/boofuzz。
Boofuzz是Sulley模糊测试框架的继承者。除了修复了许多错误,boofuzz还提升了可扩展性。主要特性有以下几点:
1.轻松快速的数据生成方式;
2.失败后的目标重置;
3.记录测试数据;
4.在线文档;
5.支持任意通信媒介;
6.内置支持串行模糊测试、以太网、IP层和UDP广播;
7.更好地记录测试数据——统一、彻底、清晰;
8.测试结果通过CSV导出;
9.方便的安装体验;
先需要在脚本运行的PC机上安装boofuzz,
根据以上分析的H1协议帧结构编写fuzz脚本,fuzz对象为下位机PLC系统,因此在参数设置中均以PLC为目标对象。如下所示:
注意:
A.将Sinec H1协议中固定字段值设置为无需fuzz属性,fuzzable=false;
B.脚本代码依照解析出的协议子块内容编写,便于维护与阅读;
C.在connecttion参数中需要注意,该协议不能重用连接,必须等待1次完成连接fuzz后再次启用1个连接;
D.同上,在fuzz过程中发现了下位机PLC处理fuzz包的过程缓慢(猜测PLC接收到不在认可范围内的包处理流程复杂,还需断开连接操作),因此restart_sleep_time值要根据实际情况调整;
0x03 总结
本文主要以西门子早期的协议Sinec H1为背景,介绍了协议分析和针对工控协议fuzz测试的大致思路和应用实践,旨在通过这些分享让更多人了解工控安全中协议方面的入门姿势,也希望通过本文为寻找Sinec H1协议相关资料的研究者们提供些许帮助。如若能帮助到需要的人,甚感欣慰。
声明:本文来自绿盟科技研究通讯,版权归作者所有。文章内容仅代表作者独立观点,不代表安全内参立场,转载目的在于传递更多信息。如有侵权,请联系 anquanneican@163.com。