金童
(北方工業(yè)大學(xué),北京 100144)
模糊測試是一種基于缺陷注入的自動化軟件漏洞挖掘技術(shù)通過向待測試的目標(biāo)軟件輸入測試用例并執(zhí)行程序,監(jiān)控程序的運行狀況,同時記錄并進(jìn)一步分析目標(biāo)程序發(fā)生的異常,進(jìn)而通過分析造成目標(biāo)程序崩潰的測試用例來發(fā)現(xiàn)目標(biāo)程序潛在的漏洞。
在模糊測試的過程中,測試用例執(zhí)行、異常監(jiān)視這兩個重要的過程完全可以自動化實現(xiàn)。
模糊測試在挖掘的漏洞數(shù)量方面具有很大優(yōu)勢,與此同時,其不足也十分明顯。比如:對訪問控制漏洞無能為力、無法發(fā)現(xiàn)糟糕的設(shè)計邏輯、無法識別多階段安全漏洞和無法識別多點觸發(fā)漏洞。
模糊測試的高效性嚴(yán)格依賴輸入測試樣本的質(zhì)量,因此模糊測試的核心就是核心測試樣本的生成,其有兩個關(guān)鍵點:(1)優(yōu)質(zhì)的測試樣本種子;(2)合理的畸變策略。針對第(1)個關(guān)鍵點,以目標(biāo)為導(dǎo)向選擇確定優(yōu)質(zhì)測試樣本種子,比如:能夠發(fā)現(xiàn)未執(zhí)行過的路徑或者執(zhí)行率較低的路徑;向某個特定待測試區(qū)域不斷逼近等。
目前常用的漏洞挖掘技術(shù)分為靜態(tài)分析、動態(tài)分析、二進(jìn)制比對、模糊測試等。靜態(tài)分析是指在不運行軟件的前提下進(jìn)行的一種分析技術(shù)。其主要通過對目標(biāo)程序的詞法、語法、語義分析來發(fā)現(xiàn)軟件中潛在的安全漏洞,特別是函數(shù)調(diào)用中參數(shù)的來源以及函數(shù)返回值,通過對參數(shù)進(jìn)行來源分析與跟蹤,很容易發(fā)現(xiàn)其中未對參數(shù)進(jìn)行邊界檢查而造成的緩沖區(qū)溢出、堆溢出等類型的安全漏洞。動態(tài)分析是一種通過動態(tài)加載并運行的目標(biāo)軟件,監(jiān)測程序運行時的堆棧信息、內(nèi)存使用情況、變量的值等狀態(tài)信息以及程序的輸出來驗證或發(fā)現(xiàn)軟件漏洞的技術(shù)。二進(jìn)制比對也稱為補丁比對。作為軟件安全漏洞的補救措施,軟件開發(fā)商會定期或不定期地提供相應(yīng)的修補程序即補丁。模糊測試是一種基于缺陷注入的自動化軟件漏洞挖掘技術(shù),其基本思想與黑盒測試類似。模糊測試通過向待測試的目標(biāo)軟件輸入一些半隨機的數(shù)據(jù)并執(zhí)行程序,監(jiān)控程序的運行狀況,同時記錄并進(jìn)一步分析目標(biāo)程序發(fā)生的異常來發(fā)現(xiàn)潛在的漏洞。
在模糊測試的過程中,測試用例執(zhí)行、異常監(jiān)視這兩個重要的過程完全可以自動化實現(xiàn)。而且,通過模糊測試技術(shù)發(fā)現(xiàn)的漏洞一般是真正存在的(原因是對半有效數(shù)據(jù)的處理不當(dāng)),即模糊測試技術(shù)存在誤報率低的優(yōu)點。其他的漏洞挖掘方法往往需要對目標(biāo)程序的源代碼或二進(jìn)制代碼進(jìn)行深入的分析,這是過程的開銷巨大,而模糊測試并不需要對目標(biāo)程序的源代碼或二進(jìn)制程序進(jìn)行分析即可進(jìn)行。
我們這次使用的就是模糊測試中的灰盒測試?;液袦y試使用輕量級工具來以可忽略的性能開銷確定輸入所執(zhí)行的路徑的唯一標(biāo)識符。通過改變提供的種子輸入來生成新輸入,如果新輸入使用了有趣的新路徑,則會添加到模糊器的隊列中。AFL負(fù)責(zé)發(fā)現(xiàn)數(shù)百個高影響力漏洞,已被證明可以“憑空”生成有效的測試文件,并且擁有大量的安全研究人員致力于擴展它。
AFLGO作為定向灰箱模糊器,重點關(guān)注用戶定義的目標(biāo)位置并進(jìn)行優(yōu)化,根據(jù)自定義的功率計算方法來生成更短距離的測試種子。此處,距離是根據(jù)輸入種子執(zhí)行軌跡上的基本塊到目標(biāo)基本塊的平均權(quán)重計算的,其中權(quán)重由程序的調(diào)用圖和過程內(nèi)的控制流圖進(jìn)行的過程內(nèi)分析得到,并且自定義的功率計算方法是基于模擬退火的。
在實際情況下,生成的大量輸入無法讓程序執(zhí)行到目標(biāo),這極大地影響了模糊測試的效率。為了使模糊的效率更高,我們在AFLGO的基礎(chǔ)上對種子篩選部分進(jìn)行了優(yōu)化,它可以更高效地找到導(dǎo)致程序崩潰的種子。我們使用一種前饋神經(jīng)網(wǎng)絡(luò),這是一種高效且可擴展的程序平滑技術(shù),該技術(shù)可以模擬程序的分支行為。并且可以使種子進(jìn)行更為高效的突變,最終可以使模糊測試的效率進(jìn)一步提升。
按測試輸入的不同種類進(jìn)行劃分,模糊測試的測試輸入可分為基于變異和基于生成兩種方式。其中,基于變異的模糊測試在修改已知測試輸入的基礎(chǔ)上生成新的測試用例,而基于生成的模糊測試則是直接在已知輸入樣本格式的基礎(chǔ)上生成新的測試輸入。
根據(jù)不同的研究側(cè)重點,本章分別介紹基于變異的模糊測試、基于生成的模糊測試。
AFLFast[1]采用特定的策略引導(dǎo)AFL優(yōu)先選擇低頻路徑的文件作為種子文件進(jìn)行變異,以此在相同的測試時間內(nèi)探索更多的路徑。AFLGo[2]采用了模擬退火算法對種子進(jìn)行賦能操作,為更接近目標(biāo)點的種子給予更多的能量,從而可以篩選出更為優(yōu)質(zhì)的種子,使得模糊測試的效率進(jìn)一步提高。
基于生成的模糊測試主要基于模型或者語法生成能滿足程序語法和語義檢查的測試輸入,常用于高度結(jié)構(gòu)化的測試輸入生成。
圖1 AFLGo模型圖Fig.1 AFLGo model diagram
SeededFuzz[3]使用各種程序分析技術(shù)來促進(jìn)初始種子的生成和選擇,這有助于實現(xiàn)定向模糊的目標(biāo)。配備改進(jìn)的種子選擇和生成技術(shù),SeededFuzz可以到達(dá)更多關(guān)鍵站點并發(fā)現(xiàn)更多漏洞。
當(dāng)前的導(dǎo)向性模糊測試旨在生成可能到達(dá)特定錯誤代碼的輸入,進(jìn)一步期望觸發(fā)該錯誤。但是在模糊測試過程中,生成導(dǎo)致程序錯誤輸入的效率卻并不高。在有限的時間內(nèi)生成盡可能多的可以導(dǎo)致程序崩潰的輸入就作為下一步的研究目標(biāo)。而且在模糊測試過程中目標(biāo)程序的執(zhí)行時間占最大比例,只有增加優(yōu)質(zhì)輸入(可以導(dǎo)致程序崩潰的輸入)的生成才能大大提高模糊測試的效率。如果存在一種足夠快的方法來生成更多優(yōu)質(zhì)輸入的方法,則在有限的時間就能找到更多有效的引起程序崩潰的種子。這樣,可以提高模糊測試的整體性能。
AFLGo的模型如圖1所示,主要由四個部分組成:圖形提取器、距離計算器、運行器和模糊器。
(1)圖提取器生成調(diào)用圖和相關(guān)的控制流圖。是作為AFL LLVM pass的擴展而實現(xiàn)的,它由編譯器AFL clang fast激活。
(2)距離計算器利用調(diào)用圖和每個過程內(nèi)控制流計算每個基本塊的進(jìn)程間距離。DC被封裝為一個Python腳本,它使用networkx包來解析圖,并根據(jù)Djikstra的算法進(jìn)行最短距離計算。DC生成BB距離文件,該文件包含每個基本塊級目標(biāo)距離。
(3)儀器獲取BB距離文件,并在目標(biāo)二進(jìn)制文件中指示每個BB。對于每個BB,它確定各自的BB級目標(biāo)距離并注入擴展的蹦匯編代碼,在每個跳轉(zhuǎn)指令之后執(zhí)行,以跟蹤覆蓋的控制流邊緣。對于每個基本塊,AFLGo儀器添加匯編代碼:1)加載當(dāng)前累積距離并添加當(dāng)前BB的目標(biāo)距離,2)加載并增加已運行BB的數(shù)量,3)將兩個值存儲到共享內(nèi)存中。
(4)Fuzzer根據(jù)我們加入樣本種子快速收斂篩選算法的退火功率計劃,并模糊化插入二進(jìn)制文件。當(dāng)前種子距離的計算方法是將累積的基本塊距離除以訓(xùn)練基本塊的數(shù)量。
我們基于退火的功率計劃為“更接近”目標(biāo)的種子分配了比“更遠(yuǎn)”的種子更多的能量,并且這種能量差隨溫度降低而增加。
在模糊測試的起始階段,首先對種子進(jìn)行距離測量,及種子到目標(biāo)點的距離。該測量結(jié)果在進(jìn)行檢測時已經(jīng)完全確定,并且在運行時可以有效地計算出來。我們的程序分析是基于調(diào)用圖和程序內(nèi)控制流圖進(jìn)行的過程內(nèi)分析,這與過程間分析相比可以節(jié)省很多時間。
首先我們使用前饋神經(jīng)網(wǎng)絡(luò)來模擬復(fù)雜的程序分支行為,進(jìn)行有效的梯度計算。我們通過使用經(jīng)過AFLGo測試過一定時間后的測試輸入語料庫來訓(xùn)練神經(jīng)網(wǎng)絡(luò)。
隨后我們使用梯度或高階導(dǎo)數(shù)來實現(xiàn)更快的收斂性,平滑的神經(jīng)網(wǎng)絡(luò)模型一旦經(jīng)過訓(xùn)練,便可以用于有效地計算梯度和高階導(dǎo)數(shù),然后可以利用它們來更快地收斂到最優(yōu)解,也就是得到更為高效的種子。
和AFLGo類似,我們定義了一種距離度量(即種子到目標(biāo)位置),該度量在進(jìn)行模糊時已完全確定,并且可以在運行時有效地計算出來。盡管我們的度量是過程間的,但我們的程序分析實際上是基于調(diào)用圖和控制流圖進(jìn)行的過程內(nèi)分析。與過程間分析相比,我們展示了如何產(chǎn)生二次儲蓄。而且調(diào)用圖和控制流圖在LLVM編譯器的基礎(chǔ)結(jié)構(gòu)中很容易得到。
使用這種新穎的距離度量,我們定義了一種新穎的功率方法,該方法集成了最流行的退火功能,即指數(shù)冷卻計劃。根據(jù)我們的距離測度,基于退火的功率計劃逐漸將更多的能量分配給更接近目標(biāo)位置的種子,同時減少更遠(yuǎn)的種子的能量。
最后,我們結(jié)合了一種新的方案平滑方法,它使用代理潛虧神經(jīng)網(wǎng)絡(luò)模型來學(xué)習(xí)和迭代地平滑逼近目標(biāo)程序,目的就是通過觀察到的程序行為來精煉目標(biāo)程序。這樣就可以替代神經(jīng)網(wǎng)絡(luò)可以平滑地延展到觀察到的程序行為,同時還可以對潛在的非線性和非凸行為進(jìn)行準(zhǔn)確建模。
同時我們通過梯度計算方法實現(xiàn)了新的邊緣覆蓋,這樣我們就可以在保留就數(shù)據(jù)的同時還可以觸發(fā)新的分支,從而生成新的訓(xùn)練數(shù)據(jù)。再將新的數(shù)據(jù)和過濾掉的舊數(shù)據(jù)重新訓(xùn)練神經(jīng)網(wǎng)絡(luò),這樣就能有效的防止訓(xùn)練數(shù)據(jù)樣本數(shù)量無休止的增加,大大增加了重新訓(xùn)練的次數(shù)。
為了顯示我們工具的有效性,我們評估了配備工具后的AFLGo和原始的AFLGo,使用LAVA-M中的4個程序uniq、md5sum、who、base64,對比其他工具的測試方法,大部分都是把測試時間都控制在了7天左右,所以我們也將用同樣的時間測試數(shù)據(jù),這樣對比結(jié)果就具有很高的有效性。
所有實驗和測量均在運行Ubuntu 16.04,具有8核CPU,16GB內(nèi)存和2TB硬盤的64位服務(wù)器上進(jìn)行的。根據(jù)實驗結(jié)果,我們的工具可以將模糊測試的性能提高到AFLGo的1.5倍多。對比AFLGo本身,改進(jìn)后模型的測試結(jié)果都要明顯好于AFLGo,總漏洞數(shù)以及去重后的漏洞數(shù)量都比之前的數(shù)量要多得多。
最近,導(dǎo)向型模糊測試可以有效地發(fā)現(xiàn)具有潛在已知位置的錯誤。為了提高模糊測試的效率,本文提出高效的樣本種子快速收斂篩選算法以使模糊測試在更短的時間內(nèi)可以找到更多的漏洞。并且我們是在AFLGo框架的基礎(chǔ)上進(jìn)行實現(xiàn)的,這樣利于對比實驗的進(jìn)行,使結(jié)果更有說服力。對LAVA-M中4個程序測試的結(jié)果表明,我們的工具可以使速度提高多達(dá)1.5倍以上。