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