AFL--模糊測試使用淺析

 一、AFL簡介

  AFLAmerican Fuzzy Lop)是由安全研究員Micha Zalewski 開發的一款基於覆蓋引導(Coverage-guided)的模糊測試工具,它通過記錄輸入樣本的代碼覆蓋率,從而調整輸入樣本以提高覆蓋率,增加發現漏洞的概率。

從源碼編譯程序時進行插樁,以記錄代碼覆蓋率(Code Coverage);
選擇一些輸入文件,作爲初始測試集加入輸入隊列(queue);
將隊列中的文件按一定的策略進行突變
如果經過變異文件更新了覆蓋範圍,則將其保留添加到隊列中;
上述過程會一直循環進行,期間觸發了crash的文件會被記錄下來。

AFL--模糊測試使用淺析356.png

 二、AFL安裝、測試

 1.安裝AFL

 下載源碼

AFL--模糊測試使用淺析382.png

 Make

AFL--模糊測試使用淺析389.png

 llvm_mode安裝

AFL--模糊測試使用淺析403.png

 之後輸入以下命令進行安裝

AFL--模糊測試使用淺析418.png

 2.AFL測試

 下載一個有缺陷的c文件

AFL--模糊測試使用淺析440.png

 使用 afl-gcc/afl-clang 編譯

AFL--模糊測試使用淺析466.png

 生成一些種子語料庫

AFL--模糊測試使用淺析478.png

 開始fuzz

AFL--模糊測試使用淺析487.png

 提示修改/proc/sys/kernel/core_pattern

AFL--模糊測試使用淺析523.png

 再次運行之前的代碼可看到fuzz進度

AFL--模糊測試使用淺析544.png

 現在就表示我們的ACL已經安裝成功了,注意出現(odd,check syntax!)是表示樣例根本沒有進入到測試中去,需要調整語料庫。

 Ctrl+C打斷可以在out文件裏看見我們的測試信息

AFL--模糊測試使用淺析641.png

 3.並行fuzz測試

 每個afl-fuzz進程佔用CPU的一個核,實際上如果是多核的主機,AFL就可以並行工作

 首先先看自己有多少內核

AFL--模糊測試使用淺析711.png

 以上可以看出有四個內核意味着可以同時運行4個實例

 首先指定主實例   -M 用於主實例,將 -S 添加到所有從屬實例。它們可以相互同步

 主實例:afl-fuzz -M master -i in/ -o out/ -m none -- ./imgRead_afl @@

 從實例:afl-fuzz -S slave1 -i in/ -o out/ -m none -- ./imgRead_afl @@

AFL--模糊測試使用淺析913.png

 在之前的out文件夾會多出倆個不同的文件夾masterhslave1

 現在嘗試假如我們一次性運行5個實例會怎麼樣

 在運行第5個實例後報錯,其他實例不受影響,也可以確定4個核在運行中

AFL--模糊測試使用淺析1007.png

 三、AFL模糊測試libjpeg-turbo

 libjpeg是專門處理Jpeg解碼、編碼、轉碼的自由軟件庫。libjpeg-turbo是其fork版本,還有一個基於libjpeg-turbo的fork的版本是MozJpeg。

 1.編譯libjpeg-turbo

 首先下載libjpeg-turbo

 之後需要修改cmakelist.txt,進行插樁編譯

 在cmakelist.txt中,在cmake_minimum_required命令下添加編譯器選項,在前面添加,免得被覆蓋,進行插樁編譯

AFL--模糊測試使用淺析1254.png

 之後在libjpeg-turbo文件夾下

 mkdir build

 cd build

 cmake ..

 make

 sudo make install

AFL--模糊測試使用淺析1331.png

   AFL--模糊測試使用淺析1336.png

 安裝好之後build的內容如下

AFL--模糊測試使用淺析1354.png

 之後利用程序的示例對是否成功安裝libjpeg-turbo庫進行測試

AFL--模糊測試使用淺析1391.png

 該函數有倆個參數  一個輸入文件名,一個作爲輸出文件名

 具體作用就是調用了turbojpeg.h這個庫函數對輸入的jpg圖片進行壓縮

 因爲修改了cmake中的編譯器設置,應該庫函數裏已經是被插過樁的,所以在編譯時是可以不用afl-gcc編譯也可以進行檢測

