winafl的使用及簡單樣例
前言
之前參加過學校老師的一個項目,大概就是對AFL原生版本進行的優化,但是最后項目可能達到的效果沒有什么技術和速率上的優化,一些所謂的速率上的提升約束性太強,很難作為漏洞挖掘實際所使用,更偏向於學術論文發布和相關比賽而生,再加上后來個人也學習過winafl,中間也有一些坎坷和曲折(全是坎),記錄下來幫助自己后續溫習也幫助別人排雷(比較適合萌新,不太適合一些深入學習的同學)
簡單介紹
接觸不多,僅代表個人觀點
個人感覺首先要明確Fuzz的局限性,Fuzz的本質理念其實就是存在一個讓程序無法執行的情況,而這個情況一般是非預期產生的,有時候存在錯誤分支,但是沒辦法Fuzz其實也就是Fuzz的局限性,比如你對某個網站進行Fuzz,但是它的報錯頁面和正常頁面一致沒有任何區別,因此就無法Fuzz(軟件同理)
因此需要明確就是AFL和Fuzz工具並非萬能,更多時候需要魔改或者自己進行二進制調試,而我之前項目中涉及到的更多的是白盒AFL-Fuzz,區別於黑盒,白盒其實很多漏洞更多是涉及到靜態分析工具,比如codesonar等工具,其實有時候會比AFL速率更快,Fuzz更多的優勢在黑盒(換句話說,白盒測試一些漏洞都被人看爛了,除非特別新的而且個人審計能力突出,否則很難從白盒找到漏洞)
所以后面更多的介紹是使用winafl黑盒測試的調試和Fuzz
DynamoRIO和WinAFL的環境配置
-
環境
- windows10
- Visual Studio 2019
- cmake 3.18.0-rc2
- git
- perl
- 網上配置多為win7+vs2013 多次嘗試搭建沒有成功,因此換為windows10 + vs2019
-
配置
-
git perl cmake等工具默認安裝即可 cmake需要安裝gui版本
-
編譯dynamorio源碼
- 編譯32位 dynamorio
32位dynamorio使用make命令行編譯會報錯,因此采用cmake-gui+vs2019模式
//創建fuzz文件夾,在文件夾內打開cmd git clone https://github.com/DynamoRIO/dynamorio.git cd dynamorio mkdir build32 && cd build32
打開cmake-gui進行編譯,設置對應的src和build目錄,configure設置當前的VS平台,我使用的是Visual Studio 16 2019
然后就一直configure,會一直報錯,隨便找一個對應版本的exe文件或dll文件就行,分別是ml.exe、mc.exe、uuid.lib、lib.exe,配置成功后configuring done
然后點擊generate即可生成解決方案DynamoRIO.sln
直接使用VS2019打開解決方案進行編譯,成功- 編譯64位 dynamorio
離譜的是64位cmake-gui會丟失文件,因此直接cmake命令行模式
//everything 找到 vcvarsall vcvarsall amd64_x86 切換到64位編譯環境 cd xxx mkdir build64 && cd build64 cmake -G"Visual Studio 16 2019" -A x64 .. cmake --build . --config RelWithDebInfo
即可正常編譯成功
- 編譯32位 dynamorio
-
編譯winafl
git clone--recursive https://github.com/googleprojectzero/winafl- 編譯32位 winafl
vcvarsall x86 //切換x86編譯環境 cd到winafl目錄 mkdir build32 && cd build32 cmake -G"Visual Studio 16 2019" -A Win32 .. -DDynamoRIO_DIR=C:\fuzz\dynamorio\build32\cmake //cmake的絕對路徑 cmake --build . --config Release
- 編譯64位 winafl
vcvarsall amd64_x86 cd到winafl目錄 mkdir build64 && cd build64 cmake -G"Visual Studio 16 2019" -A x64 .. -DDynamoRIO_DIR=C:\fuzz\dynamorio\build64\cmake //cmake的絕對路徑 cmake --build . --config Release
功能測試
- 動態插樁
drrun.exe在dynamorio/buildxx/binxx/目錄下,以test_gdiplus.exe為例
drrun.exe -c winafl.dll -debug -target_module test_gdiplus.exe -target_offset x -fuzz_iterations 10 -nargs 2 -- test_gdiplus.exe input.bmp
偏移地址X隨便用任意一個二進制調試工具就可以查看,最后會在執行目錄下生成一個log文件,可以看到一切都正常
-
winafl-fuzz功能
afl-fuzz.exe -i in -o out -D C:\fuzz\dynamorio\build32\bin32 -t 20000 -- -coverage_module gdiplus.dll -coverage_module WindowsCodecs.dll -fuzz_iterations 5000 -target_module test_gdiplus.exe -target_offset X -nargs 2 -- test_gdiplus.exe @@
正常進行
實戰測試
測試產品為某圖片庫,區別於正常的軟件Fuzz,對庫類進行Fuzz需要結合其官方使用文檔對其進行相關的學習,同時結合對應的函數進行Fuzz,也就是需要自己對harness進行構造
簡單介紹一下個人所接觸的幾種黑盒測試方法
-
正常fuzz
一般定位到對應的目標函數后直接fuzz,不做任何額外的處理,相對而言調試所消耗的時間較少,但是Fuzz速率較慢,產生新path和crash的時間間隔較長,一般為最差選項
-
構造harness
一般構造於其對應的IDA反匯編相對比較清晰,函數API調用比較明顯的情況,或用於DLL等具有較多說明文檔的情況,相對而言需要匯編能力較強
-
魔改程序
直接魔改,簡化部分不必要且沒有意義的流程
首先對此dll庫進行構造harness,得到對應的執行程序,我們構造的harness主要fuzz目標為fuzz函數
進行drrun動態插樁
C:\fuzz\dynamorio\build32\bin32\drrun.exe -c winafl.dll -debug -coverage_module xx.dll -target_module test1.exe -target_method fuzz -fuzz_iterations 10 -nargs 2 -- test1.exe C:\Users\Administrator\Desktop\input.bmp
存在一個問題,就是執行結束后會存在一個彈窗,兩種解決辦法,手動關閉或者魔改程序直接patch掉,選擇簡單的辦法,寫個while腳本把這個彈窗關閉
python調用一下cmin精簡一下輸入樣本
python C:\fuzz\winafl\winafl-cmin.py -i C:\Users\Administrator\Desktop\afl_testcases\ico\full\images -o C:\Users\Administrator\Desktop\afl_testcases\ico\test -t 20000 -D C:\fuzz\dynamorio\build32\bin32 -coverage_module xxx.dll -target_module test1.exe -target_method fuzz -nargs 2 -- test1.exe @@
進行fuzz跑一段時間
afl-fuzz.exe -i C:\Users\Administrator\Desktop\afl_testcases\ico\test -o imagegear\outforico -D C:\fuzz\dynamorio\build32\bin32 -t 20000 -- -coverage_module xxx.dll -target_module test1.exe -target_method fuzz -nargs 1 -- test1.exe @@
簡單分析一下觸發點
這里eax為我們輸入樣本中的可控值,但是ecx固定為0,也就是0x00000004,應該不可進一步利用,最后通過winafl我目前一共提交了8個cnvd,其中7個已過,1個還在驗證中
總結
無論是AFL還是其他漏洞挖掘工具,都不能離開它本身的功能去進行魔改,為了一些所謂的項目和科研而去"水"一些所謂的論文,希望以后自己能踏實學知識,踏實做事情