Jump to content

Hack The PS4 - Status for End Users


eXtreme
 Share

Recommended Posts

So from what i understand now, i think the correct structures must be look like the following:

 

struct ucred{
	ulong unknown1;	//skip first 4 bytes
	ulong cr_uid;	//mov     edx, [r12+4]
	ulong cr_ruid;	//mov     ecx, [r12+8]
	ulong unknown2;
	ulong unknown3;
	ulong unknown4;
	ulong cr_rgid;	//mov     r8d, [r12+14h]
	uchar unknonw[0x104]	//
	ulong cr_groups[xx]		// i did not know exact array size here.
}

struct proc {
	char useless[0x40];		//mov     r12, [r14+40h]
	struct ucred *p_ucred;
	char useless2[24];
	struct fdp *td_fdp;
};

I think that the register [r14] hold the pointer to the proc structure and the ucred structure is the element of proc structure located after 0x40 of other structure fields or unused data.

Also the [r12] in this case will point to the start of the ucred structure within the proc structure.

 

Edited by Abkarino
  • Upvote 3
Link to comment
Share on other sites

yea 0x40 here will set up the useless char array with 40 bytes :)

 

if i didn't mix now shit.

Edited by cfwprophet

rsz_2cfwprophet_banner_3.jpg

Link to comment
Share on other sites

5 minutes ago, cfwprophet said:

yea 0x40 here will set up the useless char array with 40 bytes :)

 

Not 40 byte my friend it is 64 byte since the value is 0x40 in Hex ;)

  • Upvote 1
Link to comment
Share on other sites

  • Developer

thanks @dreadylein & @cfwprophet this makes more sense now.

 

well done @Abkarino:)

 

@bigboss you're a twisted man, if you think this is clear as water for someone that never had to use asm before :P 

Edited by Zer0xFF
  • Upvote 3
Link to comment
Share on other sites

1 minute ago, Abkarino said:

 

Not 40 byte my friend it is 64 byte since the value is 0x40 in Hex ;)

naaaaaa right right right 

 

i didn't convert the hex digi :D

 

BAD BRAIN !!!!

rsz_2cfwprophet_banner_3.jpg

Link to comment
Share on other sites

Thank you @Zer0xFF i'm trying to help as much as i can, and i hope that i have PS4 with 1.76 FW right now to test this ;)

 

BTW, i think that i had some correction to the cred structure now as follow:

 

struct ucred{
    uchar unknown1[0x4];    //skip first 4 bytes
    ulong cr_uid;            //mov     edx, [r12+4]
    ulong cr_ruid;            //mov     ecx, [r12+8]
    ulong unknown2;       //[r12+0Ch]
    ulong cr_ngroups;     //[r12+10h]  
    ulong cr_rgid;            //mov     r8d, [r12+14h]

    uchar unknown3[0x1C];

    struct *cr_prison;
    uchar unknonw[0xE4]    //
    ulong cr_groups[xx]        // i did not know exact array size here.
}

struct proc {
    char useless[0x40];        //mov     r12, [r14+40h]
    struct ucred *p_ucred;
    char useless2[24];
    struct fdp *td_fdp;
};

Edited by Abkarino
  • Upvote 2
Link to comment
Share on other sites

now do the same for the other needed values :)

Bigboss indeed gave you a nice function as it contains most of the needed offset within a few lines

 

Out of curiosity, i never used this approach vector, does the corruption of this kq_event struct mess up the returning from kernelmode ?

 

  • Upvote 1
Link to comment
Share on other sites

  • Developer
4 minutes ago, dreadylein said:

now do the same for the other needed values :)

Bigboss indeed gave you a nice function as it contains most of the needed offset within a few lines

 

Out of curiosity, i never used this approach vector, does the corruption of this kq_event struct mess up the returning from kernelmode ?

 

nope it seems to return fine but i think you need to have  to call "asm ("swapgs; sysretq;" :: "c"(shellcode));"

edit: don't hold me to that, I've ran ALOT of test with different code permutation... there has been occasions when we returned to without crash.. others when ps4 crashed, they're all jumbled up in my head right now.