AFL--模糊測試使用淺析1521.png

 這樣是可以生成可執行文件,也可以實現壓縮圖片的功能,這裏也對之前的樣例進行了修改,只接收一個變量,並且不對壓縮文件進行保存

AFL--模糊測試使用淺析1585.png

 但在進行模糊測試時出現以下問題

AFL--模糊測試使用淺析1603.png

 沒有插樁信息,無法進行測試

 發現它是動態編譯的,雖然應該其動態鏈接庫是插過樁的。但最後已知沒有實現。這裏最後考慮是想通過鏈接靜態庫實現。也是在網上查詢未果後,發現在根目錄下輸入  make test,可以調用他自己的樣例進行測試,這其中就包括了靜態鏈接的測試

 在一個靜態鏈接測試的項目下,查看其ling.txt,得到靜態編譯的方式

AFL--模糊測試使用淺析1771.png

 最後對自己的編譯自己的樣例

AFL--模糊測試使用淺析1787.png

 之後開始模糊測試

AFL--模糊測試使用淺析1798.png

 總共測試次數超過1億次,開了4個並行

AFL--模糊測試使用淺析1819.png

AFL--模糊測試使用淺析1821.png

AFL--模糊測試使用淺析1823.png

AFL--模糊測試使用淺析1825.png

 4個樣例的的最開始輸入都是不一樣的,可以從路徑速度和總量上看出明顯的區別,確實libjpeg-turbo在更新2.0之後,其安全性能得到了極大的提升,沒有收到一個報錯信息。

 2.內存錯誤檢查工具

 這裏有很多的內存檢查工具,這裏舉個大概,只大概研究ASAN (-fsanitize=address)的使用和與AFL測試的結合

 這裏測試了幾個漏洞文件以此來明晰ASAN的作用

 編譯文件模板如下

 g++ -fsanitize=address -fno-omit-frame-pointer -o t xxx.cpp

 這裏只對幾種漏洞進行展示

 use-after-fee

    AFL--模糊測試使用淺析2113.png

   AFL--模糊測試使用淺析2118.png

 可以看到漏洞的名稱和發生的內存地址

 stack buffer overflow

AFL--模糊測試使用淺析2160.png

AFL--模糊測試使用淺析2162.png

 還有很多其他類型的漏洞可以進行檢測

 Address Sanitizer 用法 - 簡書 (jianshu.com)

 在AFL中啓用ASAN的方式也比較簡單

 在make時加上AFL_USE_ASAN=1

AFL--模糊測試使用淺析2320.png

 注意之後編譯文件時需要加上啓用asan的參數,不然會報錯

AFL--模糊測試使用淺析2351.png

 3.構造自己的字典

 AFL自帶自己的一個字典庫,主要用於各種變異操作的

 如下是AFL的jpeg的字典

AFL--模糊測試使用淺析2404.png

 爲了符合jpeg圖片的實際,需要分析在jpeg中出現次數多且固定的字符

 這裏挑選一些頻率較高的字符加入字典

AFL--模糊測試使用淺析2460.png

 這裏挑選的字符主要來源自各種jpeg的開頭部分

 之後如果要使用字典需要使用-x參數進行指定字典文件

AFL--模糊測試使用淺析2512.png

 https://paper.seebug.org/496/#dictionary

 4.語料庫蒸餾

 afl-cmin的核心思想是:嘗試找到與語料庫全集具有相同覆蓋範圍的最小子集。 舉個例子,假設有多個文件,都覆蓋了相同的代碼,那麼就丟掉多餘的文件。

AFL--模糊測試使用淺析2695.png

 最後只留下一個文件

 afl-tmin(減小單個輸入文件的大小)

 afl-tmin有兩種工作模式,

 instrumented modecrash mode。默認的工作方式是instrumented mode

AFL--模糊測試使用淺析2801.png

 後面查資料得到tmin只能處理文件,文件夾需要修改腳本

AFL--模糊測試使用淺析2831.png

 精簡到0bytes,後面在網上看到了相似的例子,這和tmin的精簡策略有關,確實存在這種情況。

 如加上了參數-x,就會調用crash mode模式,會把導致程序非正常退出的文件直接剔除。這裏測試的樣例並沒有crash例子,所以不進行測試。

 5.持久模式

 在持久模式下,AFL 僅模糊部分程序,而不是整個程序。只想模糊複雜軟件中的特定功能時,這很有用。與分叉服務器模式相比,這提供了許多速度改進。

 具體例子如下:

