压在透明的玻璃上c-国产精品国产一级A片精品免费-国产精品视频网-成人黄网站18秘 免费看|www.tcsft.com

張超:漏洞挖掘的藝術

摘要:模糊測試是近年來最流行的漏洞挖掘方法。研究人員也提出了眾多的改進方案,極大提高了自動化漏洞挖掘的效率。本文中將介紹模糊測試面臨的挑戰(zhàn),當前最前沿的研究進展,以及演講人團隊提出的解決方案。

張超

張超????清華大學副教授

今天的題目是“漏洞挖掘”。我本科和博士是在北大畢業(yè),博士后畢業(yè)在伯克利工作三年,2016年底回到清華,我研究的方向是軟件系統(tǒng)安全的方向,做了很多攻防相關事情,包括CGC做了自動化攻防,參加過微軟的防御競賽blueHat獲得了特別評委獎,隨著這個方案演化之后,變成了剛才宋凱講到的CFG那個防范和實驗部署,還有Defcon也參加過,當時藍蓮花的成員,獲得2016年第二名的成績。

我們藍蓮花隊首先是清華的學生發(fā)起的,2013年第一次打入Defcon CGC半決賽,這是大陸第一次。2016年拿到第二名,是目前國內排到最優(yōu)成績的。右邊列了過去五年Defcon的名次,第一名絕大部分都是PPP,是美國CNU大學帶隊;2015年第一名是韓國戰(zhàn)隊,因為當年出了一個很神奇的小伙子,很厲害,大家可以去了解一下。

CGC是我們做的最有意思的系統(tǒng),也是目前正在研究推進的事情,做的是自動化攻防,剛才大家聽到凱講到,真的要找到漏洞,利用漏洞這么一長串的事情,非常復雜。即使你很有經(jīng)驗,做這個事情也要花很長的時間,這個比賽是三天的時間,題目相對要簡單很多,一般大家花半天或一天的時間才能解出一道題,非常困難。真實的軟件難度更大。CGC是美國國防部DARPA發(fā)起的一個項目,兩年的時間花了5000萬美元做這個事情,最終設計自動化攻防系統(tǒng),有點像AlphaGo一樣,它的任務不是下圍棋,而是做黑客的事情,攻擊防御的事情。當時我?guī)ьI隊伍參加這個比賽,資格賽的時候我們是行域(音)第一名,決賽時是防攻擊一等獎(音)。我的研究是與CDC主題非常相關的。

今天我們的主題是漏洞挖掘,一個簡單的故事是WannaCry,大家都知道。

WannaCry背后是因為美國NASA的合作承包商被攻擊了,它的網(wǎng)絡軍火庫被偷出來了,其中包括攻擊武器,WannaCry就把這個攻擊武器做了包裝,寫了一個勒索軟件。這個泄漏的網(wǎng)絡軍火庫里有攻擊工具,這個攻擊工具是因為有漏洞,大家知道SMB的漏洞,攻擊工具可以利用這個漏洞發(fā)起攻擊。微軟在真正WannaCry爆發(fā)之前,3月份已經(jīng)發(fā)布補丁,WannaCry是5月份爆發(fā)的,如果大家打過微軟的補丁,WannaCry就沒有事。

