Mozilla一直在模糊Firefox及其底層組件,它已被證明是識(shí)別質(zhì)量和安全漏洞的最有效方法之一。通常,研究人員會(huì)在不同級(jí)別上應(yīng)用模糊測(cè)試:瀏覽器作為一個(gè)整體進(jìn)行模糊測(cè)試,但也需要花費(fèi)大量時(shí)間來(lái)對(duì)孤立的代碼(例如使用libFuzzer)或整個(gè)組件(例如使用單獨(dú)的外殼的JS引擎)進(jìn)行模糊測(cè)試。在此文中,研究人員將只負(fù)責(zé)解釋瀏覽器模糊漏洞,并詳細(xì)介紹他們已經(jīng)尋找到的方法。
構(gòu)建工具
為了盡可能有效,研究人員使用了多種漏洞檢測(cè)方法。這些包括清除器,如AddressSanitizer(帶有LeakSanitizer)、ThreadSanitizer和UndefinedBehaviorSanitizer,以及使用調(diào)試構(gòu)建來(lái)啟用斷言和其他運(yùn)行時(shí)檢查。研究人員還使用了像rr和Valgrind這樣的調(diào)試器。這些工具中的每一個(gè)都提供了不同的視角來(lái)幫助發(fā)現(xiàn)特定的漏洞類型,但許多工具彼此不兼容,或者需要使用自己的自定義版本才能發(fā)揮作用或提供最佳結(jié)果。除了提供調(diào)試和漏洞檢測(cè)外,一些工具如果沒(méi)有構(gòu)建工具就無(wú)法工作,例如代碼覆蓋率和libFuzzer。每個(gè)操作系統(tǒng)和體系結(jié)構(gòu)組合都需要一個(gè)獨(dú)特的構(gòu)建,并且可能只支持這些工具的一個(gè)子集。
最后,每個(gè)變體都有多個(gè)活動(dòng)變體,包括發(fā)行版,Beta版、nightly版本和延長(zhǎng)支持版本(Extended Support Release, 簡(jiǎn)稱“ESR”),F(xiàn)irefox CI Taskcluster實(shí)例會(huì)定期構(gòu)建每個(gè)實(shí)例。所謂nightly版本,通常是開(kāi)發(fā)者自己維護(hù)的一個(gè)版本。白天的時(shí)候開(kāi)發(fā)者們將各自的修改提交到一個(gè)中心代碼庫(kù),然后在晚上做一次編譯得到的版本。一般來(lái)說(shuō)nightly版本會(huì)包含最新的漏洞修改和新增功能,所以適合那些關(guān)注某個(gè)漏洞,或者是特別喜歡最新版本的用戶使用。但是因?yàn)闆](méi)有經(jīng)過(guò)充分的測(cè)試,可能會(huì)有很多不穩(wěn)定的地方。
下載版本
Taskcluster使得查找和下載最新版本進(jìn)行測(cè)試變得很容易。研究人員在上面討論了由不同的儀表類型創(chuàng)建的變體的數(shù)量,研究人員需要對(duì)它們進(jìn)行自動(dòng)化模糊處理。由于構(gòu)建、工件、體系結(jié)構(gòu)、操作系統(tǒng)以及每個(gè)軟件包的大量組合,因此下載是一項(xiàng)艱巨的任務(wù)。
為了幫助降低構(gòu)建管理的復(fù)雜性,研究人員開(kāi)發(fā)了一個(gè)稱為fuzzfetch的工具。Fuzzfetch可以很容易地指定所需的構(gòu)建參數(shù),并將下載并解壓縮該構(gòu)建。
如何生成測(cè)試用例
因?yàn)檫@篇博文的目的是解釋整個(gè)流程,因此研究人員不會(huì)花太多時(shí)間來(lái)解釋模糊測(cè)試,結(jié)合使用公共可用的和定制的模糊測(cè)試器來(lái)生成測(cè)試用例。
如何執(zhí)行,報(bào)告和擴(kuò)展
對(duì)于以瀏覽器為目標(biāo)的模糊測(cè)試器, Grizzly管理和運(yùn)行測(cè)試用例并監(jiān)控結(jié)果,創(chuàng)建適配器可以使研究人員輕松地在Grizzly中運(yùn)行現(xiàn)有的模糊測(cè)試器。Grizzly是一種應(yīng)用程序框架,專門解決編寫成千上萬(wàn)用戶訪問(wèn)服務(wù)器時(shí)候產(chǎn)生的各種漏洞。
為了充分利用任何給定設(shè)備上的可用資源,研究人員并行運(yùn)行多個(gè)Grizzly實(shí)例。
對(duì)于每個(gè)模糊測(cè)試器,研究人員都創(chuàng)建了容器來(lái)封裝運(yùn)行它所需的配置。這些都存在于Orion monorepo中。 什么是 Monorepo?Monorepo 其實(shí)不是一個(gè)新的概念,在軟件工程領(lǐng)域,它已經(jīng)有著十多年的歷史了。概念上很好理解,就是把多個(gè)項(xiàng)目放在一個(gè)倉(cāng)庫(kù)里面,相對(duì)立的是傳統(tǒng)的 MultiRepo 模式,即每個(gè)項(xiàng)目對(duì)應(yīng)一個(gè)單獨(dú)的倉(cāng)庫(kù)來(lái)分散管理。每個(gè)模糊測(cè)試器都有一個(gè)配置,根據(jù)該模糊測(cè)試器的優(yōu)先級(jí)來(lái)配置具體的部署和資源分配。Taskcluster持續(xù)部署這些配置以分配工作并管理模糊測(cè)試節(jié)點(diǎn)。
Grizzly Target處理諸如掛起、崩潰和其他漏洞等漏洞的檢測(cè)。Target是Grizzly和瀏覽器之間的接口。檢測(cè)到的漏洞會(huì)自動(dòng)打包并上報(bào)給FuzzManager服務(wù)器。FuzzManager服務(wù)器提供了自動(dòng)化和篩選結(jié)果的UI。
其他更有針對(duì)性的模糊測(cè)試器使用JS shell和基于libFuzzer的目標(biāo)使用模糊接口。許多第三方庫(kù)在OSS-Fuzz中也被模糊化了,這些不在本文的討論范圍之內(nèi)。
模糊測(cè)試結(jié)果
對(duì)不同的目標(biāo)大規(guī)模運(yùn)行多個(gè)模糊器會(huì)產(chǎn)生大量的數(shù)據(jù),這些崩潰不適合直接輸入到漏洞跟蹤系統(tǒng),比如Bugzilla。FuzzManager客戶端庫(kù)可以過(guò)濾崩潰變化和重復(fù)結(jié)果,然后再離開(kāi)模糊測(cè)試節(jié)點(diǎn)。唯一結(jié)果將報(bào)告給FuzzManager服務(wù)器。通過(guò)FuzzManager的web界面,可以創(chuàng)建簽名,將報(bào)表分組到存儲(chǔ)桶中,幫助客戶端檢測(cè)重復(fù)的結(jié)果。
模糊測(cè)試器通常會(huì)生成長(zhǎng)達(dá)數(shù)百甚至數(shù)千行的測(cè)試用例。FuzzManager存儲(chǔ)桶將自動(dòng)進(jìn)行掃描,以在Taskcluster中進(jìn)行隊(duì)列減少任務(wù)。這些還原任務(wù)使用Grizzly Reduce和Lithium來(lái)應(yīng)用不同的還原策略,通常會(huì)刪除大多數(shù)不必要的數(shù)據(jù)。每個(gè)存儲(chǔ)桶都將持續(xù)進(jìn)行處理,直到成功完成還原操作為止。然后,工程師可以對(duì)最小化的測(cè)試用例進(jìn)行最終檢查,并將其附加到漏洞報(bào)告中。最終結(jié)果通常用作Firefox測(cè)試套件中的崩潰測(cè)試。測(cè)試過(guò)程請(qǐng)點(diǎn)此查看。還定期測(cè)量模糊器的代碼覆蓋率,再次使用FuzzManager收集代碼覆蓋率數(shù)據(jù)并生成覆蓋率報(bào)告。
漏洞報(bào)告
由于研究人員的目標(biāo)是創(chuàng)建可操作的漏洞報(bào)告,以盡快修復(fù)漏洞,同時(shí)最小化開(kāi)發(fā)人員的開(kāi)銷。
研究人員通過(guò)以下方式做到這一點(diǎn):
崩潰信息,例如日志和堆棧跟蹤;
建設(shè)和環(huán)境信息;
減少測(cè)試用例;
Pernosco會(huì)話;
回歸范圍(通過(guò)Bugmon分割);
通過(guò)Bugmon進(jìn)行驗(yàn)證;
Grizzly Replay是形成Bugmon和Grizzly Reduce的基本執(zhí)行引擎的工具,它使收集rr痕跡提交到Pernosco變得容易。它使重新運(yùn)行瀏覽器測(cè)試用例在自動(dòng)化和手動(dòng)使用方面都很容易。
如前所述,研究人員也一直在使用Pernosco。Pernosco是一個(gè)為rr跟蹤提供web界面的工具,使開(kāi)發(fā)人員無(wú)需直接訪問(wèn)執(zhí)行環(huán)境就可以使用它們。這是一個(gè)由同名公司開(kāi)發(fā)的工具,可以極大地幫助調(diào)試大規(guī)模并行應(yīng)用程序。當(dāng)測(cè)試用例太不可靠而無(wú)法減少或附加到漏洞報(bào)告時(shí),它也非常有用。創(chuàng)建一個(gè)rr跟蹤并上傳它可以使不再使用的漏洞報(bào)告具有可操作性。
Grizzly和Pernosco的合并帶來(lái)了一個(gè)額外的好處,那就是使不常見(jiàn)的、難以重現(xiàn)的漏洞變得可行。一個(gè)非常不一致的漏洞的測(cè)試用例可以運(yùn)行數(shù)百或數(shù)千次,直到在rr下發(fā)生所需的崩潰為止。跟蹤被自動(dòng)收集并準(zhǔn)備提交給Pernosco并由開(kāi)發(fā)人員修復(fù),而不是因?yàn)樗豢刹僮鞫缓雎浴?/p>
要對(duì)新特性進(jìn)行適當(dāng)?shù)脑u(píng)估,可以通過(guò)fuzzing@mozilla.com或通過(guò)Matrix聯(lián)系。一旦開(kāi)始對(duì)組件進(jìn)行模糊測(cè)試,研究人員將主要通過(guò)Bugzilla進(jìn)行通信。如前所述,研究人員努力解決可修復(fù)的漏洞。
Bugmon用于自動(dòng)將回歸范圍平分為兩部分,并盡快通知適當(dāng)?shù)娜藛T,并在將漏洞標(biāo)記為“已修復(fù)”后進(jìn)行驗(yàn)證。關(guān)閉漏洞會(huì)自動(dòng)將其從FuzzManager中刪除,因此,如果在代碼庫(kù)中找到類似的漏洞,則可以再次對(duì)其進(jìn)行識(shí)別。
模糊測(cè)試期間發(fā)現(xiàn)的一些漏洞將阻止研究人員有效地模糊功能或構(gòu)建變體,這些被稱為模糊阻止程序,它們以幾種不同的形式出現(xiàn)。從產(chǎn)品的角度來(lái)看,這些漏洞看起來(lái)似乎是無(wú)害的,但是它們可以阻止模糊測(cè)試程序針對(duì)重要的代碼路徑,甚至完全阻止模糊測(cè)試目標(biāo)。適當(dāng)?shù)貙?duì)這些漏洞進(jìn)行優(yōu)先級(jí)排序并快速將其修復(fù)是非常有用的。
PrefPicker管理用于模糊測(cè)試的Firefox首選項(xiàng)集。在首選項(xiàng)之后添加功能時(shí),請(qǐng)考慮將其添加到PrefPicker模糊模板中,以便在模糊過(guò)程中啟用它。對(duì)PrefPicker模糊模板的定期審核可以幫助確保不遺漏區(qū)域,并盡可能有效地利用資源。
與其他領(lǐng)域一樣,衡量是評(píng)估成功的關(guān)鍵部分。研究人員利用Bugzilla的meta bug功能來(lái)幫助跟蹤由模糊器識(shí)別的漏洞。研究人員努力使每個(gè)模糊器和每個(gè)模糊的新組件都有一個(gè)meta bug。
例如,Domino的meta bug列出了該工具標(biāo)識(shí)的所有漏洞(超過(guò)1100個(gè))。使使用此Bugzilla數(shù)據(jù),研究人員可以顯示多年來(lái)各種模糊測(cè)試的影響。
模糊測(cè)中有許多組件, 這些組件在不斷發(fā)展,以適應(yīng)調(diào)試工具、執(zhí)行環(huán)境和瀏覽器內(nèi)部的變化。開(kāi)發(fā)人員總是在添加、刪除和更新瀏覽器功能。