愛伊米

利用硬體級MDS側通道漏洞實現對Chrome Sandbox的逃逸

可以利用跨程序記憶體洩漏的漏洞逃逸Chrome沙箱,在發起此攻擊之前,仍然需要攻擊者破壞渲染器,為了防止對受影響的CPU的攻擊,請確保microcode是最新的,並禁用超執行緒(HT)。

在我的上一個文章“破壞資料流”中,我描述瞭如何利用Chrome的JavaScript引擎V8中的漏洞來在渲染器中執行程式碼。為了使這種利用有用,你通常需要將其與第二個漏洞相關聯,因為Chrome的沙箱會限制你對作業系統的訪問,並且將跨站點渲染器的站點隔離移動到單獨的程序中,以防止你繞過Web平臺的限制。

在本文中,我們將研究沙盒,尤其是當從受感染的渲染器使用RIDL和類似的硬體漏洞時所產生的影響。Chrome的IPC機制Mojo基於訊息路由的機密,洩漏這些機密使我們可以將訊息傳送到特權介面,並執行不應允許渲染器執行的操作。我們將使用它來讀取任意本地檔案,以及在Windows上的沙箱外部執行。bat檔案。在撰寫本文時,Apple和Microsoft都在與Chrome安全團隊合作積極致力於修復此漏洞,以防止這種攻擊。

0x01 背景知識

以下是Chrome流程模型的簡要概述:

利用硬體級MDS側通道漏洞實現對Chrome Sandbox的逃逸

渲染器程序位於單獨的沙箱中,並且對核心的訪問受到限制,例如,透過Linux上的seccomp過濾器或Windows 上的  win32k鎖定。但是,為了使渲染器執行任何有用的操作,它需要與其他程序進行對話以執行各種操作。例如,要載入影象,將需要要求網路服務代表其獲取影象。

Chrome中用於程序間通訊的預設機制稱為Mojo。它在後臺支援訊息/資料管道和共享記憶體,但是你通常會使用C ++,Java或JavaScript中的高階語言之一繫結。也就是說,你使用自定義介面定義語言(IDL)的方法建立一個介面,Mojo用你選擇的語言為你生成存根,而你只是實現了該功能。這可以檢查出URLLoaderFactory 。mojom IDL,C ++實現,並在渲染使用。

Mojo的一項顯著功能是允許你透過現有通道轉發IPC端點。該程式碼在Chrome程式碼庫中得到了廣泛使用,即,每當你在。mojom檔案中看到接收器或遠端引數時。

利用硬體級MDS側通道漏洞實現對Chrome Sandbox的逃逸

Mojo在程序之間或更具體地在Mojo的節點之間使用特定於平臺的訊息管道。兩個節點可以直接彼此連線,但是由於Mojo支援訊息路由,因此不必連線。網路中的一個節點稱為代理節點,它具有一些其他責任來設定節點通道並執行沙箱限制的某些操作。

IPC端點本身稱為埠。在上面的URLLoaderFactory示例中,客戶端和實現方都由埠標識。在程式碼中,埠如下所示:

class Port : public base::RefCountedThreadSafe {

public:

// [。。。]

// The current State of the Port。

State state;

// The Node and Port address to which events should be routed FROM this Port。

// Note that this is NOT necessarily the address of the Port currently sending

// events TO this Port。

NodeName peer_node_name;

PortName peer_port_name;

// The next available sequence number to use for outgoing user message events

// originating from this port。

uint64_t next_sequence_num_to_send;

// [。。。]

}

上面的peer_node_name 和peer_port_name 都是用於定址的128位隨機整數。如果將訊息傳送到埠,它將首先將其轉發到正確的節點,接收節點將在本地埠對映中查詢埠名稱,並將訊息放入正確的訊息佇列。

這意味著如果瀏覽器程序中存在資訊洩漏漏洞,則可以洩漏埠名稱,並使用它們將訊息注入特權IPC通道。實際上,在Mojo核心文件的安全性部分中對此進行了宣告:

“ [。。。]任何節點只要知道埠和節點名稱,就可以將任何訊息傳送到任何其他節點的任何埠。[。。。]因此,重要的是不要將埠名稱洩漏到不應被授予相應功能的節點中。”

可以很容易地利用洩漏的埠號的一個漏洞的一個很好的例子是crbug。com/779314透過@NedWilliamson。這是blob實現中的整數溢位,它使你可以在瀏覽器程序中讀取blob前面的任意數量的堆記憶體。

該漏洞利用過程將大致如下所示:

1。 破壞渲染器。

2。 使用Blob漏洞洩漏堆記憶體。

3。 在儲存器中搜索埠(有效狀態+ 16個高熵位元組)。

4。 使用洩漏的埠將訊息注入特權IPC連線。

接下來,我們需要考慮兩件事。如何用CPU漏洞替換上面的第2步和第3步,以及如何透過特權IPC連接獲得什麼樣的原語。

0x02  RIDL

