如何使用 AFL 和 AFL++ 有效地對二進位進行模糊測試

最後更新: 28/02/2026
作者: 艾薩克
  • 模糊測試透過自動發送格式錯誤的輸入來發現軟體和系統中的安全漏洞。
  • AFL 和 AFL++ 是智慧模糊測試器,它們使用插樁編譯器,透過覆蓋率來引導自身並找到新的執行路徑。
  • 使用 AFLTriage 和 GDB 等工具分析崩潰,可以評估整數下溢等漏洞的可用性。
  • 將模糊測試整合到開發週期中可以提高系統的穩健性,有助於滿足安全標準,並降低重大事故的風險。

使用 AFL 進行二進位模糊測試

如果您有興趣 面向二進位的網路安全與漏洞利用你遲早會接觸到模糊測試,尤其是 AFL 和 AFL++。我們說的不是理論上的實驗室工具,而是每天都在用來發現知名程式中真實缺陷的工具,就像之前發現的漏洞一樣… 像 7-Zip 這樣的熱門應用程式.

接下來,我們將以友好而詳盡的方式看到: 如何使用 AFL 和 AFL++ 對二進位檔案進行模糊測試我們將詳細解釋什麼是模糊測試,它在安全性方面為何如此強大,以及如何將其整合到現代開發工作流程中。我們還將分析一個真實的漏洞案例(允許遠端程式碼執行的整數下溢漏洞),並介紹一些輔助工具,例如: GDB 及其擴充、AFLTriage 和操作模組.

什麼是 AFL/AFL++?為什麼它們被認為是智慧模糊測試工具?

用於模糊測試的 AFL 工具

AFL(美國長毛垂耳兔)及其演化版 AFL++ 這些是開源模糊測試工具,旨在自動測試二進位文件,尋找溢出、記憶體錯誤或導致崩潰甚至可利用漏洞的意外行為等故障。

AFL 的精妙之處不僅在於發送隨機數據,而在於… 智慧型模糊測試器或覆蓋引導模糊測試器從一個或多個有效範例條目(所謂的)開始 測試用例),AFL 不斷生成變體,並且由於程式的偵測功能,可以偵測到新的變異何時導致二進位檔案採取不同的執行路徑。

為了實現這種檢測功能,AFL 有自己的編譯器,例如: afl-gcc 和 afl-g++這些函數會在編譯過程中向程式碼中插入一些小的「鉤子」。這些鉤子會通知 AFL 已發現某個特定的輸入。 專案流程中的新路線這樣一來,你就可以專注於真正提供額外覆蓋範圍的突變,而不會浪費時間在不會改變任何事情的數據上。

這種方法使得 AFL 類似於「二進位檔案的 dirb」:一個廣為人知的工具,一旦理解了基本流程就很容易使用,而且功能強大到足以發現… 生產程序有嚴重缺陷即使有更高級或更專業的模糊測試器。

模糊測試簡介及其在網路安全中的作用

模糊測試,或簡稱模糊測試,是一種技術 自動化安全性和穩健性測試其目的是向應用程式發送大量格式錯誤、隨機或異常的數據,目的是觀察程式是否會崩潰、故障或行為異常。

在對軟體進行模糊測試時,目的是找出以下錯誤: 緩衝區溢位、輸入驗證失敗、記憶體管理問題或競態條件這些缺陷中有很多會導致任意程式碼執行、資訊外洩或拒絕服務攻擊。

典型的模糊測試工作流程包含三個清晰的階段:首先,產生測試資料集(可以是完全隨機的、按照特定格式產生的,也可以是透過修改有效輸入產生的);然後… 在監控下執行被測二進位檔案 對其行為進行監控;最後,記錄並分析崩潰或異常行為,以便開發人員可以調查問題的根源。

模糊測試策略有很多種。有些工具著重於… 世代模糊建立符合明確定義格式(例如,文件結構或網路協定)的條目;其他條目則基於… 有效輸入的變異這正是AFL和AFL++的優勢所在。此外,還有一些更隨機的方法,以及一些依賴對被測系統特定知識來找出其弱點的方法。

在現代網路安全中,模糊測試是一項至關重要的輔助手段:它有助於發現系統中的漏洞。 在軟體投入生產前主動採取措施並有助於遵守 ISO 27001 等法規和標準或資料保護要求。此外,它還能降低關鍵可利用漏洞落入攻擊者手中所造成的聲譽風險。

真實案例:解壓縮器中的整數下溢和遠端程式碼執行漏洞

