Jump to content
eXtreme

Hack The PS4 - Status for End Users

Recommended Posts

don't know how many of you guy's got that @CTurt added some infos to the dlclose write up. some stuff like "kernel restoration"...

https://cturt.github.io/dlclose-overflow.html

Quote

Restoration of kernel state

The BadIRET exploit had a very convoluted execution flow, and required many additional stages after initially gaining kernel code execution before being suitible for general payload development.

For example, with BadIRET we first gained kernel code execution under a very critical double fault context, which we then used to hijack an additional function pointer.

We then had to directly handle return back to userland by restoring the swapgs imbalance to ensure we had userland GS base, before then crafting a valid stack frame to return to with the iret instruction.

We could then trigger the second payload from userland to gain kernel code execution under a normal context.

Furthermore, the exploit relied on corrupting the IDT which we had to reinitialise before returning from the critical payload.

The dlclose exploit doesn't require any of this, which makes it much easier and more direct to work with than BadIRET. After calling close we immediately gain kernel code execution under a normal context. Secondly, since this exploit doesn't corrupt any global structures; if we perform it in a separate thread, any corruption will be discarded once the thread finishes and so we don't need to clean up anything manually.

The general template for this exploit is as follows:


void payload(struct knote *kn) {
	struct thread *td;
	struct ucred *cred;
	
	asm volatile("mov %0, %%gs:0" : "=r"(td));
	
	kprintf("  [+] Entered kernel payload!\n");
	
	// Privilege escalation
	...
	
	// Jailbreak
	...
	
	// Sandbox escape
	...
	
	// Enable UART output
	...
	
	// Disable write protection
	...

	// Patch kernel functions
	...
	
	// Restore write protection
	...
	
	// Install kexec system call
	...
	
	// etc...
}

void *exploitThread(void *arg) {
	// Map the buffer, spray the heap, etc
	...
	
	// Create hole for the system call's allocation
	m = kernelAllocation(bufferSize);
	m2 = kernelAllocation(bufferSize);
	kernelFree(m);
	
	// Perform the overflow
	syscall(597, 1, mapping, &count);
	
	// Execute the payload
	kernelFree(m2);
	
	return NULL;
}

int _main(void) {
	int sock;
	ScePthread thread;
	
	// Resolve functions, connect to socket, etc
	...
	
	printf("[+] Starting...\n");
	printf("[+] UID = %d\n", getuid());
	
	// Create exploit thread
	if(scePthreadCreate(&thread, NULL, exploitThread, NULL, "exploitThread") != 0) {
		printf("[-] scePthreadCreate\n");
		sceNetSocketClose(sock);
		return 1;
	}
	
	// Wait for thread to exit
	scePthreadJoin(thread, NULL);
	
	// At this point we should have root and jailbreak
	if(getuid() != 0) {
		printf("[-] Kernel patch failed!\n");
		sceNetSocketClose(sock);
		return 1;
	}
	
	printf("[+] Kernel patch success!\n");
	
	// Dump files, patch memory from other processes, boot Linux, etc
	...
	
	sceNetSocketClose(sock);
	return 0;
}

 

Conclusion

Kernel code execution gives almost complete control over the system. I've described in my previous article a few things you can experiment with: dumping the kernel, disabling CPU write protection to make patches to kernel code, reading and writing memory of other processes, privilege escalation, breaking out of FreeBSD jail, escaping sandbox and gaining full access to the file system, and I've also hinted at a few other things you can try: dumping and decrypting crash dumps (look into /dev/da0x6 and sceSblGetKernelCrashDumpEncKey), decrypting saves (look into sceSblSsDecryptSealedKey), and dumping the registry (look into sys_regmgr_call).

 


rsz_2cfwprophet_banner_3.jpg

Share this post


Link to post
Share on other sites

@cfwprophet ummm... that's been there for sometime now, he's mainly referring to BadIRET and how it needs cleanup but not some much dlclose.

Share this post


Link to post
Share on other sites

well it also explains how to use the dlclose without to need to clean up anything later, cause nothing got corrupted in case of it runs in a own thread. and it also shows some more stuff like


"// Restore write protection"


right after


"// Patch kernel functions"

 

