电力工控协议脆弱性动态分析技术的研究
2018-02-16郭志民李暖暖
陈 岑,吕 卓,郭志民,李暖暖
(国网河南省电力公司电力科学研究院,河南 郑州 450052)
0 引 言
面向电力工控协议分析的脆弱性分析技术包含静态和动态两个方面[1]。静态分析方面,在不运行电力工控协议实现程序的前提下,分析软件程序中可能存在的漏洞,主要研究软件或固件逆向解析、中间语言分析、模拟执行数据流分析和智能缺陷识别等工控协议的静态漏洞挖掘及分析技术。此外,通过分析工控协议实现程序的词法、语法、语义,检测软件中存在的弱安全函数调用和缺陷代码片段,并以中间表示语言为基础,进一步分析函数控制流图和模块函数调用图,挖掘电力工控协议实现过程中的安全漏洞[2-5]。但是,静态分析方法未考虑外界因素对待测系统安全性的影响,因此可以通过研究电力工控协议脆弱性动态分析进一步挖掘电力工控协议漏洞。电力工控协议脆弱性动态分析技术是在待测系统实际运行的前提下,通过观察待测系统执行过程中程序的运行状态、内存使用状况、寄存器的值以及协议数据处理情况等发现潜在问题。
1 电力工控协议脆弱性动态分析技术研究
针对电力工控协议实现的脆弱性,主要从两个层面进行动态分析。系统层面,研究面向工控协议数据的动态污点分析技术,跟踪工控协议数据流的传播,针对特定的控制指令做出安全性断言[6-7]。网络层面,研究双向Fuzzing测试技术,构造模糊测试指令集,同时监视协议服务器端和客户端的测试过程和返回结果,以验证待测系统协议实现的正确性[8-9]。通过分析系统和网络两个层面的测试结果,发现了工控协议存在的安全漏洞。研究步骤如图1所示。
图1 电力工控协议脆弱性动态分析技术研究步骤
1.1 基于动态污点分析的工控协议动态漏洞挖掘
污点数据指来自不可信数据源的数据或通过工控协议读入的数据。利用动态污点分析技术挖掘工控协议漏洞的基本原理如下。工控系统运行过程中,监控可以改变程序流程的数据,而这些数据往往来自可信的数据源。但是,如果攻击利用协议漏洞修改了这些数据的值,便可以控制程序的运行。比如,跳转指令(Jmp)的目的地址参数通常来自程序本身(即来源于可信的数据源),而非外部输入数据(如通过工控协议传入的数据)。然而,攻击者可以利用工控协议实现过程中的漏洞,复写跳转指令的目的地址,从而实现控制工控系统运行流程的目的。
为了检测引起工控系统运行流程异常的污点数据,需经过标识污点数据、监控污点数据传播路径、判断污点数据是否会引起系统异常三个步骤。如图2所示,基于动态污点分析的工控协议动态漏洞挖掘与分析方法可以划分为三个功能组件。
图2 基于动态污点分析的工控协议动态漏洞挖掘与分析方法功能组件
1.1.1 指令识别与污点数据标识组件
指令识别与污点数据标识组件将来源于不可信的数据标识为污点数据。因为网络数据中可能包含多种攻击向量,所以来源于网络的工控协议数据默认为不可信数据。此外,可以通过配置,将来源于文件和标准输入的数据认为是不可信数据。这是由于部分系统支持工控协议数据录播和回放,此时包含攻击向量的数据可能被文本化后输入工控系统。
电力工控指令具有不同安全等级属性。例如,与“读”指令相比,“写”指令往往会造成物理世界的变化,因此“写”指令具有更高的安全性属性。针对高安全属性的指令,需要设置更多的检测点,以便做出更加缜密的安全性断言。此外,指令识别与污点数据标识组件应识别电力工控指令,标识不同的安全属性。
工控系统包括通用寄存器和堆栈在内的存储器,且每个字节对应一个污点标识结构。如果不可信数据源的数据进入系统,存储空间对应的污点标识结构被置位,信息就会被污点数据传播路径跟踪模块和安全性断言模块使用。
1.1.2 污点数据传播路径跟踪组件
污点数据传播路径跟踪组件,通过跟踪每条X86指令的运行效果,决定污点数据的传播路径。
所有指令可以分为三类:
(1)数据移动指令,包括Load、Store、Move、Push、Pop等指令;
(2)数学运算指令,包括Add、Sub、Xor等指令;(3)无影响指令,包括Nop、Jmp等指令。
对数据移动指令而言,当且仅当源地址的数据为污点数据时,目的地址的数据被标识为污点数据。对数学运算指令而言,如果任何一个源操作数为污点数据,运行结果就会被标识为污点数据。对无影响指令而言,源操作数的污点属性不会影响目的操作数的污点属性。对数据移动指令和数学运算指令而言,因为立即数往往来自程序内部,所以立即数被认为是非污点数据。
为了跟踪数据移动指令和数学运算指令,需要在每一条数据移动指令和数学运算指令之前或之后增加记录指令,以修改源操作数或目的操作数的污点属性。
1.1.3 安全性断言组件
安全性断言组件可判断污点数据被非法使用,即污点数据被敏感指令或函数作为参数使用。敏感CPU指令/函数主要包括四类。
(1)跳转指令,安全性断言模块检测污点数据是否被用作调转指令的目的地址,如返回地址、函数指针地址、函数指针偏移量等,而许多攻击者试图通过复写上述地址实现操纵工控系统运行流程的目的。
(2)字符串格式化指令/函数,安全性断言模块检测污点数据是否被用作字符串格式化指令/函数的参数。例如,污点数据被用作C库中printf函数的参数,而攻击者通常试图利用恶意参数控制字符串格式化指令/函数,并将特定的数据写入特定的地址。
(3)系统调用,安全性断言模块检测污点数据是否被用作关键系统调用的参数。例如,Linux系统的execve系统调用,而攻击者可以通过复写execve的参数实现加载指定程序的目的。
(4)应用接口,通过配置可以使安全性断言模块检测污点数据是否被用作特定应用程序接口的参数。为了增强系统的功能,电力工控系统的上位机软件往往会留有第三方开发接口,故此类应用程序接口成为了攻击者发动攻击的首要目标。
上述的每一类敏感CPU指令和函数都附有安全等级标签,且安全等级标签与电力工控指令的安全属性相对应。如果高安全属性的电力工控指令被用作高安全等级标签的CPU指令和函数参数,就会做出带有警告的安全性断言。
1.2 基于文法模糊测试的工控协议动态漏洞挖掘
针对电力工控系统的Fuzzing测试框架,如图3所示。首先,将电力工控协议抽象为协议结构描述。其次,安全协议的结构描述生成模糊测试数据集,且模糊测试数据集在测试引擎的调度下,通过测试代理向被测系统发送变异的协议数据包。最后,被测系统的状态通过目标监控反馈给测试引擎,以指导后续的调度策略。
图3 面向电力工控系统Fuzzing测试系统架构图
(1)协议结构识别
协议结构识别主要通过智能算法,结合生物信息学思想和电力工控协议的结构,提取数据包结构中的常量,并标注包的数据区域,生成协议结构描述,从而逐步完善协议的语义结构和数据包结构。
协议结构识别的过程主要包括以下几点。首先采用类型匹配,即提取不同网络流量数据文件(PCAP)中同类型的报文序列,并将其作为一个报文组。其次,多序列比对报文组合,并分离不变域和可变域,以初步划分报文域。最后,识别报文区域,进一步得到ANSII字符串域,从而生成较准确的报文格式和测试数据。具体过程如图4所示。
图4 基于网络报文进行协议结构识别
(2)测试数据生成
在理解和解释目标应用输入数据的协议规约和文件定义基础上,创建一个描述协议规约如何工作的文法,并根据文法生成测试数据。然后,测试协议中最有可能引起异常的部分,且完成针对指令级的安全脆弱性测试。
一般情况下,除测试用例执行外,Fuzzing测试包括协议解析、测试用例生成、异常捕获和定位三个步骤,如图5所示。协议解析是通过公开资料或者分析网络数据流量,理解待测协议的层次、包字段结构、会话过程等信息,为后续测试用例的生成打下基础。测试用例生成依据上阶段整理的字段结构,采用变异的方式生成畸形测试用例,并发送给待测对象。异常捕获和定位是通过多种探测手段发现由测试用例触发的异常,且保存异常数据信息,为后续异常的定位和重现提供依据。
图5 Fuzzing测试的通用流程
实践中,采用基于文法的Fuzzing测试用例生成技术,极大地降低了测试用例的数量,提高了测试效率。
(3)测试引擎
目前,电力工控系统中,PLC、RTU、DCS扮演的角色是协议Server端,而中心站充当协议Client端。测试引擎用于调用程序,并可手动设置测试模式,测试Client端和Server端,或者同时双向测试Client端和Server端。此外,它可以根据接收的数据包自动识别Client端和Server端发送的数据包,并自动调节调用的程序模块,实现Client端和Server端的双向自动化测试。
测试引擎根据被测系统的不同,自适应选择测试数据调度策略。测试数据调度策略包括顺序调度、随机调度、代码覆盖率优先调度等。此外,针对电力工控协议的特点,设计基于电力工控协议状态机的调度算法,优化双向测试的效率。
(4)测试代理
测试代理用于调用程序监控模块、日志模块、分析模块等,并调整不同的被测系统,记录、分析测试过程中的日志。如果被测系统出现异常,则停止相应的模块调用。
(5)测试目标监控
测试目标监控用于分析错误现场保持、异常定位和漏洞类型。错误现场保持指如果系统出现异常,则立即停止测试,并保持异常情况的现场。异常定位是通过多种探测手段发现由测试用例触发的异常,保存异常相关数据信息,为后续异常的定位和重现提供依据。漏洞类型是根据测试的异常情况和导致此异常的测试用例初步分析漏洞类型。
2 结 论
本文针对电力工控协议动态脆弱性分析的研究,可应用于电力工控系统的常态脆弱性分析和攻击渗透工作。此外,将系统的安全威胁分析与电力工控实际业务深度结合,深层次识别系统协议层面的安全威胁,对实现电力工控系统规约和指令级的安全防护具有重要的指导意义。