91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎樣分析Chrome 1day 漏洞CVE-2021-21224

發布時間:2021-12-29 18:03:17 來源:億速云 閱讀:289 作者:柒染 欄目:安全技術

本篇文章給大家分享的是有關怎樣分析Chrome 1day 漏洞CVE-2021-21224,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

一、時間線

2021年4月4日 - tr0y4 在 Chromium issue tracker 中提交該漏洞;

2021年4月12日 - Chromium 修復該漏洞,除了補丁外還公開了相關的poc;

2021年4月14日 - 國內的研究員 frust93717815 公開了此漏洞的exp[1][2],影響未開沙箱的穩定版 Chrome 瀏覽器;

2021年4月20日 - Chrome發布更新及致謝,對應的CVE編號為 CVE-2021-21224。

二、背景

該漏洞發生在v8的優化編譯器 TurboFan 中,具體發生在 JIT 的 Simplified-Lowering 階段。關于TurboFan的介紹可以參考 ”Introduction to TurboFan”[3]。有關 Simplefied-Lowering 階段的具體細節可以參考 CVE-2020-16040 的分析[4]。此外,本文使用Turbolizer 展示 TurboFan 不同優化階段的 sea of nodes graph。

下面簡單介紹一下sea of nodes,它是TurboFan運行時的程序表示形式。TurboFan在優化代碼時,整個代碼是以graph的形式存儲的,每個節點就是一個node,包括數學運算、加載、存儲、調用、常數等形式。每個node的具體信息如下:

怎樣分析Chrome 1day 漏洞CVE-2021-21224

每個 node 都有一個 restriction type 和一個 feedback type,前者可以理解為節點初始化后的類型,后者則是在實際優化過程中反饋的真實類型。Node 的representation 則表示節點的表示類型,具體如下:
怎樣分析Chrome 1day 漏洞CVE-2021-21224

三、漏洞及補丁分析

根據commit信息得知,漏洞發生在 RepresentationChanger:: GetWord32RepresentationFor 函數內。該函數的調用棧如圖 1,對該函數的調用主要發生在 Simplified-Lowering 階段:

怎樣分析Chrome 1day 漏洞CVE-2021-21224

圖1. GetWord32RepresentationFor 調用棧

具體補丁如圖 2,output_rep 為傳入節點的 Representation 類型, output_type 為當前節點的 feedback type,use_info 為當前節點的后繼節點信息(主要用于區分32位或64位)。所以修復之前的邏輯是滿足兩種情況之一可以更新op:一是當前節點的 feedback type 是 Signed32 或者 UnSigned32;二是當前節點 feedback type 為 SafeInteger 且其后繼節點被用作32位使用(IsUsedAsWord32)。

修復后的邏輯則是滿足以下三個條件之一便可以更新:一是當前節點的 feedback type是Signed32;二是當前節點feedback type是UnSigned32并且后繼節點類型是None;三是當前節點為SafeInteger并且后繼節點被用作32位使用。

怎樣分析Chrome 1day 漏洞CVE-2021-21224

圖2. 補丁信息

對比修復前后的邏輯可以發現,在當前節點的 feedback type 為UnSinged32時,并不能直接修改op,需要保證后繼節點類型為 None 才能修改。漏洞正是利用了這一條件,在當前節點滿足UnSigned32時,其后繼節點類型不為None(exp中后繼節點類型如圖 3所示,為 SingdeSmall,是一個有符號數),最后 op 被賦值為 TruncateInt64ToInt32。

因此,所有傳入到當前 TruncateInt64ToInt32 節點的數字都會直接轉為一個有符號32位數,如果傳入的數字恰好使用到了對應32位數的符號位(比如 exp 中使用的 0xffffffff),那么就會發生整數下溢。

怎樣分析Chrome 1day 漏洞CVE-2021-21224

圖3. 后繼節點的 use_info

漏洞復現

為了驗證漏洞,本文使用補丁發布前一個版本的v8代碼進行實驗,commit 哈希為 f87baad0f8b3f7fda43a01b9af3dd940dd09a9a3。為了便于理解,本文簡化了 exp 中的 foo 函數如下:

怎樣分析Chrome 1day 漏洞CVE-2021-21224

這里我們通過對比 Simplified Lowering 及其前一階段 EscapeAnalysis 的graph結果來展示修復前后turbolizer graph的變化。如圖 1所示,在EscapeAnalysis 階段70號節點對應到Max的返回結果,它作為51號節點的輸入,繼續進行下一步的減法操作(SpeculativeSafeIntegerSubtract)。而經過Simplified Lowering 階段后,70號節點和51號節點之間被插入了一個新的95號節點 TruncateInt64ToInt32,直接將70號節點的輸出轉為一個32位有符號數,再進行減法操作。

此時再來看本節使用的例子,Max的返回值是 0xffffffff,即y=0xffffffff,經過TruncateInt64ToInt32節點后,y被轉成32位有符號數,也就是-1,發生了整數下溢。因此z最后經過 sign 函數得出的結果是1。

怎樣分析Chrome 1day 漏洞CVE-2021-21224

圖 4. 修復前EscapeAnalysis階段的turbolizer graph

怎樣分析Chrome 1day 漏洞CVE-2021-21224

圖 5. 修復前Simplified Lowering階段的turbolizer graph

修復之后得到的 turbolizer graph如圖 6,可以看出原本的TruncateInt64ToInt32 節點現在變成了 CheckedUint64ToInt32,在將64位無符號數轉為32位有符號數時會進行檢查,避免了整數溢出。

怎樣分析Chrome 1day 漏洞CVE-2021-21224

圖6. 修復后Simplified Lowering階段的turbolizer graph

四、漏洞利用分析

1. 漏洞利用

單獨的整數溢出并不能實現 RCE,與之前 CVE-2020-16040[5]和CVE-2021-21220[6]的exploit類似,該 exploit 的作者結合 shift 函數獲得一個長度為-1的數組,實現 OOB。

exp 中觸發漏洞的地方在 foo 函數,下面的代碼只保留了原始 exp 中獲取長度為 -1 數組的部分。注釋中標注出了每一行代碼執行后的結果,可以看到最后聲明的 arr 數組實際長度為 1,但是經過 shift 操作后長度直接變成了-1:

怎樣分析Chrome 1day 漏洞CVE-2021-21224

下面通過對 turbolizer graph(Simplified-Lowering階段)中各個節點的分析來詳細說明產生上述情況的原因。

圖7是2-4行代碼中包含的關鍵節點,首先,前兩行代碼決定x的范圍是(-1,4294967295),接著到Math.max函數中,x首先和0比較取最大值,所以更新后的范圍是(0, 4294967295),然后再與-1比較取最大值,范圍沒有變化,仍然是(0, 4294967295)。

怎樣分析Chrome 1day 漏洞CVE-2021-21224

圖7. Math.max函數輸出結果

在此之后90號節點的值會先被轉為 Int32 然后進行一個減法操作,對應代碼就是第5行中的0-y,對應的范圍是(-4294967295,0)。需要注意的是這里的范圍并不是真實的范圍,后續還會有 feedback type 的更新會進一步更新這個范圍,但是這里對后續的結果并沒有影響。Math.sign 函數會根據根據參數的正負,返回+1/-1,此外還有+0/-0/NaN,由于這里+-0并不會對最終結果有影響,所以本文不做過多討論。由于0-y的值小于等于零,所以該函數輸出結果只能是(-1,0),即z的范圍是(-1,0)。接著到第6行代碼聲明數組,會對數組的邊界做檢查(長度必須要大于零),所以把z的范圍和0取交集得到最后數組長度的范圍是(0,0)。

Shift 操作會移除數組中的一個元素,并把數組長度減一。由于數組的長度只能是0,所以 jit 在優化過程中直接把shift之后數組的長度固定為0-1 = -1,這就是為什么 shift 之前數組長度是1,shift之后長度直接變成了-1。這里其實利用了shift函數中存在的一個bug,即該函數未對數組的邊界做檢查,無論原始數組的長度如何都直接進行減一操作。由于數組長度為0,所以shift之后長度固定為-1,這一值被直接寫入到jit優化后的代碼中(在圖 9中,長度被直接賦值為0xfffffffe,也就是-2,經過調試發現 jsarry 在內存中存儲的長度數值左移了1位,這是為了保證其內存中所有的數字都是以0結尾,指針以1結尾,具體可以參考JS類型對象的內存布局[8]),因此最終得到數組的長度為-1。

怎樣分析Chrome 1day 漏洞CVE-2021-21224

圖 8. 邊界檢查結果

還有一點需要注意的是,由于shift 操作還會移除數組中的的一個元素,所以如果第6行聲明的數組中不包含任何元素,則移除元素操作會導致v8直接崩潰。exp中利用溢出恰好聲明了一個長度為1的數組,滿足了這一限制條件。這也解釋了另一個問題,如果不利用整數溢出漏洞,直接聲明一個長度為0的數組,那么根據優化后的jit代碼是不是也能得到一個長度為-1的數組呢。實際上jit代碼中在shift之前對長度做了驗證,如圖 9所示,rdi為數組的長度,如果長度為0的話會直接跳過數組長度更新而直接返回,所以無法獲得一個長度-1的數組。

怎樣分析Chrome 1day 漏洞CVE-2021-21224

圖9. 調用shift前的邊界檢查及長度賦值操作

當然,谷歌也在4月15日的更新中修復了該bug[7]。在該補丁中,shift以及類似的pop函數在計算出新的數組長度后會首先進行邊界檢查,基本上杜絕了類似的利用方式。

怎樣分析Chrome 1day 漏洞CVE-2021-21224

圖 10. [turbofan] Harden ArrayPrototypePop and ArrayPrototypeShift補丁

2. 內存讀寫

1)  越界訪問rwarr數組

exp在 arr 數組之后又聲明了一個長度為2的數組和一個長度為0x1000的ArrayBuffer,接著修改了corrput_arr[12]的值,這里其實就是利用溢出修改了rwarr數組的長度。

怎樣分析Chrome 1day 漏洞CVE-2021-21224

根據調試信息可以得知,corrput_arr中元素的位置在0x18b80828216c,每個元素的長度是4字節,rwarr中元素的位置在0x18b8082821a8,根據二者之間的距離,減去corrput_arr前八個字節(分別為元素的map和長度),就可以計算出corrput_arr數組第13個元素對應的就是rwarr數組的長度。通過將該長度修改為一個較大的值(比如0x22444),可以實現對rwarr數組的越界訪問。

怎樣分析Chrome 1day 漏洞CVE-2021-21224

2)  越界訪問corrupt_buff

setbackingStore 就是設置 corrput_buf 中 backing_store 的值,leakObjLow則是泄露地址o處的信息。

怎樣分析Chrome 1day 漏洞CVE-2021-21224

rwarr設置的第一個元素值為5.1,長度8字節,所以數組中元素都是8字節,因此rwarr[4]的位置在0x18b8082821a98+8+4*8=0x18b8082821ac0,該地址再加4便是corrupt_buff的backing_store的地址, 因此這里還需要用到rwarr[5],分別修改rwarr[4]的高四個字節和rwarr[5]的低4個字節,就可以實現對backing_store的修改。后續exp會從corrupt_buff中生聲明一個Dataview,而backing_store記錄的就是實際DataView的內存地址。如果我們將這個backing_store指針修改為我們想要寫入的內存地址,那么我們再調用view.setUint32(0, poc, true) 類似指令時,實際上就是向指定內存地址處寫入了poc,從而達到任意地址寫。

leakObjLow函數使用corrupt_buff的slot屬性,修改該屬性為某一對象o,那么o的地址就會被寫入到corrupt_buff所在的內存區間中,然后利用rwarr的溢出訪問該值,實現泄露。

怎樣分析Chrome 1day 漏洞CVE-2021-21224

3. 代碼執行

代碼執行的方法利用了WASM的RWX段。通過泄露該RWX段的地址,將shellcode寫入,最后調用WASM的導出函數即可實現代碼執行。

怎樣分析Chrome 1day 漏洞CVE-2021-21224

以上就是怎樣分析Chrome 1day 漏洞CVE-2021-21224,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

玉环县| 三亚市| 安图县| 太仆寺旗| 南雄市| 许昌县| 定襄县| 本溪市| 乌拉特中旗| 揭东县| 文昌市| 佳木斯市| 冀州市| 炎陵县| 山西省| 正阳县| 曲麻莱县| 汶川县| 泊头市| 阆中市| 鱼台县| 寻甸| 呼伦贝尔市| 闽侯县| 高州市| 永昌县| 集贤县| 平果县| 红河县| 姚安县| 平江县| 包头市| 七台河市| 兴隆县| 新巴尔虎左旗| 神木县| 武山县| 塘沽区| 贺州市| 双城市| 丹东市|