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