現(xiàn)有USB模糊測試技術(shù)的總結(jié)
Syzkaller(Google團(tuán)隊(duì)開發(fā)的一款針對Linux內(nèi)核進(jìn)行模糊測試的開源工具),最近開始支持USB模糊測試,并且已經(jīng)在Linux內(nèi)核中發(fā)現(xiàn)了80多個漏洞。目前,鑒于USB本身的復(fù)雜性導(dǎo)致的安全性的影響和潛在的大量漏洞,幾乎所有模糊測試專家都開始將他們的模糊測試技術(shù)應(yīng)用于USB的模糊測試中。
什么是USB協(xié)議棧?
按著協(xié)議,USB分為USB host(USB主機(jī)) 和 USB device/gadget(USB從機(jī)),USB主機(jī)能夠主動發(fā)起會話而USB從機(jī)則不能發(fā)起會話。HOST是主機(jī),好比電腦端那個USB,簡而言之,主機(jī)好比電腦端那個USB接口,從機(jī)好比就是連接到USB接口的U盤。當(dāng)我們談?wù)揢SB時,通常說的是USB主機(jī),例如帶有標(biāo)準(zhǔn)USB端口的筆記本電腦。下圖是Linux USB主機(jī)棧。從下到上,分為硬件、內(nèi)核空間和用戶空間。
USB主機(jī)控制器設(shè)備(又名HCD)是連接到系統(tǒng)PCI總線的PCI設(shè)備,通過USB端口提供USB連接支持。根據(jù)USB技術(shù)的發(fā)展,它也被稱為USB 1.x的UHCI / OHCI,USB 2.x的EHCI和USB 3.x控制器的XHCI。要使內(nèi)核使用此控制器,我們需要一個USB主機(jī)控制器驅(qū)動程序,它可以設(shè)置PCI配置和DMA。上面是USB內(nèi)核,實(shí)現(xiàn)底層USB協(xié)議棧,并使用通用內(nèi)核API(submit /recv URB)抽象發(fā)送/接收USB數(shù)據(jù)包的方式。上面是不同的USB從機(jī)驅(qū)動程序,例如USB HID驅(qū)動程序和USB大容量存儲驅(qū)動程序。這些驅(qū)動程序會實(shí)現(xiàn)不同的USB類協(xié)議(例如,HID,大容量存儲),為內(nèi)核中的其他子系統(tǒng)(例如輸入和數(shù)據(jù)塊)提供粘合層,方便用戶空間(例如創(chuàng)建/dev節(jié)點(diǎn))。
由于Linux也廣泛用于嵌入式系統(tǒng),例如一些USB軟件保護(hù)器(USB Dongle),USB從機(jī)指的是Linux內(nèi)的USB軟件保護(hù)器硬件和USB模式。 USB從機(jī)與USB主機(jī)模式完全不同。下圖顯示了Linux內(nèi)核中的USB從機(jī)協(xié)議棧。
底部是USB從機(jī)控制器(又名UDC),與HCD一樣,UDC也在PHY層內(nèi)實(shí)現(xiàn)特定版本的USB標(biāo)準(zhǔn)。但是,與英特爾最常用的HCD不同,UDC IP來自不同的硬件供應(yīng)商,例如DWC2/3,OMAP,TUSB和FUSB。這些控制器通常具有其自己的設(shè)計(jì)規(guī)范,并且當(dāng)它們支持USB On-The-Go(又名OTG)模式時也可遵循HCD規(guī)范(例如XHCI規(guī)范)。 OTG允許UDC在USB主機(jī)和USB從機(jī)模式之間切換。例如,當(dāng)Android設(shè)備以MTP的形式與筆記本連接時,Android USB從機(jī)控制器處于USB從機(jī)模式。如果USB閃存驅(qū)動程序插入Android設(shè)備,UDC將在USB主機(jī)模式下工作。支持OTG的UDC也被USB 3.x標(biāo)準(zhǔn)中的雙角色設(shè)備(Dual-Role Device,DRD)控制器取代。因此,不需要OTG數(shù)據(jù)線來切換UDC的角色,因?yàn)榻巧袚Q是在DRD控制器的軟件中完成的。
要使用UDC,你需要在內(nèi)核中使用UDC驅(qū)動程序,通過行業(yè)標(biāo)準(zhǔn)總線((包括 AMBA? AHB和AXI接口))提供連接和配置,并為更高層設(shè)置DMA。與USB主機(jī)協(xié)議棧中的USB內(nèi)核一樣,USB從機(jī)協(xié)議棧中的USB從機(jī)內(nèi)核也提供API,通過回調(diào)和配置來注冊和實(shí)現(xiàn)USB從機(jī)函數(shù)。例如,我們可以通過請求現(xiàn)有的大容量存儲函數(shù)(f_mass_storage)將USB描述符傳遞到USB從機(jī)內(nèi)核并實(shí)現(xiàn)典型的USB大容量存儲設(shè)備。對于諸如MTP的更復(fù)雜的協(xié)議,用戶空間守護(hù)進(jìn)程或庫提供協(xié)議邏輯并通過例如configfs或usbfs與從機(jī)函數(shù)通信。
USB主機(jī)控制器(Host Controller)
USB的拓?fù)浣Y(jié)構(gòu)決定了主機(jī)控制器就是最高統(tǒng)帥,沒有主機(jī)控制器的要求,從機(jī)永遠(yuǎn)不能主動發(fā)數(shù)據(jù)。所以主機(jī)控制器在USB的世界里扮演著重要的角色,它是幕后操縱者。
比如說USB主機(jī)發(fā)送Setup數(shù)據(jù)包獲取設(shè)備描述符是怎么發(fā)出去的?這個過程包含很多信息,比如:如何在D+和D-這兩根線上傳過去的、又傳過來的。 這一切的工作都是主機(jī)控制器給我們做的,USB主機(jī)控制器的規(guī)范有很多種,比如UHCI/OHCI。
什么是USB controller?
USB 設(shè)備和主機(jī)的接口就是host controller,一個主機(jī)可以支持多個host controller,比如分別屬于不同廠商的。那么USB host controller 本身是做什么的? 很簡單用于控制,控制所有的USB從機(jī)的通信。 CPU把要做的事情分配給主機(jī)控制器,然后自己想干什么就干什么去,主機(jī)控制器替他去完成剩下的事情,事情辦完了再通知CPU。否則讓CPU去盯著每一個從機(jī)做每一件事情,那是不現(xiàn)實(shí)的。
控制器的主要工作是什么? 把數(shù)扔出去,把數(shù)拿回來。絕對不應(yīng)該偷偷加工數(shù)據(jù)。
主機(jī)控制器控制總線上包的傳輸, 使用1ms或125us的幀。在每幀的開始時,主機(jī)控制器產(chǎn)生一個幀開始包(SOF: Start of Frame)。
SOF包用于同步幀的開始和跟蹤幀的數(shù)目,包在幀中被傳輸,或由主機(jī)到從機(jī)(輸入事務(wù)),或由從機(jī)到主機(jī)(輸出事務(wù))。傳輸總是由 主機(jī)發(fā)起的(輪詢傳輸)。回此每條USB總線只能有一個 主機(jī)。每個數(shù)據(jù)包的傳輸都有一個狀態(tài)階段同(同步傳輸除外),數(shù)據(jù)接收者可以在其中返回ACK(應(yīng)答接收),NAK(重試),STALL(錯誤條件)或什么也沒有(混亂數(shù)據(jù)階段,設(shè)備不可用或已經(jīng)斷開)。
USB模糊測試的歷史
FaceDancer
由于可編程USB硬件模糊測試工具——FaceDancer的出現(xiàn),USB模糊測試開始吸引更多的關(guān)注。它支持USB主機(jī)和從機(jī)模式模擬,并允許發(fā)送預(yù)先形成帶有漏洞的USB請求和響應(yīng)。 Umap/Umap2提供了一個用Python編寫的模糊測試框架,它具有面向FaceDancer的不同USB從機(jī)和響應(yīng)模板。TTWE框架通過使用兩個FaceDancer分別模擬USB主機(jī)和USB從機(jī)來實(shí)現(xiàn)USB主機(jī)和USB從機(jī)之間的MitM,此MitM允許兩個方向的USB數(shù)據(jù)包突變,從而實(shí)現(xiàn)雙方的模糊測試。
目前所有這些解決方案都集中在USB主機(jī)協(xié)議棧上,其原因是人們假設(shè)惡意USB從機(jī)不是惡意的USB主機(jī)(例如筆記本電腦),并且大多數(shù)USB從機(jī)固件都是閉源的,因此很難被分析。這意味著,大多數(shù)漏洞/錯誤存在于USB內(nèi)核(用于解析USB響應(yīng))和一些常見的USB驅(qū)動程序(例如鍵盤)中。這些解決方案的優(yōu)點(diǎn)是能夠完全模擬USB從機(jī)。但是,在我看來,卻有兩方面不足:
1.過于依賴硬件;
2.目標(biāo)反饋有限。
由于FaceDancer速度很慢,這使得任何基于它構(gòu)建的解決方案都無法擴(kuò)展測試功能。由于在實(shí)踐中,經(jīng)常需要將FaceDancer和目標(biāo)設(shè)備作為模糊測試的基本要素,所以,這也對FaceDancer的可擴(kuò)展性帶來了更多挑戰(zhàn)。反饋是另一個重要問題,模糊輸入的突變是基于模板和隨機(jī)化的,除了系統(tǒng)日志記錄之外,沒有來自目標(biāo)的實(shí)時反饋(例如代碼覆蓋率)。因此,模糊測試的準(zhǔn)確率是非常不可信的。
為了擺脫硬件依賴性,使用虛擬化(例如QEMU)來進(jìn)行保存。vUSBf使用QEMU/KVM運(yùn)行內(nèi)核映像,并利用QEMU中的USB重定向協(xié)議將對USB從機(jī)的訪問重定向到由模糊測試工具控制的USB模擬工具,如下所示:
雖然vUSBf提供了一個很好的編排體系結(jié)構(gòu)來并行運(yùn)行多個QEMU實(shí)例,以此解決可擴(kuò)展性問題,但模糊測試工具本質(zhì)上是基于模板的,而反饋也還仍然依賴于系統(tǒng)日志記錄。
POTUS
為此,有研究人員開發(fā)了POTUS 項(xiàng)目,POTUS 項(xiàng)目也可以發(fā)現(xiàn)位于 Linux USB 驅(qū)動程序的漏洞。
2017年,倫敦大學(xué)的安全研究人員發(fā)布了 POTUS工具,這是一種可以發(fā)現(xiàn) Linux USB 設(shè)備驅(qū)動程序漏洞的工具。該工具通過設(shè)置虛擬機(jī),通用 USB 設(shè)備以及故障注入,發(fā)送模糊符號等技術(shù)來測試 USB 驅(qū)動程序繼而查找漏洞。
研究人員通過 POTUS 測試 USB 驅(qū)動程序發(fā)現(xiàn)了兩個 Linux 內(nèi)核漏洞。一個是 CVE-2016-5400,USB 設(shè)備驅(qū)動程序中用于與 Airspy 軟件定義無線電(SDR)通信的內(nèi)存泄漏漏洞,而另一個是自 2003 年以來已存在的 Linux 內(nèi)核的樂高 USB 塔驅(qū)動器使用后釋放漏洞(無 CVE 標(biāo)識符)。
POTUS的工作原理如下所示:
systemtap是一個診斷l(xiāng)inux系統(tǒng)性能和功能問題的開源軟件,并且允許開發(fā)人員編寫和重用簡單的腳本深入探查linux系統(tǒng)的活動,可以快速安全的提取過濾總結(jié)數(shù)據(jù),以便能夠診斷復(fù)雜的性能或功能問題。
在USB模糊測試中,SystemTap用于檢測內(nèi)核存在的漏洞,并將漏洞數(shù)量記錄下來。基于不同狀態(tài)下的故障數(shù)量的路徑優(yōu)先級排序算法可以控制“分叉(fork)”的數(shù)量。fork()函數(shù)通過系統(tǒng)調(diào)用創(chuàng)建一個與原來進(jìn)程幾乎完全相同的進(jìn)程,也就是兩個進(jìn)程可以做完全相同的事,但如果初始參數(shù)或者輸入的變量不同,兩個進(jìn)程也可以做不同的事。一個進(jìn)程調(diào)用fork()函數(shù)后,系統(tǒng)先給新的進(jìn)程分配資源,例如存儲數(shù)據(jù)和代碼的空間。然后把原來的進(jìn)程的所有值都復(fù)制到新的新進(jìn)程中,只有少數(shù)值與原來的進(jìn)程的值不同,相當(dāng)于克隆了一個自己。
給定路徑的故障數(shù)量表示代碼覆蓋率,因此,故障數(shù)量越大則代碼覆蓋率越高。另外,POTUS還在QEMU中實(shí)現(xiàn)了一個通用的USB虛擬從機(jī),以使用可配置的設(shè)備描述符和數(shù)據(jù)傳輸來模擬不同的USB從機(jī)。 虛擬從機(jī)中的USB 驅(qū)動程序(USB 驅(qū)動程序)使用系統(tǒng)調(diào)用來使用暴露在虛擬從機(jī)的不同設(shè)備節(jié)點(diǎn)。與vUSBf相比,POTUS就具有模糊測試反饋機(jī)制(通過計(jì)算路徑內(nèi)的故障數(shù)量),從而支持更多USB從機(jī)模擬。但是,在USB 驅(qū)動程序中模擬某些USB從機(jī)操作的手動進(jìn)程、符號執(zhí)行的基本限制——路徑爆炸( path explosion),以及依賴于路徑故障數(shù)量的未知有效性和局限性,使得POTUS很難被廣泛使用。
本文我們先從什么是USB協(xié)議棧開始講起,然后再講到USB模糊測試的歷史,其中講到了一些過去的常用技術(shù)和工具,不過它們都存在著一些問題。下文,我們將介紹最新的USB模糊測試的解決方案。