CPU Meltdown和Spectre漏洞分析

1、背景:

         1月4日,國外爆出了整個一代處理器都存在的災難性漏洞:Meltdown和Spectre。git

幾乎影響了全球20年內全部cpu處理器;這兩個漏洞可使攻擊者經過利用並行運行進程的方式來破壞處理器的特權內存,通俗的來講:攻擊者可以竊取系統中任何數據。github

         目前,全部安全廠商都對這兩個漏洞詳細信息以及攻擊方式進行復現和驗證,可是講解的都很是專業,難懂。因此我從網上搜尋了多個分析文章,結合我的簡單理解,提取了以下一些內容,簡單介紹下此次的漏洞:數組

(因爲本人對硬件技術瞭解有限以及目前爆出來的資料不是很全面,下面分析內容僅供參考)瀏覽器

2、簡單易懂的描述下這一次的漏洞:

         首先此次的兩個漏洞原理比較相似,通俗的比喻一下:緩存

         我想要知道我同事的昨天的行蹤,那麼我就試探的對同事說:我昨天看見了你和一個女生在一塊兒逛街,大家是否是。。。? 雖然我昨天壓根兒什麼都沒看到,可是我說完,他愣了一會(愣神比較久),回了一句:我憑什麼要告訴你?!雖然他沒有認可,可是顯然我已經知道了答案。安全

         此次的漏洞也是同理,利用了CPU的兩個特殊的機制:其中Meltdown利用了CPU的亂序執行,Spectre利用了CPU的預測執行。服務器

         Spectre預測執行:在整個OS系統中,某個應用程序(惡意軟件)去詢問操做系統:「用戶剛纔登陸的密碼第一個數字是1嗎?」操做系統回覆:「不關你的事,你沒有權限知道。」架構

這個過程自己是沒有問題的,可是問題出在:操做系統雖然沒有明確的回覆,可是他內心想了一遍這個答案,尤爲是當對方問到一個正確的數字時,他回答的稍微猶豫了幾毫秒,這個事情被惡意軟件注意到了,就能夠經過反覆的提問,最後猜到了密碼是什麼。函數

        Meltdown亂序執行:假設有abc三個地址,其中a地址沒有訪問的權限,可是b和c能夠訪問,此時執行下面這個條件表達式:性能

         x= a?b:c

         表面看來,因爲a地址沒法訪問,因此係統會直接報錯!但實際上,CPU爲了加快執行速度,會採用多流水線做業方式。它會在檢查a是否可訪問的同時,預先就往下執行了。等到權限檢查結果回來,已經根據a的結果完成了b或者c的加載,只是尚未賦給x而已。通過加載的b或者c會在緩存裏。雖然報錯了,但若是再次訪問就會比較快。因而再次訪問b和c,根據返回的時間快慢,就能夠猜到a的內容!

3、Meltdown(熔斷)和Spectre(幽靈)區別:

一、Meltdown依賴於Intel的CPU設計漏洞,在OOO時,忽略對memory權限的檢查。

   Spectre則是更嚴重的漏洞,涉及到近20年的Intel, AMD, Qualcomm廠家和其它ARM的處理器,並且更難修復。

二、官方表述:

         1.Meltdown(熔燬)

         Meltdown破壞了位於用戶和操做系統之間的基本隔離,容許惡意代碼訪問主機任意內存,從而竊取其餘應用程序以及操做系統內核的敏感信息。這個漏洞「熔化」了由硬件來實現的安全邊界。容許低權限用戶級別的應用程序「越界」訪問系統級的內存,從而形成數據泄露。

         2.Spectre(幽靈)

         Spectre則是破壞了不一樣應用程序之間的隔離。問題的根源在於推測執行(speculative execution),這是一種優化技術,處理器會推測在將來可能執行的指令並預執行。這種技術的目的在於提早準備好計算結果,當這些數據被須要時可當即使用,以提高系統運行效率。內在的緣由是CPU的運行速度大大快於內存的讀取速度。在此過程當中,英特爾等CPU沒有很好地將低權限的應用程序與訪問內核內存分開,這意味着攻擊者可使用惡意應用程序來獲取應該被隔離的用戶級私有數據。

