PTFuzzer是基於AFL框架實現的一款開源fuzz工具,它採用了Intel Processor Trace硬體部件來收集程序執行的路徑信息,改進了原來AFL通過編譯插樁方式獲取程序執行路徑信息的方法。和AFL相比,硬體收集的路徑信息更加豐富,同時可以直接對目標程序進行fuzz,無需源碼支持。
技術背景1.1 AFLFuzz(也叫模糊測試)是自動化挖掘軟體漏洞的一種有效方法。基於反饋的fuzz技術是目前學術界和工業界的研究熱點,而其中的代表就是AFL。但是AFL存在一個問題,即需要對被測試的程序進行編譯插樁後才能fuzz。這也意味著必須要有目標程序的原始碼,而且必須是C代碼才行。AFL的Qemu模式採用動態二進位翻譯的手段獲取反饋信息,但是這種基於模擬仿真的方法開銷太大(5倍以上的開銷很常見),基本上不實用。
1.2 Intel Processor TraceIntel Processor Trace(PT)是Intel在其第五代CPU之後引入的一個硬體部件。該硬體部件的作用是記錄程序執行中的分支信息,從而幫助構建程序運行過程中的控制流圖。在默認情況下CPU的PT部件是處於關閉狀態,這意味著CPU不會記錄程序的分支信息,因此也不會產生任何開銷。通過寫MSR寄存器可以打開PT開關。在打開PT開關後,CPU開始記錄分支指令信息,所記錄的信息以壓縮數據包的形式存儲在內存中。由於分支信息記錄完全由硬體完成,因此開銷非常小,一般在5%以下,這個開銷對於大多數應用來講基本上可以忽略不計。PT部件最初被設計用來重構程序的控制流圖,目的是為了幫助調試和分析。最早利用PT做fuzz的工具是kAFL,其結果發表在安全領域的四大頂級學術會議之一的USENIX Security上。但是kAFL是一個針對內核的fuzz工具,而PTFuzzer是針對應用程式的fuzz工具,這兩者的設計會有很多不同。
特點和限制2.1特點PTFuzzer最大的特點是不需要目標程序有源碼,這在很多方法是非常有用的。首先,對於很多閉源程序的測試很有優勢。例如,某公司對外公布了一個二進位程序的發行版。這時拿不到程序的原始碼用AFL就無法測試,而用PTFuzzer就可以。另外,即便是對於一些有源碼的程序,可能由於其編譯環境極為複雜,用AFL來進行編譯插樁變得非常繁瑣和耗時,有時也會出現不成功的情況。還有一種情況是對於那些非C語言編寫的二進位程序,AFL就無能為力了。例如自己在測試pandoc程序時,發現pandoc是用Haskell語言編寫的。這時用AFL就無法進行編譯插樁,而使用PTFuzzer進行測試,只需要簡單通過apt-get安裝一個pandoc可執行程序就OK了。
2.2 限制目前PTFuzzer只支持Linux作業系統,並且要求Linux內核的版本至少是4.13.0. 我們測試過Ubuntu16.04.4和Ubuntu17.10,都是沒有問題的。另外,因為使用了PT硬體部件,PTFuzzer要求5代以上的CPU。
使用方法3.1 從github上下載源碼git clone https://github.com/hunter-ht-2018/ptfuzzer.git
3.2 編譯安裝編譯之前先安裝依賴項,ptfuzzer依賴的程序和庫包括python,capstone,cle以及msr-tools。在源碼目錄下有個check_dep.sh腳本,可以直接運行安裝這些依賴項。Ptfuzzer採用CMake編譯:
cd ptfuzzer/mkdir buildcd buildcmake ../ -DPREFIX=.makemake install
以上命令會在build目錄下生成bin目錄,其中包括了運行ptfuzzer所需的所有程序。afl-ptfuzz:核心fuzz二進位程序ptfuzzer.py:對alf-ptfuzz的python封裝,主要用來處理參數,解析目標二進位程序。
3.3 運行在運行之前需要打開一些開關,這個和AFL是相同的,可以通過運行config-run.sh來實現。以測試pandoc程序為例,首先安裝
pandoc:apt install pandoc
然後準備一個docx的種子放入in_dir中,最後運行ptfuzzer開始測試:
sudo python ./bin/ptfuzzer.py "-i ./in_dir -o ./out_dir" "/usr/bin/pandoc -f docx -t html"
運行狀態如圖所示:
注意:運行ptfuzzer需要root權限。
3.4 參數配置ptfuzzer有一些運行時參數可以配置,這些參數包括:BRANCH_MODE,MEM_LIMIT,PERF_AUX_BUFFER_SIZE。
其中BRANCH_MODE是指分支收集模式,其值可以是TIP_MODE或者TNT_MODE。如果採用TIP_MODE,那麼ptfuzzer只解析PT收集到的TIP包(一般為非條件跳轉),如果採用TNT_MODE,則不但解析TIP包,而且解析TNT包(條件跳轉)。TNT_MODE更加精確,開銷也較大一些。默認情況下ptfuzzer採用TNT_MODE。
MEM_LIMIT是只目標測試程序的最大內存限制,單位為MB。這個相當於AFL的-m參數。如果目標程序由於使用了太大的內存而不能運行,需要考慮增大MEM_LIMIT的設置。
PERF_AUX_BUFFER_SIZE是指存儲PT數據包的緩存大小,單位為MB。如果目標程序一次運行時間太長,可能會產生特別多的分支跳轉信息,導致緩存不夠,這時可以考慮增大PERF_AUX_BUFFER_SIZE的設置。在當前運行目錄
下編輯一個ptfuzzer.conf的文件可以配置這些參數,參考形式為:
#BRANCH_MODE=TNT_MODEBRANCH_MODE=TIP_MODEMEM_LIMIT=100 # afl -m argumentPERF_AUX_BUFFER_SIZE=32 # the size of buffer used to store PT packets.
總結PTFuzzer採用Intel CPU最新的PT部件來收集分支信息,解決了AFL需要源碼支持的問題,能夠方面的挖掘Linux中的二進位程序漏洞。
*本文作者:hunterx,轉載請註明來自FreeBuf.COM