作者:Yueqiang Cheng, Yulong Zhang, Yu Ding, Tao Wei@百度安全實驗室

1. 引言

最近Google Project Zero和一些獨立安全研究人員發現了CPU芯片硬件層面執行加速機制,也就是亂序執行(out-of-orderexecution)和推測執行(speculative execution),會引起CPU緩存的污染,從而攻擊者可以發起基于cache的側信道攻擊偷取數據。目前主要涉及到兩種攻擊方法,分別為Meltdown [4] 和Spectre [5]。Spectre涉及CVE編號CVE-2017-5753和CVE-2017-5715,而Meltdown涉及CVE編號CVE-2017-5754。

由于Meltdown和Spectre的攻擊是針對CPU硬件的缺陷進行的攻擊,因此它們的攻擊范圍特別廣,存在于各種操作系統和云平臺上。近20年的CPU/OS/VMM基本都受影響,包括從云端到桌面到移動,對業界產生巨大沖擊。這一漏洞主要用于偷取隱私數據,包括口令、證書和其他保密數據,甚至完整的內存鏡像。值得慶幸的是這些攻擊不能修改數據。影響范圍包括:

  • CPU 處理器: 近二十年的 Intel、AMD、ARM 等處理器都有影響,其中對 Intel 的處理器的影響尤為嚴重;

  • 操作系統: Windows、Linux、 Android、iOS和macOS等;

  • 虛擬機管理器:KVM, Xen等。

本文主要關注Intel CPU Meltdown和Spectre在不同場景下的攻擊以及緩解措施,包括VMM和瀏覽器等場景。這些內容對AMD/ARM的攻防也有重要的借鑒價值。這些漏洞雖然影響廣泛,但利用復雜,限制也很大。一方面,由于防護措施都是有成本的,本文給防護方提供一個指南,可以根據自己的場景來選擇必要的防護措施;另一方面,我們希望通過本文,緩解目前被夸大的恐慌情緒,但本文也同時將指出一些沒有被討論過的組合攻擊方式,這些攻擊將有比標準攻擊更加強大的威力。因此防護方不能掉以輕心,需要盡快部署相關防護措施。

2. 攻擊的場景

Meltdown [4] 和Spectre [5]具體有三個變種:

  • 變種1 (V1) Spectre: 繞過邊界檢查 (CVE-2017-5753)

  • 變種2 (V2) Spectre: 分支預測注入 (CVE-2017-5715)

  • 變種3 (V3) Meltdown: 亂序執行的CPU緩存污染 (CVE-2017-5754)

由于攻擊的影響涉及了大量的云平臺和操作系統,我們就不單獨羅列具體版本,而是針對最典型的場景來描述如何防御這些攻擊。

典型的攻擊場景

1.對虛擬機管理器 VMM 的攻擊(A1):攻擊者在 VMM 管理的一個 VM 里 面,該攻擊者完全的控制這個 VM,比如擁有這個VM kernel級別的權限,可以直接與VMM進行交互。攻擊者通過利用這些漏洞,可以獲取VMM的敏感數據,或者獲取同一物理主機下的其他VM內的數據;

2.對操作系統內核的攻擊(A2):攻擊者是用戶空間的一個應用程序,擁有任意的代碼執行能力。攻擊者通過利用這些漏洞,可以獲取內核內的敏感數據,甚至包括內核緩沖區的文件或者網絡數據;

  • 瀏覽器對操作系統內核的攻擊(A2w):攻擊者只能通過網站頁面影響瀏覽器發起攻擊,可以通過javascript,或者web assembly等機制;

3.對用戶空間其他用戶數據的攻擊(A3):攻擊者是用戶空間的一個應用程序,擁有任意的代碼執行能力。攻擊者通過利用這些漏洞,獲取同一操作系統下的其他進程的數據,包括跨docker的攻擊;

  • 瀏覽器對用戶空間其他用戶數據的攻擊(A3w):攻擊者只能通過網站頁面影響瀏覽器發起攻擊,可以通過javascript,或者web assembly等機制。