4、漏洞利用方式及影響:

利用方式:

一、雲端主機(包括物理機和同機其餘虛擬機)的相關敏感數據;對於雲服務而言,攻擊者會經過租用雲服務、利用其自身脆弱性或安裝惡意應用程序實施攻擊,並可能獲取到能夠支持雲內橫向移動的關聯數據。因爲雲服務基本都是在一臺服務器上運行多個虛擬機,致使越界訪問其餘雲主機的證書、密碼、祕鑰等

二、竊取桌面用戶敏感信息。對於桌面用戶而言,攻擊者可從瀏覽器側看成攻擊入口。目前網上已經驗證,經過一段JS代碼能夠在用戶瀏覽器中成功利用此漏洞。

三、該漏洞對於專有設備的影響,目前還在分析評估中

利用難度:

漏洞利用難度很低。相關漏洞已有成熟PoC代碼流出

利用POC驗證代碼:

 

https://github.com/Eugnis/spectre-attack

 

https://github.com/feruxmax/meltdown

 

https://github.com/gkaindl/meltdown-poc

 

https://github.com/turbo/KPTI-PoC-Collection

漏洞影響:

Windows、Linux、macOS、亞馬遜AWS、谷歌安卓均包含在內

Intel、ARM的Cortex-A架構和AMD處理器。Cortex-A目前普遍用於手機SoC平臺,包括高通、聯發科、三星等等。

漏洞危害:

相關漏洞自己只能讀取數據,不能修改數據,但因爲其獲取的數據中有可能包括口令、證書和其餘敏感數據,甚至可以完整copy內存鏡像,意味着能夠獲取全部打開的文件和信息,所以這個漏洞比通常性的虛擬機對雲的危害更大。這種攻擊對雲的安全監測機制幾乎不受影響,所以其對雲安全、包括私有云,危害極大。

5、漏洞修復:

目前Intel及其餘芯片廠商還沒有發佈修補補丁

但大多數操做系統商(微軟、CentOS)和雲技術廠商已經發布了臨時補丁,但對於系統性能會有影響,須要謹慎評估後再進行修復。

6、專業漏洞解讀:

CPU亂序執行和預測執行致使的安全問題

亂序執行(Out-of-Order Execution) [1] 和預測執行(Speculative Execution) [2] 是現代CPU爲了提升性能一般採用的優化方式。亂序就是指CPU不按照程序嚴格規定的前後順序執行,預測就是CPU基於先有經驗預先執行了後續可能執行的代碼。傳統觀念認爲,因爲CPU在運行過程當中會丟棄亂序執行和預測執行所致使的不正確的運算結果,因此亂序執行和預測執行不會對程序的正確性和安全性形成任何影響。然而,最新的發現代表攻擊者徹底能夠利用這兩種CPU特性進行側信道攻擊。目前已知的Meltdown攻擊和Spectre攻擊就是兩個典型的攻擊實例 [3]。

 

從本質上來說,這兩種攻擊都屬於基於CPU緩存(cache)的側信道攻擊的範疇。這種側信道攻擊在最近十年國外的計算機安全研究領域很是流行。它們的基本假設是攻擊者在目標主機上擁有必定的執行權限(好比操做系統的一個普通進程,雲計算中的一個虛擬主機,或者瀏覽器中的一段Java代碼),而後經過控制本身內存空間的數據(例如讀取等等)來間接的控制CPU緩存。因爲CPU緩存是攻擊者和目標主機上的目標程序共享的,這種對緩存的間接控制能夠被攻擊者用來推測目標程序的行爲。舉個例子來講,若是攻擊者和目標程序共享物理內存(好比同一個操做系統的兩個程序每每共享同一個動態連接庫),攻擊者能夠反覆的利用CPU指令把這塊內存的某個地址清除出CPU緩存(Flush階段),而後在必定的時間間隔後讀取這個地址上的內存數據而且測量讀取的時間(Reload階段)。經過這種方式,攻擊者能夠清楚的知道該地址是否被目標程序讀取過,由於一旦目標程序讀取該地址,其對應的內存會被導入CPU緩存,從而使得攻擊者本身對這個地址的訪問變快(因爲從緩存讀取要遠遠快於內存)。這種攻擊方式被稱爲Flush+Reload [6]攻擊。此外CPU緩存側信道還有Evict+Time [7], Prime+Probe [8] 等攻擊方式。

 