從科普角度看一下漏洞的模式,為什么漏洞很重要。從系統(tǒng)角度來看,用戶的數(shù)據(jù)或計算機理比較重要的是數(shù)據(jù),還有比較重要的事情是計算機上的控制權,在上面有運行代碼,可以用在系統(tǒng)里。大家可以想想,攻擊者在外面怎么攻擊你的系統(tǒng)。我認為主要是兩個攻擊鏈,一是軟件,你這個系統(tǒng)怎么著都得需要軟件與外界進行交互;二是人,這兩方面都很容易被突破,軟件方面可能存在漏洞,人這邊可能存在社交工程,比如釣魚網(wǎng)站、欺詐,它以心理學相關的東西,欺騙人去下載一個惡意程序來安裝的方式。通過這兩種渠道之后,它最后進入到你的系統(tǒng),一般形式是運行惡意代碼,大家推說過病毒、蠕蟲這些東西。我們這次通過軟件漏洞進入系統(tǒng)方式,關注的是軟件漏洞。軟件漏洞,具體我們關注很常見一類的內存漏洞,包括緩沖區(qū),除了Use-after-free等等漏洞,剛才宋凱也介紹了一個漏洞就是這個類型。這些漏洞是大家聽過很多安全故事的根源。像蘋果iOS越獄,Android的root,甚至包括伊朗核設施、震網(wǎng)病毒、心臟滴血Heart dripping等等,背后其實都是有著漏洞的。這些網(wǎng)絡漏洞危害那么大,攻擊當然也想挖洞,必須有漏洞能力攻擊。防御方也是在考慮怎么挖漏洞,把漏洞挖出來,我可以把漏洞修掉,讓攻擊者沒辦法沖擊。

怎么去挖漏洞?主要方式是兩大類,第一是帶上手機,人看源碼或逆向工程,很多黑客很擅長做這個事兒,逆向做安全程序或審這個源代碼,前段時間,360報的EOS的虛擬機漏洞,其實是人工審計中發(fā)現(xiàn)的。自動化方面,學術界提出了很多方法,包括程序分析里的靜態(tài)分析和動態(tài)分析,污點分析,符號執(zhí)行,我想重點說的最主要的是Fuzzing測試技術。當然,非公開數(shù)據(jù)說有80%以上可能都是用Fuzz技術來發(fā)現(xiàn)的,我重點介紹一下Fuzz怎么做漏洞挖掘。

Fuzz的基本想法很簡單,就是給程序做測試,給程序進行大量輸入,讓程序運行,運行過程中程序出現(xiàn)了問題,比如程序崩潰了,那就是有漏洞。更聰明一點,在運行過程中監(jiān)控這個程序,把監(jiān)控的結果反饋給前面,前面再負責新的輸入,這是基本的流程,非常簡單的流程,和程序測試很像。這樣的邏輯它都能實現(xiàn),但我們簡單實現(xiàn)一個東西效果很差,最關鍵的是我們怎么樣有效生成這個輸入,很快找到輸入的觸發(fā)漏洞,如果完全沒有辦法,隨機的話,就比買彩票還難,因為輸入空間太大了。所以,研究熱點的時候我們怎么生成這個輸入。

主要分類有兩種,第一種是基于生成的,它的想法是,我們知道這個輸入會長什么樣,知道它的格式,知道它的word文檔,是個word格式,我們生成的時候基于這個格式生成就好了。它要求我們比較知道輸入的格式和規(guī)范,這不是所有情況下都有,有的并不知道它的輸入長成這樣。第二種是更通用的基于變異的,我們不需要教它語法,你給我的輸入,我在輸入上隨便變異一下,像自然界中的變異,輸入新的再測試就好了。基于生成有很多工作可以做,PEACH這是個開元的工具,它可以自己來定義,你告訴它輸入什么樣的格式,它會有文件指定這個格式。工具自動基于這個格式幫你做輸入生成。除了數(shù)據(jù)格式之外,PEACH還提供程序內部處理輸入,可以想象是很難的,要給程序做狀態(tài)建模,相當于把程序寫一遍,本身就是很復雜的事情。這個東西還是挺有效的,但工程量非常大,我也得告訴它輸入規(guī)范,數(shù)據(jù)的規(guī)范和程序內部的狀態(tài),可能有不少工業(yè)界的人在用這個東西。基于變異,給我一個數(shù)據(jù),隨便從原來的輸入這兒隨便找一些自己進行編譯,就得到新的樣本。這是變異的第三個特點,三個樣本。