V3c組合攻擊

原始的V3攻擊,將會產生page fault,可以被kernel感知到,從而可以通過host intrusion detectionsystem (HIDS)進行探測。傳統上,可以通過Intel TransactionalSynchronization Extensions (TSX)來截獲異常,避免產生kernel異常。然而由于TSX歷史上的bug,很多云端服務器并不開啟TSX,導致該方法并不普適。

我們經過實驗后發現,可以將V3攻擊置于V1/V2的預測執行路徑上,由于這是預測執行,所以不會觸發內核異常,但該預測執行依然會觸發cache加載操作。即V1/V2->V3的這種攻擊方式,可以完成V3攻擊,但不會觸發kernel能感知的頁面異常,我們稱之為V3c組合攻擊。V3c組合攻擊的發現意味著A2攻擊場景下,要抵抗V3攻擊,必須要打內核補丁。

3. 攻擊的防御與緩解

針對上面的攻擊場景,我們把所有可行的解決方案歸納總結到表1里面。其中在云平臺上面,升級CPU微碼需要VMM的協助,用戶在自己的VM里面無法完成,除非VMM特別開放了這個功能。

表1:對虛擬機監控器和操作系統內核的攻擊評估和防御方法。“不能*”指的是攻擊者無法直接攻擊其他進程,但是攻擊者可以攻擊內核獲取數據來間接攻擊(這個是A2)。

防護措施都是有成本的,防護方可以根據自己的場景來選擇必要的防護措施。

公有云VMM的運營者,應該保障VMM不受惡意攻擊,即A1層面的防護是必須要做到的,特別是V2攻擊。使用Xen的廠商也要關注V3攻擊的防御。

云上租戶可以根據自己的需求進行防護。由于A2.V3防護的KPTI補丁有較為明顯的性能損耗,所以如果云上租戶在同一個VM內部沒有數據敏感級別區隔,而且對性能要求較高,那么可以繼續使用原始內核。如果云上租戶在同一個VM內部有多級數據敏感區隔,而且可執行代碼不固定,并能接受額外的性能損耗,那么推薦使用打了安全補丁的內核。

對于普通PC用戶,最大的威脅來自于瀏覽器訪問惡意網址以及感染上惡意代碼。這些防護與傳統PC安全沒有太大的區別,及時升級即可。

4. 攻擊能力分析

1)Spectre攻擊

Spectre攻擊有兩個變種,V1可以用于繞過內存訪問的邊界檢查,V2可以通過分支預測注入(對CPU分值預測機制的干擾)來執行代碼。

到2018年為止,幾乎所有的計算機系統都收到Spectre攻擊的影響,包括幾乎所有的服務器、桌面電腦、筆記本和移動設備。特別的是,Spectre不僅影響Intel,還影響AMD和基于ARM的處理器 [8, 2]。Intel通過官方聲明對Spectre攻擊進行了回應。AMD則回應稱,由于AMD處理器結構的不同 [1],V2攻擊對AMD處理器幾乎是不可能的。

BoundsCheck Bypass - V1

V1攻擊可以用于繞過內存訪問的邊界檢查,核心是利用了推測執行可以執行條件分支語句之后的指令這一性質。攻擊者可以利用V1攻擊來執行特定的代碼片段(gadget),獲取其無權限獲取的內存空間的內容。一個可被用于V1攻擊的代碼片段例子如:

圖1:可以被V1利用的典型代碼片段(gadget)。注意這里的x必須為攻擊者能夠影響,否則這個代碼不可以被利用發起攻擊。

這種方法惡意的利用了CPU的推測執行功能,在CPU做分支判斷期間(數十個CPU cycle內)在推測執行模式下執行if語句塊內的部分。在V1攻擊中,攻擊者在推測執行的分支中惡意執行一個越界內存訪問。雖然推測執行模式下的內存訪問不會被最后真實執行,但是其訪問的信息很有可能會被攻擊者用其他的方法感知(例如使用基于時間的側信道攻擊)。此外,感知泄露到的內存內容還可以用于構造控制流劫持的exploit。