為了理解 AFL 和模糊測試的真正價值,基於特定漏洞進行分析非常有用。 非常流行的檔案解壓縮程式中的整數下溢這是一個遠端程式碼執行 (RCE) 錯誤,在使用 Zstandard 演算法處理壓縮檔案時觸發,其 CVSS 得分很高,但不是最高分,正是因為它需要更具體的上下文(例如,正在處理特定的檔案)。

當一個具有明確下界的整數變數出現下溢時,就會發生整數下溢。 它用於減法運算,直到達到其最小值為止。由於許多整數類型不允許負值,因此當「低於」零時,由於這些數字在內部的表示方式,不會得到一個小於零的數字,而是會跳到該範圍內的最大可能值。

  使用 AppLocker 和 WDAC 對腳本進行簽署並強化執行策略。

想像一個整數變量,理論上它永遠不會是負數。如果你不斷地減去一個常數直到你得到 0,然後繼續減去, 你不會得到-1、-2等等。相反,該值會反轉,並變成允許範圍上限的一個巨大數字。如果將這個荒謬的數字用作記憶體操作的索引或大小,則可能導致超出預期限制的讀寫操作。

當使用可能發生下溢的整數變數時,問題就變得十分嚴重。 管理緩衝區或計算偏移量一個典型的偽範例是在 memcpy 類型的函數中間接使用使用者控制的變數作為偏移量,在一個循環中,每次迭代都會遞減一個常數,直到它達到零或非正數。

在這種情況下,如果初始值始終無法「乾淨利落地」滿足退出條件,下溢最終會導致數值變得非常大,循環將繼續運行,並且 記憶的大規模損壞這會導致程式崩潰,並且,透過足夠的漏洞利用,有可能執行任意程式碼。

AFL如何幫助定位這類漏洞

一旦理解了整數下溢的概念,就能明白為什麼 AFL 和 AFL++ 如此有用:從 一個或幾個完全有效的輸入文件模糊測試器可以產生數萬種變體,直到找到能夠觸發受影響的解壓縮路徑中的特定錯誤的變體為止。

在模糊測試過程中,AFL 會監控被插樁的二進位文件,以確定何時輸入會導致執行不同的流程控制路徑。每次偵測到新的路徑時, 將該條目標記為有趣 並將其保存下來,作為未來變異的基礎。這樣一來,不僅可以探索常規的執行路徑,還可以探索那些啟動非常規程式碼路徑的資料組合,例如使用特殊參數的解壓縮過程。

對於整數下溢,AFL 可以找到一個樣本,該樣本會導致循環中涉及的變數永遠無法達到預期的輸出值。結果會產生一個可檢測的崩潰,該崩潰資訊將儲存在相應的 AFL 結果資料夾中,以便進行進一步分析。

執行幾分鐘或幾小時後,AFL通常會發出信號 首次相關崩潰並非所有發現的漏洞都能被利用,但它們清楚地表明二進位檔案的記憶體管理、輸入驗證或內部邏輯中的某些東西沒有按預期工作。

這時,像 AFLTriage 這樣的支援工具或像 GDB 這樣的調試器就派上了用場,它們可以讓你更深入地了解崩潰情況,觀察寄存器和內存的狀態,並評估故障是否可以被可靠地利用,或者它是否只是一個對攻擊者來說沒什麼用的掛起。

AFL/AFL++ 與分析環境的基本安裝

在標準 Linux 系統上建立使用 AFL 進行模糊測試的最小環境非常簡單。在許多發行版中,只需安裝與已插樁編譯器對應的軟體包即可,例如,可以使用類似這樣的命令: 安裝 afl-g++ 或等效的 AFL++ 軟體包 把整套都帶來。

這樣做會同時安裝模糊測試工具(例如…) afl-fuzz例如,可以使用一些專用編譯器(afl-gcc、afl-g++ 以及它們在 AFL++ 中的現代變體)。當您需要使用插樁技術重新編譯目標程式碼時,就需要使用這些編譯器。插樁技術對於充分發揮覆蓋率引導模糊測試的優勢至關重要。

除了模糊測試器本身之外,一個良好的調試環境幾乎是必不可少的。一個擴充的 GDB 就夠了。 類似PEDA或GEF的插件 它提供了額外的命令、便捷的記憶體格式化、堆疊視覺化以及用於檢查暫存器和記憶體映射的快捷方式,使生活變得更加輕鬆。

如果您還沒有 GDB,可以使用發行版的軟體套件管理器進行安裝。然後,只需整合您選擇的插件(例如,從 GEF 或 PEDA 的儲存庫下載並將其新增至 GDB 設定檔中,或在偵錯器本身中使用 `source` 命令)。

有了這個“功能強大的 GDB”,你就可以分析那些在模糊測試下崩潰的已插樁二進位文件,下載 導致崩潰的輸入 並一步一步地追蹤執行過程中發生故障的具體步驟。