in case of you meaned, or was it @twisted89, that something seams to be corrupting the system or better say breaking system call's.


rsz_2cfwprophet_banner_3.jpg

Share this post


Link to post
Share on other sites
1 minute ago, cfwprophet said:

well it also explains how to use the dlclose without to need to clean up anything later, cause nothing got corrupted in case of it runs in a own thread. and it also shows some more stuff like


"// Restore write protection"


right after


"// Patch kernel functions"

 

in case of you meaned, or was it @twisted89, that something seams to be corrupting the system or better say breaking system call's.

 

Not how it works, trying to return from dlclose forcefully leaves resources locked in the kernel thread which breaks further system calls. 

 

 

Edited by twisted89

Share this post


Link to post
Share on other sites

got it...

 

bäää i need to do so much other stuff which i said to do and still need to do ^^...

 

anyway, should get my ass up, see what @bigboss comes up with to his birthday:) and get my stuff done.


rsz_2cfwprophet_banner_3.jpg

Share this post


Link to post
Share on other sites

Hurry up you lot I could of done this ages ago lol 

 

1287666826226.png

 

Keep up the Good work guys proud of you!  only million codes till you break the security 

Share this post


Link to post
Share on other sites

https://github.com/Thunder07/PS4-dlclose-kexploit-PoC/tree/resolve-dev-test

I've taken kernel symbol resolver from fail0verflow's ps4 kexec code and integrated it into the exploit, this allows the code to be more dynamic (it auto resolve prison0, rootvnode, sys_sendto etc), allowing it to support every firmware from 1.76 and lower, compared to before where all addresses have been hardcoded in.

 

however as a consequence, resolving sys_sendto which is used to print the msgs won't be around to send messages back until it's been resolved,

as such prints inside kernel_int() and kernel_resolve() won't print initially until we resolve sys_sendto....

 

I'm currently considering adding a micro for something like bprintf... where all the prints will be stored in a buffer until we call bflush() (after resolving sys_sendto).

 

anyone any thoughts on this? or has a different approach to this?

Edited by Zer0xFF
  • Upvote 1

Share this post


Link to post
Share on other sites

sounds good :)


either we find a other way to have the print or we may consider to use the autoresolving function for the sys_sendto only when we don't know the address to call the cast before.

 

like on 1.76 we know the offset for sys_sendto. why not just leave sys_sendto hardcoded ? just sys_sendto cause we need it asap.


rsz_2cfwprophet_banner_3.jpg

Share this post


Link to post
Share on other sites
12 minutes ago, cfwprophet said:

sounds good :)


either we find a other way to have the print or we may consider to use the autoresolving function for the sys_sendto only when we don't know the address to call the cast before.

 

like on 1.76 we know the offset for sys_sendto. why not just leave sys_sendto hardcoded ? just sys_sendto cause we need it asap.

 

if we do this, then we'd need check what firmware version we're running 1st... I'm not sure if there is a way yet.

but still, hardcoding it for any reason... such as this will defeat the whole point of it being dynamic.

Share this post


Link to post
Share on other sites

well to get a FW pointer is not the problem.

i don't really understand what you mean with this:

Quote

hardcoding it for any reason... such as this will defeat the whole point of it being dynamic.

..cause it doesn't change the fact that it will resolve all other symbols by need. but what ever. it's OpenSource ;)


rsz_2cfwprophet_banner_3.jpg

Share this post


Link to post
Share on other sites
28 minutes ago, cfwprophet said:

well to get a FW pointer is not the problem.

 

unless its a static pointer, kind of is.... unless you have an example to share?

 

28 minutes ago, cfwprophet said:

i don't really understand what you mean with this:

..cause it doesn't change the fact that it will resolve all other symbols by need. but what ever. it's OpenSource ;)

lol, what does open source have anything to do with is :/

 

if you hardcode it, you'll need to add a FW check, otherwise the bin will crash overtime it tried to load sys_sendto on any other FW... inevitably, everyone would start hardcoding their values in, defeating the point of this.

Share this post


Link to post
Share on other sites
5 minutes ago, Zer0xFF said:

 

unless its a static pointer, kind of is.... unless you have an example to share?