為了利用此硬體漏洞,我需要尋找另一個漏洞,該漏洞使你可以跨程序邊界洩漏記憶體。來自MDS攻擊的 RIDL 似乎是最理想的選擇,因為它完全可以保證:它允許你從受影響的CPU上的各種內部緩衝區洩漏資料。有關其工作原理的詳細資訊,請檢視論文或PPT,因為它們比我能解釋的要好得多。

已經發布了 microcode和作業系統更新來解決MDS攻擊。但是,如果你閱讀了英特爾對該問題的深入](https://software。intel。com/security-software-guidance/insights/deep-dive-intel-analysis-microarchitectural-data-sampling)研究,你會注意到,緩解措施在切換到特權較低的執行上下文時清除了受影響的緩衝區。如果你的CPU支援超執行緒,你仍然可以從物理核心上執行的第二個執行緒中洩漏資料。解決此問題的建議是禁用超執行緒或實現組排程程式。

你可以在網上找到多個驗證了該MDS 漏洞的PoC,他們中的一些具有不同的屬性:

·

它們以載入或儲存目標。

·

有些要求從L1快取中清除key。

·

你可以控制64位元組快取記憶體行中的索引從先前的訪問中洩漏或洩漏64位的值。

·

速度變化很大,取決於變體和漏洞利用。我看到的最高是針對Brandon Falk的228kB / s 的MLPDS攻擊。為了進行比較,我的機器上的漏洞利用僅達到25kB / s。

https://gamozolabs。github。io/metrology/2019/12/30/load-port-monitor。html#an-mlpds-exploit

所有利用變體有一個共同屬性是,它們在洩漏的內容上具有機率。儘管RIDL論文描述了一些針對某些值的同步原語,但通常需要觸發對key的重複訪問才能將其完全洩漏。

我最終使用不同的MDS變體為Chrome編寫了兩個漏洞利用,一個針對Xeon Gold 6154上的Linux構建,另一個針對Core i7-7600U上的Windows。我將描述這兩種方法,因為它們在實踐中最終面臨不同的挑戰。

0x03  MFBDS

微體系結構填充緩衝區資料取樣(MFBDS)

我的第一個漏洞是使用針對CPU的行填充緩衝區的MFBDS。PoC非常簡單:

xbegin out            ; start TSX to catch segfault

mov   rax, [0]        ; read from page 0 => leaks a value from line fill buffer

; the rest will only execute speculatively

and   rax, 0xff       ; mask out one byte

shl   rax, 0xc        ; use as page index

add   rax, 0x13370000 ; add address of probe array

prefetchnta [rax]     ; access into probe array

xend

out: nop

此後,你將定時訪問探針陣列以檢視已快取了哪個索引。

你可以在開頭更改0 ,以控制洩漏的快取記憶體行中的偏移量。另外,你還希望按照本文所述在洩漏值上實現字首或字尾過濾器。請注意,這隻會洩漏不在L1快取記憶體中的值,因此你希望有一種方法可以在兩次訪問之間從快取記憶體中移出key值。

https://mdsattacks。com/files/ridl。pdf

對於我的第一個洩漏目標,我選擇了一個特權URLLoaderFactory。如上所述,渲染器使用URLLoaderFactory來獲取網路資源。它將為渲染器強制執行同源策略(實際上是相同站點),以確保不會破壞Web平臺的限制。但是,瀏覽器程序還將URLLoaderFactories用於不同的目的,並且它們具有其他特權。除了忽略同源策略外,還允許它們上傳本地檔案。因此,如果我們可以洩漏其埠名之一,則可以使用它將/ etc / passwd 上傳到https://evil。website。

下一步將觸發對特權載入程式的埠名的重複訪問。使瀏覽器程序發出網路請求可能是一種選擇,但似乎開銷太大,我決定針對節點中的埠查詢。

class COMPONENT_EXPORT(MOJO_CORE_PORTS) Node {

// [。。。]

std::unordered_map ports_;

// [。。。]

}

每個節點都有一個儲存所有本地埠的雜湊對映。如果我們將訊息傳送到不存在的埠,目標節點將在對映中查詢它,發現它不存在並刪除訊息。如果我們的埠名與另一個埠名位於同一雜湊庫中,它將讀取未知埠的完整雜湊值以與之進行比較。由於埠名通常與雜湊儲存在同一快取記憶體行中,因此這還將埠名本身載入到快取記憶體中。MFBDS允許我們洩漏整個快取行,即使未直接訪問值也是如此。

該maps在一個新的Chrome例項上以大約700的儲存大小,並且主要隨著渲染器數量的增加而增長。這使攻擊變得不可行,因為我們將不得不強制使用儲存區索引和快取行偏移量。但是,我注意到一個程式碼路徑,該路徑使你可以使用服務工作者建立大量特權URLLoaderFactories。如果你建立啟用導航預載入的服務工作,則每個導航都將建立這樣的loader。透過簡單地建立多個iframe並在伺服器端停止請求,你可以同時使數千個載入程式保持活動狀態,並使暴力破解變得更加容易。

唯一缺少的是從L1快取中尋找目標值。在實踐中,簡單地用32KB資料填充我們的訊息似乎可以解決問題,因為我認為資料將被載入到受害者的L1快取中。

總結完整的利用:

1。 破壞渲染器。

2。 在$ NUM_CPU-1程序中以不同的快取行偏移量執行RIDL漏洞。

3。 安裝具有導航預載入的服務。

4。 建立許多iframe並暫停其請求。

5。 使用隨機埠名稱將訊息傳送到網路程序。

6。 如果我們在儲存索引上發生衝突,則2。中的過程可能會洩漏埠名稱。

7。 將訊息欺騙到URLLoaderFactory以將本地檔案上傳到https://evil。website。

0x04 TSX非同步中止(TAA)

在2019年11月釋出了MDS攻擊的新變種,並且由於TAA PoC似乎比我的MFBDS攻擊更快,因此我決定將其改編為Chrome攻擊。此外,VUSec釋出了一項針對儲存操作的漏洞利用程式,如果我們可以將key寫入到記憶體中的不同地址,則該漏洞應允許我們逃脫快取重新整理要求。如果我們可以觸發瀏覽器將訊息傳送到特權埠,則應該發生這種情況。在這種情況下,secret埠名稱也將以節點名稱作為字首,並且我們可以使用RIDL檔案中的技術輕鬆對其進行過濾。

我還開始尋找一個更好的原語,發現如果可以與NetworkService進行通訊,它將允許我建立一個新的NetworkContext,從而選擇儲存cookie的sqlite3資料庫的檔案路徑。

為了找出如何觸發從瀏覽器程序到NetworkService的訊息,我查看了介面中的IPC方法,以找到一種看起來可以從渲染器影響它的方法。NetworkService。OnPeerToPeerConnectionsCountChange引起了我的注意,實際上,每次更新WebRTC連線時都會呼叫此方法。你只需要建立一個偽造的WebRTC連線,每次將其標記為已連線/斷開連線時,都會觸發一條新訊息給NetworkService。

利用硬體級MDS側通道漏洞實現對Chrome Sandbox的逃逸

一旦從受破壞的渲染器中洩漏了埠名稱,我們就獲得了編寫具有完全受控路徑的sqlite3資料庫的原語。

雖然起初聽起來並不是很有用,但是你實際上可以濫用它來獲得程式碼執行。我注意到Windows批處理檔案是一種非常好的檔案格式。如果檔案的開頭有gadget,它將跳過它直到下一個“ \ r \ n”並從那裡執行下一個命令。在我的漏洞利用中,我使用它在使用者的自動執行目錄中建立一個cookies。bat檔案,新增帶有“ \ r \ n”的cookie和其中的命令,它將在下次登入時執行。

最終,此漏洞利用平均在我的機器上執行了1-2分鐘,並且持續不到5分鐘。而且我敢肯定,由於某些技術可以大大提高速度,因此可以大大改善這一點。例如,實際上MLPDS似乎比我使用的變體更快。

利用步驟:

1。 破壞渲染器。

2。 在$ NUM_CPU-1程序中以不同的快取行偏移量執行RIDL漏洞。

3。 建立偽造的WebRTC連線,並在已連線和已斷開連線之間切換。

4。 洩漏NetworkService埠名稱。

5。 使用c:\ path \ to \ user \ autorun \ cookies。bat中的cookie檔案建立一個新的NetworkContext

6。 插入cookie“ \ r \ ncalc。exe \ r \ n”。

7。 等待下一次登入。

0x05  分析總結

當我開始研究此問題時,我感到驚訝的是,即使漏洞已經公開了一段時間,它仍然可以被利用。如果你閱讀有關該主題的指南,則他們通常會在你的作業系統為最新的情況下談論如何緩解這些漏洞,並應注意你應禁用超執行緒以完全保護自己。專注於緩解措施無疑給我一種感覺,那就是漏洞已得到解決,我認為這些文章對於啟用超執行緒的影響可能會更加清楚。

話雖如此,我希望你從這篇文章中思考兩個問題。首先,資訊洩漏漏洞不僅僅可以繞過ASLR。即使不是依靠key埠名,也可能會洩漏其他有趣的資料,例如Chrome的UnguessableTokens,Gmail cookie或計算機其他程序中的敏感資料。如果你對如何大規模查詢資訊洩漏有所瞭解,Chrome可能是一個不錯的選擇。

其次,由於硬體漏洞超出了我的研究範圍,因此我長時間忽略了它們。但是,我希望我可以透過此文章為你提供有關其影響的另一個數據點,以幫助你做出是否應該禁用超執行緒的決定。對於可以用類似的方式破壞其他軟體的方式,還有很多探索的餘地,我很樂意看到更多應用硬體漏洞突破軟體安全性邊界的示例。

參考及來源:https://googleprojectzero。blogspot。com/2020/02/escaping-chrome-sandbox-with-ridl。html