這兩個方案的對比,基于變異這種,它很容易設置,不需要知道這個輸入應該采用什么格式,它的缺陷是,因為它不知道格式,格式進而是錯的,錯誤的格式輸入扔進去之后,程序給他拒絕了,導致代碼測試的時候測試覆蓋率比較低。還會遇到特殊的像校驗格檢查,MagicNubmer檢查等等,如果你這個不對,程序也不幫他走,他測試的時候,后面代碼測不到,會有這樣的情況。反過來,基于生成類的話,它的特點是相反的。

在實踐中,有很多種方案,除了這兩種分類,還分黑盒、白盒、灰盒的,所謂白盒一般是指源碼的;黑盒是什么都沒有,只是搭個黑盒來測;介于兩者之間的灰盒,意思是你可以在這個程序執(zhí)行過程中獲取一定程序的信息,灰盒應該說現(xiàn)在很常見,大家用的很多,我們重點介紹這一類。

實踐中,如果人工去做Grammar based,要輸入文檔,可以做這個事情。通常我們沒有這種,一般會采用基于編譯的方法更好,它的擴展性更好。但它的局限在于coverage,它的覆蓋率比較低,因為它沒有格式信息,所以導致覆蓋率比較低。為什么大家會關心覆蓋率呢?漏洞,代碼如果沒覆蓋的話,一定存在漏洞,肯定沒法觸發(fā)。在一定程度上,如果覆蓋率不夠的話,找到漏洞就更少,大家盡量提高自己的覆蓋率,不同F(xiàn)uzz都會嘗試做覆蓋率的提升。

怎么做覆蓋率提升呢?有一類方法是基于覆蓋率導向的Fuzz,代碼是AFL。AFL是個開源的工具,是Google開發(fā)人員提供的。他的想法還比較聰明,類似跟雜交水稻一樣進化的想法,雜交水稻目標是要找好的水稻種子,有比較高的產(chǎn)量。現(xiàn)在怎么做呢?他們會不斷地培育新的種子,一輪一輪地培育,有好有壞,會把好的種子留下來,好的種子再進行下一輪種子雜交,會生成下一批種子,再選出好的種子進行雜交,這樣的方式不斷迭代,進化的想法,一代會比一代好,最終挑選出比較好的種子。在這里,AFL用了類似的想法,他找了一些種子觸發(fā)漏洞或提高代碼覆蓋率,這是它的目標。它的做法也是一樣的,其實中間的大循環(huán)也是一輪一輪的測試,它會把好的種子留下來,進入下一輪測試,會把這個好的種子進行編譯,然后再測試,把好的留下來,這樣一輪輪下來,最后達到比較好的效果。

什么是它的好種子?定義的標準是,如果這個種子對覆蓋率的貢獻,早期的代碼別人沒走過的代碼,你的種子就是好的,就留下來了。就這么一個想法,讓這個東西不斷走下去,自然而然地最終達到測試的效果,它的覆蓋率會比較好。AFL這個方案是基于編譯的,可擴展性比較好,不需要太多的先驗知識,它的測試速度非常快,基本和原始程序執(zhí)行沒有太多差別,原來程序能測多快它就能測多快。而且它可以支持并行化測試。另外一個特點,它比較敏感,與其他工具結合起來,可以捕獲很多類型的漏洞,而不是簡單地依賴Crash崩潰,有些漏洞觸發(fā)時并不會崩潰,如果不會捕獲這種漏洞你會漏掉這個漏洞。這幾個特點導致AFL效果非常好,大家用的非常多,學術界也對它進行了很多擴展。