BranchTarget Injection - V2

V2攻擊主要利用分支預測機制進行攻擊。其主要思路利用CPU內部的間接跳轉預測器(Indirect branch predictor),在推測執行模式下執行特定代碼片段。攻擊者可以通過許多方法影響甚至控制間接跳轉預測器的行為,使得間接跳轉預測器會預測執行攻擊者指定位置的代碼,從而在推測執行下執行攻擊者想要的代碼片段。條件跳轉指令可以分成兩種:條件直接跳轉和條件間接跳轉。條件直接跳轉很難被用于V2攻擊,因為其跳轉的目標位置代碼通常是不可控的。條件間接跳轉可以被用于V2攻擊,因為其跳轉的目標地址有可能被攻擊者控制。攻擊者通過控制條件間接跳轉的目標位置,或是其目標位置的代碼,使得跳轉目標處的指令片段對于隱私數據(例如密鑰、token等)有相當強的side-effect,再使用側信道感知推測執行模式下產生的side-effect來推測隱私數據(密鑰、token),從而完成攻擊。由于不同的CPU的間接跳轉預測器原理不同,因此對CPU的間接跳轉預測器進行干擾、注入的方法也各不相同。此外,超線程模式下,跑在同一個CPU核心上的兩個線程和間接跳轉預測器之間也有相當復雜的關系,也有可能參與到V2攻擊中。

關于ASLR

為了完成攻擊,攻擊者需要在污染指令的虛擬地址(Virtual Address)上與被攻擊目標的虛擬地址滿足一定的約束,從而污染目標的預測分支。因此,理論上如果有完善的地址空間隨機化(ASLR),那么攻擊者很難有效的完成攻擊。但是由于現有ASLR機制經常有信息泄露,因此攻擊者在對目標系統進行充分研究后,往往有機會構造出成功的漏洞利用代碼。為了進行有效的防護,往往需要更細粒度、更安全的ASLR防護。

關于預測執行中的內存加載時延

預測執行的時間是有限的,比如V1只有數十個CPU Cycle。而攻擊目標的內存數據如果不在cache里,很有可能從DRAM中加載目標數據就不止數十個CPU Cycle,從而無法在時間限制內完成完整的攻擊流程。

針對這種情況,攻擊者可能可以簡單的發起多次攻擊。前次攻擊雖然無法完成完整的攻擊流程,但會將目標內存數據加載進Cache,從而使得后繼的攻擊不用再阻塞在內存加載上。但是這個可能性還未被確認成功,現有的PoC也無法對任意內核地址進行攻擊以獲得成功。

2)Meltdown攻擊 - V3

V3攻擊可以被用于從用戶態讀取內核態數據。通常來說,如果用戶態程序直接訪問內核的內存區域會直接產生一個頁錯誤(由于頁表權限限制)。然而,在特定條件下,攻擊者可以利用推測執行機制來間接獲取內核內存區域的內容。例如,在某些實現中,推測執行的指令序列會將緩存在L1 Cache中的數據傳遞給隨后的指令進行操作(并影響Cache狀態)。這會導致用戶態程序能通過Cache側信道的方式推測得到內核態數據。需要注意的是該攻擊只限于已被內核分配頁表的內存(在頁表里被標為supervisor-only),被標為not present的內存區域是不能被攻擊的。

Meltdown漏洞主要影響Intel處理器,而對AMD處理器幾乎無效。Intel聲明該缺陷幾乎影響其發售的所有處理器,AMD則聲稱其處理器并不存在此缺陷 [7]。ARM聲稱主流的ARM處理器不受該漏洞影響,并發布了一份受影響的處理器列表。然而ARM的Cortex-A75處理器直接受Meltdown漏洞影響,同時Cortex-A57、Cortex-A72受到Meltdown漏洞變種的影響 [7]。同時,Raspberry Pi平臺不受所有Meltdown和Spectre漏洞的影響。

圖2:典型的Meltdown攻擊代碼樣例。>圖2:典型的Meltdown攻擊代碼樣例。

