[轉載]專業角度說說這次的CPU漏洞,從原理到答疑

轉載原帖標題:[農企日常翻身] 專業角度說說這次的CPU漏洞,從原理到答疑
原文為簡體中文,發表於:http://bbs.ngacn.cc/read.php?tid=13191205

 

  • 這次的漏洞是啥?

我們先從機制說起來。這次曝光的漏洞一組三個,基本原理都是一樣的。

  • 緩存(Cache)

CPU執行指令,最大的速度瓶頸不在計算,而在於內存訪問。
為了降低內存訪問需要的時間,現代CPU全部都設計了緩存。
通俗地說,就是把曾經讀過的內存,備一份在速度更快的緩存裡。
下次再讀同一塊數據的時候就可以直接從緩存裡取,就會更快。

  • 亂序執行(OOO)

因為有訪存瓶頸,指令之間的執行時間差距可能非常大。
一條普通的計算指令1拍結束。一條訪存指令如果緩存命中,需要10到100拍;如果緩存不命中,到內存裡取,需要上萬拍甚至更多。
如果上一條指令被訪存卡了十萬拍,後面其他的指令只能等著嗎?不可能的,所以現代CPU全部都設計了亂序執行的特性。
把指令比做人的話,
順序執行就是排隊入場,先來後到,一直保持同一個順序。前邊的人停下了,後邊所有人都必須跟著停。
亂序執行就好像逛超市,大家排著隊進場每人發個編號,之後自由亂逛,到結賬的地方如果你前邊編號的還有人沒出去,你就在出口坐著等會兒,最終實現大家出去的時候仍然按進入的順序排成一隊。
坐著等前邊人回來的那個地方,你可以想像有幾排椅子的等候區,有個保安看著給大家排號,這個機構學名叫做ROB。

  • 異常

計算機只有一塊內存,這塊內存上既存著某個不知名應用的運行信息,也存著你的支付寶密碼。
怎麼樣防止不知名小程序看到你的支付寶密碼呢?當程序讀內存的時候,CPU會幫忙檢查讀的地址是否屬於這個程序。如果不屬於,就是非法訪問,CPU會在這條指令上產生一個異常,報操作系統槍斃。
操作系統為了處理異常,有一個要求:如果出現異常,那麼異常指令之前的所有指令都已經執行完,異常指令之後的所有指令都尚未執行。
但是我們已經亂序執行了啊,怎麼辦?所以ROB承擔起這個責任。
指令亂序執行的時候,要修改什麼東西都暫且記著,不真正修改。只有在從ROB裡排隊出去的時候,才真正提交修改,維持指令之間的順序關係。
如果一條指令產生了異常,那麼它會帶著異常來到ROB排隊。 ROB按順序把之前的正常指令全部提交了,看到這條指令帶有異常之後就封鎖出口,異常指令和其後其他指令會被拋棄掉,不予提交。

  • 投機執行

分支指令是最討厭的。例如“如果x<3,則執行a-b-c;否則,就執行d-e-f”。
CPU大超市的入口保安,遇到正常指令只管按順序放進場,控制下超市裡的人流量就OK。但遇到分支指令就會傻掉,因為不等這個分支指令執行完,就不知道該放abc進場,還是放def進場。
能傻傻的等分支出來再繼續放人嗎?不可能的。現代CPU都設計有投機執行的特性。
入口保安會根據歷史上這條分支取過哪邊,來猜測這一次會取哪邊。比如以前一百次分支都取的是abc那邊,那這一次我肯定猜它還會取abc那邊,我就直接放abc跟著進去。
萬一猜錯了?讓出口那的ROB把abc取消掉不讓他們提交就行了,我這邊再放def進去。

  • 微結構側面效應

被取消掉的指令不會得到提交,所以它們修改不了任何東西,也不會產生異常。所以我大可以隨意去投機執行指令,不會有任何危險,因為大不了我取消掉他們就萬事大吉了。 ——體系結構設計者如是想。
這次的全部幾個BUG就都出在這裡。被取消掉的指令,雖然不會造成結構上的影響,但在微結構上會留下可以觀測的影響——就是緩存。
這些被取消掉的指令不受異常的控制,可以訪問任何東西,比如你的支付寶密碼,然後藉口自己執行錯了被取消掉,就不會被操作系統管。
體系結構設計者認為被取消掉的指令看到你的支付寶密碼不會產生問題,因為它們留不下任何痕跡,但它們還是留下了:它們曾訪問過哪些內存,哪些內存的後續訪問就會變快。

  • 攻擊示例

執行這樣一句代碼:

if (x < array1_size)
y = array2[array1[x] * 4096];

看起來這程序好像非常正經,對array1的訪問甚至有邊界檢查,不讓下標x超過array1的大小。
這邊界檢查很重要,因為要訪問任何地址,比如你的支付寶密碼的第一位(假設為k),存儲在地址v的話,令x=v-array1,array1[x]就是在訪問地址v了。
不過這種赤裸裸的越界訪問一定會觸發異常,然後被操作系統槍決罷了。我們不能那麼露骨。

if (x < array1_size)
y = array2[array1[x] * 4096];

開始執行的第一步,CPU首先會遇到一條分支指令,判斷x和array1_size誰大。假設array1_size沒在緩存裡,CPU需要跑去內存裡取。
在把array1_size取回來之前沒人知道x和array1_size誰大,於是有一萬拍的時間內CPU都不知道這個邊界檢查是成功了還是失敗了,這個時間窗口內CPU將繼續投機執行。
CPU猜測可能是x更小,投機執行下面的語句。你會發現這種猜測是可以被攻擊者誤導的,攻擊者可以在開始之前先用x=0多次執行這句代碼,讓CPU誤以為x大多數時候都很小。
但實際上,這次的x突然暗藏殺機,因為x=v-array1,而可愛的CPU就這樣被騙過去了。