Edited by Zer0xFF
  • Upvote 1
Link to comment
Share on other sites

@dreadylein i just updated some other offsets but i'm not 100% sure of my work so please can you confirm if this is right or not?

A small update to cred structure

 

struct ucred{
    ulong cr_ref;             //not sure about this but at least it uses 4 bytes. 
    ulong cr_uid;             //mov     edx, [r12+4]
    ulong cr_ruid;            //mov     ecx, [r12+8]
    ulong unknown2;       //[r12+0Ch]
    ulong cr_ngroups;     //[r12+10h]  
    ulong cr_rgid;            //mov     r8d, [r12+14h]

    uchar unknown3[0x1C];

    struct prison *cr_prison;
    uchar unknonw[0xE4]    //
    ulong cr_groups[NGROUPS];
}

struct proc {
    char useless[0x40];        //mov     r12, [r14+40h]
    struct ucred *p_ucred;
    char useless2[24];
    struct fdp *td_fdp;
};

 

Link to comment
Share on other sites

  • Developer
1 hour ago, Abkarino said:

@dreadylein i just updated some other offsets but i'm not 100% sure of my work so please can you confirm if this is right or not?

A small update to cred structure

 

 

You have a typo in

uchar unknonw[0xE4]    //

Carefull! :)

 

  • Upvote 1
Link to comment
Share on other sites

  • Developer

reading about sizes of different structures and sizes and ran a quick PC demo

	printf("sizeof:\n");
	printf("\tlong:\t%d\n", sizeof (long));
	printf("\tulong:\t%d\n", sizeof (unsigned long));
	printf("\tint:\t%d\n", sizeof (int));
	printf("\tuint:\t%d\n", sizeof (unsigned int));

[@BSD demos]$ gcc main.c && ./a.out
sizeof:
	long:	8
	ulong:	8
	int:	4
	uint:	4

so in that we shouldn't be using along/long for 4byte structures since they're 8 on 64bit machine, aka PS4

uct ucred{
    uchar unknown1[0x4];    //skip first 4 bytes
    uint cr_uid;            //mov     edx, [r12+4]
    uint cr_ruid;            //mov     ecx, [r12+8]
    uint unknown2;       //[r12+0Ch]
    uint cr_ngroups;     //[r12+10h]  
    uint cr_rgid;            //mov     r8d, [r12+14h]
    uchar unknown3[0x1C];
    struct prison *cr_prison;	//mov     rcx, [r12+30h]
    uchar unknonw[0xE4];    //
    uint *cr_groups;        // mov     rax, [r12+118h] //pointer
}
struct proc {
    char useless[0x40];        //mov     r12, [r14+40h]
    struct ucred *p_ucred;
    char useless2[24];
    struct fdp *td_fdp;
};

yes?

 

Edit: also for prison structure, is the only way to get it, is to do a size of on the PS4?

Edited by Zer0xFF
Link to comment
Share on other sites

9 hours ago, SonyUSA said:

You have a typo in


uchar unknonw[0xE4]    //

Carefull! :)

 

 

9 hours ago, SonyUSA said:

You have a typo in


uchar unknonw[0xE4]    //

Carefull! :)

 

 

Yes thank you so much @SonyUSA i just typed it quickly ;)

now it is fixed.

 

 

1 hour ago, Zer0xFF said:

reading about sizes of different structures and sizes and ran a quick PC demo


	printf("sizeof:\n");
	printf("\tlong:\t%d\n", sizeof (long));
	printf("\tulong:\t%d\n", sizeof (unsigned long));
	printf("\tint:\t%d\n", sizeof (int));
	printf("\tuint:\t%d\n", sizeof (unsigned int));

[@BSD demos]$ gcc main.c && ./a.out
sizeof:
	long:	8
	ulong:	8
	int:	4
	uint:	4

so in that we shouldn't be using along/long for 4byte structures since they're 8 on 64bit machine, aka PS4