pardon what ? o.O

the browser can't get the FW version of the console ?

 

6 minutes ago, Zer0xFF said:

lol, what does open source have anything to do with is :/

o.O what's so lol on that or on OpenSource ?

it means that every one can use that code and add or remove stuff and bring up something. but what ever dude, what ever...

 

8 minutes ago, Zer0xFF said:

if you hardcode it, you'll need to add a FW check, otherwise the bin will crash overtime it tried to load sys_sendto on any other FW... inevitably, everyone would start hardcoding their values in, defeating the point of this.

not really but as said. open source.... ;)


rsz_2cfwprophet_banner_3.jpg

Share this post


Link to post
Share on other sites
37 minutes ago, cfwprophet said:

pardon what ? o.O

the browser can't get the FW version of the console ?

 

I'm asking how?

 

Edit: i pushed the buffer commit into that branch if anyone wants to test it and post a log, so i can confirm it's working correct.

use pastebin please.

Edited by Zer0xFF

Share this post


Link to post
Share on other sites

^^ standart .html

 

i used that for my basic test.html to identify if it is a PC, PS4, or a Vita and you even can read the FW version of it. well i didn't need it for my test's but as example for the Vita it did tell that it is FW 1.06.

 

i share you my basic.html with you. it's not perfect and missing stuff. how ever you can see how you can get the browser and also FW version of the console with a .html.

 

keep in mind that i have done this test on PS4 eg. as the console was released with my 0-day PS4.

 

uh...yea additional here is a google link:)

 

and a stackoverflow link :)

 

EDIT:

beside that the WK sploit allready need to know which fw vesion it is in case of the ROP gadgets and their offset's. then we may can overload some arguments to the binary, just like we also can see in the log from @bigboss  argc, argv. ;)
anyway, in end im sure that a lot can be automated and made much easyer then on the first run but there for i like open source. :) 

Edited by cfwprophet

rsz_2cfwprophet_banner_3.jpg

Share this post


Link to post
Share on other sites
33 minutes ago, Zer0xFF said:

 

Edit: i pushed the buffer commit into that branch if anyone wants to test it and post a log, so i can confirm it's working correct.

use pastebin please.

 

Memory error with this one (tried multiple times :) )

Share this post


Link to post
Share on other sites

@cfwprophet the html/js is useless as that data is not passed to the application, but I'll have a look at bigboss's work to see if there is anything useful...

again, I'd rather there be nothing hardcoded at all.

 

@fx0day thanks, was there any log at all?

Share this post


Link to post
Share on other sites

that was not the point ^^

 

the point was to get the fw version BEFORE executing the sploit to eg. craft some info for it before. ;)

 

just like what you said at last as example. and don't misunderstood me. it's no force, nothing. it was a though cause it is a forum. if you like it or not is not the subject or not the point i wanted to come to. if you don't like my idea, simple discard it.

 

it's not like that i can not code and mod me my own version of dlclose. :)

Edited by cfwprophet

rsz_2cfwprophet_banner_3.jpg

Share this post


Link to post
Share on other sites

@Zer0xFF My PS4 was on 1.71, HOWEVER, as stated in the PS Playground readme, it uses 1.76 hardcoded stuff and never worked for me (out of memory, etc.) so I updated to 1.76 via USB. I don't think you need to worry about lower firmwares -just- yet because 1: No reason to stay lower firmware and 2: Probably he won't back port to older firmwares because they are rare and can't test reliably.

Share this post


Link to post
Share on other sites
2 minutes ago, SonyUSA said:

@Zer0xFF My PS4 was on 1.71, HOWEVER, as stated in the PS Playground readme, it uses 1.76 hardcoded stuff and never worked for me (out of memory, etc.) so I updated to 1.76 via USB. I don't think you need to worry about lower firmwares -just- yet because 1: No reason to stay lower firmware and 2: Probably he won't back port to older firmwares because they are rare and can't test reliably.

 

well, it was @CTurt's suggestion that we use the dynamic resolver... so he either wants us to do it as practice for future releases, or he plans to update his playground as well.

Edited by Zer0xFF

Share this post


Link to post
Share on other sites
7 minutes ago, Zer0xFF said:

 

