刘金永, 王 勇, 李双飞, 朱毅文
(1.上海电力大学, 上海 200090; 2.上海云剑信息技术有限公司, 上海 200433)
电力网的稳定运行对国民经济和社会稳定具有不可替代的作用,但是近年发生了许多电力系统被黑客攻击的事件,如伊朗震网病毒事故,因此电力网的信息安全已经上升到国家安全层面。监控和数据采集(Supervisory Control and Data Acquisition,SCADA)系统作为智能配电网发展的重要组成部分,是提高供电可靠性、提升优质服务水平以及提高配电网精益化管理水平的重要手段,是配电网现代化、智能化发展的必然趋势。可编程逻辑控制器(Programmable Logic Controller,PLC)是现代工业控制系统中的一个重要组成部分,特别是在SCADA系统中。干扰PLC的正常运行可能会导致严重的损害,威胁着人们的生命及财产安全,如乌克兰大面积停电事故。
目前,随着技术的变化,我国正在逐步走向工业互联网,人们开始将SCADA连接到互联网上,PLC设备接入互联网后将会面临更大的安全性问题。PLC的安全性已经引起广泛关注,专家学者对PLC设备从硬件和软件两大方面进行了研究,其中包括PLC的逻辑漏洞、通信协议漏洞等。针对西门子PLC结构以及通信协议分析,基于访问控制问题的攻击屡见不鲜[1]。针对访问控制问题,有研究者利用此漏洞对PLC成功进行了DoS攻击[2]。利用访问控制问题,攻击者可以以合法的方式,进行非法的操作。文献[3]针对此问题提出了一种采用纵深防御措施来保护系统,从而使系统有效防止误操作或者攻击。对于已知问题我们可以采取安全防护措施以弥补缺陷,防止被黑客利用,但是对于未知漏洞却无能为力,因此有研究者对PLC设备进行漏洞扫描工作。张亚丰等人[4]提出了基于心跳的异常监测与定位方法,对被测嵌入式设备进行异常行为监测和异常用例定位。在漏洞扫描方面,国外的研究者也取得了重大突破。PALMATIER T E[5]提出了一种通用的PLC固件分析方法,并通过概念验证实验来证明合法固件是如何更新并上传到PLC的。德蒙福特大学COFFEY K等人[6]研究了在各种不同网络上检测资产的不同方法,对在SCADA网络上执行扫描的可行性进行评估,并设计开发了网络扫描仪,以满足SCADA网络的要求。许多学者对工控协议的模糊测试方法进行了大量的研究。黄河等人[7]则利用循环神经网络对Modbus TCP协议进行模糊测试,测试的效率更加高效。文献[8]基于改进后的CSSR算法对协议进行结构分析,并用心跳监测和定位的异常监控系统提高模糊测试的效率。赖英旭等人[9]采用可变字节值概率统计方法、长度域学习方法、Apriori和Needle-man/Wunsch算法学习私有协议特征,有效提高了私有协议的测试用例接收率。阮伟等人[10]提出私有协议的解析方法和入侵检测方法,但并没有提出模糊测试的针对性方法。
目前,研究者已对工控协议分析并借助深度学习设计模糊测试的方法,但是对私有协议针对性不强,因此本文提出针对私有协议的特性,设计模糊测试的方法,提高模糊测试漏洞检测的效率。本文的工作主要是针对系统中核心的设备控制器进行漏洞扫描,控制器不仅仅局限于某种特定的型号,泛化性较强。
本文首先对西门子的通信协议进行分析,并针对存在的问题进行攻击性测试验证漏洞的真实存在性。
西门子私有通信协议自使用以来不断地更新换代,从最初的S7协议,到S7Comm再到现在有更多的安全措施的S7Comm plus协议,但协议的结构仍然使用最初的S7协议结构。
S7通信协议是建立在TCP/IP提供的网络传输功能之上,处于OSI参考模型第7层的会话层、表示层和应用层。其中TPKT协议处于会话层,是一个传输服务协议,主要用来在COTP和TCP之间建立桥梁。COTP协议处于表示层,定义了数据传输的基本单位。应用层则是用S7协议来传输PLC的数据。
私有协议不公开协议规约,构建Fuzzing的测试用例比较困难,可能存在安全漏洞。S7协议同样存在身份认证缺陷,没有进行相应的身份认证机制。我们可以构造数据包对其进行操作,并且如果设备固件版本较低,通过构造的数据包可以让设备停止工作。S7协议虽然是私有协议,但是已有研究者对其进行了协议解析,目前也有相关的Wireshark协议解析插件,可以对S7协议进行解析。虽然部分内容仍然没有得到解析,但是对于其主要的功能码、数据类型等重要信息都可以正确解析。因此,S7协议存在的问题也会慢慢地暴露出来,对于存在的未知漏洞应及时发掘并进行修复。
根据私有协议的特点和扫描方法的效率,PLC漏洞扫描需要实现的功能应包括以下几个方面:获取PLC网络地址、硬件型号、软件版本号等信息;对PLC安全漏洞进行检测并输出漏洞相关信息;由于需要应用于工业安全装置,所以系统应尽可能轻量且方便配置。
PLC漏洞检测系统设计采用以下3大模块:PLC信息扫描,获取设备版本信息;CVE漏洞库匹配,根据扫描结果输出漏洞信息;Fuzzing漏洞检测,对潜在漏洞进行扫描并输出结果。
出于轻量化考虑,本文系统在Linux平台设计实现,漏洞信息库存储于SQLite数据库,采用模块化设计,易于扩展。
在运行系统时,PLC信息扫描模块首先会通过Nmap调用工业系统设备信息扫描脚本对PLC信息进行扫描,识别设备版本信息,进而在CVE漏洞信息库模块检索SQLite vul数据库中的相关漏洞信息并输出到运行界面,最后执行Fuzzing漏洞检测模块,调用ISF工控协议组件和Kitty Fuzzing框架实现对未知漏洞检测。
主机和PLC设备使用S7进行通信时,不同PLC的CPU机架号、插槽号和功能码及值类型长度等通信数据包都将会发生改变,因此在设备已有的漏洞扫描模块和未知漏洞检测的模糊测试模块都需要得到准确的设备信息。信息扫描模块得到的信息准确性对后面工作的效率有着至关重要的作用。
针对PLC的扫描模块开源资料包很多,根据扫描模块的特点和扫描效率,本文借助Python调用Nmap,Nmap根据指定IP地址、端口号调用所创建的工业系统扫描NSE脚本,进行SYN或UDP扫描,获取设备基本硬件和版本号信息。其中,NSE脚本针对 SIMATIC S7工控系统设备,通过构造S7协议数据包,与设备建立通信。该脚本使用set_nmap()函数将主机端口信息传入Nmap,在与PLC设备建立通信连接后,分别发送两次SZL请求数据包,依次解析包含基本硬件信息和系统名、模块类型、序列号、设备标识、版权额外信息的响应。PLC信息扫描模块执行流程如图1所示。
图1 PLC信息扫描模块执行流程
PLC信息扫描算法描述如下。
输入:IP和端口号。
输出:PLC版本型号信息。
步骤:
1.初始化环境变量;
2.WHILE 扫描目标列表!= NULL;
主机发现;
端口扫描;
服务于版本侦测;
脚本扫描;
扫描指向列表下一个目标;
WEND
3.输出扫描结果。
工业互联大背景下,根据工业互联网安全应急响应中心(ICS-CERT)数据显示,我国电力系统网络安全存在很多问题,部分设备存在严重安全漏洞,可能的风险包括拒绝服务攻击、远程命令执行以及信息泄露。因此,根据上一步扫描得到的信息,匹配响应漏洞信息并输出到主界面,得到设备已经存在的漏洞。这对于系统安全性同样有很大的意义。此外,还可以根据模糊测试挖掘的漏洞信息,匹配数据库信息输出漏洞的威胁等级,访问向量等信息。
基于CVE工控系统行业漏洞库,选择部分漏洞信息使用SQLite建立本文所需要调用的漏洞信息库,主要由漏洞列表和漏洞详情表组成。本文用于调用工控设备的漏洞信息如表1所示。
表1 漏洞信息
模糊测试是一种介于完全手工渗透测试与完全自动化测试之间的安全性测试类型。能够在一项产品投入市场使用之前对潜在的安全性问题进行提示。随着模糊测试的广泛使用,有关模糊测试的工具也越来越多。主要的工业控制系统模糊测试工具有Sulley,Peach,Kitty等,各种模糊测试工具都有各自的特点和适用的场景。Sulley模糊测试是一种基于Python的Fuzzing框架,主要应用于网络协议方面的测试。Peach 3是一种面向Data Cosumer的跨平台模糊测试,对UEFI network test来说更为有效。
本文中使用Kitty Fuzzing框架运行于非TCP/IP通道上的私有和内部协议,是一个通用、抽象的框架,应该包含所有我们能想到的模糊测试过程中用到的所有通用功能,并且能方便用户扩展,以便用来攻击特定目标。
2.3.1 测试策略设计
S7协议通信中启动、停止、下载程序、上载程序和读/写数据等关键事件,在每一项关键事件中的通信报文中大体相同,但又有所区别,因此针对S7协议设计针对协议字段类型的测试策略。对每个字段类型进行测试,例如针对启动关键事件中的功能码0x28进行测试,此字段占两个字节,针对这两个字节进行变异测试,其他字节按照合法数据进行测试。
关键事件的通信报文中,字段之间、报文之间都有关联,因此本文设计了多字段关联测试策略。同样以停止事件为例,通信报文中的功能码为0x28,但是功能码为0x28的事件不一定是停止事件,也有可能是其他关键事件,评断是哪个事件还要看通信报文PI的内容,因此字段关联校验也非常关键。例外在通信报文中,参数字段的项目数和数据字段中的项目数是保持一致的,当两者不一致时,则为畸形报文。如果设备没有对相应畸形报文的处理机制,设备接受到畸形报文时就会出现故障。
2.3.2 数据变异算法设计
Kitty实现了Fuzzer主循环,并为每个用于创建完整模糊测试会话的元素的数据和基类建模提供了语法。但是,Kitty无法完成类的特定实现。Kitty定义了与目标执行数据事务的接口和基类,主要有数据模型、目标、控制器、监控、模糊器和接口组成。数据模型定义了由模糊器发送的消息结构,包括将消息分离为字段(例如S7协议的标头、长度和有效负载)、这些字段的类型(例如S7协议的字符串,校验和和反重放算法计算规则)以及它们之间的关系(例如S7协议的属性块中的长度,开头标识符,校验和和计数)。数据模型还描述了将不同消息链接在一起以形成模糊测试会话的顺序。这在尝试模糊系统的更深层部分时非常有用,例如利用S7协议和设备实行3次连接以模糊系统中只有经过身份验证的用户才能访问的部分。数据模型还可以指定发送消息的顺序是模糊的。
数据模型算法用来构造模糊测试数据,由3部分组成。首先列出S7Comm协议可用字段,这些字段组成了Kitty的基本语法。之后,使用可用的编码器进行编码。最后提供了有关如何使用前两部分中列出的字段、容器和编码器组成完整模板的示例。数据模型算法中有S7协议基本块、属性块字段的计算、变异字段的生成等。
其中基本块字段是数据模型的基本构建块。每个字段都是独立和离散的。属性块字段的计算是默认情况下从默认值范围之外的属性计算其值的字段,例如,其他字段的长度或校验和等。这些字段也可以模糊,但是当它们没有模糊时,将计算其字段值,以确保其呈现为有效值。
数据模型算法中变异字段生成最为关键,直接关系到模糊测试的效率。变异模糊化的策略是采取一些有效的信息并以各种方式对其进行变异。
变异生成字段程序算法描述如下。
输入:有效字段。
输出:变异字段。
步骤:
1.定义字段执行N个连续位的位翻转突变类;
2.定义从默认值复制一个字节块,每个突变向前移动一个字节类;
3.定义使用多个重复执行块复制;
4.定义用于执行块级突变的基类;
5.定义从默认值中删除一个字节块,每个突变向前移动一个字节类;
6.定义将一个字节块从默认值设置为特定值,每个突变向前移动一个字节类;
7.定义翻转消息中连续字节的数量,每个突变向前移动一个字节类;
8.根据输入字段格式调用所定义的类进行变异;
9.将变异的字段存储到容器中。
2.2.3 Fuzzing漏洞检测模块执行流程及算法描述
使用Kitty Fuzzing框架结合ISF中的工控协议组件对西门子S7Comm协议执行Fuzzing测试协议进行Fuzzing漏洞检测。模块执行流程如图2所示。
Fuzzing漏洞检测算法描述如下。
输入:IP和端口号。
输出:Fuzzing漏洞检测结果。
步骤:
1.初始化环境变量;
2.有变异字段生成测试用例;
3.向目标发送测试数据包;
4.接收目标返回响应;
5.输出测试日志。
图2 Fuzzing漏洞检测模块执行流程
实验采用2台西门子PLC(型号SiemensS7-1200)作为通信的主站和从站。另外使用2台电脑作为通信控制端(系统采用Windows 7 x64)和漏洞检测端系统采用(Windows 10 x64)。其具体的通信网络拓扑图如图3所示。
图3 PLC通信网络拓扑
选择IP地址为192.168.0.200的PLC,型号为Siemens S7-1200,执行嗅探模块,系统输出了目标设备类型、型号、硬件版本号等信息。扫描设备信息如表2所示。
表2 扫描设备信息
系统将目标PLC版本信息与修改后的CVE漏洞库进行匹配,输出相关漏洞信息,包括CVE ID、威胁等级、威胁利用难易性、机密性、完整性、可用性影响、详细描述和参考链接等。
扫描出的已知漏洞结果有3个,根据扫描结果和漏洞库信息进行匹配,并输出结果。扫描已知漏洞具体信息如表3所示。
表3 扫描已知漏洞具体信息
在CVE漏洞扫描完成后,系统调用Fuzzing模块对PLC进行未知漏洞检测。首先根据模糊测试中的数据模型中的有效数据和设备建立连接,随后给设备发送测试用例,同时有监视器对设备的异常状态进行监视,一旦设备出现异常状态,记录此次过程,并输出测试结果。终端与Web所显示检测结果分别如图4所示。经过多次实验验证,未能扫描出未知漏洞。
图4 未知漏洞扫描
3.5.1 漏洞扫描结果
本文使用基于OpenVAS的虚拟机系统Greenbone Security Manager(GSM)对目标PLC进行漏洞扫描,为PLC漏洞检测系统扫描结果提供参照比对,验证系统有效性。测试过程如下:首先,运行GSM系统,查看Web Interface配置信息并打开相应Web接口界面;然后,登录到控制台,创建高级扫描任务;最后,完成对目标PLC扫描。深度扫描历时约10 min,结果显示目标PLC存在一个ICMP Flood漏洞,可能导致主机宕机,并给出了解决方案、漏洞检测方法和参考链接等信息。扫描详情如图5所示。
图5 OpenVAS漏洞扫描详情
漏洞信息为p-smash DOS(ICMP 9 flood)漏洞,攻击者可以利用这个漏洞让主机设备持续崩溃,一旦攻击者攻击成功,正在工作的PLC工作异常会给电网造成不可估计的损害。
3.5.2 漏洞检测对比
本文系统共检测到3个数据处理或输入验证方面的安全漏洞,而OpenVAS检测发现设备可能会因ICMP洪泛攻击崩溃。在漏洞数据库的选择上,本文系统使用CVE漏洞库,OpenVAS使用NVT。综合测试结果比较如表4所示。
表4 漏洞检测率比较
由表4可知,在漏洞检测率方面,本文所提方法能够更加有效地检测到PLC的已知与未知漏洞,但是相比于OpenVAS缺少精确的漏洞验证机制,需要进一步的人工分析,漏洞数据库也需要进行手动更新。
在漏洞信息完整性方面,本文所提方法与OpenVAS均提供了完整的漏洞信息,包括漏洞详情、威胁等级、修复建议等。此外,本系统还给出漏洞威胁利用难易度、机密性影响、完整性影响、可用性影响等额外信息,相比于OpenVAS更具有参考价值。
在安装、配置、使用过程中,本文所提方法均有优势,操作简便,架构与交互界面设计复杂度远低于OpenVAS。在扩展性和可移植性方面,由于二者都采用模块化设计,且不同模块间预留了必要接口,能够方便地实现扩展功能。此外,依托Python语言的跨平台特性,二者通过调用必要的Python开发库很好地实现了多平台支持,为漏洞检测提供了极大便利。
本文通过对PLC、工业网络协议以及漏洞检测等相关技术的研究,借助SQLite数据库、Kitty与ISF框架,实现了对PLC存在的CVE和未知漏洞检测。测试结果验证了该方法的可用性,且相较于通用漏洞扫描工具能够以较快速度给出扫描结果,但同时也反映出其PLC潜在漏洞检测方面存在的局限性,主要体现在对最新版本S7Comm plus私有协议进行Fuzzing时未挖出未知漏洞,对PLC的版本与漏洞信息尚未能精准识别。因此,下一步的工作主要是改进完善模糊测试的方法,使其PLC版本固件扫描更加精确和未知漏洞检测效率更高。