使用 AFL 編譯目標二進位檔案以進行模糊測試

一旦你準備好了 AFL 或 AFL++,下一步就是進行真正的模糊測試了。 使用 AFL 編譯器編譯目標並且要採取適當的措施,以便進行分析和潛在的利用,以防此次演習的目標是進攻性研究。

  SmartScreen 阻止合法應用程式:會發生什麼以及該怎麼辦

在大型專案中,例如解壓縮程式或歸檔實用程式套件,啟用偵錯符號(選項)是一個好主意。 調試模式或類似 -g 的標誌並儘量減少優化(例如,使用 -O0 而不是 -O2)。這極大地有助於理解原始程式碼中與觀察到的崩潰相關的具體情況。

通常你需要找到對應的Makefile或建置文件, 修改定義編譯標誌的行。這可能包括啟動 DEBUG 變數、強制執行特定的最佳化級別,以及最重要的是,用 afl-gcc 和 afl-g++(或等效的 AFL++ 工具)取代 CC 和 CXX。

例如,您可以使用類似 CC=afl-gcc 和 CXX=afl-g++ 的參數以及對應的 Makefile 檔案來啟動建置。最終會產生一個經過插樁的二進位文件,其中包含必要的鉤子,以便 AFL 可以在整個執行過程中測量程式碼覆蓋率。

編譯完成後,最好使用類似這樣的命令檢查生成的二進位檔案是否包含偵錯符號和正確的架構。 關於可執行檔的文件這樣可以確保你不會盲目地進行模糊測試,並且可以輕鬆調試出現的任何崩潰。

準備測試用例並執行 AFL

在對你的二進位檔案啟動 AFL 之前,你需要準備一套… 最低有效條目如果您正在測試一個解壓縮程序,該程序無法處理使用特定演算法壓縮的文件,則您需要建立至少一個使用該壓縮方法的格式良好的文件。

通常的做法是建立一個目錄,例如名為 testcases 的目錄,並在其中儲存一個或多個可運行的範例。這些範例將作為 AFL 的起點。 產生越來越具攻擊性的突變嘗試發現新的執行路徑,最終導致崩潰。

啟動 AFL 的典型命令如下所示:指定會話或同步名稱、包含測試案例的輸入資料夾、儲存結果的輸出路徑,以及一些附加參數,例如逾時時間,以避免陷入無限循環。

命令列也指定如何使用目標程式執行。 記分板@@AFL 會自動將其替換為它產生的每個測試案例的路徑。因此,您可以指定類似這樣的路徑: ./binary 參數 @@ AFL 將負責使用不同的文件啟動可執行檔數千次。

需要注意的是,AFL 最初可能會報錯,提示系統配置存在問題(例如資源限制、核心轉儲等)。在這種情況下,通常會有一個輔助腳本或工具來調整核心和會話參數,以優化模糊測試環境。在重複測試之前,應使用適當的權限來執行該腳本或工具。

使用 AFLTriage 和 GDB 進行碰撞分析

經過一段時間的模糊測試後,AFL 將逐漸在輸出資料夾中填充有趣的新條目,最重要的是,還有 導致崩潰的文件這些檔案通常儲存在特定的子目錄中(例如,崩潰檔案儲存在 session 資料夾中)。

為了避免逐一審查每個輸入內容而感到崩潰,可以使用像 AFLTriage 這樣的工具來做到這一點。 自動針對每個崩潰文件執行該二進位文件 並產生結構化報告,詳細說明故障發生的位置和方式。

啟動 AFLTriage 時,您需要指定輸入目錄(崩潰資料夾)、用於儲存報告的輸出目錄以及使用 @@ 執行二進位檔案的命令。該工具將分析每個案例並 它將產生包含相關資訊的文字檔案。 對於分析師而言。

這些報告的典型內容包括導致崩潰的訊號類型、失敗的方向、基本堆疊跟踪,以及在許多情況下,程式碼出錯的函數或巨集(例如,特定的複製操作、壓縮循環或每次迭代中減去大小的 COPY_CHUNKS 巨集)。

一旦找到一個有趣的崩潰,下一步就是在 GDB 中重現它。為此,需要啟動偵錯器,並將二進位檔案和導致崩潰的輸入檔案作為參數,然後在 GDB 內部執行程式。當崩潰重現後,需要記錄以下狀態: 關鍵記錄,例如 RAX、RDX 等。檢查正在執行的確切指令,並查閱記憶體映射(vmmap)以查看正在讀取或寫入哪個區域。

從崩潰到潛在利用:GDB 中的分析模組

