search
尋找貓咪~QQ 地點 桃園市桃園區 Taoyuan , Taoyuan

漏洞挖掘之利用Broadcom的Wi-Fi棧

眾所周知,平台安全性是複雜系統安全性的一個不可或缺的組成部分,移動設備更是如此。現代移動平台包括多個處理單元,全都精巧地彼此通信。在應用處理器(AP)上運行的代碼已得到廣泛研究,但對其他組件的審查卻很少。

圖1

多年來,由於安全人士的持續關注,在應用處理器上運行的代碼的防禦力得到了加強。但是,攻擊者往往會另闢蹊徑。提高一個組件的安全性將不可避免地導致一些攻擊者開始在別處尋找更容易的進入點。

該博客系列分兩部分,我們將探討由在移動設備上使用的Broadcom Wi-Fi SoC(系統級晶元)引入的暴露的攻擊面。我們將專註於運行安卓的設備(本研究基本上也適用於包括相同的Wi-Fi SoC的其他系統)。第一篇博文將專註於利用Wi-Fi SoC本身,我們將發現和利用能讓我們在晶元上遠程執行代碼的漏洞。在第二篇博文中,我們將進一步將我們的許可權從SoC提升到操作系統的內核。通過這兩篇文章,我們將展示如何在無需用戶交互的情況下僅通過Wi-Fi鄰近就完全接管設備。

我們將專註於Broadcom(博通)的Wi-Fi SoC,因為其是移動設備上最常見的Wi-Fi晶元組。使用該平台的設備很多,出於本文目的,我們將展示運行安卓7.1.1版NUF26K的完全更新(當時,現已修復)的Nexus 6P的一個遠程代碼執行漏洞。

為什麼是Wi-Fi?

在過去十年中,Wi-Fi在移動設備上的使用已變得很普遍。Wi-Fi已漸漸演變為一套強大的規範——一些注重物理層,另一些則側重於MAC層。為了應對日益增加的複雜性,供應商已經開始生產「FullMAC」Wi-Fi SoC。

本質上,這些是獨立執行所有的物理層、MAC層及MAC子層管理實體(MLME)處理,從而使操作系統可以從與Wi-Fi有關的複雜(有時是晶元特定的)功能抽離的小型SoC。Wi-Fi FullMAC晶元的推出也改善了移動設備的功耗,因為大部分處理是在低功耗SoC而不是耗電量較大的應用處理器上完成的。也許最重要的是,FullMAC晶元更容易集成,原因是其在固件中實施MLME,從而降低了主機端的複雜性。

但Wi-Fi FullMAC晶元的推出也有代價。引入這些新的硬體、運行專有和複雜的代碼庫可能會削弱設備的整體安全性,並引入可能危及整個系統的漏洞。

圖2

探索平台

為了開始研究,我們需要找到一些方法來探索Wi-Fi晶元。 幸運的是,賽普拉斯最近收購了Broadcom的無線物聯網業務,併發布了許多與Broadcom Wi-Fi晶元組相關的數據手冊。 通過閱讀數據手冊,我們深入了解了Wi-Fi晶元組背後的硬體架構。

圖3

具體而言,我們可以看到使用的是ARM Cortex R4內核,其運行處理幀的所有邏輯。此外,該數據手冊顯示,ARM內核具有用於保存固件代碼的640KB ROM,以及用於數據處理(例如堆)和存儲固件代碼補丁的768KB RAM。

要開始分析在ARM內核上運行的代碼,我們需要提取ROM的內容,並定位載入到RAM中的數據。

我們先來解決第二個問題——載入到ARM內核的RAM中的數據位於何處?由於該數據不存在於ROM中,因此必須在晶元首次上電時從外部載入。因此,通過讀取主機驅動程序中的初始化代碼,我們應該可以找到包含RAM內容的文件。實際上,通過驅動程序的代碼,我們找到了BCMDHD_FW_PATH配置,其用於表示驅動程序將內容上傳到RAM的文件的位置。

那麼ROM的內容呢?提取ROM的一種方法是使用主機驅動程序的晶元存儲器訪問功能(通過SDIO或PCIe上的PIO)直接讀取ROM的內容。但是,這樣做將需要修改驅動程序,以使我們能夠發出轉儲ROM所需的命令。檢索ROM的另一種方法是將我們自己修改的固件文件載入到RAM中,我們將插入一個可用於轉儲ROM內存範圍的小型存根。幸運的是,本文的情況實際上並不需要這些方法,Broadcom提供了一個非常強大的命令行實用程序dhdutil,可用於通過bcmdhd驅動程序與晶元進行交互。