然而,以往的側信道攻擊針對的目標是被攻擊者內存讀取的模式,例如某條指令是否被執行或者某個數據是否被訪問,而不能直接讀取被攻擊者的內存。而Meltdown攻擊[4] 和Spectre攻擊[5] 的目標是越權的內存讀取,好比讀取(dump)整個內核的內存數據。這就使得這種側信道攻擊的後果更加嚴重。這也是爲何這個CPU漏洞會被媒體大肆渲染。下面咱們就對這兩種攻擊的基本形式和本質作一下介紹。

 

Meltdown攻擊

 

Meltdown攻擊利用現代CPU中亂序執行 (out-of-order execution)的特性,完全攻破本來由硬件保證的內存隔離,使得一個僅僅具備普通進程權限的攻擊者能夠用簡單的方法來讀取內核內存。應該強調一點,Meltdown攻擊不是針對KASLR[9]的攻擊。攻擊KALSR相對要簡單不少,由於它的目標僅是獲取內核內存的虛擬地址,而Meltdown的攻擊目標是獲取內核內存的內容。

 

Meltdown攻擊的本質是利用CPU進行的安全檢查和亂序執行之間的race condition,給攻擊者創造一個很短的攻擊窗口。亂序執行是指當CPU中的某些指令須要等待某些資源,好比內存讀取時,CPU不會在當前指令中止,而是利用空閒的計算能力繼續執行後續的指令。這大大地增長了計算能力的利用率,從而提高了CPU性能。在支持亂序執行的CPU上,指令的執行並非順序進行的。好比後面的指令可能在前面指令執行結束以前就開始執行。然而,爲了保證程序的正確性,指令退休(retirement)必須是順序進行的,而CPU的安全檢查是在指令退休時纔會進行。這樣的結果是,在CPU對某一條指令進行安全檢查以前,一部分在該指令後面的指令會因爲CPU的亂序執行而被提早執行。例如,一條用戶空間的指令訪問內核內存會致使CPU拋出異常,然而該異常只有在這條指令退休的時候纔會被CPU處理,而因爲亂序執行而被提早執行的指令會被CPU丟棄。因爲CPU保證程序的正確性,亂序執行本不會產生安全隱患。然而,因爲亂序執行的指令對緩存的操做在這些指令被丟棄時不會被重置,攻擊者就能夠經過緩存側信道的方式來獲取這些亂序執行的信息,從而致使了Meltdown攻擊。本質上,Spectre攻擊的原理也是同樣的。咱們會在後面介紹。

 

如下是一個簡化的Meltdown攻擊的基本指令:

 

1 ; rcx = kernel address2 ; rbx = probe array3 mov al, byte [rcx]4 shl rax, 0xc5 mov rbx, qword [rbx + rax]

 

首先,在指令3中一個具備用戶級權限的攻擊者訪問目標內核內存地址(存儲在寄存器rcx中)。因爲訪問了內核地址,這一條指令將會觸發異常,使得它和它以後的指令對寄存器的修改將被所有丟棄。可是在等待CPU完成執行該指令的同時,後兩條指令由於亂序執行實際上已經被執行過了,而且此時的計算是根據指令3所讀取到的數據所進行,並不受CPU權限限制。指令4將會把這個數據乘以4096,並在指令5中將其做爲offset來對數組probe array進行訪問。因爲一個內存頁的大小是4KB,不一樣的數據將會致使不一樣的內存頁被訪問並存放到CPU緩存中。此後,另外一個攻擊者進程就能夠經過緩存側信道攻擊,來了解哪一個內存頁被訪問過了,從而推斷出被訪問的內核內存數據。

 

