張經(jīng)宇
?
CPU漏洞熔斷、幽靈原理、風(fēng)險(xiǎn)與應(yīng)對(duì)措施
張經(jīng)宇1,2
1.中國(guó)移動(dòng)通信集團(tuán)有限公司,北京 100033 2.天津大學(xué)微電子學(xué)院,天津 300072
分析了Intel、AMD和ARM等CPU芯片存在熔斷、幽靈系列等安全漏洞的技術(shù)背景、漏洞原理、風(fēng)險(xiǎn)及影響,提出了應(yīng)對(duì)措施和修復(fù)方法。
CPU;安全漏洞;熔斷;幽靈
旁路攻擊是一種從電子系統(tǒng)物理實(shí)現(xiàn)過(guò)程中獲得信息的攻擊方式。電子設(shè)備在計(jì)算過(guò)程中除了輸出正常結(jié)果外,通常會(huì)有其他可觀察的特征。其中運(yùn)行時(shí)間、功率消耗、電磁泄漏甚至聲音都可以作為信息源,用來(lái)進(jìn)一步進(jìn)行系統(tǒng)破解。對(duì)于個(gè)人電腦、手機(jī)等,由于可執(zhí)行未知來(lái)源的程序,它的旁路攻擊手段可以不需要外部測(cè)量設(shè)備,主要針對(duì)緩存時(shí)間、分支預(yù)測(cè)歷史、分支目標(biāo)緩沖器等,還有裝載錯(cuò)誤攻擊來(lái)改變物理內(nèi)存和CPU的值。
現(xiàn)代CPU的線程之間共享緩存,意味著內(nèi)核數(shù)據(jù)和不同程序的數(shù)據(jù)混合放在一起,只有在計(jì)算結(jié)果提交時(shí)才會(huì)檢查權(quán)限。這就會(huì)為不同線程間竊取數(shù)據(jù)留下隱患,常見(jiàn)的高速緩存隱蔽通道竊取數(shù)據(jù)方式有Flush+Reload和Evict+Reload[1]。
為了提高CPU執(zhí)行效率,亂序執(zhí)行被引入。在傳統(tǒng)的順序執(zhí)行架構(gòu)中,指令嚴(yán)格按照順序執(zhí)行。由于存儲(chǔ)讀取速度低于CPU執(zhí)行速度,因此經(jīng)常會(huì)出現(xiàn)CPU停下來(lái)等待數(shù)據(jù)讀取的情況,從而降低整體運(yùn)行速度。如從內(nèi)存中提取數(shù)據(jù)需要超過(guò)100個(gè)時(shí)鐘周期,而處理一條指令一般僅需4~5個(gè)時(shí)鐘周期,就會(huì)出現(xiàn)CPU等待的現(xiàn)象。亂序執(zhí)行可以交替執(zhí)行不同的流水線,從而節(jié)省等待時(shí)間,保證整體運(yùn)行速度。預(yù)測(cè)執(zhí)行是CPU根據(jù)現(xiàn)有信息,利用空閑時(shí)間提前執(zhí)行一些將來(lái)可能會(huì)使用的指令,如果將來(lái)使用,就能大幅提高執(zhí)行速度。如果將來(lái)未用,計(jì)算結(jié)果便會(huì)廢棄,并回退到未執(zhí)行前的狀態(tài)[2]。分支預(yù)測(cè)是CPU嘗試提前猜測(cè)分支(如if-then-else結(jié)構(gòu))結(jié)果來(lái)提前執(zhí)行,可以通過(guò)多種算法提高預(yù)測(cè)準(zhǔn)確率。
在微指令被重排序緩沖器(Reorder Buffer)排序后就會(huì)轉(zhuǎn)發(fā)到統(tǒng)一保留站。沒(méi)有統(tǒng)一保留站之前CPU每次執(zhí)行需要從寄存器中讀取數(shù)據(jù),而現(xiàn)在可以從保留站中提前讀取操作數(shù)并保存操作結(jié)果,這樣亂序執(zhí)行的后續(xù)指令可以在第一時(shí)間獲得需要的數(shù)值。
為了實(shí)現(xiàn)進(jìn)程之間的隔離,目前進(jìn)程均被操作系統(tǒng)分配使用虛擬地址空間,而虛擬地址通過(guò)轉(zhuǎn)化表轉(zhuǎn)化到物理地址,轉(zhuǎn)化表中定義了映射和權(quán)限[3]。操作系統(tǒng)內(nèi)核也同樣使用虛擬地址空間,但所需的讀寫(xiě)權(quán)限較高,所以用戶進(jìn)程無(wú)法直接訪問(wèn)內(nèi)核數(shù)據(jù),只有CPU在特權(quán)模式下可以訪問(wèn)內(nèi)核地址空間。在將虛擬地址轉(zhuǎn)換為物理地址的同時(shí),CPU會(huì)檢查虛擬地址的權(quán)限位,確認(rèn)其訪問(wèn)權(quán)限。這種安全隔離方式被認(rèn)為是安全的。所以現(xiàn)在的操作系統(tǒng)都會(huì)將整個(gè)內(nèi)核映射到每個(gè)用戶進(jìn)程的虛擬地址空間。
2018年1月3日,國(guó)外安全研究機(jī)構(gòu)Google Project?Zero公布了兩組CPU漏洞,即Meltdown(熔斷),對(duì)應(yīng)漏洞CVE-2017-5754(亂序執(zhí)行緩存污染)[1]和Spectre(幽靈),對(duì)應(yīng)漏洞CVE-2017-5753(邊界檢查繞過(guò))、CVE-2017-5715(分支目標(biāo)注入)[2]。
熔斷攻擊是利用亂序執(zhí)行漏洞和高速緩存旁路通道攻擊結(jié)合,繞過(guò)正常權(quán)限檢查,讓未授權(quán)進(jìn)程讀取到其他正在運(yùn)行進(jìn)程地址空間的任何數(shù)據(jù)。幽靈攻擊是利用推測(cè)執(zhí)行和微體系結(jié)構(gòu)隱蔽通道的數(shù)據(jù)泄漏結(jié)合,穿透內(nèi)存隔離邊界獲取機(jī)密信息。這兩種攻擊竊取數(shù)據(jù)后傳輸方式均通過(guò)高速緩存Flush+Reload、Evict+Reload,但兩種攻擊的竊取方式不同[3]。
熔斷利用了亂序執(zhí)行,使用了非法內(nèi)存訪問(wèn)和引發(fā)異常之間的時(shí)間窗口執(zhí)行指令。攻擊包括三個(gè)步驟:攻擊者選擇的內(nèi)存地址(但無(wú)法訪問(wèn)到)被加載到寄存器里;瞬態(tài)指令根據(jù)寄存器內(nèi)容將探測(cè)陣列內(nèi)容加載至高速緩存中;攻擊者使用Flush+Reload來(lái)確定被訪問(wèn)的探測(cè)陣列行數(shù),從而確定所選內(nèi)存地址的內(nèi)容,如圖1所示。
圖1 熔斷的核心代碼
圖1中,rcx內(nèi)存儲(chǔ)的是要訪問(wèn)的核心內(nèi)存地址,rbx是一個(gè)256*4? 096(28*212)的探測(cè)陣列,2的8次方源于1? byte=8? bit,4? 096源于一個(gè)內(nèi)存塊是4? kB,從而避免CPU預(yù)讀取附近內(nèi)存內(nèi)容,混淆被讀取地址的真實(shí)內(nèi)容。
當(dāng)執(zhí)行第四條指令時(shí),CPU對(duì)其做權(quán)限檢查,并發(fā)現(xiàn)用戶級(jí)權(quán)限無(wú)法訪問(wèn)核心地址從而觸發(fā)異常。但由于亂序執(zhí)行的緣故,第五、六、七條指令已經(jīng)在第四條指令從內(nèi)存讀取數(shù)據(jù)期間執(zhí)行了。第五條指令是指將讀取的數(shù)據(jù)乘以4? 096,而第七條指令是指根據(jù)讀取的數(shù)據(jù)內(nèi)容,將探測(cè)陣列該行數(shù)的內(nèi)容加載到寄存器里(期間也會(huì)加載到高速緩存里)。由于使用了前文所述的統(tǒng)一保留站,在CPU讀取數(shù)據(jù)的第一時(shí)間(還沒(méi)有進(jìn)行權(quán)限確認(rèn)時(shí)),數(shù)據(jù)就已經(jīng)被后續(xù)指令讀取。雖然在權(quán)限確認(rèn)后這些指令帶來(lái)的所有操作狀態(tài)改變已全部恢復(fù),管線清空,但由于高速緩存沒(méi)有被清空,其中的部分探測(cè)陣列還在,就為下一步的Flush+Reload提供了便利。
Flush+Reload的原理為:逐行讀取探測(cè)陣列(256行,4? 096列)并對(duì)讀取用時(shí)計(jì)時(shí)。由于攻擊代碼之前已經(jīng)讀取過(guò)一行內(nèi)容,可以發(fā)現(xiàn)相比其他行,該行的內(nèi)容讀取用時(shí)特別短。該行的行數(shù),就是想要的內(nèi)容字節(jié)。這樣的過(guò)程重復(fù)多次,即可將全部需要的內(nèi)容逐個(gè)字節(jié)地讀取出來(lái)。
假設(shè)需要讀取的內(nèi)容是“123456789”,需要通過(guò)熔斷攻擊方式探測(cè)出來(lái)。第一個(gè)字節(jié)內(nèi)容是“1”,根據(jù)ASCII碼表對(duì)應(yīng)49,那么核心攻擊代碼的第七條指令就會(huì)把探測(cè)矩陣的第49行內(nèi)容讀取到高速緩存中,在后期Flush+Reload過(guò)程中,第49行也會(huì)讀取得特別快,從而識(shí)別到該字節(jié)內(nèi)容是“1”,然后將要訪問(wèn)的內(nèi)存地址加一后讀取下一個(gè)字節(jié),從而逐個(gè)字節(jié)讀取出該內(nèi)容。
幽靈5753攻擊分為三步:首先攻擊者訓(xùn)練CPU的分支預(yù)測(cè)器,確保分支預(yù)測(cè)在下一次循環(huán)時(shí)順利執(zhí)行;然后把分支條件清出高速緩存,誘使CPU推測(cè)并錯(cuò)誤執(zhí)行惡意代碼,從而泄露機(jī)密信息;最后通過(guò)隱蔽通道將機(jī)密信息傳輸出來(lái)。最后一步是與熔斷相同的Flush+Reload過(guò)程,不再?gòu)?fù)述[2]。
當(dāng)具有分支預(yù)測(cè)的CPU遇到類似IF語(yǔ)句的分支條件語(yǔ)句時(shí),由于判斷條件可能并不在CPU的寄存器或高速緩存中,因此為了避免等待,CPU會(huì)根據(jù)以往判斷的結(jié)果預(yù)測(cè)本次的結(jié)果。
在現(xiàn)在Intel、AMD的CPU中,分支預(yù)測(cè)機(jī)制為全局分支預(yù)測(cè),包含兩個(gè)層次:內(nèi)部是飽和計(jì)數(shù)器。只有連續(xù)選擇“真”兩次,才可以將預(yù)測(cè)方向從原有強(qiáng)“假”改變至“真”,反之亦然。外部是全局預(yù)測(cè)歷史寄存器,包含了分支結(jié)果歷史、不同分支之間的關(guān)聯(lián)關(guān)系(當(dāng)分支0、1是真時(shí),分支2是假)等。這意味著訓(xùn)練分支預(yù)測(cè)器需要比2次更多的次數(shù),才可以確保分支預(yù)測(cè)選擇“真”,保證攻擊程序持續(xù)讀取機(jī)密信息。在幽靈的原理驗(yàn)證代碼中,訓(xùn)練次數(shù)為5次。
圖2 幽靈的核心代碼
在幽靈的核心代碼(見(jiàn)圖2)中,array1是某一長(zhǎng)度較短的數(shù)組,array1_size是array1的長(zhǎng)度,array2是探測(cè)數(shù)組,數(shù)組長(zhǎng)度256*512,用途和熔斷基本相同。幽靈為了讀取機(jī)密,需要將array1[x]指向機(jī)密字節(jié)的地址,即x=機(jī)密字節(jié)地址-array1的開(kāi)始地址。但這超出了array1的邊界,在正常的代碼執(zhí)行會(huì)觸發(fā)異常,機(jī)密讀取不到,所以需要繞過(guò)邊界檢查。核心代碼就是為了這個(gè)目的編寫(xiě),繞過(guò)邊界檢查需要:
(2)array1_size和array2不在CPU的高速緩存中,而秘密字節(jié)內(nèi)容被緩存。
高速緩存的要求可以通過(guò)大量讀取不相干的內(nèi)存數(shù)據(jù)來(lái)沖洗,或者在X86中使用CLFLUSH指令,清除包含指定信息的緩存線。
核心代碼執(zhí)行時(shí),CPU會(huì)先將x與array1_size進(jìn)行對(duì)比,由于array1_size不在高速緩存中,需要從內(nèi)存中提取,用時(shí)較長(zhǎng)。CPU會(huì)根據(jù)訓(xùn)練結(jié)果假定該判斷條件為真,讀取秘密字節(jié)內(nèi)容并計(jì)算array1[x]*256,將array2[array1[x]*256]的內(nèi)容讀取到高速緩存中。此時(shí)array1_size被讀取到,發(fā)現(xiàn)判斷預(yù)測(cè)錯(cuò)誤,CPU就將CPU狀態(tài)回置,寄存器相應(yīng)內(nèi)容清空,但是高速緩存中仍然保留了array2[array1[x]*256]的內(nèi)容,再通過(guò)第三步的Flush-Reload即可讀出機(jī)密字節(jié)。
經(jīng)過(guò)各方的測(cè)試,熔斷、幽靈攻擊影響到1995年以后Intel生產(chǎn)的CPU、除Cortex-M型號(hào)之外的ARM及部分AMDCPU芯片。使用上述處理器的各類操作系統(tǒng)和云計(jì)算平臺(tái)均受影響,廣泛涉及目前大部分的PC、手機(jī)、平板電腦等。其中公有云平臺(tái)由于存在多個(gè)租戶共用一臺(tái)宿主機(jī)的情況,虛機(jī)到虛機(jī)、虛機(jī)到主機(jī)是漏洞攻擊的薄弱點(diǎn),需要盡快完成升級(jí)補(bǔ)丁。
由于熔斷、幽靈漏洞的攻擊目的均為竊取機(jī)密數(shù)據(jù),所以未對(duì)任何系統(tǒng)的正常運(yùn)行造成較大影響(實(shí)施攻擊時(shí)會(huì)導(dǎo)致短時(shí)CPU利用率飆高,但并沒(méi)有長(zhǎng)期影響)。
主要通過(guò)內(nèi)核頁(yè)表隔離(KPTI)來(lái)防護(hù)熔斷漏洞,KPTI可以不再映射內(nèi)核內(nèi)存至用戶進(jìn)程空間,從而杜絕了竊取內(nèi)核數(shù)據(jù)的可能性。目前可以通過(guò)操作系統(tǒng)內(nèi)核補(bǔ)丁程序修復(fù)。
幽靈變體1(CVE-2017-5753):主要通過(guò)靜態(tài)分析來(lái)防護(hù),一旦系統(tǒng)發(fā)現(xiàn)有攻擊代碼時(shí)會(huì)暫停CPU分支預(yù)測(cè)功能,從而防止竊取數(shù)據(jù)。目前也可以通過(guò)操作系統(tǒng)內(nèi)核補(bǔ)丁程序修復(fù),由于漏洞可以通過(guò)網(wǎng)頁(yè)瀏覽器的JavaScript執(zhí)行,系統(tǒng)內(nèi)核補(bǔ)丁會(huì)加強(qiáng)瀏覽器防護(hù)。
幽靈變體2(CVE-2017-5715):由于該漏洞允許虛擬機(jī)非法讀取宿主機(jī)數(shù)據(jù),修補(bǔ)最為復(fù)雜。Google提供了用Retpoline分支代替間接分支的軟件防護(hù)方法,但需要將全部涉及代碼重新編碼編譯,工作量巨大故不常被使用。而Intel在新的微碼中提供了間接分支限制預(yù)測(cè)(IBRS)、單線程間接分支預(yù)測(cè)器(STIBP)、間接分支預(yù)測(cè)器屏障(IBPB)三個(gè)硬件防護(hù)方式??梢酝ㄟ^(guò)強(qiáng)制刷新分支預(yù)測(cè)緩存、禁用單CPU中多個(gè)同級(jí)線程互相影響分支預(yù)測(cè)的情況。這些硬件防護(hù)手段雖然帶來(lái)約20%性能損失,但由于簡(jiǎn)單易行,被各大廠商廣泛使用[4]。
對(duì)于云環(huán)境中需要升級(jí)物理CPU的微碼、安裝虛擬機(jī)操作系統(tǒng)、虛擬化層的操作系統(tǒng)的安全補(bǔ)丁,物理機(jī)里也需要升級(jí)CPU微碼及安裝操作系統(tǒng)補(bǔ)丁。目前Intel、AMD已經(jīng)向主流PC廠家提供了微碼修補(bǔ)程序,用戶通過(guò)下載升級(jí)最新的BIOS就可以完成升級(jí)微碼工作。即使硬件廠家暫時(shí)沒(méi)有推出的BIOS升級(jí)包,根據(jù)微軟的官方說(shuō)明,通過(guò)將虛擬機(jī)與宿主機(jī)操作系統(tǒng)使用的CPU物理核之間進(jìn)行強(qiáng)行隔離以及虛擬機(jī)之間的物理核獨(dú)占分配,也可以對(duì)5715漏洞做到有效防護(hù)[5]。
目前的熔斷、幽靈的安全補(bǔ)丁都不同程度地造成系統(tǒng)性能下降及其他穩(wěn)定性問(wèn)題。根據(jù)Intel的官方說(shuō)明,在舊CPU上的變體2相關(guān)BIOS升級(jí)可能導(dǎo)致意外重啟及系統(tǒng)穩(wěn)定性問(wèn)題,建議在充分測(cè)試確認(rèn)影響可接受后再全面升級(jí)[6]。
近幾年來(lái),雖然各種安全漏洞層出不窮,但像熔斷、幽靈漏洞這樣從根本上挑戰(zhàn)現(xiàn)有芯片結(jié)構(gòu)和運(yùn)行方式的還是非常罕見(jiàn)的。因此,需要從根本上改變芯片及軟件的設(shè)計(jì)思想,在進(jìn)一步挖掘芯片制式、結(jié)構(gòu)、算法潛力的同時(shí),安全問(wèn)題不容忽視。同時(shí),由于目前的安全補(bǔ)丁均導(dǎo)致性能下降,短期內(nèi)對(duì)云平臺(tái)及用戶不可避免地會(huì)造成影響。安全與性能之間的平衡與取舍,值得每個(gè)IT、通信從業(yè)者思考。
[1] Moritz Lipp,Michael Schwarz,Daniel Gruss,Thomas Prescher,Werner Haas,Stefan Mangard,Paul Kocher,Daniel Genkin,Yuval Yarom,Mike Hamburg. Meltdown[J]. Unpublished,2018.
[2] Paul Kocher,Daniel Genkin,Daniel Gruss,Werner Haas,Mike Hamburg,Moritz Lipp,Stefan Mangard,Thomas Prescher,Michael Schwarz,Yuval Yarom. Spectre Attacks:Exploiting Speculative Execution[J]. Unpublished,2018.
[3]Jann Horn. Project Zero. Reading privileged memory with a side-channel[J/OL]. https://googleprojectzero. blogspot.com/2018/01/reading-privileged-memory-with-side. html.
[4]Leslie Culbertson.Addressing New Research for Side-Channel Analysis[J/OL].https://newsroom.intel. com/editorials/addressing-new-research-for-side-channel-analysis/.
[5] Justin Hall. Alternative protection for Windows Server 2016 Hyper-V Hosts against the speculative execution side-channel vulnerabilities[J/OL].https://docs.microsoft. com/en-us/virtualization/hyper-v-on-windows/cve-2017-5715-and-hyper-v-hosts.
[6] Microsoft. Windows Server guidance to protect against speculative execution side-channel vulnerabilities[J/OL]. https://support.microsoft.com/en- us/help/4072698/windows-server-guidance-to-protect-against-the-speculative-execution.
The Principle Risks and Mitigation of CPU Vulnerabilities Meltdown and Spectre
Zhang Jingyu1、2
1.China Mobile Communication Group Co., Ltd., Beijing 100033 2.School of Microelectronics,Tianjin University, Tianjin 300072
The technical background, principle of vulnerabilities, risks and the impact of the security vulnerability Meltdown and Spectre, which could attack Intel, AMD and ARM CPU, is analyzed. The countermeasures and mitigation options are proposed.
CPU; security vulnerability; Meltdown; Spectre
TP309
A
張經(jīng)宇(1988—),山西忻州人,工程師,在讀博士,主要從事信息與通信工程領(lǐng)域的研究與維護(hù)維修工作。