在該實用程序支持的各種功能中,其還允許我們通過發出特殊命令「membytes」直接讀取和寫入適配器上的內存。由於我們已經知道了ROM的大小(從數據手冊中),我們可以直接使用membytes命令來讀取ROM的內容。但是,我們還需要先回答最後一個問題——ROM位於哪裡?根據有關人員的研究,ROM被載入到地址0x0,RAM被載入到地址0x180000。

最後,把所有這一切放在一起,我們可以從固件文件獲取RAM的內容,使用dhdutil轉儲ROM,並將這兩個文件合併成一個文件,然後便可在IDA中開始分析。

圖4

分析固件

由於可用內存(ROM和RAM)相對較小,Broadcom為了節省內存而進行了極大的努力。首先,他們從二進位文件中刪除了符號和大部分字元串。這樣做的額外好處是使固件代碼的逆向工程稍微更麻煩。他們還專門選擇了Thumb-2指令集,這樣可以實現更好的代碼密度。因此,BCM4358上的ROM鏡像的封裝非常緊湊,僅包含不到300個未使用的位元組。

但是,這還不夠。別忘了,RAM必須容納堆、棧、全局數據結構及ROM功能的所有補丁或修改。這對少得可憐的768KB而言是一個相當高的要求。為了解決這個問題,Broadcom決定將固件初始化期間使用的所有功能放在兩個特殊區域。初始化完成後,這些區域被「回收」,隨後轉換為堆塊。此外,堆塊散布在RAM中的代碼和數據結構之間,因為後者有時有對齊要求(或直接從ROM引用,因此無法移動)。最終的結果是RAM是一堆混亂的堆塊、代碼及數據結構。

圖5

在花了一些時間分析固件后,我們至少可以開始識別一些包含函數名和其他提示的字元串,以幫助我們了解代碼庫。此外,NexMon研究人員發布了對應於BCM4339固件的收集的符號。我們可以將相同的符號應用於BCM4339的固件,然後使用bindiff關聯更新晶元的更新版本的固件的符號名稱。

最後還有一個訣竅——除了我們正在分析的FullMAC SoC外,Broadcom還生產SoftMAC晶元。由於這些SoftMAC晶元不處理MLME層,所以其相應的驅動程序必須執行該處理。因此,許多Broadcom的MLME處理代碼都包含在開源SoftMAC驅動程序-brcmsmac中。雖然這並不能幫助我們了解任何晶元特定的功能或更多的內部處理代碼,但它似乎與固件的代碼有許多相同的實用功能。

尋找bug

現在我們已掌握了固件的結構,並且有了分析的手段,我們終於可以開始尋找bug了。 但我們應該從哪裡開始呢?

雖然有上文所述的所有技巧,這仍是一個相對較大和不透明的二進位文件,字元串或符號很少。一種可能的方法是測試固件,以便跟蹤在接收和處理數據包時所採用的代碼路徑。Cortex R4確實有調試寄存器,可用於設置斷點和檢查各個位置的代碼流。或者,我們可以手動定位一組用於從接收到的幀解析和檢索信息的函數,並從那裡逆向。

這正是熟悉Wi-Fi派上用場之處。Wi-Fi管理幀以小的「標記」數據塊(稱為信息元素(IE))對大多數信息進行編碼。這些標記的數據塊為TLV結構,其中標籤和長度欄位是單位元組長。

圖6

由於在Wi-Fi幀(數據本身除外)中傳輸的大部分信息是使用IE進行編碼的,所以其是我們逆向工作的良好候選者。此外,由於「標籤」值是唯一且標準化的,所以我們可以使用其值來幫助我們熟悉當前處理的代碼流。

從brcmsmac驅動程序可以看到,Broadcom使用一個函數從bcm_parse_tlvs幀提取IE。經過簡短搜索(通過關聯附近的字元串提示),我們在固件的ROM中找到了相同的函數。太好了。

