網(wǎng)絡(luò)安全知識(shí):什么是模糊測試?
什么是模糊測試?
模糊測試,也稱為模糊測試,是一種允許開發(fā)人員和安全研究人員對給定程序(網(wǎng)絡(luò)協(xié)議、二進(jìn)制文件、Web 應(yīng)用程序等)執(zhí)行黑盒分析的技術(shù)。分析將包括一系列輸入,范圍從已知的“以自動(dòng)方式將任意格式錯(cuò)誤的數(shù)據(jù)輸入到應(yīng)用程序中。
模糊測試的目標(biāo)是檢測未知的漏洞或錯(cuò)誤。模糊測試通過被模糊處理的應(yīng)用程序中的意外或異常行為揭示潛在的錯(cuò)誤,例如崩潰、無限循環(huán)或用戶或開發(fā)人員可能認(rèn)為“不良”的其他行為。它通常通過改變輸入到程序中的輸入來實(shí)現(xiàn)這一點(diǎn),希望進(jìn)一步覆蓋代碼,因此程序的每個(gè)角落和縫隙都可以暴露給這個(gè)任意輸入。目標(biāo)是聲稱給定的程序足夠健壯,可以按預(yù)期執(zhí)行或找到程序中的錯(cuò)誤,以便開發(fā)人員可以修復(fù)它們。
過去,模糊測試主要由安全社區(qū)使用。今天,模糊測試的能力比以往任何時(shí)候都容易;因此,模糊測試不僅被安全研究人員廣泛使用,而且被軟件開發(fā)人員和計(jì)算機(jī)工程師廣泛使用。Fuzzing 的流行來自于使用自動(dòng)化過程的能力,無需付出太多努力就能發(fā)現(xiàn)手動(dòng)代碼審查中遺漏的錯(cuò)誤。模糊測試應(yīng)用程序可以保持運(yùn)行 - 只需最少的交互 - 一次最多可運(yùn)行數(shù)天。
模糊測試是如何工作的?
雖然模糊測試看起來像是暴力破解,但實(shí)際上遠(yuǎn)不止于此。有一些活動(dòng)部件使其與眾不同。此外,并不是所有的模糊器都是一樣的。
模糊器的類型
模糊器有兩種形式:啞模糊器和智能模糊器。最流行的模糊測試應(yīng)用程序往往是智能模糊測試器。然而,對于啞巴和智能模糊器仍然有有效的用例。
啞模糊器
dumb fuzzer 為在應(yīng)用程序上執(zhí)行模糊測試提供了一種快速簡便的解決方案。這些模糊器的主要驅(qū)動(dòng)概念是他們正在模糊測試的程序缺乏上下文或狀態(tài)。模糊器通常不知道程序是否處于執(zhí)行狀態(tài),也不知道程序是否正確接收了輸入。他們只知道兩件事:
- 程序中輸入了什么?
- 如果程序崩潰了?
鑒于這兩個(gè)知識(shí)點(diǎn),一個(gè)愚蠢的模糊器可以判斷是否有一些隨機(jī)輸入輸入到程序中導(dǎo)致它崩潰?;蛘?,通過在向程序輸入輸入后分析程序的輸出,可以使啞模糊器變得稍微聰明一些。這可能有助于找到不一定導(dǎo)致崩潰的其他問題,而是另一個(gè)意外操作。
愚蠢的模糊測試的缺點(diǎn)是缺乏對它所測試的程序的了解。這可能是一個(gè)問題的一個(gè)很好的例子是,如果輸入的格式需要在特定的模板中,例如對于需要密鑰、用戶名或目錄等參數(shù)的程序的某些配置文件。這對于一個(gè)愚蠢的模糊器來說可能是個(gè)問題,但是一個(gè)聰明的模糊器可以輕松解決這個(gè)問題!
智能模糊器
智能模糊器(或至少比基本的模糊器更智能)將允許開發(fā)人員或研究人員探索更多應(yīng)用程序并可能發(fā)現(xiàn)以前未發(fā)現(xiàn)的錯(cuò)誤?!爸悄堋眮碜赃@些類型的模糊器中內(nèi)置的一些通用智能。一些情報(bào)點(diǎn)可能包括:
- 輸入格式是什么樣的?
- 最后一次輸入是否比之前的輸入導(dǎo)致了更多的代碼覆蓋?
- 可以對輸入進(jìn)行哪些修改以探索進(jìn)一步的代碼覆蓋率?
如果模糊器能夠識(shí)別這三個(gè)因素,那么為應(yīng)用程序生成的輸入類型將針對特定應(yīng)用程序進(jìn)行更精心的策劃,從而比愚蠢的模糊測試更快地發(fā)現(xiàn)錯(cuò)誤。
通常,智能模糊器將使用不同類型的算法來生成這些任意輸入。這與簡單地使用絕對隨機(jī)輸入(例如從 /dev/urandom 讀?。┑挠薮滥:鞣椒ㄏ喾础R恍┓椒òǎ?/span>
模糊測試方法 | 描述 |
模板/語法模糊測試 |
|
引導(dǎo)模糊測試 |
|
基于突變的模糊測試 |
|
基于生成/進(jìn)化的模糊測試 |
|
每種技術(shù)都有其優(yōu)點(diǎn)和缺點(diǎn),可能并不適合所有用例。模糊測試作為一個(gè)整體往往是一種“見機(jī)行事”的游戲,這意味著它是一個(gè)試穿多雙鞋直到找到適合你的場景的過程。
出于本文的目的,我們將避免關(guān)注“愚蠢”的模糊器,而更多地關(guān)注智能模糊器的結(jié)構(gòu)和操作。
模糊結(jié)構(gòu)
模糊測試環(huán)境可能因所需的實(shí)施而異。在這篇文章中,我們將重點(diǎn)關(guān)注大多數(shù)智能模糊器的一般結(jié)構(gòu),并為模糊器的操作方式提供簡單的視覺效果。
模糊測試的組件
要執(zhí)行有效的模糊測試,您的模糊器必須能夠執(zhí)行一些不同的任務(wù):
- 生成新的種子/測試用例
- 啟動(dòng)目標(biāo)程序(通過線束或僅通過程序)
- 為目標(biāo)程序提供一個(gè)測試用例
- 確定給定案例是否提供了新的代碼覆蓋率
- 變異/進(jìn)化提供正回報(bào)的輸入
- 檢測程序是否崩潰或停止
當(dāng)然,這個(gè)列表并不詳盡。但是,這些屬性允許模糊器高效執(zhí)行。
模糊測試的一般流程
在大多數(shù)情況下,為了對應(yīng)用程序進(jìn)行模糊測試,您的模糊器將執(zhí)行以下步驟:
- 讀取模糊器用戶提供的種子文件夾中的種子
- 用每個(gè)種子啟動(dòng)目標(biāo)程序并比較哪些提供了較新的代碼覆蓋率
- 對于第一次迭代,它將是所有這些,因?yàn)闆]有用于比較的先前執(zhí)行
- 對于提供較新代碼覆蓋率的每個(gè)測試用例,使用選定的變異方法對其進(jìn)行更改。在執(zhí)行基于語法/模板的模糊測試時(shí),確保它符合模板。
- 將這些新測試用例中的每一個(gè)添加到種子/測試用例隊(duì)列中,以便模糊測試應(yīng)用程序執(zhí)行
一般來說,模糊測試看起來像這樣:
在該工作流程中,模糊測試應(yīng)用程序?qū)⒉粩鄼z查目標(biāo)應(yīng)用程序是否已崩潰。如果有,導(dǎo)致崩潰的輸入將被重新定位到與其他種子分開的文件夾中;因此,用戶知道是哪個(gè)輸入導(dǎo)致了這種意外行為。
有了這些組件和程序,模糊測試應(yīng)用程序現(xiàn)在只需要一種與目標(biāo)應(yīng)用程序交互的方法。但有時(shí),并非所有輸入都是直截了當(dāng)?shù)?。例如,有時(shí)需要修改文件以更改程序的輸入。其他情況可能包括非標(biāo)準(zhǔn)輸入方法,例如通過套接字、通過庫調(diào)用或可能通過一些交互式輸入。無論哪種方式,通常最好的做法是使用線束與目標(biāo)程序進(jìn)行交互。
模糊線束
當(dāng)您想到安全帶時(shí),您可能會(huì)想到登山扣、高空滑索和登山裝備。然而,當(dāng)涉及到模糊測試時(shí),它們的工作方式有很大不同。開發(fā)了一個(gè)模糊測試工具來彌合模糊器期望輸入發(fā)生的方式與輸入在應(yīng)用程序中實(shí)際發(fā)生的方式之間的差距。它通過攜帶來自模糊器的輸入并將其正確地傳遞給模糊測試目標(biāo)來實(shí)現(xiàn)這一點(diǎn),以便目標(biāo)可以像任何正常交互一樣處理輸入。
一些程序需要特定的方法來將輸入輸入到程序中。不幸的是,模糊器不可能是所有行業(yè)的專家。試圖適應(yīng)世界上所有類型的程序是不現(xiàn)實(shí)的。為了使模糊器更容易與目標(biāo)程序?qū)υ?,模糊器的用戶需要?jiǎng)?chuàng)建一個(gè)工具。harness 只是將從模糊器輸入的標(biāo)準(zhǔn)測試用例輸入轉(zhuǎn)換為目標(biāo)應(yīng)用程序可以理解的內(nèi)容。這允許模糊測試應(yīng)用程序根據(jù)它對輸入的反應(yīng)來確定進(jìn)一步的操作。
在大多數(shù)情況下,這些是有效模糊測試的要素。精心設(shè)計(jì)以幫助模糊器與目標(biāo)程序?qū)υ挼木€束與足夠智能以根據(jù)目標(biāo)程序生成測試用例的模糊器配對,將證明是一項(xiàng)極好的資產(chǎn)。
有效的模糊測試和交易工具
在以下部分中,我們將討論有效模糊測試的一些關(guān)鍵要素以及一些流行的工具以及這些工具之間的一些比較。
模糊測試工具
對于大多數(shù)需要模糊測試功能的用戶來說,沒有必要重新造輪子。有很多免費(fèi)的構(gòu)建良好的工具,您可以使用它們來對特定目標(biāo)進(jìn)行模糊測試。此類免費(fèi)和開源工具包括:
- American Fuzzy Lop (AFL)
- 庫模糊器
- 紅旗
- Boo Fuzz
- 毛毛蟲
- 趣味Fuzz
如果希望對程序進(jìn)行徹底的模糊測試,您可能需要考慮使用這些模糊測試器中的多個(gè)。這一點(diǎn)尤其明顯,因?yàn)椴⒎撬羞@些模糊器的工作方式都完全相同。正如我們將看到的,并非所有的模糊器都適用于每種語言。
請記住,上述模糊測試器列表并不詳盡,讓我們快速瀏覽一下 AFL、LibFuzzer 和 Fuzzili,以了解它們各自的不同之處。
澳式橄欖球聯(lián)盟
根據(jù)官方描述,“American fuzzy lop (AFL) 是一種面向安全的模糊器,它采用一種新型的編譯時(shí)檢測和遺傳算法來自動(dòng)發(fā)現(xiàn)干凈、有趣的測試用例,這些用例會(huì)觸發(fā)目標(biāo)二進(jìn)制文件中的新內(nèi)部狀態(tài)。”
好處:
- 支持黑盒和白盒測試。(有或沒有源代碼)
- 支持?jǐn)U展到您自己的實(shí)施需求
- 使用基因模糊測試技術(shù)
缺點(diǎn):
- 不是多線程
- 不提供任何本地模糊網(wǎng)絡(luò)協(xié)議的能力
庫模糊器
LibFuzzer 是最流行的模糊測試工具之一,它是一種進(jìn)程內(nèi)、覆蓋引導(dǎo)的模糊測試引擎。LibFuzzer 與被測庫鏈接,通常通過模糊測試工具通過特定的模糊測試入口點(diǎn)將模糊輸入輸入到庫中。顧名思義,這是一個(gè)專門設(shè)計(jì)用于模糊庫功能而不是單個(gè)程序的模糊器。目前,如果你想模糊一個(gè)目標(biāo),所討論的庫必須能夠用 Clang 編譯,因?yàn)?LLVM 帶有 Clang 編譯器。
好處:
- Fuzzer 已經(jīng)是編譯器的一部分,可以更輕松地與任何項(xiàng)目集成
- 立即支持地址消毒劑
- AFL 僅在您檢測應(yīng)用程序時(shí)才有此功能(這就是 LibFuzzer 的工作方式)
- 覆蓋引導(dǎo)的模糊測試
缺點(diǎn):
- 無法開箱即用地執(zhí)行黑盒測試(通常只有在您有源代碼時(shí)才使用)
- 主要用于模糊共享庫而不是獨(dú)立的二進(jìn)制文件
毛毛蟲
這是另一個(gè)覆蓋引導(dǎo)的模糊器;但是,此模糊器適用于 JavaScript 等動(dòng)態(tài)語言解釋器。模糊器的主要目標(biāo)是在 JavaScript 引擎上執(zhí)行模糊測試并允許適應(yīng)特定的 JavaScript 實(shí)現(xiàn)。
好處:
- 為 JavaScript 精心策劃
- 在生成測試用例期間使用的四個(gè)修改器選項(xiàng)
- 使用多線程
缺點(diǎn):
- 只為 JavaScript 編寫
您可以很容易地看出,每個(gè)模糊器都有可以使用和不能使用的特定情況。在您的程序中使用多個(gè)模糊器可以提供更好的整體代碼覆蓋率,而不是只使用一種類型的模糊器。例如,如果您使用 LibFuzzer 從源代碼檢測程序,然后使用 AFL,您將獲得兩全其美的效果,甚至可以在兩個(gè)模糊器之間共享崩潰數(shù)據(jù)。
不過,關(guān)于不同的模糊器已經(jīng)說得夠多了。最終將幫助您決定選擇哪種模糊器取決于目標(biāo)應(yīng)用程序。
模糊什么
在任意級別上,您可以對任何內(nèi)容進(jìn)行模糊測試。困難的部分是如何將您想要模糊測試的內(nèi)容偽造成可以以編程方式傳遞給應(yīng)用程序進(jìn)行處理的輸入。例如,假設(shè)您想要對消息傳遞應(yīng)用程序進(jìn)行模糊測試。在這個(gè)消息傳遞應(yīng)用程序中,您希望將文本框作為目標(biāo),用戶可以在其中鍵入消息。您將如何以編程方式創(chuàng)建可以將來自模糊測試框架的輸入傳遞到文本框中的線束?
在某種程度上,這可能非常困難,并且可能會(huì)導(dǎo)致一些有趣的利用。這也是為什么利用是模糊測試中比較困難的部分之一。您不僅必須處理運(yùn)行時(shí)問題,還必須將輸入獲取到您想要的位置。
選擇目標(biāo)應(yīng)用程序時(shí)的一些注意事項(xiàng)是:
- 這個(gè)應(yīng)用程序受歡迎嗎?
- 如果是這樣,您最終的模糊測試投資回報(bào)率可能會(huì)很低
- 這可能需要您針對程序中更深層次的內(nèi)容進(jìn)行模糊測試
- 這是什么類型的應(yīng)用程序/庫?
- 如果應(yīng)用程序使用 GUI,您將如何從 harness 發(fā)送輸入?
- 如果應(yīng)用程序不使用 GUI,您如何對無法從命令行訪問的輸入進(jìn)行模糊測試?
尋找模糊測試目標(biāo)的另一種途徑可能源于主要項(xiàng)目所依賴的公共庫或依賴項(xiàng)。但是,這些庫不像使用它的主庫或程序那樣頻繁地進(jìn)行模糊測試。對庫或依賴項(xiàng)進(jìn)行模糊測試可以發(fā)現(xiàn)以前未檢測到的漏洞。(參見https://github.com/python-pillow/Pillow/issues/5544)
編寫一個(gè)“好的”工具(又名 Fuzzing Target)
線束或模糊測試目標(biāo)是將要執(zhí)行的目標(biāo)文件,是目標(biāo)應(yīng)用程序和模糊測試框架之間的有效橋梁。一個(gè)示例實(shí)現(xiàn)可能是一個(gè) harness,它旨在與 LibFuzzer 一起工作,將從標(biāo)準(zhǔn)輸入讀取,將參數(shù)傳遞給庫函數(shù),然后將結(jié)果返回給被調(diào)用者。在這種情況下,輸入將來自 LibFuzzer,當(dāng)出現(xiàn)成功返回值時(shí),LibFuzzer 知道一切順利。
在大多數(shù)情況下,想法是盡可能多地執(zhí)行此線束。這通常是通過使用分叉服務(wù)器或外部導(dǎo)出 (LibFuzzer) 形式的模糊測試框架來實(shí)現(xiàn)的。因此,在嘗試確保我們的線束盡可能高效時(shí)需要考慮的一些注意事項(xiàng)是:
- 處理非標(biāo)準(zhǔn)/畸形輸入的能力
- harness 不應(yīng)退出或中止,除非絕對必要以允許進(jìn)一步的代碼覆蓋
- “垃圾收集”任何線程或創(chuàng)建的子進(jìn)程的能力
- 避免超過 n^2(最多 n^3)的任何復(fù)雜性
- 最后,保持模糊測試目標(biāo)更窄以允許更具體的模糊測試
上述注意事項(xiàng)在很大程度上取決于您的模糊測試實(shí)施。請記住,這些是大多數(shù)模糊器遵循的一般意識(shí)形態(tài)。為了更廣泛和詳細(xì)地描述制作一個(gè)好的模糊測試目標(biāo),谷歌有一個(gè)專門用于教學(xué)模糊測試的存儲(chǔ)庫。可以在此處找到目標(biāo)創(chuàng)建部分。
誰應(yīng)該進(jìn)行模糊測試?
由于易于部署和自動(dòng)化,模糊測試在計(jì)算機(jī)科學(xué)和工程領(lǐng)域的各個(gè)團(tuán)體中獲得了更多的關(guān)注。雖然模糊測試是網(wǎng)絡(luò)安全研究人員工具箱中的一個(gè)有效工具,但它也應(yīng)該是軟件開發(fā)人員工具箱中的一個(gè)重要工具。
模糊驅(qū)動(dòng)開發(fā)
如果現(xiàn)在開始一個(gè)新的開發(fā)項(xiàng)目,并且沒有將模糊測試納入您的測試管道,那么您就會(huì)發(fā)現(xiàn)重要的錯(cuò)誤!如果你沒有見過測試驅(qū)動(dòng)開發(fā)(TDD),它就是根據(jù)項(xiàng)目需求為給定項(xiàng)目開發(fā)測試用例的過程。這個(gè)想法是在達(dá)到每個(gè)需求里程碑時(shí)創(chuàng)建這些,而不是等到最后為給定項(xiàng)目構(gòu)建所有測試用例。純 TDD 的缺點(diǎn)是測試空間對于許多開發(fā)人員來說是多么不完整。
在大多數(shù)情況下,使用 TDD 的開發(fā)人員會(huì)創(chuàng)建一組預(yù)期的失敗和預(yù)期的成功。然而,這些情況僅限于開發(fā)人員的知識(shí)和應(yīng)用程序目的的上下文。開發(fā)人員只知道他們知道的,不知道他們不知道的。因此,雖然他們可能已經(jīng)成功地測試了他們的程序或庫的功能,但并非所有可能輸入可能造成嚴(yán)重破壞的邊緣情況都被擊中。為了確保每個(gè)測試用例都被命中,重要的是不僅要使用 TDD,還要使用模糊驅(qū)動(dòng)開發(fā) (FDD)。
在 FDD 中,不需要被測試的候選人是項(xiàng)目需求或主要功能。有時(shí),這可能只是一般功能,例如打開和解析開發(fā)人員想要測試該文件或代碼段的穩(wěn)健性的文件。無論如何,總體思路是:
- 在開發(fā)人員想要模糊測試的應(yīng)用程序或庫中找到目標(biāo)位置
- 創(chuàng)建一個(gè)將輸入饋送到目標(biāo)的線束
- 運(yùn)行模糊器!
- 利潤?
這里的想法是,因?yàn)殚_發(fā)人員可以完全控制應(yīng)用程序的工作方式,所以他們可以輕松地操縱和分離目標(biāo)位置。此外,在模糊測試時(shí)擁有源代碼允許對目標(biāo)程序或庫進(jìn)行檢測。Instrumentation 允許模糊測試框架的用戶更好地跟蹤某些輸入到給定模糊測試目標(biāo)所達(dá)到的代碼覆蓋率。擁有源代碼的另一個(gè)好處是能夠?qū)崿F(xiàn)額外的模糊測試助手,例如地址清理器,可以幫助捕獲不會(huì)導(dǎo)致應(yīng)用程序崩潰的錯(cuò)誤和其他漏洞。作為開發(fā)人員,這是一個(gè)很好的機(jī)會(huì),可以在其他人之前找到導(dǎo)致應(yīng)用程序中出現(xiàn)意外操作的輸入。
假設(shè)發(fā)生了崩潰。在開發(fā)人員對崩潰進(jìn)行分類后,這意味著它已位于崩潰和修復(fù)的位置,開發(fā)人員可以開始將此輸入重新處理到他們的測試流程中。請記住,TDD 本身并不是壞事。然而,通過將 FDD 與其結(jié)合使用,軟件開發(fā)人員可以通過回歸測試的藝術(shù)為其代碼的特定功能創(chuàng)建更健壯的單元測試。在這種情況下,回歸測試只是一種確保先前導(dǎo)致崩潰的任何輸入不會(huì)在項(xiàng)目生命周期的后期導(dǎo)致崩潰的一種方法。
從這往哪兒走
你應(yīng)該從這篇文章中學(xué)到什么?首先,理解模糊測試不再只是安全研究人員的專利。軟件開發(fā)人員、應(yīng)用程序用戶和安全愛好者可以不受限制地訪問用于許多不同用例的無數(shù)不同的模糊測試實(shí)用程序。其次,無論是在開發(fā)運(yùn)營管道中使用還是在閃亮的新無人機(jī)中尋找漏洞,模糊測試都是必須的,應(yīng)該盡可能實(shí)施!無論您使用的是愚蠢的模糊器還是我們討論的智能模糊器,模糊器的適用性和實(shí)用性都是無與倫比的。展望未來,看看您可以在項(xiàng)目中的哪些地方使用模糊器來幫助確保您的項(xiàng)目即使是最抽象的用戶輸入也是安全的。