When HENkaku came out exactly a month ago from today, we posed a challenge to the scene to reverse our hack. The reason for this decision rather than to just post our writeups immediately and take all the limelight is because we believe that the Vita is a device that is so unique in its security features that we won’t be doing it proper justice by just revealing the flaws. We want people to know about how good the security is rather than just point out the mistakes made. In doing so, we hoped that hackers new and old will take the challenge and have fun with it. Today, one such challenger by the name of st4rk completed the second third of the challenge. He has written a detailed post on how he reversed the payload and I recommend you read it right now.
Stage 1 of HENkaku was a previously patched but undocumented WebKit exploit. Many people including st4rk and H figured out most of the details within days. xyz of molecule then posted a complete writeup and focus shifted to stage 2 and all was quiet for weeks. Now that st4rk has published his writeup, I want to add some comments from our side.
The best way to understand what each part does is debugging and know well about the Vita’s security measures.
This was a smart and unique way of approaching the problem. Instead of starting from the bottom up (look at the dumps and try to figure out what each set of bytes means) he looked from the top down. Sometimes such change in perspective really help in clearing a path to the solution. By asking questions like “how did they get past the KASLR?” or “what did they do to put code into the kernel?” st4rk was able to rebuild the exploit piece by piece. This is what “reverse engineering” truly means.
The stage2 is a huge rop-chain and to solve this problem I written a python script using capstone to help me to deal with it, you can find it here
The rop-chain is actually generated from roptool by Davee of molecule. It’s an amazing piece of work that lets you turn Turing-complete code into ROP chains. It’s no surprise that decomposing the chain would require an automated tool.
The first time that I read it, it didn’t make any sense, first because we don’t have a “molecule0” device on PS Vita and second that I didn’t know anything about the SceIoDevCtl. I read the vitasdk and psp2sdk to give me a good base and decided to write a ROP code for my 1.50 Vita and test the Syscalls.
Smart thinking in using a low firmware version Vita. There is no kernel ASLR and stack canaries before firmware 1.80. That’s why I recommend it for hackers and aspiring hackers.
This is our first kernel exploit, it’s used to defeat Kernel ASLR and to write our Kernel ROP chain.
Yup. The first kernel exploit we use is an information leak in
sceIoDevCtl. The function copies the 0x400 bytes from the kernel stack into the user output buffer without checking the size field. That means if we call some random function that leaves pointers in the stack (in this case, a call to
sceIoOpen), the next call to
sceIoDevCtl does not clear it and copies it back to user. This is enough to defeat kernel ASLR.
This vulnerability was found back in late 2014 by our very own Davee. We finally made use of it years later.
The Kernel exploit is in the the module that handle the SceNet functions (it’s the SceNetPs).
Ah, the exploit that made all of this possible. A use-after-free in the socket handling function triggered by a race condition. st4rk managed to get as much information as he could without seeing the code, but the actual exploit is a complex and truly marvelous piece of work that this margin is too narrow to contain. This vulnerability was found and exploited by xyz earlier this year and is what sparked us to create HENkaku. He will be posting a detailed explanation of this exploit later this week.
Now things get truly interesting. Stage 3 is the final part of the exploit and is, what I believe, the hardest part to reverse. Stage 3 is a kernel ROP chain that executes the code to make all the HENkaku patches. Typically, to reverse a ROP chain, you would dump the code memory and reconstruct the gadgets in order to analyze the chain. Indeed, this is what st4rk did for our userland ROP code. However, we did not release any exploit that leaks arbitrary kernel memory. The
sceIoDevCtl vulnerability can only leak kernel stack memory–which in this case is just the ROP chain that we inject. So how would you crack this code? You can either
- Find a Vita vulnerability that lets you dump kernel memory
- Find a novel way of cracking ROP chains blind
In either cases, everybody wins. If you find another kernel exploit, it would be groundwork for the next Vita hack. Since our
sceIoDevCtl is patched now, we have no way of defeating kernel ASLR on newer firmwares–which is a prerequisite for any hack. If you manage to crack the ROP chain blind, well, for one you are definitely smarter than me. Of all the members of molecule, I am the only one who does not think the task is impossible. We honestly cannot think of a way of cracking the ROP chain blind. Davee claims it is impossible and xyz thinks we should provide more help. However, I think it is arrogant to assume that nobody can do it just because we can’t do it. The king-of-the-hill challenge really is about finding people better than ourselves to both collaborate with and to continue the work.
Back when I was working on reversing Gateway, I saw some of the most ingenuous hackers coming up with novel ways of reversing Gateway’s (in comparison: simple) ROP chain. I learned a lot from these people and I am hoping that there are more of them out there to impress me. That is why I pose this impossible challenge.
Today, as promised, we are releasing the full source of stage 1 and 2 written in roptool. This will allow you to make easy changes to the exploit code as well as test changes to the binary payload for your reversing endeavor. I can’t wait to see what you guys come up with next!