現在我們可以開始交叉引用調用該函數的位置,並逆向每一個調用站點。雖然比逆向固件的每一部分要容易得多,但這仍然需要相當長的時間。

完成所有調用站點的逆向工程后,我發現了一些與處理嵌入在管理幀中的信息元素有關的漏洞。

當連接到支持無線漫遊功能(FT或思科的CCKM漫遊)的網路時,可以觸發其中的兩個漏洞。一方面,這些漏洞相對易於利用——是簡單的棧溢出。此外,在固件(HNDRTE)上運行的操作系統不使用棧cookie,因此不需要額外的信息泄漏或繞過。

但是,雖然這些漏洞可能很容易利用,但需要一些設置來實現。首先,我們需要廣播支持這些功能的Wi-Fi網路。802.11r FT是一種由hostapd實現的開放標準。相比之下,CCKM是一種專有標準。了解如何模擬CCKM網路很不容易。

另外,我們需要弄清楚哪些設備實際上支持上述功能。Broadcom提供許多可由客戶授權的功能——並非所有設備都具有所有功能。

幸運的是,Broadcom使區分每個固件鏡像中實際存在哪些功能變得容易。下載到晶元的RAM內容中的最後幾個位元組包含固件的「版本字元串」。該字元串包含固件編譯的日期、晶元的修訂版本、固件的版本及一列破折號分隔的「標籤」。每個標籤代表固件鏡像支持的一個功能。例如,以下是Nexus 6P的版本字元串:

圖7

802.11r FT功能的存在由「fbt」標籤指示。類似地,CCKM的支持由「ccx」標籤指示。不幸的是,Nexus 6P似乎並不支持這些功能。事實上,在我自己的Android固件鏡像庫中快速搜索「ccx」功能(支持CCKM)后發現Nexus設備不支持此功能,但眾多三星旗艦設備支持該功能。

那麼其他兩個漏洞呢?兩者均與 隧道直接鏈路建立(TDLS)的實現有關。TDLS連接允許Wi-Fi網路上的對等體在彼此之間交換數據——不通過接入點(AP),這樣可防止AP擁塞。

固件中對TDLS的支持由「betdls」和「tdls」標籤指示。通過搜索我的固件庫可以看到,絕大多數設備確實支持TDLS。

此外,TDLS被指定為802.11z標準的一部分。因為可以獲得有關TDLS的所有信息,所以我們可以閱讀該標準,以便熟悉Broadcom實現中的相關代碼路徑。作為開放標準,其還受到開源請求者的支持,比如wpa_supplicant。因此,我們可以檢查wpa_supplicant中TDLS功能的實現,以進一步提高對固件中相關代碼的了解。

最後,正如我們稍後將看到的,觸發這兩個漏洞可以由Wi-Fi網路上的任何對等體完成,而無需在被攻擊設備上進行任何動作。這使探索這些漏洞更有意思。

無論如何,我們都決定利用TDLS漏洞。但是,在我們這樣做之前,讓我們先花點時間了解一下TDLS和發現的漏洞(如果您已熟悉TDLS,可跳過這一部分)。

802.11z TDLS 101

有許多同一Wi-Fi網路上的兩個對等體希望在彼此之間傳輸大量的數據的用例。例如,將視頻從您的移動設備投射到Chromecast將需要傳輸大量數據。在大多數情況下,Chromecast應該是相對靠近投射體。因此,將整個數據流從設備傳遞到AP(只為隨後將其傳遞到Chromecast)是浪費的。

增加一個額外的跳躍(AP)會增加延遲並降低連接的質量。向AP傳遞這樣大量的數據也會對AP本身造成壓力,導致擁塞,並且會降低網路上所有對等體的Wi-Fi連接的質量。

這正是TDLS的用武之地。TDLS旨在提供一種不依賴AP的Wi-Fi網路上的對等通信方式。

在空中

我們先熟悉一下TDLS幀的結構。您可能知道,802.11幀使用「標誌」欄位來指示幀正在傳播的「方向」(從客戶端到AP、AP到客戶端,等等)。TDLS流量選擇使用指示Ad-Hoc (IBSS)網路中流量的標誌值。

圖8

接下來,TDLS幀由特殊的以太類型值0x890D來標識。通過Wi-Fi傳輸的TDLS幀在「有效載荷類型」欄位中使用常數值,表明有效載荷具有以下結構:

圖9