uct ucred{
    uchar unknown1[0x4];    //skip first 4 bytes
    uint cr_uid;            //mov     edx, [r12+4]
    uint cr_ruid;            //mov     ecx, [r12+8]
    uint unknown2;       //[r12+0Ch]
    uint cr_ngroups;     //[r12+10h]  
    uint cr_rgid;            //mov     r8d, [r12+14h]
    uchar unknown3[0x1C];
    struct prison *cr_prison;	//mov     rcx, [r12+30h]
    uchar unknonw[0xE4];    //
    uint *cr_groups;        // mov     rax, [r12+118h] //pointer
}
struct proc {
    char useless[0x40];        //mov     r12, [r14+40h]
    struct ucred *p_ucred;
    char useless2[24];
    struct fdp *td_fdp;
};

yes?

 

Edit: also for prison structure, is the only way to get it, is to do a size of on the PS4?

 

You are right @Zer0xFF but this depend on the CPU used and OS i mean in other cases Long will stored in 4 bytes also not in 8 Bytes.

 

Link to comment
Share on other sites

Hey Zer0xFF Ive been using your source that you put on on your git, and have been playing with the cred structure based on what has been talked about here. I don't even think it is the cred that is causing the PS4 to crash. For example i have commented out the priv escalation and the struct ucred so the payload just prints entered payload this way i could test if the cred was causing trouble atal . Im still getting a crash. I wanted to find out if it is kernelFree(m2); so i put a printf("kernelFree happened\n"); just after and it doesn't reach that command. Im thinking that it could be the kernelFree function since if the payload just prints to the debug socket and nothing else, why would the ps4 shut down?

 

The only changes i made is to payload and having it just do this..

 

void payload(struct knote *kn)
{
    struct thread *td;
  
    asm volatile("mov %0, %%gs:0" : "=r"(td));

    kprintf("\t[+] Entered kernel payload!\n");

 

}

 

my last lines on TCP-Dump are

 

moment of truth
Trigger sceKernelDeleteEqueue
    [+] Entered kernel payload!

Edited by wildcard
Link to comment
Share on other sites

  • Developer

Probably because you're miss the asm swpgs sysretq... Check above @wildcard

  • Upvote 1
Link to comment
Share on other sites

21 minutes ago, Zer0xFF said:

Probably because you're miss the asm swpgs sysretq... Check above @wildcard

 

ah yup, thanks! Now with that im returning to browser without memory error but the creds are wrong so its a kernel patch failed. You any closer to getting proc and ucred stucts setup correctly?

Link to comment
Share on other sites

  • GregoryRasputin

Sorry @lezek20 i upgraded the forum software and it broke loads of shit, like posting and thread creation, i had to revert to a previous backup which was before you posted, this is your post which i saved:

 

Quote

 

try this for the ucred struct


struct ucred
{
  char useless[4];
  uint32_t cr_uid;
  uint32_t cr_ruid;
  uint32_t cr_svuid;
  int cr_ngroups;
  uint32_t cr_rgid;
  char useless2[18];
  void *cr_prison;
  char useless3[224];
  uint32_t *cr_groups;
};

 

 

 

If you want to post it again you can.