對它感興趣的,首先會想我怎么選它初始種子?初始種子挺重要的,因為初始種子選得好,F(xiàn)uzz測試會非常快,能達到比較好的出事狀態(tài),底下會走出很多代碼。而且初始種子可以在不同的被測試程序之間進行共享,測一個PDF軟件有一批種子,這批種子可以在下一個PDF軟件里重用,效果非常好。怎么去找這種初始種子呢?我們程序里會自帶benchmark,benchmark通常用于測功能的,它會有大量訓練代碼會輔到,所以,benchmark是比較好的輸入live。沒有benchmark的時候,我們會從網(wǎng)絡上爬的樣本里篩選,學術界里也有一些研究,2017年南洋理工的李奧(音)他們做的一篇文章,去年微軟做的用RNN學習的想法,這兩個工作核心的想法,是從大量已知樣本里學出一種模式,比較符合有效輸入格式,基于這個模式再生產(chǎn)新的種子。

對AFL第二塊感興趣的在于它的選種,剛才這個循環(huán)里,它每輪迭代其實是說,它會把上一輪留下來好的種子選一部分出來再進行變異雜交操作。怎么操作?上一輪留下來的可能不是一個種子,而是一百個種子,這一百個種子到底先選誰出來變異,這塊學問研究非常多。先選為什么重要?如果選得好的話,展開100個種子,如果第一輪選第一個,第二輪選第二個,第一百輪選第一百個。選得特別好的話,第一輪你就把這個漏洞給觸發(fā),選得不好的話,等到第100個人才會觸發(fā)這個漏洞,差別非常大。所以,選種子順序是非常關鍵的。學術界在這塊做了很多研究,包括2016年的CCS,這里列的都是頂級會議地,就是安全圈或者軟件圈里的頂級漏洞。2016年CCS漏洞的想法是,怎么選這個漏洞,他會考慮這個種子被選出來過多少次,因為每個人會選出一個種子,他會評估100個種子哪個種子被選出多少次,有的種子選擇了1萬次,有的只選擇了1次,這時候他會優(yōu)先選被選的少的種子,背后的原理是,要給每個種子均等的機會,你選出來1萬次的那個種子已經(jīng)被充分測試過了,沒有什么剩余價值了。

AFLgo 2017年CCS方案,這是一個比較特殊的方案,它不是針對覆蓋率的,是針對另外一個時間,是定向化的。我們程序員寫代碼每次會提交commit,我們可能關心提到的這個commit里會不會有問題,他會說我用Fuzz測試新提出來的代碼,按目標定向測試對象,他的目標是像原來Fuzz一樣最終是要探索指定的代碼行的東西。他的想法是,也是改種子選擇策略,選種子的時候會考慮,這個種子離目標有多遠,近的話如何選擇,這樣可以迭代,比較快地找到這些輸入,觸發(fā)目標的路徑。

選完種子之后下一步進行變異,到測試地來測試。怎么編譯,給你一個輸入,你對這些輸入進行改動,改動成什么內容?現(xiàn)在研究也包括Vuzzer的,Vuzzer這個工作是NDSS發(fā)表的,它其實核心解決兩個問題,對什么地方進行編譯,以及用什么值,他用數(shù)據(jù)模分析,分析這個程序輸入怎么影響這個程序的運行。對哪些字節(jié)變異,他會考慮輸入如果影響到某一個判斷語句,輸入的這幾個字節(jié)就是他需要變異的地方。變異采用什么值呢?就是magic number,因為你經(jīng)常會檢查,IF某些字節(jié)等于magic number,這個magic number就是它要變異的值。最近,學者有提出來QEI(音)、RNN、GAN強化學習的方法來輔助指導Fuzz怎么進行編譯,大家感興趣可以去查這個paper。編譯完之后要進行測試,核心問題是怎么讓它測得更快。CCS有個工作室是做并行化測試,AFL本身是有并行化模式,但它的并行化模式效率比較低,達不到線性速率,CPU數(shù)量加上去之后沒有效果,所以,CCS把這個并行化基本讓它做線性,很好地提高了。在測試過程中,還有很關鍵的問題,怎么跟蹤測試中出現(xiàn)的安全漏洞。

