作者:SungLin@知道創宇404實驗室
時間:2021年6月25日

概述

為啥叫傻瓜式fuzzing呢,可能我覺得吧,一步一步從最初始的部分去探索和研究將會很好玩,不過有時候也會很難(遇到問題的時候),但是解決每一個問題都會有小小的成就感,繼續激勵前行,堅持下去總會有收獲的,我會把我對fuzzing的探索與研究做成一系列的paper,希望大家同樣覺得很好玩,have fun。

0x00 探索與學習

在2020年的年終時候,我在知乎上對2020年的開源fuzzing做了一些總結與些許研究,一個開源的研究與項目叫FormatFuzzer[1],這個項目的出現,讓我想起了aflsmart[2]的開源fuzzing項目,兩者都是類似的文本結構fuzzing,和aflsmart不同的是FormatFuzzer項目還處于開發階段,通過我對aflsmart fuzzing項目的熟悉(我用aflsmart挖了不少漏洞),我決定以Formartfuzzer為契機來做一些有意思的事情,可能我覺得有意思就行,hhhhh

0x01 Formartfuzzer

Formartfuzzer fuzzing我就不做過多介紹了,簡單的來說,它就是以010 Editor眾多結構模板為基礎來生成與構造所需的各種結構數據,再通過對數據做一些變異算法來生成最終的畸形數據,Formartfuzzer 現在支持結構有:avi、bmp、gif、jpg、midi、mp3、mp4、pcap、png、wav、zip等,作者們還在繼續編寫中,既然010 Editor支持上百種結構,而這里只有10多個呢,因為010 Editor只是一個做了解析的軟件,而Formartfuzzer 不僅做了解析,而且通過模板結構生成了可用的相關結構數據,所以沒法直接使用010 Editor的模板,還需要做很多工作,再熟悉了Formartfuzzer 后,我決定自己修改一種模板結構,我將目標定為了ttf結構,這是一種字體結構,可以說字體結構也是相當復雜了,并且選擇字體也和我最近的工作有些許聯系。

0x02 ttf結構模板的修改與定義

ttf結構的描述可以參考蘋果或者微軟的鏈接,這里我們參考蘋果的鏈接[3],ttf結構主要是以眾多的table表構成,每個table表直接有相關的聯系,所有的table表加起來有大概40多個,在蘋果字體的描述中,以下的幾個table表是必須構成字體的9個table表:

也就是說,想要生成一個可以被正常解析的字體,至少得定義以上9個table表,在010 Editor中,原始的ttf.bt大概解析了以下幾個表:

生成字體必須的9個table表已經有了,但是像以上的定義是不能用的,經過我的簡單研究tff的結構其實和png的結構框架是非常相似的,和png的chunk對應的是tff的table,少許不一樣的是tff有個定義了所用到的table的頭部,而這個頭部包含了Tag、offset、length等關鍵結構,我將會簡單介紹幾個重要的table表和修改。

第一步,我將會隨機生成table表,而這些table表將會包含9個重要的table表,通過其定義ReadBytes api能實現:

第二步,隨機生成table表后將會獲取到table表的數量和具體的table,這樣就可以去生成具體的table格式,獲取實際的offset、length了,其中IO操作主要有FTell()和FSeek,這樣就可以隨時定位到指定位置修改數值了:

第三步,定義maxp、loca、glyf:

maxp的定義很簡單,基本沒變

定義好maxp后,就可以獲取到maxp.numGlyphs的個數了

有了Glyph的個數后,就可以定義loca表了,而loca表包含了每個Glyph的偏移offset

最后就可以定義glyf表了,tglyf結構體主要由tSimpleGlyph結構體構成,tSimpleGlyph結構體包含了tSimpleGlyphFlags和tSimpleGlyphPoints,在這里主要注意的是offset和length的計算,并且最后一定要把IO流定位到數據末尾

這里每次獲取到tSimpleGlyph的長度后,得重新定位到loca表設置正確的offset,這樣才能生成能夠被解析的結構

之后定義好tSimpleGlyphFlags和tSimpleGlyphPoints就行了。

0x03 生成字體

上一節簡單介紹了table表的定義與字體的一些結構組成,通過正確定義好了必須的9個tabel表和其他特殊的table表后,通過項目自帶的ffcompile將定義好的bt模板生成cpp文件,一般情況會有很多錯誤,直到調試到正確為止,我自己修改好的ttf模板可以生成正確的字體了,編譯的命令如下:

1、生成ttf.cpp

./ffcompile templates/ttf.bt ttf.cpp

2、生成.o文件

g -c -I . -std=c17 -g -O3 -Wall tff.cpp

這里介紹生成器fuzzer.cpp主要調用了generate_file()

生成的ttf.cpp中,generate_file翻譯了bt中我定義的結構主體,而這些api都可以找到,所以后面可以去優化和擴展自己的功能等。

3、編譯fuzzer.cpp

g -c -I . -std=c17 -g -O3 -Wall fuzzer.cpp

4、最后鏈接ttf和fuzzer生成ttf-fuzzer:

g++ -O3 ttf.o fuzzer.o -o ttf-fuzzer -lz

最后通過ttf-fuzzer生成字體,在macos中,打開是這樣的:

好了,字體生成成功。

0x04 開啟fuzzing

既然字體生成成功了,那就開始試水了噻,我打算直接fuzz macos自帶的字體冊/System/Applications/Font Book.app/Contents/MacOS/Font Book,我寫了個簡單的啟動shell:

通過這個shell能直接打開生成的字體。。。。

但是這樣沒法檢測crash,還不算fuzzing。

稍加修改后,我弄了個簡單的代碼如下:

這樣就可以檢測到crash了,雖然很簡單哈哈

之后重新修改shell腳本,修改后如下:

好了,雖然很簡單,但是可以跑起來了。

0x05 傻瓜fuzzing系列一

經過了200000次fuzzing,大概花了12個小時還要多,雖然沒仔細統計,結果如下:

哈哈哈,牛逼哇,就這都能搞崩。

這次的fuzzing系列就到這了哈,后面我會慢慢分享我的fuzzing研究與探索,盡請期待傻瓜fuzzing系列。

0x06 參考鏈接

1、https://uds-se.github.io/FormatFuzzer/

2、https://github.com/aflsmart/aflsmart

3、https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6.html


Paper 本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/1615/