具體的緩存攻擊方式有Flush+Reload [6],Evict+Time [7],或者Prime+Probe [8]。在Meltdown這個場景中(數組probe array是在攻擊者本身的內存空間的),比較簡單並且有效的攻擊方法是Flush+Reload,前面已經描述過其基本思想。簡單的講,Flush+Reload攻擊首先把probe array的相對應的內存用clflush指令清除出CPU緩存,而後在執行了上述攻擊代碼後再逐一訪問probe array的各個內存頁並記錄訪問時間。訪問時間短說明上述代碼執行過程當中CPU已經把對應的內存頁加載到緩存中了,緣由是這個內存頁對應的offset正好是內核空間中rcx指向的內存內容。

 

總的來講,Meltdown攻擊的指令由兩部分組成:第一部分利用亂序執行來訪問受限內存,第二部分根據所讀取到的數值再編碼到內存的訪問,並經過緩存側信道提取信息。攻擊的關鍵在於,亂序執行的這兩條指令必須在讀取內核內存的指令退休以前,也就是權限審覈以前,執行完畢。另外,因爲訪問受限內存會致使操做系統拋出異常,攻擊者能夠經過hardware transaction memory等方式抑制異常[11]或者用其餘方式處理異常[4],從而反覆不間斷的對受限內存進行遍歷訪問。

 

Spectre攻擊

 

Spectre攻擊利用了CPU的預測執行對系統進行攻擊。預測執行是另一種CPU優化特性。在分支指令執行時,因爲分支指令執行可能須要內存讀取(上百個CPU週期),在分支指令執行結束以前,CPU會預測哪個分支會被運行,提取相應的指令代碼並執行,以提升CPU指令流水線的性能。CPU的預測執行是經過分支預測單元(BPU)進行的。簡單的理解,BPU儲存了某個分支指令最近執行過的分支跳轉的結果。CPU的預測執行遇到分支指令時,會根據BPU的預測結果進行跳轉。當預測執行發現預測錯誤時,預測執行的結果將會被丟棄,CPU的狀態會被重置。然而,與亂序執行相似,預測執行對CPU緩存的影響會被保留。Spectre和Meltdown攻擊在這一點上比較相似。

 

Spectre攻擊主要分爲三個階段:

 

準備階段: 在這一階段,攻擊者經過一些操做來訓練CPU的BPU,以使其在運行目標代碼時會進行特定的預測執行。同時,攻擊者能夠執行一些操做來提升預測執行發生的機率,好比把條件判斷所需的數據擠出緩存,這樣執行分支指令的時間會加長。另外,攻擊者也能夠在這一階段作好側信道的準備工做,好比Flush+Reload攻擊中的Flush部分。

 

攻擊階段:攻擊者利用CPU的預測執行把目標的機密數據轉移到微架構側信道中。具體的攻擊方法咱們下面詳細描述。

 

機密數據提取階段: 經過測量Flush+Reload或其餘緩存攻擊的方法中Reload內存時間,攻擊者能夠從緩存側信道中提取出目標機密數據。這一點跟Meltdown攻擊十分類似。

 

在攻擊階段,攻擊者利用CPU的預測執行把目標的機密數據轉移到微架構側信道中。常見的分支指令包括條件分支指令和間接分支指令。因此相對的Spectre攻擊也有兩種不一樣的方式。其主要的思想是,攻擊者經過控制目標程序的某個變量或者寄存器,使其讀取攻擊者指定的內存地址。這裏攻擊者指定的內存地址的內容就是攻擊者試圖獲取的機密數據(好比用戶密碼)。若是目標程序中含有將這個機密數據做爲內存訪問的指針或者數組offset,那麼攻擊者就能夠利用緩存側信道來提取被訪問的內存地址,進而提取目標機密數據。

 

