陳 岑,呂 卓,郭志民,李暖暖
(國網河南省電力公司電力科學研究院,河南 鄭州 450052)
面向電力工控協議分析的脆弱性分析技術包含靜態和動態兩個方面[1]。靜態分析方面,在不運行電力工控協議實現程序的前提下,分析軟件程序中可能存在的漏洞,主要研究軟件或固件逆向解析、中間語言分析、模擬執行數據流分析和智能缺陷識別等工控協議的靜態漏洞挖掘及分析技術。此外,通過分析工控協議實現程序的詞法、語法、語義,檢測軟件中存在的弱安全函數調用和缺陷代碼片段,并以中間表示語言為基礎,進一步分析函數控制流圖和模塊函數調用圖,挖掘電力工控協議實現過程中的安全漏洞[2-5]。但是,靜態分析方法未考慮外界因素對待測系統安全性的影響,因此可以通過研究電力工控協議脆弱性動態分析進一步挖掘電力工控協議漏洞。電力工控協議脆弱性動態分析技術是在待測系統實際運行的前提下,通過觀察待測系統執行過程中程序的運行狀態、內存使用狀況、寄存器的值以及協議數據處理情況等發現潛在問題。
針對電力工控協議實現的脆弱性,主要從兩個層面進行動態分析。系統層面,研究面向工控協議數據的動態污點分析技術,跟蹤工控協議數據流的傳播,針對特定的控制指令做出安全性斷言[6-7]。網絡層面,研究雙向Fuzzing測試技術,構造模糊測試指令集,同時監視協議服務器端和客戶端的測試過程和返回結果,以驗證待測系統協議實現的正確性[8-9]。通過分析系統和網絡兩個層面的測試結果,發現了工控協議存在的安全漏洞。研究步驟如圖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指令和函數參數,就會做出帶有警告的安全性斷言。
針對電力工控系統的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)測試目標監控
測試目標監控用于分析錯誤現場保持、異常定位和漏洞類型。錯誤現場保持指如果系統出現異常,則立即停止測試,并保持異常情況的現場。異常定位是通過多種探測手段發現由測試用例觸發的異常,保存異常相關數據信息,為后續異常的定位和重現提供依據。漏洞類型是根據測試的異常情況和導致此異常的測試用例初步分析漏洞類型。
本文針對電力工控協議動態脆弱性分析的研究,可應用于電力工控系統的常態脆弱性分析和攻擊滲透工作。此外,將系統的安全威脅分析與電力工控實際業務深度結合,深層次識別系統協議層面的安全威脅,對實現電力工控系統規約和指令級的安全防護具有重要的指導意義。