AFL--模糊測試使用淺析3041.png

 對想要進行的部分進行修改

AFL--模糊測試使用淺析3056.png

 此時修改的文件是turbojpeg.c

 再修改cmakelist.txt如下

AFL--模糊測試使用淺析3097.png

 之後對庫進行重新編譯

AFL--模糊測試使用淺析3110.png

 編譯方式

AFL--模糊測試使用淺析3117.png

 再進行afl-fuzz(與之前一致)

AFL--模糊測試使用淺析3138.png

 速度上確實比之前的速度要快,最快時比之前要快上倆倍多

 6.Afl-cov使用

 可以快速幫助我們調用lcovgcov處理來自afl-fuzz測試用例的代碼覆蓋率結果

 安裝

 GCOV,它隨gcc一起發佈,所以不需要再單獨安裝,和afl-gcc插樁編譯的原理一樣,gcc編譯時生成插樁的程序,用於在執行時生成代碼覆蓋率信息

 LCOV,它是GCOV的圖形前端,可以收集多個源文件的gcov數據,並創建包含使用覆蓋率信息註釋的源代碼HTML頁面。

AFL--模糊測試使用淺析3360.png

 這裏也可以使用apt-install afl-cov來安裝,不過看網上建議這個版本實際使用上會有問題,所以這裏還是直接下載源碼

AFL--模糊測試使用淺析3426.png

 爲了實現檢查覆蓋率需要修改cmakelist.txt如下

AFL--模糊測試使用淺析3457.png

 再次編譯庫

 編譯文件

AFL--模糊測試使用淺析3470.png

 這裏的afl-cov選擇實時監控 也就是添加--live,先啓動afl-cov,後啓動afl-fuzz,當afl-fuzz退出時,afl-cov就會跟着退出

 啓動afl-cov的命令

 /home/user/Desktop/afl-cov/afl-cov -d afl-cc --live --enable-branch-coverage -c . -e "cat AFL_FILE | ./ttt AFL_FILE" --overwrite

AFL--模糊測試使用淺析3693.png

 -d是之後afl-fuzz的輸出文件,-c是直向源碼文件的,在編譯.c文件後,會生成一個.gno文件,-c 後面跟該文件的目錄

 啓動afl-fuzz(與之前一致)

AFL--模糊測試使用淺析3777.png

 Afl-fuzz退出後,afl-cov需要等一會才能正常退出,此時就可以看見生成分析的網頁了

AFL--模糊測試使用淺析3826.png

 也可以針對已經生成的數據直接開啓afl-cov,但要求編譯已經加上了-fprofile-arcs -ftest-coverage

 

 網頁首頁

AFL--模糊測試使用淺析3899.png

 也可以進入到文件裏,查看具體語句的執行次數

AFL--模糊測試使用淺析3923.pngAFL--模糊測試使用淺析3925.png

 7.afl_postprocess使用

 它最主要的作用就是可以規定生成種子的格式

AFL--模糊測試使用淺析3968.png

 作者在github上的樣例的作用是讓每個測試用例開頭的標頭都是GIF89a

 https://github.com/mirrorer/afl/blob/master/experimental/post_library/post_library.so.c

 編譯方法

 gcc -shared -wall -O3 post_library.so.c -o post_library.so

 可以看看afl-fuzz.c對該方法的支持

AFL--模糊測試使用淺析4286.png

 獲取AFL_POST_LIBRARY環境變量的值,自動加載afl_postprocess函數

 這裏推薦使用export設定環境變量,需要說明的是export的環境變量只在當前的shell(BASH)或其子shell(BASH)下是有效的,shell關閉了,變量也就失效了,再打開新shell時就沒有這個變量,需要使用的話還需要重新定義。如果需要一直使用,需要修改配置文件方法推薦

 https://blog.csdn.net/wx_it/article/details/118450790

AFL--模糊測試使用淺析4533.png

 加載後處理器庫成功

AFL--模糊測試使用淺析4545.png

 也可以看到我們的測試樣例變成了GIF格式,後處理庫有效。

 測試其他的例子

AFL--模糊測試使用淺析4584.png

AFL--模糊測試使用淺析4586.png

 這部分需要注意的是對源碼的處理,確保樣例格式的滿足輸入的要求

 

 實驗推薦

 實驗:Fuzz之AFL(合天網安實驗室) 點擊進入實操>>

 更多靶場實驗練習、網安學習資料,請點擊這裏>>

 

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章