攻擊的危害

 

本質上講Meltdown和Spectra都是基於側信道的攻擊,主要用於信息泄露,並不能對目標內存地址進行任意修改。Meltdown攻擊每每用於攻擊者代碼因爲權限的限制而不能任意讀取其所在的內存地址空間的狀況。好比在操做系統中內核內存會被映射到全部普通進程的地址空間,儘管普通進程能夠經過虛擬地址訪問全部受限內存,包括內核的地址空間,直接訪問內核地址會拋出異常而終止。而Meltdown攻擊能夠幫助攻擊者完成這樣的操做。在雲計算的虛擬機架構上也有相似的問題,使得虛擬機能夠經過Meltdown攻擊任意讀取雲服務器宿主機(host)虛擬機管理程序(VMM)的內存地址。而Spectra攻擊則利用目標程序的特殊結構,經過系統調用或者函數調用的方式控制其中的某個變量來達到泄漏目標程序(或內核)地址空間中內存內容的目的。好比文獻[5]提出了Java代碼訪問整個瀏覽器進程內存的方法。而文獻[10]提出了利用內核即時編譯(Just-in-time compilation)的特性進行提權攻擊,正是因爲即時編譯出得代碼具備Spectra攻擊所須要的特殊結構。

 

Meltdown攻擊所攻擊的並非軟件漏洞,而是CPU設計自己的安全缺陷。因此Meltdown攻擊適用普遍,後果嚴重。它已經被證實在2010年後發佈的Intel桌面及服務器CPU架構上所有可行。實驗證實我的計算機和雲服務器全都會受到影響,而被成功攻破的操做系統包括Linux,MS Windows,以及包含Docker,LXC,和OpenVZ在內的container。在ARM和AMD處理器上,儘管Meltdown攻擊所依賴的硬件漏洞一樣被證明存在,目前尚無完整的攻擊。可能的緣由包括指令執行過慢,CPU的流水線(Pipeline)太短等等。相比之下,Spectre攻擊須要目標程序具備特殊結構,因此受到目標軟件的限制。若是目標程序不具備該特殊結構,那麼Spectre攻擊就很難進行。可是相對於Meltdown攻擊目前僅限於Intel處理器上,Spectre攻擊適用於Intel,AMD,ARM等衆多處理器上。

 

漏洞的防護

 

雖然Meltdown和Spectre是CPU漏洞,短期內很難經過CPU升級來修補漏洞。目前對Meltdown的主要防護手段是以軟件徹底隔離用戶態和內核態來實現,雖然有分析稱這樣程序的性能可能會大幅降低。而Spectra的防護就更加困難,藉助編譯器作程序分析,添加順序執行指令(好比lfence,cpuid)是一種可能的方案。咱們也會繼續跟蹤重要廠商對漏洞的修補,並對這些修補方式進行測試。咱們實驗室也會研究和開發其餘安全技術對這些攻擊進行防範。

 

對於通常用戶,只要不被執行惡意代碼,好比不去訪問惡意網站,就不會有不可信代碼進入內存執行,就不會被Spectra和Meltdown攻擊。因此我的用戶仍是能夠利用已有的防護手段(好比惡意網站攔截)對本身進行保護。同時也應該及時關注系統軟件廠商,好比操做系統廠商和瀏覽器廠商的補丁而且隨時更新。

 

對於在雲端,因爲攻擊者能夠租借虛擬環境來執行攻擊者想執行的任何代碼,因此攻擊者能夠利用它們去從虛擬機用戶態讀宿主機的內核態以及虛擬態的關鍵數據,從而能夠攻擊其餘虛擬機。因此雲廠商有責任在第一時間對這些CPU漏洞進行軟件修補。企業用戶應該採起積極的態度配合或者推進漏洞的控制。

相關文章
相關標籤/搜索