這里經(jīng)典的工具是AddressSanitizer,這是很經(jīng)典的工具,是Google提供的,能捕獲緩沖區(qū)溢出和Use-after-free運行漏洞,非常經(jīng)典。學術界在去年阿迪森(音譯)的時候提出對AddressSanitizer感興趣的工作AMAZ(音),除了捕獲安全問題,還有更多代碼覆蓋率的問題,代碼覆蓋率是它的屬性,要用覆蓋率指導Fuzz,根據(jù)這個覆蓋率跟蹤判斷這個種子是好的還是不好的,應不應該留下來。剛才已經(jīng)簡單回復了絕大多數(shù)基于Coverage based Fuzz學術界改進,獲得更好效率的方案。這些方案考慮得很全面了了,還有可以改進的地方。我們注意到,他們說的是Coverage Guider Fuzz,這些方案里很少有幾個方案真的很關心Coverage。

我們做了一個工作,就是Fuzz的CollAFL。

我們有兩個觀察,測試過程中,它會跟蹤Coverage,它會和Coverage有碰撞。這不是我們第一次關注到,AFL作者知道碰撞,也寫到自己文檔里,但他選了折中的辦法放在那兒。碰撞是怎么回事呢?要簡單說一下細節(jié),AFL要用到一個64KB bitmap來保存Coverage的信息。怎么保存的呢?他關心的是邊的Coverage,這個程序的邊到底怎么走過,邊是有兩個塊連接構成,它怎么保存呢?它對每個基本塊附了一個key,上面是prev,下面是cur,然后他算這個邊,他給這個邊算了哈希出來,這個哈希就代表這條邊,更新bitmap的技術細節(jié)。這樣的做法,原理很簡單。大家看這個哈希算法很簡單,會進行碰撞。兩個不同的邊算出來的哈希是一樣的,碰撞有什么問題呢?最大的問題,它而影響這個Fuzzer的判斷,這個Fuzzer會根據(jù)bitmap來判斷當前這個種子是不是號種子,判斷這個種子是不是走了新的邊,如果碰撞了,它是看不出來這是新的邊。如果新的邊出現(xiàn)了,它的哈希值與前哈希值是一樣的,那么Fuzzer認為這個邊是測過的邊,認為這個種子沒用,其實扔掉了,但它實際是好的種子。

第二,它甚至可能幫你找到漏洞里了,因為找到漏洞,崩潰了,F(xiàn)uzzor和AFL會做一個檢測,會檢查這是不是重復的崩潰,這個種子走的是和原來一模一樣的東西,不是一模一樣就認為是重復的,要扔掉了。同樣的,碰撞以后導致這樣的情況,就可以導致你漏掉漏洞。還有比較嚴重的是,bitmap碰撞以后導致它提供Coverage信息不準確,其他依賴Coverage信息做決策的,就會做出錯誤的決策,這就包括前面講的怎么選種的問題,有策略,選種子的時候是基于Coverage做的判斷,Coverage不準的話會導致他做出錯誤的判斷。

這個問題是非常嚴重的,比大家想象的嚴重。我們做的測量,測了二十多個開元軟件,他們碰撞像Libtorrent是75%的邊會碰撞,整體效果影響會非常大的;nm邊數(shù)小于64kb,碰撞率是36%;vim邊數(shù)是大于64kb,碰撞更嚴重,超過60%(61.04%)。這個碰撞的問題不僅僅是AFL中存在,AFL會有更多邊的概念,這算做得比較好的,其實有的Fuzz只是做基本塊的覆蓋率。大家注意,邊的覆蓋率會推導出基本塊覆蓋率,但基本塊覆蓋率推導不出來邊的覆蓋率。基本塊的覆蓋,很多工具是這么做的,像lib Fuzzer,cloud里帶著這個,honggfuzz是Google后來提供的一個開源的Fuzz,他們都用的基本塊覆蓋率,里面的碰撞問題更嚴重。其實邊覆蓋率還不夠,最好的情況應該考慮做路徑覆蓋率。因為邊的順序對漏洞還有影響,最理想的情況下是做漏洞覆蓋率,但在代碼中,工具沒法實現(xiàn)的時候,我們做路徑做到兩條不同路徑,它的內部表示還不一樣,這個事情太大了,這個路徑太長了,這個怎么存儲?這中間太多了,每一次記錄runtime的開銷特別大,沒有好的辦法做這個事情,微軟選擇Edge也是非常好的選擇,也許將來還會有提升。