3)瀏覽器攻擊

在瀏覽器中,可以通過JavaScript或者WebAssembly進行攻擊代碼構造。但是這樣的攻擊面臨著幾個嚴重的限制。

首先是ASLR,V1/V2攻擊需要對可執行代碼的地址做精確控制,而現代瀏覽器都部署了地址隨機化。由于BTB碰撞只依賴于虛擬地址的低bit位,所以理論上攻擊者依然有機會通過大內存段堆風水操作以及多次嘗試來實現攻擊,但在瀏覽器環境下,目前尚沒有高效的攻擊方法出現。

已有的JavaScript V1攻擊,充分利用了同一個瀏覽器內部的相對地址固定的前提,完成了瀏覽器內部的跨站數據獲取。但是對于V1攻擊,要有可控的index來操縱越界讀,在PoC中可以直接傳輸。但對于現實場景下,尋找到可用的目標腳本片段也是一個很大的挑戰。

對于V3攻擊,由于JavaScript引擎會檢查數組越界,所以無法直接發起V3攻擊。但是可以結合V1攻擊,形成V3c組合攻擊。但是這依然受限于ASLR。要發起有意義的攻擊,需要結合其他的安全漏洞獲取地址泄露信息,或者做長時間大范圍的內存掃描。此外,由于JavaScript的Array index類型長度是一個32bit整數 [11],所以很難在64bit系統上有效的指向kernel內存區域。Web Assembly會提供比JavaScript更合適的攻擊環境,但單獨的攻擊實戰意義依然有限。

5. 緩解方案

邊界檢查繞過的緩解 - V1的緩解

V1攻擊高度依賴于特殊的代碼片段(gadget)。因此,簡單有效的軟件解決方案就是插入一個barrier來阻止推測運行機制在這段特殊代碼里面執行。Barrier可以選用LFENCE指令。MFENCE同樣可以,不過它的性能損失比LFENCE大。

圖3:加入LFENCE指令在判斷語句之后,防止后面的代碼執行推測運行機制。>圖3:加入LFENCE指令在判斷語句之后,防止后面的代碼執行推測運行機制。

對于Linux系統,禁用eBPF機制可以阻斷現有PoC攻擊,使得攻擊者無法通過eBPF接口注入V1 gadget到內核空間,從而顯著提升exploit的構造難度。Intel的一個分析報告 [3]指出,可以作為V1攻擊的代碼片段在Linux內核中很少。這樣使得攻擊者發起V1攻擊的可行性降低。

跳轉目標注入攻擊的緩解 - V2的緩解

對于跳轉目標注入攻擊,有兩個可行的緩解方案。

RSB 填充 + BTB 刷新。這是一個純軟件解決方案。其核心思想就是對跳轉目標的buffer, 即RSB和BTB進行清理,使得攻擊者注入的跳轉目標不再有效。因為RSB是一個32個槽的循環buffer,因此只需要32個虛假的call指令就可以把整個RSB清理一遍(實例代碼如圖4所示)。BTB的槽從1K到16K不等,而且從虛擬地址到BTB索引的映射函數f(x)還不公開,因此要清除BTB,需要首先使用逆向工程方法找到f(x),然后根據f(x)找到1k到16K的虛擬地址來對應每個BTB的槽。最后發起1K到16K個虛假的call/jmp把所有BTB的槽清空(實例代碼如圖5所示)。需要指出,該方案的性能overhead很大。

圖4:RSB Padding。32個虛假call來清空RSB。

圖5:BTB Flushing。使用1K或16K跳轉來清空BTB。

微碼升級 + 系統軟件(VMM/kernel)補丁.這個緩解方案需要CPU微碼升級和系統軟件(VMM/kernel)更新。CPU微碼的升級提供了三個新的接口給系統軟件:

  1. Indirect Branch Restricted Speculation (IBRS)。當IBRS被設置上時,高優先級代碼不會使用低優先級的跳轉地址。比如VMM不會使用任何VM提供的地址,kernel也不會使用任何用戶進程提供的地址。

  2. Single Thread Indirect Branch Predictors (STIBP)。當STIBP被設置上時,同一物理CPU上的兩個HyperThreading邏輯內核直接的跳轉地址不再共享。

  3. Indirect Branch Predictor Barrier (IBPB)。當IBPB被設置時,之前的跳轉地址不會影響之后的跳轉預測。這個功能一般用于從高優先級到低優先級切換上下文的時候。比如VMM回到VM或kernel回到用戶空間。

這三個功能是否支持可以用CPUID加ax=0x7來檢測。返回結果中rdx的第26位表明這三個新功能是否支持。對系統軟件(VMM/kernel)的更新,各個操作系統已經發布了相關的補丁。

如果無法得到微碼升級,可以考慮使用Retpoline指令替換技術 [10] 進行防御,替換掉容易被V2攻擊的間接跳轉和間接調用指令。

此外,類似于V1,Linux下關閉eBPF也可以有效的提升V2攻擊的難度。

Meltdown攻擊的緩解措施 - V3的緩解

抵御Meltdown攻擊最有效的方式就是KAISER/KPTI。KAISER/KPTI方案中要求操作系統維護兩個頁表,一個頁表給用戶程序使用,一個給kernel自己使用。并且確保程序所使用的頁表不會映射高優先級的頁面,即不會映射kernel的頁面。KAISER/KPTI方案最早提出時是為了側信道攻擊對內核地址隨機化(KASLR)的影響。該方案恰巧也可以用來抵御Meltdown攻擊。

兩個頁表的切換,會導致CR3的重新加載,從而引起TLB刷新,進而降低內存的訪問速度。如果某些應用場景需要大量的內核和用戶空間切換(兩個頁表之間的切換),會造成較高的性能開銷。為了降低這些性能開銷,kernel需要使用充分的利用PCID特性,把TLB的刷新降低。

6. 結語

本文對Meltdown和Spectre攻擊及其緩解措施進行了總結。一方面,由于防護措施都是有成本的,本文給防護方提供一個指南,可以根據自己的場景來選擇必要的防護措施;另一方面,我們希望通過本文,緩解目前媒體上夸大的恐慌情緒,但本文也同時指出了一些沒有被討論過的組合攻擊方式,這些攻擊有比標準攻擊更加可怕的威力。因此防護方不能掉以輕心,需要盡快部署相關防護措施。我們仍在研究這兩種攻擊和其他緩解措施,會在后面陸續發布最新進展。

參考資料

  1. AMD. An update on amd processor security. 2018.
  2. Douglas Busvine and Stephen Nellis. Security aws put virtually all phones, computers at risk. 2018.
  3. Intel. Intel analysis of speculative execution side channels. 2018.
  4. Lipp Moritz, Michaelm Schwarz, Gruss Daniel, Prescher Thomas, Haas Werner, Mangard Stefan, Kocher Paul, Genkin Daniel, and Hamburg Yuval, Yarom Mike. Meltdown. 2017.
  5. Kocher1 Paul, Genkin Daniel, Gruss Daniel, Haas Werner, Hamburg Mike, Lipp Moritz, Mangard Stefan, Prescher Thomas, Schwarz Michael, and Yarom Yuval. Spectre attacks: Exploiting speculative execution. 2017.
  6. Raspberrypi. Why raspberry pi isn’t vulnerable to spec-
  7. tre or meltdown. https://www.raspberrypi.org/blog/why-raspberry-pi-isnt-vulnerable-to-spectre-or-meltdown/
  8. Wikipedia. Meltdown (security vulnerability). 2018.
  9. Wikipedia. Spectre (security vulnerability). 2018.
  10. Retpoline: a software construct for preventing branch-target-injection. https://support.google.com/faqs/answer/7625886
  11. Standard ECMA-262, ECMAScript? 2017 Language Specification, https://www.ecma-international.org/ecma-262/8.0/index.html#sec-array-exotic-objects

致謝

感謝騰御安Shawn提出的寶貴意見和建議。


Paper 本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/501/