看到某個二進位檔案崩潰並不總是意味著該漏洞可以被利用。這時,像該模組這樣的 GDB 擴充就派上用場了。 可利用的旨在分析崩潰的背景,並粗略地對故障是否可以被利用進行分類。

這類擴充程式會研究諸如指令指標的有效性、堆疊指標的狀態、讀寫嘗試所在位址的記憶體權限以及導致崩潰的訊號性質等各個面向。憑藉所有這些信息,它們可以提供… 對開發潛力的指示性結論 (例如,將漏洞分類為可能可利用、或許可利用或不太重要)。

  如何防止 Microsoft Teams 中的惡意鏈接

如果整數下溢最終寫入只讀內存,該插件可能會提示這是一個潛在的可利用漏洞,因為寫入操作在預期範圍之外執行,而該區域不應該被觸摸。

並非所有場景都如此簡單,但將 AFL 用於發現崩潰,AFLTriage 用於對案例進行分組和描述,以及帶有擴展功能的 GDB 用於評估可用性,這種組合構成了一種… 非常強大的二元審計管道之後的工作純粹是漏洞利用的研究和開發,其複雜程度會因二進位和主動保護措施的不同而有很大差異。

分析的另一個關鍵部分,尤其是在發布 CVE 編號和相關修補程式時,是審查漏洞在原始程式碼中的修復方式。這通常涉及 所用資料型態的變化 (例如,從有符號位元組到無符號位元組,擴大範圍)以及添加額外的檢查(如果超過某些限制則傳回錯誤代碼),以防止下溢或記憶體損壞。

生態系中其他相關的模糊測試工具和工具

儘管 AFL 和 AFL++ 是模糊測試原生二進位檔案最知名的選擇之一,但模糊測試生態系統遠比這廣泛得多,如果您經常使用原生二進位文件,就值得密切關注。 軟體安全.

最常用的選項之一是 LibFuzzer,這是一個最初由 Google 開發的庫,它可以直接與 C/C++ 程式碼整合並執行測試。 在特定功能層面進行模糊測試非常適合用高度可控的輸入測試各個組件。

此外還有 Peach Fuzzer,這是一個更通用、更可配置的平台,可讓您定義 協定、文件格式和複雜結構的精確模型它在可靠性至關重要的領域非常受歡迎,例如工業系統或物聯網環境。

在 Web 領域,OWASP ZAP 等工具包含專門針對 Web 應用程式的模糊測試模組,能夠發送 篡改請求、畸形加載和注入測試 HTTP 端點用於偵測 SQL 注入、輸入驗證問題或表單處理錯誤等漏洞。

所有這些都與 AFL/AFL++ 二進位模糊測試相輔相成,因為它能夠覆蓋從底層本地程式碼到最終用戶最直接接觸的應用層的所有層級。所有方法的共同目標都是一樣的:在攻擊者之前自動尋找漏洞。

如何將模糊測試整合到開發週期中

要讓模糊測試持續發揮真正的價值,光是偶爾執行一下 AFL 或 AFL++ 就置之不理是不夠的。這樣做效果好得多。 將模糊測試整合到軟體開發生命週期中類似於單元測試或整合測試的方式。

第一步是定義 系統中哪些部分最為關鍵文件解析器、網路模組、處理使用者資料的元件或對外暴露的服務。可以圍繞這些目標設計特定的模糊測試活動,並使用精心挑選的測試案例。

接下來,你需要根據具體情況選擇合適的工具。對於複雜的本機二進位文件,AFL++ 或 LibFuzzer 通常是理想的選擇;而對於 Web API 或 HTTP 應用程序,使用面向 Web 的工具則更為合適。關鍵在於模糊測試能夠正確執行。 可重複且可自動化.

與 CI/CD 系統的整合非常有用:可以配置管線,以便在某些分支或某些部署之前,啟動一個有限時間的模糊測試電池,保存發現的任何新崩潰,並在出現潛在的嚴重漏洞時使建置失敗。

最後,需要理解的是,模糊測試是一個迭代過程。每次修復一個 bug 後,都應該對受影響的元件再次進行模糊測試,以驗證補丁是否有效,以及是否引入了新的 bug。 沒有新的回歸或漏洞這樣一來,模糊測試就成為持續保護的額外一層,而不是孤立的審計。

綜上所述,以上所有內容表明 AFL、AFL++ 和模糊測試如何使我們能夠從僅基於人工審查的安全方法轉向更全面的方法。 更加自動化和徹底它能夠發現那些原本會被隱藏的錯誤。透過處理實際案例,例如常用解壓縮器中的下溢漏洞,也有助於理解這並非僅僅是理論,而是已被利用的問題。因此,保持軟體更新並定期進行模糊測試,是系統能否安全抵禦攻擊的關鍵所在。