(海軍工程大學(xué)艦船綜合電力技術(shù)國(guó)防重點(diǎn)實(shí)驗(yàn)室 武漢 430033)
隨著工業(yè)互聯(lián)網(wǎng)的不斷發(fā)展,以及信息化和工業(yè)化的不斷融合,傳統(tǒng)工業(yè)控制系統(tǒng)[1]與互聯(lián)網(wǎng)的聯(lián)系越來越緊密。原本只設(shè)計(jì)在內(nèi)網(wǎng)通信的工控系統(tǒng)逐漸接入互聯(lián)網(wǎng),這在增加工業(yè)控制系統(tǒng)的開放性、互連性和提高生產(chǎn)力的同時(shí),也使得傳統(tǒng)工控系統(tǒng)將面臨著越來越多來自互聯(lián)網(wǎng)的安全威脅[2]。與常規(guī)軟件漏洞挖掘相比,使用模糊測(cè)試[3~5]來挖掘工控協(xié)議漏洞的困難在于工控協(xié)議是狀態(tài)機(jī),并且數(shù)據(jù)包的正確性具有很強(qiáng)的約束性。如果構(gòu)造的異常數(shù)據(jù)包與工控協(xié)議格式不一致,工控設(shè)備很容易將其丟棄,將沒有機(jī)會(huì)觸發(fā)漏洞。因此,模糊測(cè)試工具應(yīng)該具有一些基本的智能,而遺傳算法(Genetic Algorithm,GA)[6]非常適合此任務(wù),本文提出一種基于遺傳算法的Modbus TCP協(xié)議模糊測(cè)試方法。
編碼的目的是將問題空間的參數(shù)轉(zhuǎn)換成遺傳算法可以處理的形式,編碼的方法會(huì)對(duì)交叉等接下來幾個(gè)步驟產(chǎn)生直接的影響。因此,選擇合適的編碼方法會(huì)有效提高計(jì)算效率。常見的編碼方式包括:二進(jìn)制編碼和格雷編碼等。二進(jìn)制編碼是遺傳算法中經(jīng)常使用的編碼方式。它的缺點(diǎn)是不適用于多維、高精度連續(xù)函數(shù)優(yōu)化問題,還可能存在較大的漢明距離,也被稱為漢明懸崖,因此本文選擇格雷編碼方式。
遺傳算法在計(jì)算搜索最優(yōu)解時(shí),不依賴外部的信息,只依靠構(gòu)造的適應(yīng)度函數(shù)。因此,如何構(gòu)造合適的適應(yīng)度函數(shù)是遺傳算法的核心問題。
傳統(tǒng)針對(duì)Modbus TCP協(xié)議[7]的模糊測(cè)試方法,未考慮根據(jù)可編程邏輯控制器(Programmable Logic Controllers,PLC)[8]接收到模糊測(cè)試用例后的響應(yīng)報(bào)文,對(duì)模糊測(cè)試用例的生成過程進(jìn)行及時(shí)調(diào)整,導(dǎo)致產(chǎn)生大量冗余數(shù)據(jù)[9~10]。
為了能根據(jù)模糊測(cè)試結(jié)果對(duì)遺傳算法的進(jìn)化方向進(jìn)行及時(shí)調(diào)整,使用返回的異常碼來指示測(cè)試用例的代碼覆蓋率,并為不同的異常碼[11]分別賦予不同的權(quán)重,如式(1)所示,異常碼為4時(shí)權(quán)重最大為w4,其次是異常碼2、異常碼3和異常碼1,分別賦予權(quán)重w2、w3和w1,若生成的測(cè)試用例被工控設(shè)備正常響應(yīng),即構(gòu)造的測(cè)試用例屬于正常數(shù)據(jù)包,則該測(cè)試用例被賦予的分?jǐn)?shù)最小為w0。
首先,創(chuàng)建一個(gè)測(cè)試用例隊(duì)列,用于存儲(chǔ)每次遺傳算法計(jì)算出的最佳測(cè)試用例,以及在接收該測(cè)試用例后被測(cè)PLC響應(yīng)報(bào)文中的異常碼。初始隊(duì)列由上位機(jī)與PLC進(jìn)行正常通信時(shí)捕獲的Modbus TCP協(xié)議數(shù)據(jù)包組成。
然后,在生成個(gè)體px后,將測(cè)試用例隊(duì)列中所有與個(gè)體px功能碼相同的個(gè)體組成一個(gè)集合Py。計(jì)算px與集合Py中個(gè)體pj每個(gè)字節(jié)的距離,再將每個(gè)字節(jié)的距離進(jìn)行累加,計(jì)算出px與個(gè)體pj的距離,之后對(duì)計(jì)算出的距離加1,此處加1是為了避免距離為0。再取倒數(shù),并乘以根據(jù)py的異常碼計(jì)算得出的權(quán)重wj,如式(2)所示。
之后,再將px與集合Py中每個(gè)個(gè)體的距離相加,并除以集合Py的數(shù)量n,得出個(gè)體px和初始種群的平均距離,如式(3)所示。
最后,將最終計(jì)算出的平均距離作為該個(gè)體的適應(yīng)度值,如式(4)所示。
在完成上一步個(gè)體適應(yīng)度值的計(jì)算后,為了篩選出具有優(yōu)良基因的個(gè)體繼續(xù)生存繁衍,本文的使用“輪盤賭選擇算子”從父代種群中挑選出雙親。
輪盤賭算子的計(jì)算步驟如下:
步驟1):如式(5)所示,依據(jù)公式計(jì)算出個(gè)體的適應(yīng)度值,計(jì)算出種群中所有個(gè)體被遺傳的概率Pro(msgi)。
步驟2):如式(6)所示,計(jì)算出種群中所有個(gè)體的累計(jì)概率Qi。
步驟3:之后在[0,1]區(qū)間內(nèi)生成隨機(jī)值rand。若r<Q1,則選擇個(gè)體1,否則選擇滿足式(7)的個(gè)體k,將挑選出來的個(gè)體進(jìn)入子代種群進(jìn)行下一步操作。
步驟4):不斷重復(fù)步驟3,得到的個(gè)體形成一個(gè)新種群。
適用于二進(jìn)制編碼個(gè)體的交叉算子有單點(diǎn)交叉和兩點(diǎn)交叉等。本文選擇采用單點(diǎn)交叉,即在兩個(gè)父代個(gè)體編碼后的二進(jìn)制基因序列上隨機(jī)選擇一個(gè)位點(diǎn),將這個(gè)交叉位點(diǎn)后部的兩個(gè)父代基因序列進(jìn)行交換,以產(chǎn)生新的下一代個(gè)體。
變異本文采取較為簡(jiǎn)單的實(shí)現(xiàn)方式。由于編碼后的基因序列都是二進(jìn)制數(shù)據(jù)串,因此本文采用基本位變異算子。變異算法如算法1所示,首先獲取個(gè)體的編碼后的基因序列的長(zhǎng)度length。然后再結(jié)合變異概率Pm計(jì)算出需要變異的基因序列的數(shù)目count。再在0~length-1之間生成一個(gè)隨即數(shù)k,用以指定將要進(jìn)行變異的基因序列的位置,對(duì)第k位基因進(jìn)行取反,變異過程循環(huán)執(zhí)行count次。最后輸出變異后的個(gè)體基因序列Msg。
為了保留適應(yīng)度值高的個(gè)體,并剔除適應(yīng)度值低的個(gè)體,本文使用自適應(yīng)遺傳算法[12]計(jì)算交叉概率Pc和變異概率Pm,如式(8)所示。
其中fmax表示種群中所有個(gè)體適應(yīng)度值的最大值;favg表示種群中所有個(gè)體適應(yīng)度值的平均值;f表示兩個(gè)將要交叉?zhèn)€體的適應(yīng)度值中的較大值;f'表示將要變異的個(gè)體的適應(yīng)度值。
如圖1所示,本文提出的Modbus TCP協(xié)議模糊測(cè)試系統(tǒng)是在模糊測(cè)試工具Peach的基礎(chǔ)上進(jìn)行二次開發(fā)而成。模糊測(cè)試用例生成模塊在生成測(cè)試用例后,將測(cè)試用例傳入Peach Fuzzer的格式解析模塊,通過狀態(tài)控制模塊控制交互發(fā)布模塊將生成的模糊測(cè)試用例輸入被測(cè)PLC,同時(shí)代理監(jiān)控模塊檢測(cè)被測(cè)PLC是否出現(xiàn)崩潰,若出現(xiàn)異常則通過日志記錄模塊進(jìn)行記錄,并終止測(cè)試,若未出現(xiàn)異常,則通過交互發(fā)布模塊獲取PLC響應(yīng)報(bào)文,并利用狀態(tài)控制模塊調(diào)用格式解析模塊對(duì)響應(yīng)報(bào)文進(jìn)行解析,最后將解析結(jié)果反饋給公有協(xié)議模糊測(cè)試用例生成模塊,用以指導(dǎo)下一個(gè)模糊測(cè)試用例的生成。
圖1 Modbus TCP協(xié)議模糊測(cè)試系統(tǒng)架構(gòu)圖
在進(jìn)行Modbus TCP協(xié)議模糊測(cè)試實(shí)驗(yàn)時(shí),本文對(duì)兩款支持Modbus TCP協(xié)議的國(guó)內(nèi)外廠商的PLC進(jìn)行了模糊測(cè)試,實(shí)驗(yàn)結(jié)果如表1所示。在對(duì)信捷XG1-16T4 PLC進(jìn)行模糊測(cè)試實(shí)驗(yàn)時(shí)發(fā)現(xiàn)了一個(gè)0-Day漏洞,該漏洞在提交國(guó)家信息安全漏洞共享平臺(tái)(China National Vulnerability Database,CNVD)后,獲得一個(gè)原創(chuàng)CNVD漏洞編號(hào);在對(duì)施耐德M241 PLC進(jìn)行模糊測(cè)試實(shí)驗(yàn)時(shí),成功挖掘到一個(gè)拒絕服務(wù)漏洞,下面將分別介紹兩次實(shí)驗(yàn)。
表1 公有協(xié)議模糊測(cè)試實(shí)驗(yàn)結(jié)果
1)實(shí)驗(yàn)1
實(shí)驗(yàn)1中的被測(cè)工控設(shè)備是信捷XG1-16T4 PLC,這款PLC是無錫信捷電氣股份有限公司的一款中型PLC,支持Ethernet通訊、X-NET現(xiàn)場(chǎng)總線、MODBUS通訊等功能。在對(duì)信捷XG1-16T4 PLC進(jìn)行模糊測(cè)試時(shí),發(fā)現(xiàn)了一個(gè)原創(chuàng)CNVD漏洞,漏洞編號(hào)CNVD-2020-04095。攻擊者可利用該漏洞向502端口發(fā)送過長(zhǎng)的數(shù)據(jù)包,會(huì)導(dǎo)致502端口拒絕服務(wù),須斷電重啟才能恢復(fù)PLC正常工作。
圖2 信捷正常運(yùn)行與拒絕服務(wù)
如圖2所示,初始時(shí)信捷XG1-16T4 PLC正常運(yùn)行,有PWR和RUN指示燈亮綠燈。在經(jīng)模糊測(cè)試觸發(fā)異常后,信捷XG1-16T4 PLC拒絕服務(wù),此時(shí)PWR指示燈亮綠燈,ERR指示燈亮紅燈。拒絕服務(wù)后需要將其斷電重啟才能恢復(fù)工作。圖3為信捷PLC拒絕服務(wù)后通過Peach的監(jiān)控窗口監(jiān)控到的信息。因?yàn)樾沤菰撔吞?hào)PLC的固件被加密,所以無法通過逆向分析固件準(zhǔn)確地定位漏洞的位置。
2)實(shí)驗(yàn)2
實(shí)驗(yàn)2中的被測(cè)工控設(shè)備是施耐德M241,該款PLC支持以太網(wǎng)、CANOpen和串行通訊。在使用本文提出方法對(duì)施耐德M241進(jìn)行實(shí)驗(yàn)時(shí),模糊測(cè)試大約2h,觸發(fā)異常,該異常導(dǎo)致施耐德M241拒絕服務(wù),須斷電重啟才能恢復(fù)工作。具體原因還在分析中。
圖3 觸發(fā)崩潰
為驗(yàn)證本文提出的公有協(xié)議模糊測(cè)試方法具有更高的模糊測(cè)試效率,本文在上位機(jī)上部署Peach[13]與 Sulley[14],對(duì)相同的工控設(shè)備進(jìn)行模糊測(cè)試,并對(duì)三種方法的模糊測(cè)試結(jié)果進(jìn)行比對(duì)。
表2 模糊測(cè)試工具對(duì)比結(jié)果
圖4 測(cè)試用例接收率
根據(jù)表2中結(jié)果可知,與已有模糊測(cè)試工具Peach和Sulley相比,在使用本文提出方法進(jìn)行實(shí)驗(yàn)時(shí),雖然生成的模糊測(cè)試用例數(shù)比Peach和Sulley少,且模糊測(cè)試時(shí)間比Peach和Sulley短,但是卻成功觸發(fā)兩個(gè)拒絕服務(wù)漏洞。將本文所提出方法、Peach和Sulley三者進(jìn)行生成測(cè)試用例接收率進(jìn)行比較,如圖4所示,可見截取的前一個(gè)小時(shí)里本文所提出方法的測(cè)試用例接受收率遠(yuǎn)高于Peach和Sulley的測(cè)試用例接受收率。因此,通過表2和圖4的結(jié)果可知,本文提出方法能有效提高針對(duì)Modbus TCP協(xié)議的模糊測(cè)試效率。
本文提出了基于遺傳算法的Modbus TCP協(xié)議模糊測(cè)試方法,在使用遺傳算法生成Modbus TCP協(xié)議的模糊測(cè)試用例時(shí),建立了一個(gè)種子隊(duì)列用于存儲(chǔ)遺傳算法生成的測(cè)試用例和測(cè)試用例的異常碼,之后從相似度和異常碼兩個(gè)方面來計(jì)算生成個(gè)體的適應(yīng)度值,以調(diào)整生成測(cè)試用例的方向,最后本文將實(shí)驗(yàn)結(jié)果與已有同類工具從挖掘到的漏洞數(shù)量、所需的時(shí)間、發(fā)送模糊測(cè)試用例數(shù)和測(cè)試用例接收率四個(gè)方面進(jìn)行比較,比較結(jié)果驗(yàn)證了本文所提方法的有效性。