摘要
1. 引言
2. 背景
3. 威脅模型
4. 尋找標記洩漏小工具
5. TIKTAG 小工具
6. 真實世界攻擊
6.1. 攻擊 Chrome
7. 評估
8. 相關研究
9. 結論與參考文獻
\
為了展示 TIKTAG 小工具在基於 MTE 的緩解措施中的可利用性,本節針對 Chrome 和 Linux 核心開發了兩個真實世界攻擊(圖 9)。使用 TIKTAG 小工具發動真實世界攻擊面臨幾個挑戰。首先,TIKTAG 小工具應在目標位址空間中執行,這要求攻擊者從目標系統中構造或尋找小工具。其次,攻擊者應控制並觀察快取狀態以洩漏標記檢查結果。接下來,我們展示在兩個真實世界系統上使用 TIKTAG 小工具的真實世界攻擊:Google Chrome 瀏覽器(§6.1)和 Linux 核心(§6.2),並討論緩解策略。
\ 6.1. 攻擊 Chrome
瀏覽器 網頁瀏覽器是基於網路攻擊的主要攻擊面,因為它處理不受信任的網路內容,如 JavaScript 和 HTML。我們首先概述威脅模型(§6.1.1),並提供在 V8 JavaScript 引擎中構造的 TIKTAG 小工具(§6.1.2)。然後,我們展示 TIKTAG 小工具在利用瀏覽器方面的有效性(§6.1.3),並討論緩解策略(§6.1.4)。
\ ==6.1.1. 威脅模型。== 我們遵循 Chrome 瀏覽器攻擊的典型威脅模型,攻擊者旨在利用渲染進程中的記憶體損壞漏洞。我們假設受害使用者訪問攻擊者控制的網站,該網站提供惡意網頁。該網頁包含精心製作的 HTML 和 JavaScript,利用受害者渲染進程中的記憶體損壞漏洞。我們假設 Chrome 的所有最先進緩解技術都已就位,包括 ASLR [18]、CFI [15]、網站隔離 [53] 和 V8 沙箱 [56]。此外,作為正交防禦,我們假設渲染進程在 PartitionAlloc [2] 中啟用隨機 MTE 標記。
\ ==6.1.2. 構造 TIKTAG 小工具。== 在 V8 JavaScript 環境中,TIKTAG-v2 被成功構造並洩漏了任何記憶體位址的 MTE 標記。然而,我們沒有找到可構造的 TIKTAG-v1 小工具,因為在我們的推測性 V8 沙箱逃逸技術(§A)中,BR 和 CHECK 之間嚴格的時序約束是不可行的。
V8 TikTag-v2 小工具。 圖 8 是在 V8 JavaScript 引擎中構造的 TIKTAG-v2 小工具及其 JIT 編譯後的偽 C 代碼。使用此小工具,攻擊者可以了解猜測標記 Tg 是否與分配給 target_addr 的標記 Tm 匹配。攻擊者準備三個陣列,slow、victim、probe 和一個 idx 值。slow 是長度為 64 的 Unit8Array,在 BR 中訪問以觸發分支預測錯誤。victim 是長度為 64 的 Float64Array,訪問它以觸發儲存到載入轉發。probe 是長度為 512 的 Uint8Array,在
\ TEST 中訪問以洩漏標記檢查結果。Number 類型的 idx 值用於 victim 的越界訪問。選擇 idx 值使得 victim[idx] 指向帶有猜測標記 Tg 的 target_addr(即 (Tg«56)|target_addr)。為了在 V8 沙箱外推測性訪問 target_addr,我們利用了我們在研究期間發現的推測性 V8 沙箱逃逸技術,我們在 §A 中詳細說明。圖 8a 的第 8 行是 TIKTAG-v2 小工具的 BR 區塊,使用 slow[0] 觸發分支預測錯誤。
\ 第 12-13 行是 CHECK 區塊,它使用 victim[idx] 執行儲存到載入轉發,使用猜測標記 Tg 訪問 target_addr。當此代碼被 JIT 編譯時(圖 8b),執行邊界檢查,將 idx 與 victim.length 進行比較。如果 idx 是越界索引,代碼返回 undefined,但如果載入 victim.length 欄位需要很長時間,CPU 會推測性地執行後續的儲存和載入指令。
\ 之後,第 17 行實現 TEST 區塊,它使用轉發值 val 作為索引訪問 probe。同樣,先進行 val 對 probe 長度的邊界檢查,但此檢查成功,因為 PROBE_OFFSET 小於 probe 陣列的長度。結果,僅當儲存到載入轉發成功時才快取 probe[PROBE_OFFSET],這是 Tg 與 Tm 匹配的情況。
\ ==6.1.3. Chrome MTE 繞過攻擊。== 圖 9a 說明了使用 TIKTAG 小工具的任意標記洩漏原語對 Chrome 瀏覽器的整體 MTE 繞過攻擊。我們假設渲染進程中存在緩衝區溢位漏洞,其中利用時序漏洞(例如,釋放後使用)在很大程度上是相同的。該漏洞溢位指向易受攻擊物件(即 objvuln)的指標(即 vuln_ptr),破壞相鄰物件(即 objtarget)。
\ 通過 PartitionAlloc 的 MTE 強制執行,兩個物件有 14/15 的機率具有不同的標記。為了避免引發異常,攻擊者需要確保 objvuln 和 objtarget 的標記相同。TIKTAG-v2 可用於洩漏 objvuln 的標記 ( 1 ) 和 objtarget 的標記 ( 2 )。如果兩個洩漏的標記相同,攻擊者利用該漏洞,這不會引發標記檢查故障 ( 3 )。否則,攻擊者釋放並重新分配 objtarget,並返回第一步,直到標記匹配。
\ ==觸發快取側通道。== 要成功利用 TIKTAG 小工具,攻擊者需要滿足以下要求:
i) 分支訓練,
ii) 快取控制,以及
iii) 快取測量。所有三個要求都可以在 JavaScript 中滿足。
首先,攻擊者可以通過使用非零 slow[0] 和邊界內 idx 執行小工具來訓練分支預測器,並在 BR 中使用 slow[0] 中的零值和越界 idx 觸發分支預測錯誤。
其次,攻擊者可以使用 JavaScript 快取逐出技術 [8, 21, 70] 逐出 slow[0]、victim.length 和 probe[PROBE_OFFSET] 的快取行。
第三,攻擊者可以使用基於 SharedArrayBuffer [16, 58] 的高解析度計時器測量 probe[PROBE_OFFSET] 的快取狀態。
\ ==利用記憶體損壞漏洞。== 給定洩漏的 MTE 標記,攻擊者可以利用渲染器中的空間和時序記憶體損壞漏洞。攻擊策略與傳統的記憶體損壞攻擊基本相同,但應確保該漏洞不會利用洩漏的標記引發標記檢查故障。我們在 §C 中進一步詳細說明攻擊策略。
\ ==6.1.4. 緩解。== 為了緩解瀏覽器渲染進程中基於 TIKTAG 小工具的 MTE 繞過攻擊,可以採用以下緩解措施:
i) 推測執行感知沙箱: 為了阻止攻擊者從類似 V8 沙箱的沙箱環境中發動基於 TIKTAG 的攻擊,可以通過防止任何超出沙箱記憶體區域的推測性記憶體訪問來加固沙箱。雖然現代網頁瀏覽器採用沙箱將不受信任的網路內容與渲染器隔離,但它們經常忽視推測路徑。
\ 例如,Chrome V8 沙箱 [56] 和 Safari Webkit 沙箱 [1] 沒有完全調解推測路徑 [27]。基於當前的指標壓縮技術 [64],可以通過遮罩指標的高位將推測路徑限制在沙箱區域。
\ ii) 推測屏障: 如 §5 所建議,在潛在 TIKTAG 小工具的 BR 之後放置推測屏障可以防止推測性標記洩漏攻擊。然而,這種緩解措施可能不適用於性能關鍵的瀏覽器環境,因為它可能引入顯著的性能開銷。
\ iii) 防止小工具構造:如 §5.2 所建議,可以通過在儲存和載入指令之間填充指令來緩解 TIKTAG-v2 小工具。雖然我們還沒有找到可利用的 TIKTAG-v1 小工具,但可以通過在分支和記憶體訪問之間填充指令來緩解,如 §5.1 所述。
\ 6.2. 攻擊 Linux 核心
ARM 上的 Linux 核心廣泛用於行動裝置、伺服器和 IoT 裝置,使其成為有吸引力的攻擊目標。利用核心中的記憶體損壞漏洞可以提升使用者的權限,因此 MTE 是 Linux 核心的一種有前途的保護機制。針對 Linux 核心的基於 TIKTAG 的攻擊與瀏覽器攻擊(§6.1)不同,構成獨特的挑戰。
\ 這是因為攻擊者的位址空間與將執行小工具的核心位址空間是隔離的。接下來,我們首先概述 Linux 核心的威脅模型(§6.2.1),並提供我們在 Linux 核心中發現的概念驗證 TIKTAG 小工具(§6.2.2)。最後,我們展示 TIKTAG 小工具在利用 Linux 核心漏洞方面的有效性(§6.2.3)。
\ ==6.2.1. 威脅模型。== 這裡的威脅模型與針對核心的典型權限提升攻擊基本相同。具體來說,我們專注於基於 ARM 的 Android Linux 核心,使用預設核心保護(例如,KASLR、SMEP、SMAP 和 CFI)進行加固。我們進一步假設核心使用 MTE 隨機標記解決方案進行加固,類似於生產就緒的 MTE 解決方案 Scudo [3]。
\ 具體來說,每個記憶體物件都被隨機標記,當物件被釋放時分配一個隨機標記,從而防止空間和時序記憶體損壞。攻擊者能夠執行非特權進程,並旨在通過利用核心中的記憶體損壞漏洞來提升其權限。假設攻擊者知道核心記憶體損壞漏洞,但不知道核心記憶體的任何 MTE 標記。觸發核心物件之間具有
\ 不匹配標記的記憶體損壞會引發標記檢查故障,這對於真實世界的利用是不希望的。此攻擊中的一個關鍵挑戰是小工具應通過重用現有核心代碼來構造,並由攻擊者可以呼叫的系統呼叫執行。由於 ARMv8 架構分離使用者和核心分頁表,使用者空間小工具無法推測性訪問核心記憶體。此設置與攻擊瀏覽器的威脅模型(§6.1)非常不同,後者利用攻擊者提供的代碼來構造小工具。我們也排除了基於 eBPF 的小工具構造 [17, 28],因為 eBPF 不適用於非特權 Android 進程 [33]。
\ ==6.2.2. 核心 TikTag 小工具==。如 §4.1 所述,TIKTAG 小工具應滿足幾個要求,每個要求都在核心環境中帶來挑戰。
首先,在 BR 中,應使用 cond_ptr 觸發分支預測錯誤,該指標應可從使用者空間控制。由於最近的 AArch64 處理器隔離使用者和核心之間的分支預測訓練 [33],因此需要從核心空間執行分支訓練。
其次,在 CHECK 中,應解除參考 guess_ptr。guess_ptr 應從使用者空間製作,使其嵌入猜測標記 (Tg) 並指向核心位址(即 target_addr)以洩漏標記 (Tm)。與瀏覽器 JavaScript 環境(§6.1)不同,使用者提供的資料在系統呼叫中經過大量清理,因此很難建立任意核心指標。
\ 例如,access_ok() 確保使用者提供的指標指向使用者空間,array_index_nospec 巨集防止使用使用者提供的索引進行推測性越界訪問。因此,guess_ptr 應該是現有的核心指標,特別是導致記憶體損壞的易受攻擊指標。例如,可以使用釋放後使用 (UAF) 中的懸空指標或緩衝區溢位中的越界指標。最後,在 TEST 中,應解除參考 test_ptr,並且 test_ptr 應可從使用者空間訪問。為了簡化快取狀態測量,test_ptr 應該是通過系統呼叫參數提供的使用者空間指標。
\ ==發現的小工具。== 我們手動分析了 Linux 核心的原始碼,以尋找滿足上述要求的 TIKTAG 小工具。結果,我們在 snd_timer_user_read() 中發現了一個潛在可利用的 TIKTAG-v1 小工具(圖 10)。此小工具滿足 TIKTAG-v1 (§5.1) 的要求。在第 10 行(即 BR),switch 語句使用使用者可控值 tu->tread(即 cond_ptr)觸發分支預測錯誤。在第 14-17 行(即 CHECK),tread(即 guess_ptr)被四個載入指令解除參考。tread 指向攻擊者可以任意分配和釋放的 struct snd_timer_tread64 物件。
\ 如果時序漏洞將 tread 轉換為懸空指標,則可以將其用作 guess_ptr。在第 20 行(即 TEST),使用者空間指標 buffer(即 test_ptr)在 copy_to_user 中被解除參考。由於此小工具無法直接從使用者空間訪問,我們對核心代碼進行了輕微修改;我們刪除了第 6 行預設情況的早期返回。這確保僅在推測路徑中訪問 buffer,以觀察由於推測執行而導致的快取狀態差異。
\ 儘管這種修改在真實世界場景中並不現實,但它展示了如果進行類似代碼更改,小工具的潛在可利用性。我們發現了更多潛在可利用的小工具,但我們無法觀察到標記匹配和不匹配之間的快取狀態差異。儘管如此,我們認為利用這些小工具具有很大的潛力。發動基於 TIKTAG 的攻擊涉及複雜且敏感的工程,因此我們無法實驗所有可能的情況。
\ 特別是,TIKTAG-v1 依賴於錯誤路徑事件的推測收縮,這也可能包括分支預測錯誤路徑中的位址轉換故障或其他異常。由於系統呼叫涉及複雜的控制流,因此可能不會按預期觸發推測收縮。此外,當核心代碼更改時,幾個小工具可能變得可利用。例如,ip6mr_ioctl() 中的 TIKTAG-v1 小工具在從其系統呼叫路徑(即 ioctl)呼叫時沒有表現出 MTE 標記洩漏行為。然而,當小工具移植到具有簡單控制流的其他系統呼叫(例如 write)時,它具有標記洩漏。
\ ==6.2.3. 核心 MTE 繞過攻擊。== 圖 9b 說明了對 Linux 核心的 MTE 繞過攻擊。以釋放後使用漏洞為例,我們假設攻擊者已識別相應的 TIKTAG 小工具 SysTikTagUAF(),能夠洩漏由該漏洞建立的懸空指標的標記檢查結果。例如,snd_timer_user_read() 中的 TIKTAG-v1 小工具(圖 10)可以洩漏 tread 的標記檢查結果,tread 可以通過釋放後使用或雙重釋放漏洞變成懸空指標。
\ 攻擊過程如下:首先,攻擊者釋放核心物件(即 objvuln)並將其指標(即 vuln_ptr)保留為懸空指標 ( 1 )。接下來,攻擊者使用 SysAllocTarget() 在 objvuln 的位址處分配另一個核心物件(即 objtarget)( 2 )。然後,攻擊者使用使用者空間緩衝區(即 ubuf)呼叫 SysTikTag()( 3 ),並通過測量 ubuf 的訪問延遲洩漏標記檢查結果(即 Tm == Tg)( 4 )。如果標記匹配,攻擊者觸發 SysExploitUAF(),一個利用釋放後使用漏洞的系統呼叫 ( 5 )。否則,攻擊者重新分配 objtarget,直到標記匹配。
\ ==觸發快取側通道。== 如 §6.1.3 所述,成功的 TIKTAG 小工具利用需要 i) 分支訓練,ii) 快取控制,以及 iii) 快取測量。對於分支訓練,攻擊者可以訓練分支預測器,並從使用者空間使用使用者控制的分支條件觸發推測。對於快取控制,攻擊者可以刷新使用者空間緩衝區(即 ubuf),而核心記憶體位址可以通過快取行跳躍 [25] 逐出。對於快取測量,可以使用虛擬計數器(即 CNTVCT_EL0)或基於記憶體計數器的計時器(即接近 CPU 週期解析度)測量 ubuf 的訪問延遲。
\ ==利用記憶體損壞漏洞。== TIKTAG 小工具能夠繞過 MTE 並利用核心記憶體損壞漏洞。攻擊者可以呼叫核心中的 TIKTAG 小工具以推測性觸發記憶體損壞並獲得標記檢查結果。然後,攻擊者可以獲得標記檢查結果,並僅在標記匹配時觸發記憶體損壞。我們在 §D 中詳細說明 Linux 核心 MTE 繞過攻擊過程。
\ ==6.2.4. 緩解。== 為了緩解 Linux 核心中的 TIKTAG 小工具,核心開發人員應考慮以下緩解措施:
i) 推測屏障: 推測屏障可以有效緩解 Linux 核心中的 TIKTAG-v1 小工具。為了防止攻擊者通過使用者空間緩衝區洩漏標記檢查結果,可以使用推測屏障加固訪問使用者空間位址的核心函式,例如 copy_to_user 和 copy_from_user。如 §5.1 所述,通過在儲存訪問(即 TEST)之前放置推測屏障,可以緩解通過儲存訪問洩漏標記檢查結果。
\ 例如,為了緩解利用 copy_to_user 的小工具,可以在 copy_to_user 呼叫之前插入推測屏障。對於利用載入訪問使用者空間緩衝區的小工具,如果在分支和核心記憶體訪問(即 CHECK)之間插入屏障,則可以緩解小工具。例如,為了緩解利用 copy_from_user 的小工具,核心開發人員應仔細分析核心代碼庫,以尋找條件分支、核心記憶體訪問和 copy_from_user() 的模式,並在分支和核心記憶體訪問之間插入推測屏障。
\ ii) 防止小工具構造: 為了消除 Linux 核心中潛在的 TIKTAG 小工具,可以分析和修補核心原始碼。由於 TIKTAG 小工具也可以通過編譯器優化構造,因此可以進行二進位分析。對於每個發現的小工具,可以重新排序指令或插入額外的指令以防止小工具構造,遵循 §5.1 和 §5.2 中的緩解策略。
:::info 作者:
:::
:::info 本論文在 CC 4.0 授權下可在 arxiv 上獲得。
:::
\