well, it was @CTurt's suggestion that we use the dynamic resolver... so he either wants us to do it as practice for future releases, or he plans to update his playground as well.

 

That may be, but you run into the same thing the WiiU faced... people wanted a back-ported version of some of the kernel based tools, but there was no reason to stay on a lower firmware so they never got ported. I think you are just causing yourself extra trouble in the long run...

 

think of it this way: once you get the exploit stable and loading what you want it to load, you won't even need debug output so you will probably remove it from the code anyway to slim it/tidy it up, so you may as well hardcode it for 1.76 now and just remove it altogether later.

 

Edit: The dynamic resolver will also help for -forward- firmwares when webkit bugs are released, and that's why he mentioned to use them. I don't believe he's worried about older FW...

Edited by SonyUSA

Share this post


Link to post
Share on other sites

that's what i meaned. ^^

 

he simple shall forget what i said and go on with his stuff. ;)

 

but i think we allready cleared that. :)

Edited by cfwprophet
  • Upvote 1

rsz_2cfwprophet_banner_3.jpg

Share this post


Link to post
Share on other sites

By the way the PS4-SDK of CTurt also auto resolve the symbols, just to say ;)

 

I added now sys_sendto() to the source kernel.h/.c of PS4-SDK.

 

and i found another bug in the PS4-SDK in usb.h but only by luck :P

 

will push a commit later...

Edited by cfwprophet

rsz_2cfwprophet_banner_3.jpg

Share this post


Link to post
Share on other sites

@cfwprophet

you should double check your PR, it's not mergable as it contains unnecessary commits.

you should start a new base based on master, add your modification then commit them before sending a PR.

also, i don't think sendto is part of the kernel module, but the kernel itself, as such it can't be resolved by libkernel.

 

Share this post


Link to post
Share on other sites

well he don't necessary need to add my commit. he can change his source on his own too. but anyway, will clean up the mass and change that later.

 

about sys_sendto im not sure about or better say i can't really say in case of i didn't invest any analysis or what ever. i simple toked it from a other source and since sysctl, sysctlbyname, sysarch and execve are also in, in the libkernel module, i highly guessed that sys_sendto will also be there. but either CTurt will teach us or i see it when i run the code. :)

 

EDIT:

ok, sys_sendto is a kernel symbole. @CTurt don't want to have kernel symboles in the PS4-SDK. so we have to respect that and go arround the easy way. but doesn't matter. i added sys_sendto to f0f kernel.h/.c, added the kexec.a to the SDK of my VM, added a ps4kexec.h also to it which we can use on the same way like ps4.h and which is a pragma and add's all the header's of the ps4kexec of f0f. it's a bit like LEGO but still the cleanesd way i think. so i share my VM and dev's only need to add #include <ps4kexec.h> into their project and then they can make use of all the Cast's and Function Call's from f0f's project. like eg. we can then easy use kernel_init(); as soon we entered the kpayload and will now have auto resolved ksymboles just like @Zer0xFF mentoined earlier. still there are 2 hardcoded things, well may only one but this for sure. there is one time the buffer in kmem where sys_kexec() will run from and which i extrem highly guess will change from fw to fw. and then second time we would have the *early_printf which (if defined) use also a offset based function call to debug symbole resolving. 

 

well uh....we may find a way to also either dynamical resolve this kmem buffer or we may find some other place that can be dynamical resolved or we find a place in mem which we map for the sys_kexec and which will be mostly the same on the FW's we can use with dlclose.

about the early_printf, we could use the offset we know from sys_sendto on 1.76 to eg. have early_printf but it would break on any other fw. on the other hand then it would only affect ksymbole resolving. so just a view lines.

Edited by cfwprophet

rsz_2cfwprophet_banner_3.jpg

Share this post


Link to post
Share on other sites

I'm not sure we can cleanly exit dlclose through 'fixing' the knote. You can get a list of valid knotes through proc with td->td_proc->p_klist.kl_list.slh_first, if you memcpy one of them over the broken note in kernel payload the Ps4 still panics and shuts down. 

Edited by twisted89

Share this post


Link to post
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

×
×
  • Create New...