文獻(xiàn)標(biāo)識(shí)碼: A
DOI:10.16157/j.issn.0258-7998.171175
中文引用格式: 魏驍,劉仁輝,許鳳凱. 基于靜態(tài)二進(jìn)制分析的工控協(xié)議逆向解析[J].電子技術(shù)應(yīng)用,2018,44(3):126-130.
英文引用格式: Wei Xiao,Liu Renhui,Xu Fengkai. Reverse analysis of industrial control protocol based on static binary analysis[J]. Application of Electronic Technique,2018,44(3):126-130.
0 引言
工業(yè)控制系統(tǒng)(Industrial Control Systems,ICS)是工業(yè)生產(chǎn)的基礎(chǔ),ICS的安全直接關(guān)系到經(jīng)濟(jì)、社會(huì)發(fā)展的穩(wěn)定和國家安全。與其他計(jì)算機(jī)系統(tǒng)不同,工業(yè)控制系統(tǒng)中存在著大量的私有非標(biāo)準(zhǔn)非公開協(xié)議[1],而通信協(xié)議作為工控設(shè)備間信息交互的基礎(chǔ),其安全性是工控系統(tǒng)安全的重要組成部分,研究工控協(xié)議解析技術(shù)對提高工業(yè)控制系統(tǒng)安全性具有重要意義。
傳統(tǒng)的協(xié)議逆向分析方法需要耗費(fèi)大量的時(shí)間和人力。目前,協(xié)議自動(dòng)化逆向解析領(lǐng)域主要有兩種方法:一種是基于網(wǎng)絡(luò)報(bào)文序列分析的方法,另一種是基于程序執(zhí)行軌跡的方法?;诰W(wǎng)絡(luò)報(bào)文序列分析的方法對于文本協(xié)議處理效果比較好,但是缺乏針對性對協(xié)議的語義分析[2],尤其在面對工業(yè)控制環(huán)境中普遍存在的多層封裝的應(yīng)用層協(xié)議時(shí)有些力不從心;而基于執(zhí)行軌跡方法以動(dòng)態(tài)二進(jìn)制程序分析為基礎(chǔ),包括Polyglot、AutoFormat、Tupni、Prospex等方法,這些方法要求樣本的覆蓋率,需要對程序反復(fù)地運(yùn)行調(diào)試[3],但調(diào)試過程中對代碼的直接修改嚴(yán)重破壞了工控系統(tǒng)的穩(wěn)定性,雖然這種方法解析結(jié)果更為準(zhǔn)確,但并不適合工業(yè)控制系統(tǒng)要求高穩(wěn)定、高實(shí)時(shí)的實(shí)際情況。
針對以上問題,本文提出了一種基于靜態(tài)二進(jìn)制分析的工控協(xié)議解析方法,此方法以只讀的方式訪問二進(jìn)制文件,既能獲取協(xié)議語義,又能保證不破壞工控系統(tǒng)的穩(wěn)定性。分析的結(jié)果除提供協(xié)議信息以外,還可以在通信協(xié)議健壯性測試平臺(tái)中作為fuzzing測試模塊的輸入,解決普通的fuzzing系統(tǒng)在面對私有協(xié)議時(shí)無法有針對性地構(gòu)造測試樣本的問題。
1 總體設(shè)計(jì)
本文將此工控協(xié)議解析方法作為工業(yè)控制系統(tǒng)健壯性測試平臺(tái)的一個(gè)子系統(tǒng)來加以介紹,協(xié)議健壯性測試平臺(tái)結(jié)構(gòu)如圖1所示。
當(dāng)今的ICS中越來越廣泛地使用了基于x86平臺(tái)的Windows操作系統(tǒng),故本文中的方法在實(shí)現(xiàn)時(shí)主要針對Windows操作系統(tǒng),反匯編引擎使用Hex-Rays公司的IDA Pro。IDA Pro是一款強(qiáng)大的靜態(tài)二進(jìn)制分析工具,能夠提供功能豐富的IDC函數(shù)庫(IDA Pro的一種原生腳本語言)和軟件開發(fā)包(Software Development Kit,SDK)[4]。
協(xié)議解析子系統(tǒng)主要包括以下子模塊:文件掃描子模塊、協(xié)議提取子模塊和格式化處理子模塊。其中,協(xié)議解析模塊包括數(shù)據(jù)預(yù)處理階段、交叉引用分析階段、協(xié)議幀重構(gòu)階段、語義提取階段;格式化處理模塊的輸出既可以作為測試平臺(tái)模糊測試模塊的輸入,為模糊測試樣本數(shù)據(jù)的構(gòu)造提供參考,又可以作為測試平臺(tái)交互模塊的輸入,為用戶提供圖形化的結(jié)果展現(xiàn)。協(xié)議解析模塊的子模塊結(jié)構(gòu)如圖2所示。
2 文件掃描模塊
掃描模塊的掃描目標(biāo)是組態(tài)軟件等運(yùn)行于通用計(jì)算機(jī)的工控軟件。通常,工控軟件體積較為龐大,由眾多功能模塊構(gòu)成,但協(xié)議分析只需要其中的通信模塊,對ICS軟件的所有功能模塊執(zhí)行協(xié)議解析算法不但會(huì)增加時(shí)間開銷,也會(huì)降低分析的準(zhǔn)確度。掃描模塊的主要作用就是定位協(xié)議分析的對象,為協(xié)議分析模塊過濾掉與通信無關(guān)的操作。
文件掃描子模塊有兩種實(shí)現(xiàn)方式,一種是遠(yuǎn)程掃描,掃描進(jìn)程運(yùn)行于測試平臺(tái),通過遠(yuǎn)程讀取工程師站或操作員站上的ICS軟件可執(zhí)行文件并進(jìn)行分析來實(shí)現(xiàn)過濾操作;另一種是以硬件插卡的方式通過USB接口在工控機(jī)本地執(zhí)行掃描進(jìn)程,并收集掃描結(jié)果反饋給測試平臺(tái)。這兩種實(shí)現(xiàn)方式的區(qū)別在于掃描進(jìn)程的運(yùn)行位置不同,遠(yuǎn)程掃描對工控機(jī)沒有性能影響,但需要工控機(jī)打開文件訪問權(quán)限;本地掃描在掃描過程中可能會(huì)占用一定的CPU時(shí)間,但不需要額外的權(quán)限,其具體差異如表1所示。
以上兩種實(shí)現(xiàn)方法在算法本質(zhì)上是沒有區(qū)別的,都是通過讀取動(dòng)態(tài)鏈接庫(Dynami Link Library,DLL)文件的導(dǎo)入表和導(dǎo)入函數(shù)表來查找和預(yù)測DLL涉及到的操作。一般來講,涉及到TCP協(xié)議通信則需要導(dǎo)入WS2_32.dll中的send和recv函數(shù),UDP協(xié)議則需要導(dǎo)入WS2_32.dll中的sendto和recvfrom函數(shù)[5],通過掃描模塊搜索到的某協(xié)議通信模塊的導(dǎo)入表以及導(dǎo)入函數(shù)如圖3所示。另外,通過掃描并過濾WriteFile等系統(tǒng)調(diào)用還可以找到ICS軟件自己封裝的一些發(fā)包和封包函數(shù),通過這些函數(shù)還可以解析那些不基于TCP/IP的工控協(xié)議,如基于COM串口的工控協(xié)議,這是基于網(wǎng)絡(luò)流量的協(xié)議分析方法無法做到的。
3 協(xié)議提取模塊
協(xié)議解析模塊基于IDA Pro的IDC腳本和SDK來實(shí)現(xiàn),以IDA腳本或IDA插件的形式提供協(xié)議解析服務(wù)。
3.1 數(shù)據(jù)預(yù)處理
ICS使用的軟件種類繁雜,在實(shí)現(xiàn)結(jié)構(gòu)上也是千差萬別,有些廠商在設(shè)計(jì)軟件時(shí)并沒有嚴(yán)格地遵循模塊化設(shè)計(jì)的原則,軟件通信模塊沒有獨(dú)立地封裝在DLL中,而是與其他的功能代碼混雜在一起放入DLL,甚至分散在多個(gè)DLL中。數(shù)據(jù)預(yù)處理針對這種情況,通過讀取IDA Pro反匯編后的匯編代碼,對DLL中的函數(shù)進(jìn)行標(biāo)記處理,剔除與通信過程無關(guān)的函數(shù)。對于無法確定的函數(shù),則選擇保留處理。
篩選算法同時(shí)使用兩種標(biāo)準(zhǔn),第一種標(biāo)準(zhǔn)的依據(jù)是向上的代碼交叉引用,利用了函數(shù)調(diào)用的層次結(jié)構(gòu);第二種標(biāo)準(zhǔn)的思想源自于動(dòng)態(tài)二進(jìn)制逆向分析中常用的污點(diǎn)算法,經(jīng)過修改后基于數(shù)據(jù)交叉引用實(shí)現(xiàn),用于此處的靜態(tài)二進(jìn)制分析場景[6]。
定義 二元組f(N,F(xiàn))表示DLL中的一個(gè)函數(shù),其中,N為函數(shù)名,F(xiàn)為標(biāo)記,取值從UNKNOW、STAY、DELETE中枚舉。
篩選算法的基本流程如下:
(1)將目標(biāo)DLL中的函數(shù)(包括DllMain、導(dǎo)出函數(shù)和內(nèi)部函數(shù))f加入到函數(shù)集合S中初始的標(biāo)記F均為DELETE。
(2)使用第一種標(biāo)準(zhǔn),以發(fā)送、接收數(shù)據(jù)包的函數(shù)地址為底層起點(diǎn),使用IDC函數(shù)Rfirst和Rnext訪問其所有的引用函數(shù)fn(N,F(xiàn)),并將fn(N,F(xiàn))的標(biāo)記F置為STAY。
(3)迭代執(zhí)行步驟(2),直至所有引用了起點(diǎn)函數(shù)的函數(shù)標(biāo)記均被置為STAY。
(4)使用第二種標(biāo)準(zhǔn),以步驟(2)中底層函數(shù)的參數(shù)中使用的內(nèi)存緩沖區(qū)為污點(diǎn)源,逆序搜索被標(biāo)記為污點(diǎn)的內(nèi)存區(qū)域的訪問位置,如果有fn(N,F(xiàn))中引用了污點(diǎn)內(nèi)存區(qū)域,則將fn(N,F(xiàn))的標(biāo)記F置為STAY;如果代碼中存在以污點(diǎn)內(nèi)存為左值的賦值操作,則將作為右值的內(nèi)存區(qū)域也標(biāo)記為污點(diǎn)內(nèi)存,并記錄污點(diǎn)傳播的關(guān)系,系統(tǒng)為S中的每個(gè)fn(N,F(xiàn))維護(hù)一個(gè)污點(diǎn)關(guān)系數(shù)據(jù)結(jié)構(gòu)func_pollut,數(shù)據(jù)結(jié)構(gòu)內(nèi)容如表2所示;如果函數(shù)fn(N,F(xiàn))沒有顯示地引用污點(diǎn)內(nèi)存區(qū)域且其引用的其他內(nèi)存位置無法直接判斷是否與污點(diǎn)內(nèi)存有關(guān),則將fn(N,F(xiàn))的標(biāo)記F置為UNKNOW。
(5)迭代執(zhí)行步驟(4)。枚舉集合S中的函數(shù),刪除所有標(biāo)記F為DELETE的函數(shù)元素,此時(shí)的集合S則為待處理的目標(biāo)集合。
3.2 交叉引用分析
從軟件逆向工程的角度來看,被不同的上層函數(shù)引用次數(shù)越多的底層函數(shù)通用性越好,封裝程度越高,在設(shè)計(jì)協(xié)議封裝和解析的軟件模塊中,則往往表現(xiàn)為在函數(shù)中處理了某一類通用性較強(qiáng)的幀結(jié)構(gòu),比如攜帶數(shù)據(jù)載荷的幀和心跳幀;而被不同的上層函數(shù)引用次數(shù)較少,甚至僅在某一處有過引用的函數(shù),在協(xié)議封裝和解析的軟件模塊中往往完成一些連接建立、通信對端認(rèn)證等控制類的操作,這一類幀屬于控制幀。
協(xié)議解析系統(tǒng)在交叉引用分析階段的主要工作是調(diào)用IDC函數(shù)獲取交叉引用信息并將信息歸類存儲(chǔ)在數(shù)據(jù)結(jié)構(gòu)func_info中,某協(xié)議的函數(shù)依賴關(guān)系如圖4所示。通過對獲得的引用數(shù)據(jù)進(jìn)行統(tǒng)計(jì)來推斷函數(shù)類型,并將推斷結(jié)果作為協(xié)議幀分類階段的輸入。結(jié)構(gòu)func_info的內(nèi)容如表2所示。
函數(shù)類型推斷使用的分界值與協(xié)議的復(fù)雜度有關(guān),一般來說,與控制幀相關(guān)的函數(shù)與底層函數(shù)間的距離短,被調(diào)用的次數(shù)少,調(diào)用底層函數(shù)的次數(shù)多。經(jīng)過實(shí)驗(yàn)對比,具體的分界點(diǎn)取值為距底層函數(shù)的距離為2、被調(diào)用次數(shù)為1、調(diào)用底層函數(shù)次數(shù)為3~5時(shí),系統(tǒng)具有較高準(zhǔn)確度,系統(tǒng)在此處預(yù)留配置接口,用戶可以根據(jù)協(xié)議復(fù)雜度指定分界點(diǎn)取值。另外,通過IDA Pro自帶的WinGraph32應(yīng)用程序系統(tǒng)可以獲得較為直觀的函數(shù)依賴圖形,依賴圖直接作為模塊的一項(xiàng)輸出結(jié)果呈現(xiàn)給用戶,用戶可以根據(jù)自己的判斷為系統(tǒng)指定重點(diǎn)分析的模塊或校正系統(tǒng)的推測結(jié)果,提高解析精準(zhǔn)度。
3.3 協(xié)議幀重構(gòu)
協(xié)議幀重構(gòu)階段以前兩個(gè)階段中獲得的函數(shù)依賴關(guān)系和對函數(shù)類型的推定為參考,判斷函數(shù)代碼特征,對目標(biāo)協(xié)議中存在的幀進(jìn)行重構(gòu)與分類。算法中涉及到的函數(shù)代碼特征主要包括距底層函數(shù)的距離是否為1、是否存在較多的幻數(shù)賦值操作、是否定長等。一個(gè)典型的控制幀組幀操作如圖5所示,可以看到明顯存在較多的幻數(shù)賦值操作。
幀重構(gòu)的算法流程如下:
(1)將幀集合A初始化為空集,將函數(shù)集合S中標(biāo)記F為STAY和UNKNOW的函數(shù)按照上一階段獲取的func_info結(jié)構(gòu)的route_len域值升序排列,存儲(chǔ)到順序表D中。
(2)從順序表D中取出一個(gè)函數(shù)fn(N,F(xiàn)),如果fn(N,F(xiàn))的函數(shù)距為1,檢查底層函數(shù)調(diào)用參數(shù),并在本函數(shù)的代碼中檢索緩沖區(qū)長度參數(shù)的數(shù)據(jù)引用,如果緩沖區(qū)長度為定值,且該值與集合A中所有定長幀的幀長都不相同,則創(chuàng)建一個(gè)定長幀,幀長度為緩沖區(qū)長度,并將該幀加入到集合A中。
(3)如果步驟(2)中無法確定緩沖區(qū)長度為定值,則創(chuàng)建一個(gè)不定長幀,將該幀加入到集合A中。
(4)針對步驟(2)或步驟(3)中新加的幀,從底層函數(shù)調(diào)用地址處向上檢索代碼,直至函數(shù)頭或另一次底層函數(shù)調(diào)用,對所有的幻數(shù)賦值操作,直接將字段長度和幻數(shù)值記錄到新加的幀的對應(yīng)結(jié)構(gòu)中;對于變量賦值操作,記錄字段長度后字段值暫時(shí)以符號代替。統(tǒng)計(jì)幻數(shù)賦值數(shù)量H和變量賦值數(shù)量B,如果H>2B,則將此幀標(biāo)記為控制幀,否則標(biāo)記為數(shù)據(jù)幀。
(5)如果fn(N,F(xiàn))的函數(shù)距不為1,檢索函數(shù)代碼,記錄所有的對污點(diǎn)內(nèi)存區(qū)塊的幻數(shù)賦值操作,檢索完畢后訪問其func_pollut結(jié)構(gòu),通過污染源所在的函數(shù)編號在集合A中檢索對應(yīng)的幀結(jié)構(gòu),并以幻數(shù)值替代幀結(jié)構(gòu)中相應(yīng)位置的符號。
(6)重復(fù)執(zhí)行步驟(2),直到順序表D中的所有函數(shù)均被訪問。
算法執(zhí)行完畢后,集合A中的幀即是經(jīng)過初步構(gòu)造后的協(xié)議幀,此時(shí)的幀結(jié)構(gòu)記錄了初步字段結(jié)構(gòu)和常量字段值。
3.4 語義提取
協(xié)議的語義信息主要包括分隔符、關(guān)鍵字、校驗(yàn)域、長度域、指示域等,通過檢索處理協(xié)議幀的字段的二進(jìn)制代碼是否存在相關(guān)的特征,可以提取到協(xié)議幀的語義信息[7]。例如:校驗(yàn)域通常伴隨著大量的移位運(yùn)算;關(guān)鍵字和分隔符會(huì)涉及到常量賦值操作,它們的主要區(qū)別在于關(guān)鍵字通常為一般數(shù)據(jù),分隔符的值通常可以映射成ASCII表中的的特定字符;長度域也會(huì)涉及到常量賦值操作,但對于同一類幀結(jié)構(gòu)來說,不同的調(diào)用點(diǎn)常量值一般不同。
對于一些無法提取比較顯著的特征的代碼段,系統(tǒng)選擇的策略是直接提取相關(guān)的二進(jìn)制代碼,轉(zhuǎn)儲(chǔ)到文件后在數(shù)據(jù)結(jié)構(gòu)中記錄該二進(jìn)制代碼段與對應(yīng)的協(xié)議字段的關(guān)聯(lián)關(guān)系。
3.5 格式化處理
以上過程處理得到的協(xié)議格式有可能存在冗余,同一種變長幀由于個(gè)別字段值不同而被記錄為兩種或多種幀,另外,幀之間的邏輯關(guān)系信息也不完整。在格式化處理模塊,系統(tǒng)通過比對集合中幀的已知語義來實(shí)現(xiàn)去冗余,不定長幀之間雖然長度和某些字段值不完全相同,但只要通過語義對比發(fā)現(xiàn)已知語義重復(fù)率超過閥值,就判定兩種幀應(yīng)是同一種幀,對二者執(zhí)行合并操作。
最后,系統(tǒng)通過對集合中的幀進(jìn)行格式化處理,將協(xié)議信息以一種標(biāo)準(zhǔn)的格式輸出到結(jié)果文件。模糊測試模塊通過讀取文件獲取協(xié)議的幀結(jié)構(gòu)和語義等信息,并針對協(xié)議結(jié)構(gòu)構(gòu)造測試用例。
4 實(shí)驗(yàn)與分析
協(xié)議解析系統(tǒng)的主體部分、語義提取和格式化處理通過C語言實(shí)現(xiàn),數(shù)據(jù)預(yù)處理和交叉引用分析通過IDC腳本實(shí)現(xiàn),協(xié)議幀重構(gòu)通過C語言調(diào)用IDA Pro SDK實(shí)現(xiàn)。
在實(shí)驗(yàn)中,將獨(dú)立實(shí)現(xiàn)的系統(tǒng)應(yīng)用于分析組態(tài)王軟件提供的某私有協(xié)議的驅(qū)動(dòng)程序,成功獲取了部分協(xié)議格式,利用得到的協(xié)議格式可以實(shí)現(xiàn)與設(shè)備的簡單互通,證明了方法的正確性和有效性。經(jīng)解析,該協(xié)議在連接建立時(shí)考慮了協(xié)議版本的識(shí)別,實(shí)驗(yàn)分析得到的協(xié)議幀如圖6所示。
另外,在對某DCS系統(tǒng)進(jìn)行滲透測試的項(xiàng)目中,本協(xié)議解析系統(tǒng)作為協(xié)議健壯性測試平臺(tái)的一個(gè)模塊,為模糊測試模塊提供了參考。模糊測試模塊以協(xié)議解析系統(tǒng)的輸出作為輸入,根據(jù)解析結(jié)果,針對此DCS系統(tǒng)的應(yīng)用層協(xié)議生成了80組測試用例,在測試過程中多次造成了目標(biāo)系統(tǒng)的通信異常,證明了該方法的實(shí)用性。模糊測試結(jié)果示例如圖7所示,圖中的曲線為系統(tǒng)心跳幀攜帶的正弦數(shù)據(jù)流,測試開始后可明顯觀測到心跳幀發(fā)生中斷和錯(cuò)序。
5 結(jié)束語
本文介紹了一種通信協(xié)議逆向解析方法,該方法結(jié)合靜態(tài)二進(jìn)制代碼分析工具,將動(dòng)態(tài)污點(diǎn)算法思想應(yīng)用于靜態(tài)二進(jìn)制分析過程,實(shí)現(xiàn)了對工控協(xié)議的逆向解析并為模糊測試提供了參考,實(shí)驗(yàn)結(jié)果證明了方法的有效性。該方法具有對被測系統(tǒng)影響小、針對性較強(qiáng)的特點(diǎn),適用于工業(yè)控制環(huán)境,具有較強(qiáng)的實(shí)用價(jià)值。
參考文獻(xiàn)
[1] 吳禮發(fā),洪征,潘璠.網(wǎng)絡(luò)協(xié)議逆向分析及應(yīng)用[M].北京:國防工業(yè)出版社,2016.
[2] 羅杰.基于動(dòng)態(tài)二進(jìn)制分析的網(wǎng)絡(luò)協(xié)議逆向方法研究[D].武漢:華中科技大學(xué),2014.
[3] 何永君.基于動(dòng)態(tài)二進(jìn)制分析平臺(tái)的協(xié)議逆向解析技術(shù)研究[D].鄭州:解放軍信息工程大學(xué),2010.
[4] EAGLE C.The IDA Pro book: The unofficial guide to the world’s most popular disassembler second edition[M].No Starch Press,2010.
[5] CUI W,PEINADO M,CHEN K,et al.Tupni:automatic reverse engineering of input formats[C].ACM Conference on Computer and Communications Security.ACM,2008:391-402.
[6] 劉豫,聶眉寧,蘇璞睿,等.基于可回溯動(dòng)態(tài)污點(diǎn)分析的攻擊特征生成方法[J].通信學(xué)報(bào),2012,33(5):21-28.
[7] 潘璠.基于高階屬性文法的協(xié)議逆向關(guān)鍵技術(shù)研究[D].南京:解放軍理工大學(xué),2013.
作者信息:
魏 驍,劉仁輝,許鳳凱
(華北計(jì)算機(jī)系統(tǒng)工程研究所,北京100083)