TDLS幀的類別也被設置為一個常數值。這使我們只有一個欄位來區分不同的TDLS幀類型——「動作代碼」。該1位元組欄位指示我們正在傳輸的TDLS幀的種類。這反過來控制著接收端解釋「有效載荷」的方式。

高級流

在兩個對等體可以建立連接之前,雙方必須先知曉彼此的存在。這稱為「發現」階段。希望在網路上發現支持TDLS的對等體的Wi-Fi客戶端可以通過向對等體發送「TDLS發現請求」幀來實現。接收到此幀的支持TDLS的對等體通過發送「TDLS發現響應」幀進行響應。請求和響應使用1位元組的「對話令牌」彼此相關。

圖10

接下來,對等體可能希望建立連接。為此,其必須執行3次握手。這種握手具有雙重目的,首先表示兩個對等體之間成功建立了連接,其次是用於導出TDLS對等體密鑰(TPK,用於保護對等體之間的TDLS流量)。

圖11

最後,創建連接后,兩個對等體就可以在彼此之間交換對等流量。當其中一個對等體希望斷開連接時,可以通過發送「TDLS斷開」幀來實現。在接收到這樣的幀后,TDLS對等體將斷開連接並釋放所有相關資源。

現在我們已對TDLS有了很好的了解,接下來我們來仔細看看手頭的漏洞!

原語

為了確保在建立和斷開階段傳送的消息的完整性,相應的TDLS幀包括消息完整性碼(MIC)。對於建立階段,接收到第二個握手消息(M2)后,雙方便可導出TPK。使用TPK,TDLS發起者可以計算第三個握手幀內容的MIC,然後可由TDLS響應者驗證。

MIC通過編碼在握手幀中的IE的內容計算,如下所示:

圖12

同樣,斷開幀也包括一個MIC,通過一組略微不同的IE計算:

圖13

那麼我們如何在固件的代碼中找到這些計算呢?湊巧,一些指向TDLS的字元串遺留在了固件的ROM中,使我們可以快速定位相關的函數。

在對大部分指向處理TDLS動作幀的流程進行逆向工程后,我們最終到達了負責處理TDLS建立確認(PMK M3)幀的函數。該函數首先執行一些驗證,以確保請求是合法的。其查詢內部數據結構,以確保確實正在與請求對等體建立TDLS連接。然後,其驗證Link-ID IE(通過檢查其編碼的BSSID與當前網路的匹配),並且還驗證32位元組的發起者隨機數(「Snonce」)值(通過將其與存儲的初始隨機數進行比較)。

建立對請求可能確實是合法的一定程度的置信度后,該函數開始調用一個內部幫助函數,任務是計算MIC並確保其與編碼在幀中的一致。固件還包括該函數的名稱(「wlc_tdls_cal_mic_chk」)。

對該函數進行逆向工程后,我們得出以下近似高級邏輯:

圖14

從上面可以看出,雖然該函數驗證RSN IE的長度不超過分配的緩衝區長度(第13行),但其未能驗證後續的IE也不會溢出緩衝區。因此,將RSN IE的長度設置為較大的值將導致Timeout Interval和Fast Transition IE越界複製,從而溢出緩衝區。

圖15

例如,假設我們將RSN IE(x)的長度設置為最大可能值224,我們會獲得如下元素位置:

圖16

在該圖示中,橙色欄位與溢出「無關」。因為其位於緩存區邊界內。紅色欄位表示我們無法完全控制的值,綠色欄位表示完全可控的值。

比如,Timeout Interval IE在MIC計算之前驗證,且僅具有容許值約束集,這使其不可控制。同樣,FTIE的標籤和長度欄位是恆定的,因此是不可控的。最後,32位「Anonce」值由TDLS響應者隨機選擇,因此其位於我們的影響範圍之外。

但情況並非如此嚴峻。FTIE本身中的幾個欄位可以任意選擇——比如,在握手中的第一個消息期間,「Snonce」值由TLDS發起者選擇。此外,FTIE中的「MIC Control」欄位可以自由選擇,因為其不是在執行此函數之前驗證。



熱門推薦

本文由 yidianzixun 提供 原文連結

寵物協尋 相信 終究能找到回家的路
寫了7763篇文章,獲得2次喜歡
留言回覆
回覆
精彩推薦