if (x < array1_size)
y = array2[array1[x] * 4096];

投機執行的第一步,就是array1[x],試圖訪問你的支付寶密碼。 CPU說不可以,於是給這條指令的臉上貼了一張異常罰單,但仍然允許它帶著密碼的真實值k到ROB那裡去排隊。 口嫌體正
如果這條指令沒有被撤銷,操作系統就會槍斃這個犯規的程序;如果撤銷了,那麼體系結構設計者相信你絕對沒辦法活著把k帶走。

if (x < array1_size)
y = array2[k * 4096];

投機執行的第二步。攻擊者嘗試讓投機指令把k留下,而這些最終將被撤銷的指令,唯一能留下的信息就是緩存。
第二條投機指令以k作為地址去訪問array2。 k被乘以一個較大的數值,例如頁大小4096,這是出於一個技術細節原因。
假設array2的所有內容都不在緩存中,那麼這條指令執行後,將僅有一個位置被加載到緩存上,這個位置的訪問速度將明顯快於其他位置,這個位置就標明了k的值。

if (x < array1_size)
y = array2[array1[x] * 4096];

隨後,array1_size的值讀取到了,CPU後知後覺發現投機執行錯了,於是上面投機執行的犯罪指令全部被取消。
然而這時被取消的指令已經留下了一條緩存項,出賣了密碼k。
攻擊者只需要讀取array2的每一個位置,測量讀取花費的時間,然後找到讀取最快的那個位置對應著k是多少,就這樣攻破了你支付寶密碼的第一位。

之後攻擊者讀取一些其他數據,將array1_size和array2再次擠出緩存,使用x=0反复執行這段代碼欺騙CPU的分支預測,就可以故伎重施,取出你支付寶密碼的下一位,以至於每一位。

 

  • Q&A

Q:真能取出密碼?
A:真的能。
你問攻擊者怎麼知道v應當是多少?他不需要知道,他可以讀走你係統內存條上的每一個字節,然後寫封郵件傳回去自己慢慢找。

研究人員用這種方法扒出來的Firefox保存的網站密碼。

Q:為什麼CPU說不可以還讓指令把密碼取走了,不給它取不行嗎?口嫌體正?
A:因為判斷訪問越界與否是比較耗時的,體系結構設計上通常讓取數和判斷越界同時進行,互不干擾。最終依賴異常來防止越界訪問取得的數值被帶走。
如果先判斷是否越界再取數,會慢;如果判斷越界後再追繳非法取得的數,芯片會太複雜。

Q:為什麼CPU不在這種情況下把緩存清了?
A:正常程序也會非常頻繁地發生投機執行被撤銷、撤銷指令訪問越界的情況,是無法與惡意攻擊區分的。
如果每次發生這種情況都清空緩存,緩存的作用就很低了。

Q:我被這漏洞影響了嗎?
A:基本上跑不了,因為這不是某一家公司某一個產品的設計缺陷,而是一個極其廣泛的體系結構漏洞,整個學術界長期以來都沒有意識到這樣的設計是會有問題的。

Q:怎樣中招?
A:執行一段攻擊者編寫的native code。
例如執行了莫名其妙的可執行程序,或者在瀏覽器上瀏覽攻擊者的網頁(瀏覽器內帶有javascript JIT編譯器,可以生成攻擊者想要的native code),都會有可能中招。
但BUG是由好人先發現的,技術又很複雜,短時間內壞人還寫不出惡意代碼。這幾天注意更新就行了不用草木皆兵。

Q:現有電腦上的漏洞可以修復嗎?
A:可以以性能損失的代價降低被攻擊的風險,但無法用軟件補丁的方式杜絕。

Q:意思是說這個漏洞只能讀,不能寫或者執行什麼吧?
A:據我所知是只能讀。

Q:英特爾故意的?
A:英特爾故意留後門不需要這麼麻煩,你小瞧牙膏廠了。

Q:AMD翻身了?
A:農企同樣有BUG,但被研究者猜測可能是因為流水線太淺CPU太慢了,投機執行的惡意代碼無法在時間窗口內完成預期的動作,所以實測的攻擊代碼一直沒能成功(針對Meltdown)。 [s:ac:噴]

Q:國產芯片怎麼樣了?
A:看不到邏輯判斷不了會不會被影響,會不會有等他們自己發言吧。 我的體系結構還是胡偉武教的[s:ac:喘]
所有現代CPU,有OOO有ROB有投機執行反悔的機制,都有可能會中招。
但是龍芯在自主可控的角度來說還不會有太大問題,因為龍芯上面跑的應用也都是我們自己搞的,坦克飛機導彈這些CPU上又不會跑莫名其妙的javascript,即使有同樣漏洞也不需要過度擔心。

Q:我該怎麼辦?
A:注意軟件更新,特別是瀏覽器和操作系統,包括你所有的智能設備,無論是PC、Mac還是手機。
例如微軟已經發布https://support.microsoft.com/en-us/help/4056890/windows-10-update-kb4056890,可以降低IE和Edge受到攻擊的可能性。
不要執行莫名其妙的程序,下載軟件多留個心眼,這一點在任何時候都是對的,本次漏洞期間依然如此。

 

  • 引用

https://meltdownattack.com/
https://googleprojectzero.blogspot.co.at/2018/01/reading-privileged-memory-with-side.html

======
 

  • 轉載後本站附加信息

Intel漏洞自查工具官方下載
https://downloadcenter.intel.com/download/27150?v=t

1 關於 “[轉載]專業角度說說這次的CPU漏洞,從原理到答疑” 的評論

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *