作者:啟明星辰ADLab
原文鏈接:https://mp.weixin.qq.com/s/yeu9IZSNrp1f_lK5oIdL9A
4月13日,國外安全研究人員在社交媒體上發布了Chrome 的0Day 漏洞[1],漏洞編號為CVE-2021-21220,并在github上公開了該漏洞的POC以及利用代碼,相關的利用代碼在關閉沙盒的情況下可達到遠程代碼執行。由于chromium 相關框架的廣泛應用,該漏洞在其他瀏覽器或腳本引擎中仍有存在的可能。該漏洞在chrome 90.0.4430.72版本已經修復,提醒廣大用戶及時更新到最新版本[2],以規避該漏洞存在的攻擊風險。
啟明星辰ADLab分析發現,該漏洞存在于Chrome 的JavaScript 解析引擎V8中,POC主要代碼如下:

在POC line4執行異或操作,(2**31)^0=-2147483648。根據ECMA標準[3],異或的結果是32位整數:

在v8 SimplifiedLowering階段,增加了對異或的結果執行ChangeInt32ToInt64的操作:

SimplifiedLowering 執行后,異或的類型被標記為Word32:

在MachineOperatorOptimizer階段,由于是和0做異或,所以用左操作數代替異或操作。

此時的結構圖如下,可以看出異或的結果是Word32|TypeUint32:

在指令選擇時,對于VisitChangeInt32ToInt64操作,根據其輸入類型選擇操作碼:

所以,這里的操作碼是kX64Movl操作碼,該指令在將源操作數移至目的位置時并不做符號擴展,這樣在POC line4中x的值為2147483649,于是在poc line12的位置,編譯器其實使用的是x=1的值作為創建數組的長度。這是編譯器未曾預料到的情況。
在變量的范圍分析中,編譯器認為創建的數組長度是0:

在執行POP時,會先判斷數組的長度是否為0,如果不是就會將其長度減1:

由于數組長度固定,編譯器在LoadElimination 的過程中會進行常量折疊,在代碼路徑走到這里的時候通過StoreField操作將數組的長度直接賦值為-1:

由于是smi,所以是0xfffffffe:

打印數組長度:

這時超長的數組就出爐了,任由你玩了。從補丁對比上來看[4],對于ChangeInt32ToInt64將其輸入作為有符號對待,這樣就避免了該漏洞通過該路徑觸發。

關于利用的部分,基本是老套路,不再贅述。
參考鏈接:
[1] https://twitter.com/r4j0x00/status/1381643526010597380
[2] https://www.google.com/chrome/
[3] https://www.ecma-international.org/publications-and-standards/standards/ecma-262/
[4] https://chromium-review.googlesource.com/c/v8/v8/+/2820971/3/src/compiler/backend/x64/instruction-selector-x64.cc#1379
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/1563/
暫無評論