關于Coverage第二個環(huán)節(jié),現(xiàn)在這些策略里對Coverage沒有考慮太多,其中一個是選種子,選種子也是基于它的測試速度,是不是離目標最近的策略選種子,但所有提到的策略里沒有一個是直接和Coverage相關的,也沒有哪個策略說我優(yōu)選對Coverage有貢獻的策略。Coverage會有碰撞,Coverage并沒有被很好地應用Seed selection里去。

基于這兩個觀測,我們提出了新的方案——CollAFL方案,我們做了兩嗯個改進,一是消除Coverage跟蹤碰撞問題,二是選種的時候把Coverage作為優(yōu)先策略來應用。

具體做法。

1、消除碰撞。

AFL用到64kb bitmap跟蹤邊的覆蓋率。它的跟蹤方式大概是這樣的哈希算法。怎么消除碰撞呢?一個很簡單的方式,把64kb bitmap增大,把哈希表變大一些,碰撞概率自然就會降低,這是很顯然的事情,我們也試了一下,把bitmap大小變大,碰撞率自動降低了。但把bitmap加大之后,AFL測試速度也跟著馬上往下降。所以,這不是個最優(yōu)方案。

我們提出一個方案,不降低它的測試速度。怎么做呢?是按照替換哈希算法,哈希算法原來很簡單,就是current key,當前基本塊的key與上一個基本塊的key做個異或的操作的,這里很簡單,他用了1的常量,我們把它做了泛化,把當前的key做了x bit,前一個基本塊key做了一個y,另外再加一個z,這樣分三個參數(shù)泛化,原來是固定的。這樣變成每條邊就是x、y、z,變成我們尋找一個答案,每條邊路來復制一個x、y、z來消除碰撞。我們碰到一個邊搜一個x、y、z,讓以前的哈希值不碰撞就行了。我不斷地沿著這條邊搜索下去,前面是一條邊,顯而易見搜索到后面的時候,前面已經(jīng)搜索的,到了后面就非常難以找到合適的x、y、z與以前的哈希值不碰撞,非常難找,剛開始沒有碰撞,到后來邊就很難找。

怎么解決這個問題呢?我們不用對所有邊那么不用算,有些直接賦個哈希值或者固定值就可以了。怎么做呢?有兩種情形,第一種情形,這個基本塊只有一個前驅,它直接就復制,這樣就直接給條邊附一個常數(shù),不要運行時算這個哈希值,只要這個常數(shù)和別的哈希值不碰撞就完了,他就隨便選,只要是沒有人用這個哈希值就可以。第二種情形,還是我原來的策略,我搜索x、y、z,我怎么都搜索不出來x、y、z,怎么辦呢?做法就是要用時間換空間的想法,我們直接給這條邊也賦一個哈希值,這個哈希值存到哈希表里了,我們運行的時候就搜索哈希表。比如這邊有條邊,有個基本塊,有兩個前驅,我們搜不出來合適的x、y、z怎么辦?我們就給這兩個邊靜態(tài)賦一個哈希值,但這個哈希值不能將靜態(tài)寫死,只能通過runtime去查。我們把哈希值放到哈希表里,它的key就是前一個基本塊的key和底下key兩個組合起來做到key。之所以不能寫死,因為有很多個禁區(qū)(音188:35),沒法寫死。對這兩個問號都不用進行計算,要么直接靜態(tài)賦行,要么運行查一下哈希表。總的來說,這三種模式,第一種是我們通常情況下去邊搜索x、y、z,第二種是我實在搜不動了,它有多全驅,但我搜不到了,找不到x、y、z了,這時候就用哈希表,把它事先在靜態(tài)中把它放到哈希表里,Hash demo里,runtime的時候去查這個哈希表就可以了;第三是single-precedent單驅,我直接給它賦個常數(shù),這個常量我沒用過就好。這個順序必須嚴格按照這個順序來,我們要解決碰撞問題。

實驗室數(shù)據(jù),這是基本把碰撞率消除為零,我們會對某些bitmap大小還是會擴大一些,因為邊的數(shù)bitmap size超過64K,如果不把這個bitmap加大到64k怎么消除,這樣的情況下,我們會把bitmap順其自然地擴大,不是任意擴大。這三類當前區(qū)域最簡單,給它賦予靜態(tài)的哈希值,不需要運算,原來A表示對所有變量進行運算,現(xiàn)在要對當前變量進行運算。這個比例非常高,單前驅的基本塊比例非常高,在程序中大部分的基本塊都是單前驅的,這是好事兒,對這一情況都不用做運行式計算,它的碰撞和operate沒有。最麻煩的是查哈希表的內容,我們嚴格控制哈希表的大小,如果哈希表大的話,runtime查詢哈希表會非常慢,測試的時候會受到嚴重的影響。這里哈希表最多126個,查起來還是非常快,不受什么影響。它的速度比AFL快一些,相當于優(yōu)化了,比原來的算法快一點,并且可以消除碰撞。

2、改進種子選擇策略。

優(yōu)先選擇對Coverage有貢獻的種子。我們提出幾個策略,第一個策略,考慮每個種子會走一條路徑,一條路徑實際有不同分支的,有些分支是被其他種子測過,有的分支沒有。我們會統(tǒng)計這個種子多樣分支被測過,有多少分支沒有被測過,可能有兩個種子。第一個種子有一個分支沒測過,第二個種子有100個分支沒測過,我們選擇第二個,因為在第二個進行變異的時候要有非常大的概率,種子有沒有被觸發(fā)、測試過的分支,第一個種子只有一個分支沒有被測過,你的變異想觸發(fā)這個測試種子的概率要低一些。第二個種子有100個分子,你都要對它變異,更大的概率是觸發(fā)沒有走過的分支,會更快提升覆蓋率,這是它背后的想法。

第二個是改進,剛才分支技術這兒只記1,這兒分支后面會跟著一些子路徑,也要考慮子路徑的數(shù)目,計數(shù)不再是1,而是把后面的分支根據(jù)路徑數(shù)量加進來。

第三個策略,會考慮到內存訪問,我們會統(tǒng)計這個種子所走的路徑,基本塊訪問的數(shù)量,會優(yōu)先排序那些訪問數(shù)量多的。為什么會這么排序呢?因為我們關注的是內存破壞漏洞,如果你的內存訪問操作多,會更大概率地觸發(fā)內存破壞漏洞的想法,所以,會優(yōu)先排序。

這樣三個策略都有一些改進,看一下實驗效果。

第一,是Coverage這邊的,代碼覆蓋率到底提升多少,三個策略,這里分別表示br、desc、memory三個策略,把這個策略加上去之后,路徑覆蓋率提升20%;如果不加策略,消除碰撞里的效率只提升9.9%,加上br策略它能提升到20%,這是br最好的策略。最后兩個策略是對比Fuzz的種子選擇策略,我們的方案可以應用在他們上面,所以比他們還是有提升的。

第二,考察挖漏洞的能力,第一個評估是它能找多少crash,這個數(shù)量我對比了好幾組,包括原始AFL,消除碰撞之后的CollAFL,還加上br策略之后的CollAFL,還有另外幾個策略,包括Fuzz還有平均值,100%是7個Fuzz的平均值。平均下來還是br這個策略效果最好,應該有320%的提升。

最后看bug,我們有157個bug在24個開源軟件里,其中23個被別人報的,但沒有公開,開發(fā)者知道。所以,有134個別人沒有報過,其中95個我們拿到CVE,沒有全部分析完,分析了一部分,其中9個可以阻擋任意代碼執(zhí)行,效果是非常好的。我們這張表里AFL找到51個,br策略找到141個,就是這157個中有141個是br策略找到的。

基本上我的報告就這么多。

結論是,F(xiàn)uzz是現(xiàn)在比較流行的方法,AFL是代碼整合率(音196:10)學術界很多Fuzz是基于這個來做的,如果大家感興趣,非常建議從AFL開始,因為想法獲得實現(xiàn)非常容易。在工業(yè)界,他們不是直接把AFL拿過來用,也會進行改進。更多的改進是基于對特定對象的知識,比如Fuzz瀏覽器,對瀏覽器也有經(jīng)驗,知道什么叫可觸發(fā)的漏洞,做一些指導,這個其實很有效。學術界對這個東西沒有辦法泛化,所以學術界這邊沒有太多的研究。我們提供了一個CollAFL方案,在AFL上做了更多的改進,消除了它的碰撞,改進了它的種子選擇策略,更快地提出代碼覆蓋率,找到更多的漏洞。

謝謝大家!

主持人潘柱廷:謝謝張超的演講,張超講的比較偏學術。今天四位講者內容各有特色。下面大家還有什么問題可以提問。

Q:張超老師您好,久仰你的大名。我有個問題,AFL我了解的不是特別多,我之前對符號執(zhí)行那套東西有點了解,2015年開始有個文章開始叫driner(音)把符號執(zhí)行和AFL做了一個結合,后來這方面的東西我關注的比較少,但一直有個疑惑,想聽聽您對這個事情的判斷,純做AFL更有前途還是做driner(音)這套更有前途?

宋凱:Driner(音)這個想法是他們UCSB參加CGC方案里一個創(chuàng)新點,這不光是給CGC做補充,我們系統(tǒng)也是類似的方案。非常簡單的想法,F(xiàn)uzz到一定瓶頸的時候,你調節(jié)一下就好了,然后再做,用這樣簡單的方法。那個效果沒有想象中那么好,如果你自己實現(xiàn)這個工具,最主要局限在符號執(zhí)行或者背后的應用場景,UCSB目前那個文件還是個變量(171:35),它對真實程序路徑下的約束很多執(zhí)行不了,這是最討厭的,目前沒有特別好的辦法。有些東西有些比較有意思的進展,有工作會把這個符號執(zhí)行的工作轉成Fuzz的工作,有人說Fuzz??(172:05聽不清),現(xiàn)在有人說有些場景求不出來的時候扔回來,扔給??(172:10)。總的來說,應用場景是另外一個commit社區(qū)在做這個事情,非常困難。??(172:20)很早就有,一九七幾年就開始有這個東西,中間一直沉寂,零幾年又開始熱鬧起來,因為零幾年計算機開始非常流行。但目前它還是非常有限的,理論上它是很完美的東西,實踐中還用不起來,學術界為什么一直不放棄Fuzz呢?因為在很多應用場景下互相沒有替代方案,目前在漏洞挖掘利用,CGC是有漏洞利用的,宋凱介紹的是人機來做利用。如果讓機器來做這個利用怎么辦呢?目前一定要依賴Fuzz,F(xiàn)uzz在一些應用場景上還是必須的,所以大家一直在探索和改進,如果想有更好效果和收獲的話,還是想去改進Fuzz最有效,如果想解決學術上的難題還是需要探索。

上一篇:宋凱(exp-sky):Chakra引擎的非JIT漏洞與利用

下一篇:ABBA GARBA (廣博):Security and Privacy of Blockchain Technologies