Sorry to everyone else for the problems :(

 

And thanks to @Zer0xFF for informing me about it.

  • Upvote 1
Link to comment
Share on other sites

haha no worries i was just about to edit that post when it disappeared

here is the corrected version.

struct ucred
{
  char useless[4];
  uint32_t cr_uid;
  uint32_t cr_ruid;
  uint32_t cr_svuid;
  int cr_ngroups;
  uint32_t cr_rgid;
  char useless2[24];
  void *cr_prison;
  char useless3[224];
  uint32_t *cr_groups;
};

credits to Twist3d89 for the corrected struct

https://gist.github.com/twisted89/99485d4c7496dbd0dcff/revisions

Edited by lezek20
  • Upvote 2
Link to comment
Share on other sites

1 hour ago, lezek20 said:

haha no worries i was just about to edit that post when it disappeared

here is the corrected version.


struct ucred
{
  char useless[4];
  uint32_t cr_uid;
  uint32_t cr_ruid;
  uint32_t cr_svuid;
  int cr_ngroups;
  uint32_t cr_rgid;
  char useless2[24];
  void *cr_prison;
  char useless3[224];
  uint32_t *cr_groups;
};

credits to Twist3d89 for the corrected struct

https://gist.github.com/twisted89/99485d4c7496dbd0dcff/revisions

 

Thanks lezek20! With that i am now getting


[+] Entered kernel payload!

[+] Rooted and Jailbroken!

[+] Escaped from the sandbox!


but it ends there and if i use the asm("swapgs; sysretq;" :: "c"(shellcode)); like zer0 suggested i get out of memory, if i change it to iretq the ps4 is stuck on executing and shuts off. It also shuts it off without the return to userland method. Im not getting the kernel patch success message so the thread doesn't seem like it closes. I tried adding a getuid method inside the payload and tried inside the exploit tread function but when i do that it gets frozen on a queue. Anyone got any ideas?

 

*trying your new post for the cred and proc struct im getting the same results which may suggest the creds are now being executed but something in them is off so it is still causing the thread to remain open? I wish there was a way to check if im true root but like i said if i use a getuid in the payload or in the thread i get stuck on a queue.

  • Upvote 3
Link to comment
Share on other sites

if your root and escaped out of the SB, then try now to dump the kernel, or some other stuff, with some simple cast's ;)

 

and well you may also want to allocate some space of the JIT array to run your shell code / payload in there or from there how ever.

rsz_2cfwprophet_banner_3.jpg

Link to comment
Share on other sites

[+] Entered kernel payload!

[+] Rooted and Jailbroken!

[+] Escaped from the sandbox!

[+] Kernel patch success!

 

And we are back to userland without crashing ;)

 

thanx to Twister and all others ppl involved ;)

 

You can check https://github.com/Thunder07/PS4-dlclose-kexploit-PoC

 

You can also change :

uint64_t *cr_prison; // jail(2) 48

by

void *cr_prison; // jail(2) 48

 

You will have less warnings when compiling  ;)

 

Edited by fx0day
  • Upvote 5
Link to comment
Share on other sites

CefzOfbXIAE0CO-.jpg:large

  • Upvote 3

rsz_2cfwprophet_banner_3.jpg

Link to comment
Share on other sites

  • Developer

I feel like there is some kernel memory corruption that still needs to be addressed. Mainly, you can't cleanly shut down the system.

 

Edit: Nevermind, I saw they realized that on the other forum ;D

Edited by SonyUSA
Link to comment
Share on other sites

  • Developer
15 hours ago, SonyUSA said:

I feel like there is some kernel memory corruption that still needs to be addressed. Mainly, you can't cleanly shut down the system.

 

Edit: Nevermind, I saw they realized that on the other forum ;D

 

Yeah it seems to be locking some resources which also breaks subsequent system calls. Looking into it.

  • Upvote 2
Link to comment
Share on other sites

  • Developer
3 hours ago, twisted89 said:

Yeah it seems to be locking some resources which also breaks subsequent system calls. Looking into it.

 

instead of jumping back few stacks to return to user land, how about allow the call to continue..

https://github.com/freebsd/freebsd/blob/release/9.0.0/sys/kern/kern_event.c#L404

https://github.com/freebsd/freebsd/blob/release/9.0.0/sys/kern/kern_event.c#L582

 

	//struct proc *p;
    //p = kn->kn_ptr.p_proc;
    //void (*knlist_remove)(void *knl, struct knote *kn, int islocked) = (void *)0xFFFFFFFF82401950;
    //knlist_remove(&p->p_klist, kn, 0);
	//to use knlist_remove you'd need to find offset of p_klist 1st since we didn't define it
	//but just so, we never populate p_klist, so it might be useless still


	#define KN_DETACHED	0x08
	#define KN_INFLUX       0x10

    kn->kn_ptr.p_proc = NULL;
	kn->kn_status |= KN_DETACHED;
	kn->kn_status |= KN_INFLUX; //to avoid asset... or do you not mind triggering it?
	//but perhaps this will be enough?

 

Edited by Zer0xFF
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...