Sunday, January 14, 2018

Anatomy of a Wii U: The End...?

Welcome to a new write-up! Last time I wrote one of these was months ago, but I had good reasons for that (*cough*Switch*cough*).

Since as early as March, I've been working non-stop on hacking and reverse engineering the Switch alongside extremely talented hackers/developers such as plutoo, derrek, yellows8 and SciresM.
Together we have achieved incredible milestones and I'm really glad all our hard work eventually paid off.

That said, let's move on to the reason for this post: the Wii U.
If you are one of those few weirdos enthusiasts that still care about this console, you might recall last year's CCC where derrek, naehrwert and nedwill showcased their progress in hacking the last bits of the 3DS and Wii U.
Back then, they demonstrated their own exploitation path for taking down both the PPC and ARM processors on the Wii U, which was something that had already been publicly achieved using different bugs/exploits. This was also achieved much earlier by the hacking group fail0verflow which showcased their findings during the 30th edition of the CCC (back in 2013).

It was a very cool talk all around, but the main highlight for Wii U hacking fans was something derrek brought up: boot1.
This particular piece of the Wii U's boot chain was never obtained up until derrek and his team (plutoo, yellows8, smealum and naehrwert) successfully launched an hardware based attack that resulted in dumping the boot1 key.
The setup for this attack remained private, but the overall exploitation process was explained during the talk and is also documented here:

That was the last nail in the Wii U's coffin... or was it? Naturally, after obtaining the boot1 binary, derrek and his team began looking for vulnerabilities in it. While most of the usually critical stuff (signature handling, file parsing, etc.) was found to be safely implemented, derrek, plutoo, yellows8, naehrwert and shuffle2 did find one potential bug. However, due to lack of motivation and time, it remained just a theory.

I even wrote a blog post about all this where I mistakenly assumed some things that weren't true. Then I issued another blog post apologizing for said assumptions... Those were confusing times. :P
However, that's what got me to chat with derrek and get to know him better.

After some discussions about boot1, derrek agreed on sharing with me the potential bug that was mentioned during CCC. His team was already getting ready for the Switch release and they had little to no time left to work on trying to exploit this bug, so I offered my help.

A few days later I found a way to exploit this bug and achieved boot1 code execution! Neat, huh?
So, without further ado, I present you a writeup on the mythical boot1hax. :D

NOTE: Obtaining the boot1 binary in the first place is out of scope for the purposes of this writeup.

The Bug

The bug itself is really simple.
After some hours reverse engineering the boot1 binary and using the information derrek had shared with me, finding the bug was straightforward.
However, to understand it, we have to look into a specific IOSU process: IOS-MCP.

Wait, IOS-MCP? That loads AFTER boot1, what could possibly relate them?
Turns out, IOS-MCP manages something that plenty of people have already looked into (and maybe even guessed it's purpose), but couldn't exactly undestand what it does.

There is a range of physical memory mapped in IOSU that appears to serve no clear purpose: 0x10000000 to 0x100FFFFF (see

The typical layout of this region is as follows:
Breaking it down, we have a pattern filling the first 0x400 bytes followed by NULL bytes up until this PRSH/PRST structure:
This structure is created by IOS-MCP to keep track of the addresses and sizes of several memory regions. It is encapsulated with a header (PRSH) and a footer (PRST) and contains an array of structures describing memory regions.
In the latest firmware version, only 7 regions are registered in this structure. Here's an example parsed from my console:
While most of these regions contain nothing particularly interesting, there is one exception: boot_info.
This region stores data passed along from boot0 and boot1 to IOS-MCP! An example from my console:
As an example, the last 8 fields contain the time spent on each boot0/boot1 stage and this data is printed on crash logs.

What derrek and his team found out by looking at the boot1 binary is that this structure is also passed back to boot1!
How? Well, right before a reset is asserted, IOS-MCP encrypts the entire 0x10000400 to  0x10008000 range with the Starbuck ancast key. When the console reboots, RAM contents are not cleared and boot1 will decrypt this range and parse the PRSH/PRST struct looking for the boot_info region.

Even though this might look like a weird way to pass data back and forth across the boot chain, this process is actually properly implemented and boot1's code for parsing the PRSH/PRST structure is sound. But there is one exception...

On coldboot, where the RAM contents are cleared, it's boot1 that creates boot_info for the fist time at the hardcoded address 0x10008000 and inserts this information into the PRSH/PRST structure. However, on a warmboot, boot1 decrypts and parses the already existing PRSH/PRST structure in RAM which might have been changed by IOS-MCP. This means that boot1 actually locates the boot_info section inside the PRSH/PRST structure and uses the pointer stored there to read/write the actual data.

This shouldn't be a problem, but they forgot to validate the pointer to boot_info data, which means that if IOS-MCP changes it, boot1 will attempt to read/write the boot_info data from any address we want (instead of 0x10008000)!

What derrek and his team were able to verify is that changing the pointer for boot_info to an address within boot1's stack region would crash boot1. A plausible exploitation path here would be to take advantage of whatever boot1 writes into boot_info to overwrite some LR address stored in boot1's stack and gain code execution.
Unfortunately, this is very impractical. Turns out, the way boot_info is parsed and modified by boot1 is very, very restricted.

The Exploit

So, we have this weird small structure that boot1 uses to communicate with IOSU (and vice versa) and we can control the pointer for said structure to force boot1 to read it from anywhere we want. The only way to tell if this can be exploited or not is to know exactly why this boot_info structure exists and how boot1 handles it, so I'm going to cheat and jump straight to a breakdown of how it's done:
As you can see, there's not much going on. The PRSH/PRST structure is decrypted from RAM and boot1 tries to locate boot_info inside it. If it fails, a new boot_info entry is created and inserted into the PRSH/PRST structure, but the pointer for it's data will be hardcoded to 0x10008000, thus causing any subsequent reads/writes to occur in a perfectly safe address range. However, if it does find a preexisting boot_info entry, boot1 will fetch it's data from the pointer stored inside the PRSH/PRST structure and this is what we are interested in causing.

The attack plan is simple:
  •  Use any exploit we want and escalate to IOS-MCP (or even better,  to the IOSU's kernel);
  • Craft/modify the PRSH/PRST structure in memory using a modified boot_info pointer;
  • Encrypt the PRSH/PRST structure with the Starbuck ancast key and boot_info IV (stored at 0x050677C0 in IOS-MCP);
  • Force a reboot.

As expected, we can force boot1 to take a modified boot_info pointer and start reading the data from anywhere we want. Now comes the real challenge: where should we point to?

We must focus on the boot_info fields that are always modified by boot1, but we also need to take into account how boot1 tells if boot_info already exists or not. This happens in sub_D40AF10 and it goes like this:
  • Each PRSH/PRST section is parsed and it's name is compared against the string "boot_info";
  • If the boot_info section is found, it's size is checked and it must be 0x58;
  • Finally, the boot_info_04 field must have bit 0x80 (big endian) set.

This last check is very important since boot1 only accepts a preexisting boot_info structure if the word at offset 0x04 has that specific bit set.

It's now clear that we can achieve a semi-arbitrary write in boot1 by abusing this particular bug. All we need is to change the boot_info pointer inside our crafted PRSH/PRST into something that resembles a valid boot_info structure from boot1's point of view. This would then result in boot1 updating those boot_info fields listed before and, therefore, write data to an arbitrary address.

Let's leave the "boot_info_04 field must have bit 0x80 set" aside for a while and focus on which fields might be useful to write into boot1's address space:
  • boot_info_08: this is only modified by boot1 when a specific RTC event has occurred.
  • boot_info_38 to boot_info_54: these are used to store the time spent on the various boot0/boot1 stages.
  • boot_info_0C: this is increased by 1 each time a warmboot occurs (gets set back to 0 on a coldboot).

To be more precise, there are indeed a few more fields that are modified by boot1, but these are always set to either 0 or -1 in a way that doesn't make it really practical to choose them.

I began by focusing on the time related fields, but these just turned out to be too volatile for a reliable memory corruption. Also, boot_info_0C is not really useful either since it keeps changing on each warmboot.
What about boot_info_08? For this field to be read/written the RTC must have the SLEEP_EN flag set. Luckily, we can just force this flag to be set by calling the system call ios_shutdown(1) (see which also happens to trigger a system reset!

Still, boot_info_08 will be overwritten with rtc_events |= (boot_info_08 & 0x101E). From blind tests, I could tell the final value that got written was always 0x0020XXXX, which means I could write a NULL byte followed by 0x20 and whatever was in the lower bits of boot_info_08. This is far from optimal... :\

Took me about 2 afternoons of reading boot1's binary until I finally found the perfect place to corrupt:

This particular snippet is the epilogue of sub_D40AC30, which runs immediately after boot_info_08 is modified. Doesn't look particularly interesting, but let's check the hex:
Jackpot! Since we are running way before MMU is set up and all that, we can do unaligned memory reads/writes just fine, so, if I change the boot_info pointer to 0x0D40AC6D, boot1 will see the following structure:
  • boot_info_00: 0x00BC0E46 
  • boot_info_04: 0x93469D47
  • boot_info_08: 0x080000XX 

Since boot_info_04 has bit 0x80 (big endian) set, boot1 will overwrite boot_info_08 with 0x0020XXXX. Why is this important? Because we now have mutated the instruction BX R1 into BX R0 and R0 is 0.
This means boot1's execution will fall into NULL. Normally this isn't very exciting, but in the Wii U's case the physical address range 0x00000000 to 0x01FFFFFF maps to MEM1 (which is frequently used for graphics).

This memory range is not cleared on a warmboot either so, as long as boot0 and boot1 leave it alone, we can actually plant our payload there and have arbitrary code execution going!

It's known that boot0 doesn't touch any relevant RAM regions, but what about boot1? Well, boot1 actually accesses the three RAM regions (MEM0, MEM1 and MEM2):
  • MEM0 is fully cleared by boot1 as soon as it starts;
  • MEM2 is left untouched, with the exception of the first 0x400 bytes at address 0x10000000 which are filled with a binary pattern for testing RAM self-refresh;
  • MEM1 is also left untouched, with the exception of a single word (0x20008000) being written at address 0x0000000C for unknown reasons.

As long as our payload starts right away with a jump over address 0x0000000C, we are good!

So, I cook up a small payload to copy boot1 from SRAM into some unused MEM2 region, patch the corruption I just caused, jump back to where execution fell to NULL and let boot1 finish. Now I just need to escalate into IOS-MCP or IOSU's kernel and fish out the binary!

As a bonus, this particular method allows me to hijack execution before the 2 mysterious OTP blocks get locked (see so I can easily piggyback on boot1's OTP reading functions and get them too!
Sadly, these blocks are never used and were likely locked out as a preemptive measure so a future update could begin to use them instead of some other key material (especially since the 2 blocks are not per-console). 

And there you have it, boot1 code execution from a RAM based attack!
Along with this writeup, I'll be publicly documenting boot1 over at and I'm releasing a patch for my long forgotten project hexFW that gives you the option to dump your console's boot1 and unlocked OTP:

NOTE: This does not include the boot1 AES key, since that one is long gone by the time we are running code in boot1!

What about CFW? Well this attack on it's own doesn't really help you there.
In order to get a custom firmware running straight from boot1 another kind of attack is preferred, specially something that actually survives a coldboot. :\
Remember that this only works due to RAM not being cleared on a warmboot so it's impossible to achieve persistence this way.

However... There's one plausible vector that could be used to create a much safer alternative to current methods.
Leveraging this bug from the vWii environment, for example, could grant a nice boot(ish) time CFW by combining some form of contenthax in a way that entering vWii mode would launch the boot1hax payload, reset the console and send you right into a CFW. The total time spent on this would be minimal and it would create a dual-boot environment where you could hold down the "B" button on boot to jump into CFW or do nothing to land on the vanilla OS. That is, of course, if you wouldn't mind sacrificing your vWii channel for a while (it would then be possible to restore it from within the CFW environment, so that's not really an issue).

I've been looking into this for quite some time with derrek, but the Switch has been taking most of our time so I kept postponing this project endlessly. Regardless, I still plan on picking this up one last time during the start of this new year, but derrek and I agreed on sharing this anyway so others can also get the chance to research boot1 and hopefully find some new bugs in the process.

All this has been kept under wraps for quite a while for a very good reason: it's insanely easy to patch. Now that the Wii U reached it's EoL and the Switch is the new kid on the block, it seems appropriate to end (for good) the Wii U cycle while homebrew on the Switch is just beginning to flourish.

Retail plaintext boot1 (v8377) SHA-256: 5013BFABC578CBA08843D9A0F650171942A696CBC54DF12E754D9E0978FCD3B1

I hope you enjoyed reading this as much as I did writing it. :)
Stay safe and have fun!

Saturday, January 13, 2018

The Switch - State of Affairs

Let's kick off the new year with a new blog post!

Since this last year's CCC talk where derrek, naehrwert and plutoo showcased their progress on hacking the Switch, tons of misinformation began floating around about which firmware is necessary for homebrew.
I believe it's now time to put up a nice and comprehensive FAQ on all things Switch hacking related.
So, buckle up, and if you have the questions, here are the answers.

Q: Who the hell are you and why should I take your answers seriously?
A: I've been working on hacking the Switch since day 1. I've found bugs and developed exploits on my own at first and eventually ended up integrating a small loose crew of hackers that share the same interests. While we work together on a certain level, we also work either individually or among other groups (Switchbrew, ReSwitched, etc.).

Q: Were you involved in 34c3?
A: Not directly. Just like many others who were credited during the talk, I've worked with derrek, naehrwert and plutoo on hacking the Switch, but what was presented during the talk is a reflection of these hackers separate work.

Q: I have been told for quite a while that firmware 3.0.0 is where I should be at. They even said so during the talk! What does that mean?
A: Firmware 3.0.0 introduced a specific bug that allowed for userland code execution, but the same bug was patched immediately after on the next firmware update. This created the perfect starting point for publicly disclosing this vulnerability and laying down the foundations of homebrew.
The idea was simple: get as many people as possible on firmware 3.0.0 so everybody can start working on writing homebrew right away. What wasn't particularly clear is that this is ultimately an advice for homebrew developers and not the average end user.

Q: And what about [insert firmware version here]?
A: Here's something that you probably don't know yet: ALL current firmware versions are exploitable up to the point of running your own code.
Yes, you read that right. This includes firmware 1.0.0 all the way up to 4.1.0.

Q: So, can I just update my Switch?
A: Yes and no. This is a question many have been asking and conflicting answers are causing a great deal of confusion among people.
The basic principle is the following: if you have no reason to upgrade from your current firmware version (regardless of what it is), then simply don't upgrade.

However, the real answer is quite more nuanced. Increasing firmware versions obviously include additional patches for a myriad of vulnerabilities, therefore, the lowest firmware version (1.0.0) is the most vulnerable. Obviously, for a number of reasons, not everybody will be able to get their hands on a launch day system, so there's always interest in exploiting new updates.

In an effort to clear the air and promote a less toxic environment, here comes the current state of affairs regarding Switch hacks:
- Firmware 1.0.0:
-> Contains critical system flaws that allow code execution up to the TrustZone level;
-> Most of what was showcased during 34c3 originally targeted this firmware version;
-> Allows for a full blown emuNAND/CFW setup.

- Firmware 2.0.0-2.3.0:
-> Contains system flaws that allow code execution up to the kernel level;
-> Can be exploited to run homebrew using private methods (e.g.: nvhax).

- Firmware 3.0.0:
-> Contains system flaws that allow code execution on the userland level;
-> Can be exploited to run homebrew using private methods (e.g.: nvhax);
-> Can be exploited to run homebrew using public methods (e.g.: rohan).

- Firmware 3.0.1-4.1.0:
-> Contains system flaws that allow code execution on the userland level;
-> Can be exploited to run homebrew using private methods (e.g.: nvhax).

As you can see, the higher the firmware version, the less options you have. However, code execution for homebrew is still assured across all firmware versions.

Q: Wait, did I read that right? Firmware 2.0.0 to 2.3.0 can be exploited up to the kernel?
A: Yes, but no additional information will be disclosed at this point.

Q: What is that nvhax thing?
A: This is currently a private method that I originally discovered and exploited. Joined by SciresM and plutoo, we have successfully used it to exploit pretty much all firmware versions to the point where running homebrew is possible.

Q: Will nvhax be released? When?
A: Yes, but there are no plans to release it any time soon. Having code execution on the latest firmware version available is a privilege that ought to be maintained for as long as possible.
That said, when it stops being useful it will be released as an alternative for people on firmware versions above 3.0.0 to enjoy homebrew.

Q: Ok, so, I'm a developer with a strong passion for homebrew and would love to start right away. What do you suggest?
A: Update your Switch to firmware version 3.0.0, read about rohan and get to work!

Q: Now, I'm just a regular user that loves homebrew, but has no intent or knowledge to develop my own. I also want to play the latest games on my Switch and don't really mind waiting. What do you suggest?
A: Update to the latest firmware version and wait.

Q: What if I'm an avid hacker/developer who wants to explore the system as much as possible?
A: Find a 1.0.0 unit and stay there.

Q: And what if I just want to pirate games?
A: You're barking at the wrong tree.

Hopefully this FAQ will put to rest some of the doubts people have been expressing lately and help them understand the necessary steps to enjoy homebrew on their consoles.
More information will be shared when the time is right, but rest assured we are all working hard on really cool stuff and, hopefully, helping to build a strong homebrew community for the Switch.

Also, stay tuned for a very special blog post in the following days. ;)

As always, have fun!

Wednesday, March 15, 2017

Yet Another Apologetic Moment

So, just a quick status update first: I've been doing some lv0 research on my free time, but I've mostly moved on to the Switch (who hasn't at this point?).
I'm really enjoying the public efforts showing up in regards to hacking it (see PegaSwitch for example) and I  truly hope this will turn out to be a more sane "scene" than the previous ones.

Anyway, on to the reason behind this post.
I was very happy to exploit lv1 on my 1.50 Vita, did a small write-up on the process and documented the exploit used.
Well, there was something I left out on my previous post (on purpose): a lot of the information that led me to achieve a successful lv1 hack was leaked from someone else (who shall not be named for privacy).

First, a bit of context. I did find a memory leak using the 0x12F SMC (which I tweeted about) and discovered the meaning of the shared memory areas earlier on January. However, I was stuck there for quite a while, limited to an arbitrary 8 byte read primitive.
Then, suddenly, I began receiving anonymous emails with *very* *specific* information about this particular bug and how to use it to achieve lv1 code execution. The person made very clear that didn't want to be involved and allowed me to do whatever I deemed right with the information.
After successfully recreating the exploit and achieving code execution I tried to contact the person again for a few reasons (mainly, trying to understand how he/she/it had this knowledge). After days without a reply and getting my emails bounced back (the individual's email address even seemed to be randomly generated and was using a widely popular secure email service) I decided to write-up about the bug while keeping certain details away.

I honestly thought I was doing no harm, but, at the same time I had my suspicions. Fast forward to today, the real author of this exploit contacted me and after chatting for a while it became clear that this information I was provided with was leaked.
The main reason behind this post is to properly acknowledge the author of the exploit (who also found the bug in the first place) and to stress out how important the author's work is.

I favor honesty over fame, but unfortunately a lot of people think differently. I still don't know exactly what was the point of all this, nor do I know if the leaker shared this with more people (in that case, it would be a matter of time until someone did the same thing I did).
I began working on security and writing on this blog always having a strict policy of not getting involved in drama. Turns out, it simply can't be avoided.

I apologize publicly to the author of the exploit for publishing it and to everyone that was misled into thinking it was entirely my work. I hope you all can understand the position I was in and also that it was never my intention to shine through the efforts of others.
I obviously take the blame for taking the wrong decision and publishing the exploit, while I should've just kept it for myself or at least try to understand better where it came from.

I'm truly not used to all this backstabbing, secrecy and wars over fame that brew from the console hacking "scenes", so I naively assumed this was someone sharing the information with the single purpose of bringing it to the public without his/hers/its name attached to it.

I've learned my lesson from this event and I'm deeply sorry for what happened.

Saturday, February 11, 2017

The aftermath: A tale of (Secure) Worlds

Welcome once again to one of my adventures! This is going to be a long one, so bear with me please.

I've been busy lately and I know I've promised a decent write-up on Wii U exploitation, but even though I've began writing it up, I must confess the motivation to finish it is deeply lacking (starting to understand derrek now).
So, as a way to compensate for that (and also to buy me extra time), I'm presenting something else that many have been waiting for (or not, I really don't know): a new Vita related post!

I still plan to finish up my work on the Wii U and document a lot of stuff I had been working on (previously unknown hardware registers, the RTC, and so on). I'll be pushing some of that to from time to time (nothing major, so don't get your hopes high).

Anyway, on to what brought you here, the Vita.
As you may recall, my last blog post about the Vita was a small recap of the HENkaku challenge and also my plans for the future. One of my main goals after winning Team molecule's challenge was to push further and defeat the next layer of security found on the Vita: the TrustZone.
I achieved this feat a while back and made a small remark about it on twitter, but I'm here now to fully explain how it was done and what it really means.
This is being published with the permission of Team molecule's members and doesn't conflict with their past and/or present work.

The beginning


Once the HENkaku challenge was over, Team molecule released a lot of useful tools and a full blown framework to write and execute code on the Vita's kernel. Obviously, all these efforts were directed towards the firmware version 3.60.
I began by setting up the taiHEN framework and writing a small kernel application to fuzz SMCs (Secure Monitor Calls). Analogous to how SVCs (Supervisor Calls or syscalls) work, SMCs are present on ARM based systems that implement the Secure Monitor mode.
The Vita implements a complex security scheme with many layers of execution, but, for the purposes of this write-up we can divide them as:
  • Userland: The least trusted environment on the Vita's ecosystem. This is where user applications such as the browser run in.
  • System: System applications and SceShell run on this level. While this level is still part of the userland, there are special permissions granted to applications running here and communication with the next level on the chain is made easier due to the access to more important SVCs.
  • Non-secure World Kernel (dubbed lv2): This is where all kernel level modules ("os0:kd") are loaded into and executed. It can be seen as the system's kernel in it's traditional sense, since this level is responsible for the sensitive operations often locked away from direct user interaction (thread and process management, filesystem, memory, and so on).
  • Secure World Kernel (dubbed lv1): This level is commonly found on modern devices (such as smartphones) and provides a more trusted environment than the regular kernel. It's often used for highly sensitive operations such as cryptography and hardware communication.
  • F00D (dubbed lv0): Not much is known about this level, but it's hypothesized to be a separate CPU with the sole purpose of handling crypto operations and executing secure modules.

So, with HENkaku we had an exploit chain that was capable of defeating the userland and run code on the non-secure world kernel (lv2). From there, we would get a privileged application running at the system level that we could communicate with for various purposes.
After the challenge was over, Team molecule released taiHEN, a full blown CFW framework that could be used as basis to write kernel level patches to be run on the Vita.
This left lv1 and lv0 left to exploit (not counting with the bootloaders) in order to fully take over the Vita's chain of trust.

For a while, I focused on passing along random data to as much SMCs as possible. Unfortunately, there aren't many registered SMCs which makes the attack surface from lv2 to lv1 very limited.
This was going nowhere on firmware 3.60 as I kept getting error codes from lv1 due to sane validation of my inputs.
At this point, I knew my best option would be to track down a Vita with a low firmware version since the very first successful efforts on taking down lv1 were done on such units (see

The quest for the right firmware


I've had low firmware Vitas on my hands before (back when I was taking the HENkaku challenge), but I had to go further than that. My ideal goal was to find a launch day Vita, since it would be as unpatched as it can possible be.
Locating one turned out to be very hard and the ones available ended up being too expensive, so I decided to go after something a bit higher.
One thing I knew for sure: looking into the update files for the Vita (psp2-updatelist.xml), you can see that lv0 (the F00D processor) was updated once and only once on firmware version 1.60. Regardless of what this may mean, I wanted to find an unit on something lower than that just in case some critical lv0 bug was patched there.
Fortunately, I managed to track down an unit on firmware version 1.50 and so the journey began...

On such an old firmware version, the browser was based on a quite old WebKit version which means the most recent exploits (sort() method, CSSSelectorList) can't be used there.
Still, Team molecule's Davee had worked on such low firmware versions and by chaining together two bugs they were able to leak memory and do ROP under the browser application (see This was also how roptool (a tool for assembling ROP chains) and  HTMLit (a packager to convert ROP payloads into vulnerable HTML files) was born and, obviously, these tools served as basis for all my next exploitation efforts.
I also had my work cut short thanks to a roptool target for firmware 1.50 being already available (see This saved me from manually leaking the browser's memory and locating gadgets, so I skipped right into ROP.
NOTE: the most recent versions of roptool seem to have an issue when generating payloads for HTMLit, so I had to compile an older version of roptool to work on firmware 1.50.

Right in the kernel


Now I can do ROP inside the browser, but that's not even near enough. On firmware version 3.60, after compromising the browser, we could target the kernel by exploiting two specific bugs (which I've detailed during my HENkaku KOTH challenge posts). This time, we have a couple more options:

First thing I did was testing out the sceIoDevctl bug on this low firmware and leak a few bytes from a kernel level thread's stack:

Note that on such low firmware versions userland ASLR was not as effective, kernel ASLR was not implemented at all and memory regions were allocated aligned to 0x1000 bytes. So, looking at that stack leak we can easily tell that SceSysmem is loaded at virtual address 0x00480000.
That's nice and all, but we need to be running code under the non-secure world kernel (lv2) if we want to even get to the same level as HENkaku.

Team molecule documented two old (and patched) bugs on the HENkaku wiki that look very attractive: a stack buffer overflow in sceSblDmac5EncDec and an integer overflow on the syscall handler itself.
Firmware 1.50 is still vulnerable to these bugs, so it seems only logical to try taking advantage of them. The sceNetSyscallIoctl UAF could still be an option, but exploiting it is far more convoluted in comparison.

So, time for an attack plan:
  • Plant a ROP payload using sceIoDevctl;
  • Use the sceSblDmac5EncDec stack buffer overflow and overwrite the current LR value;
  • Jump to our ROP chain and profit!

Simple, but has many issues:
  • Without a memory leak, we're essentially blind and ROP would be useless;
  • We know where SceSysmem is, but that's not really helpful;
  • sceSblDmac5EncDec is not imported by any userland module, so we can't even access it.

I was able to solve that last issue after finding a reference to sceSblDmac5EncDec here:

If this function is used to encrypt/decrypt PSVIMG files, then launching CMA should install the necessary SVC. However, it's still not imported anywhere so I have to brute-force syscall IDs (which are randomized) until I get it.
Still, even if I get this working and manage to jump into my ROP payload, what am I supposed to do? I need to find gadgets and that's not going to happen without a memory leak.

Eventually, I found a way to leak kernel memory, but at this point I had found the syscall table's location already so, I ditched my previous effort and focused instead on the syscall handler's integer overflow.
Passing a large value in R12 and executing the SVC instruction will overflow the syscall's table pointer, which means that we can force it to point into some module's import table and get an arbitrary function pointer dereferenced! In sum: arbitrary kernel code execution.

Taking down (Un)TrustZone


Now comes the fun part. With arbitrary kernel code execution, I'm essentially at the same level as HENkaku on firmware 3.60, which means it's time to fuzz SMCs once again.
In parallel, I dumped the entire non-secure kernel (lv2) memory space and began reverse-engineering several kernel modules. I had done this already for most of firmware 3.60 modules, but perhaps one of these older binaries could suggest something new.

I focused on kernel modules that invoked SMCs: SceKernelIntrMgr, SceKernelBusError, SceLowio and SceSblSmSchedProxy.
A call to the very first SMC (0x101) can be found inside SceKernelIntrMgr and it does something very interesting:

It seems to be used to set a physical memory region visible by both non-secure and secure worlds! Eventually, when reversing SceSblSmSchedProxy I figured out this region is used to send data back and forth across the two worlds.
This shared area is located on the non-secure kernel at the virtual address 0x00400000 and it's a 0x5000 sized buffer split into 160 blocks of 0x80 bytes each. Analyzing one block:

Hmm... Some values in there don't make much sense...
Anyway, back to the fuzzer. I decided to focus on the SMCs that SmSchedProxy invokes, mainly because they appear to access this shared region. Then, one particular SMC began displaying erratic behavior. It would cause a full kernel panic on some values, but would execute normally on others, so I decided to take a closer look:

The value in *(status_struct_addr + 0x04) seems to come from shared_mem_block + 0x14 (0x002A8109), but that's not a valid memory address. I tried to increment and pass similar values until I got a crash. After repeating this for a while, something became very clear:
  • ((0x002A8109 - 0x01) << 0x01) == 0x00550210
That's right, the first argument for SMC 0x12F must be a secure world kernel pointer (shifted for some reason)! I was able to confirm this successfully by matching the values that wouldn't crash with clearly defined memory regions (0x00550000, for example). So, I decided to test a few values in this format and dump the shared memory region each time it didn't crash. The return values (stored back into out_buf) are copied from shared_mem_block + 0x00 and shared_mem_block + 0x04 and every time the call didn't crash, those 0x08 bytes would have data written to them.
I dumped part of the 0x00550000 region this way and found pointers to another region: 0x00510000. I tried passing it to the vulnerable SMC and, eventually, code was being copied! This SMC was leaking 0x08 bytes from an arbitrary lv1 memory region!

Unfortunately, despite my best efforts I couldn't find a reliable way to dump more than 0x08 bytes at a time (caching issues?), so it took me a loooong time to dump a few relevant modules.
I dumped SceSblSmSched first (which happened to be the module located at 0x00510000) so I went looking for the flawed function mapped as SMC 0x12F.
The function is located at virtual address 0x0051DDFC and to my surprise, it's simply doing an uncheck copy of 0x08 bytes from (smc_arg0 << 0x01) + 0x28 into a 0x80 byte aligned pointer to a shared memory block.

Upon taking a closer look, the shared_mem_index is also unchecked. So, not only the first argument can be an arbitrary address, but the second argument is an unchecked array index? This means we have an arbitrary(ish) memory read/write on lv1!

Looking into SceSblSmSched's import table I was able to locate SceSysmem (TrustZone version) and eventually the SMC table. After dumping enough of SceSysmem and locating some nice read/write primitives, I went back to the flawed SMC and tried to go the other way around: plant pointers to read/write primitives on the shared memory region, pass the shared memory region's address as the first argument for SMC 0x12F (since TrustZone is also able to access this region) and overflow the second argument (the index) to point somewhere into the SMC table.
This was not working and it took me a while to find out why: lv1 sees the shared memory region on a different address than lv2. I only figured that out after dumping a lot more of SceSysmem, which took me a few days...

Anyway, now I can do something like this:
  • Write some pointers to 0x00400028 (shared_mem_blk0 + 0x28) and 0x0040002C (shared_mem_blk0 + 0x28 + 0x04). These pointers must be from TrustZone memory because Secure World can't access Non-secure World's memory space outside of this shared memory region.
  • Call do_smc(shared_mem_addr, index, 0, 0, 0x12F). shared_mem_addr should be 0x002B0001 so it translates to 0x00560000 which is where the shared memory is located inside TrustZone (this is set inside the Sysroot region). index can be calculated by finding the SMC table, subtracting 0x00560000 (shared memory region) from it's address and multiplying the result by 0x80. This will overflow the destination across 0x80 sized memory blocks until it hits the SMC table and writes there.
  • Now I should have two arbitrary pointers installed as SMC calls to do whatever I want.
It works! I can now call these planted SMCs to read/write lv1 memory, for example!
Note that you can only read memory from lv1 into lv2, which means you still need to copy the memory from lv2 into userland (this can be easily achieved with sceKernelMemcpyKernelToUser).
I also thought about looking into the SMC handler inside SceKernelIntrMgr (TrustZone version) hoping they screwed up the same way they did with lv2 SVCs (not checking the R12 value), but unfortunately:

Still, that's pointless at this stage since this single bug granted me arbitrary lv1 code execution! After finding the necessary functions, I was able to allocate memblocks to plant lv1 payloads and run code freely on the Secure World!

And that's it. Another security layer peeled off from the Vita.
Unfortunately, this bug was patched somewhere around firmware version 1.80, which means it's absolutely useless for most users. Still, if you have a low firmware version and wish to dig deeper into it, this will help you taking down that nasty lv1.

Next steps


I'm currently fuzzing the F00D's main interface on firmware 1.50 while trying to find new lv1 bugs on firmware 3.60. I'm also going to update the HENkaku wiki across the following days with all the information I've been gathering during my adventures (not just lv1 related).
I may release my 1.50 ROP scripts if necessary, but this post contains all the information necessary to recreate the exploit.

Please contact me for any clarification or doubts.
Until next time!

Wednesday, January 4, 2017

Apologetic shenanigans

This is going to be a short post.

In my previous blog entry I shared my views on the 33C3 Nintendo Hacking talk. After chatting with derrek (one of the speakers) I have to admit how unfair I was.
There's a lot going on at events like these and speaking for a broad and curious audience is never an easy task.

I was very eager to learn more about the Wii U's boot1 that I ended up misunderstanding something very important: there is no XML parsing bug.
What derrek was saying is that there might be a bug in boot1, but it turned out to be too much of a boring task to look into it. Whatever the bug might be, it's not in the XML parsing code.
Taking that into account, it's quite possible that the nature of the bug itself (if proven to exist) may just translate into a complicated, or even pointless, exploit.
Also, I wasn't fully aware of how uninterested hackers and developers are in the Wii U. Now I see that the inclusion of the Wii U portion was more of a projection of what the team had achieved before moving on to different things.
It makes sense to detail attacks that interest people and such happened during the 3DS part. If the team decided to go into further detail on the Wii U, their audience would be fairly disappointed.

Apologies to derrek, naehrwert and nedwill for my caustic comments and misinformation.

Sunday, January 1, 2017

New year, same challenges...

WARNING: The following blog post is filled with the author's own opinions. Reader discretion is advised!

New year, new blog post.

I would like to start off by issuing a public apology to Wii U's homebrew developer dimok. I've given my opinion publicly about the "Mocha CFW" project and I'm afraid I may have expressed myself poorly.
I do think Mocha CFW's code base is weak. It lacks structure and has plenty of poorly optimized solutions for certain features. That doesn't mean it won't change in the future or that my work is any better.
I appreciate, like many others, dimok's contributions to the Wii U scene and I think him and other developers have been doing great work under the public eyes.
I clarified my opinions on IRC with MaschellDev, but I haven't been able to contact dimok directly yet. Meanwhile, MaschellDev brought to my attention that a Reddit user made a negative comment on dimok's work using arguments very similar to mine.
My suspicion is that some user in IRC saw my arguments and attempted to bash dimok's work with them without having a clear idea on what they meant.
I'm not going to play the drama game that has turned many developers against each other, so I'm taking this chance to publicly address dimok and apologize for my comment on Twitter and also to report that I have nothing to do with whoever made negative remarks on Reddit or whatever.

Anyway, on to more interesting things!

33C3... Unfortunately, I was unable to attend the event, but I spent the past days watching talk after talk on multiple ingenious exploitation methods and achievements.
If you have been following this blog for a while, you know I've been recently researching and developing tools for the Wii U. Therefore, I was particularly excited to know that derrek and naehrwert were going to talk about the Wii U and it's vulnerabilities.
I was glued to the live stream and watched the whole talk, but I ended up feeling very disappointed.

I'm aware that the 3DS is a much more popular console and I was already expecting it to be the main focus of the talk, with just a brief overview of the Wii U exploitation path.
On that note, Ned Williamson was certainly the star of the talk for me. While the bugs presented were nothing particularly new (UAFs, overflows), he presented novel ways to exploit them ("soundhax" and "fasthax") and was very assertive in detailing the attacks.
Hacker naehrwert only talked during the Wii U portion and detailed two distinct exploits: "ioctlvhax" and "mqhax". The "ioctlvhax" exploit was already publicly disclosed by naehrwert himself, but it's understandable why it was brought to the talk. This flaw exposes a large attack surface, both on the PPC and ARM sides.
IOSU userspace flaws were not presented during the talk, which is a bummer, but I can also understand their reasons specially due to time constraints.
A new IOSU kernel exploit was present though, "mqhax". Interesting, but nothing really groundbreaking.
It's also worth noting that IOSU userspace and kernel exploits were already available publicly and had been implemented by several people (myself included).
There was also a brief mention to "contenthax", "haxchi" and "coldboothax" which, despite the names, are not exactly exploits but design choices (a.k.a. flaws) instead.

Up to this point, nothing new was presented since fail0verflow had achieved this level of access years ago. Then came the part I was really excited for: boot1.
This was something that fail0verflow didn't manage to crack and remained the last mystery of the Wii U.
Now, I had high expectations for this so I guess it was my fault I was let down. Hacker derrek had published, quite some time ago, a tweet with boot1 key's hash were you could read "BOOT1_FAIL":
I naively assumed he had found a flaw in boot1 itself (whence boot1 + fail) and managed to blindly exploit boot1's execution and stumbled upon some silly mistake from Nintendo (like leaving a duplicate boot1's key inside boot1's binary :P).

Unfortunately, they simply confirmed something I had found and documented days before: boot0 has no useful bugs.
I had reversed and fully documented boot0 ( and even left a small note regarding the dangerous size check done on the boot1's ancast image (see "
Stages 0x15, 0x16 and 0x17").
If that size check was flawed, it would be trivial to overflow boot1's memory region into boot0's region and hijack the next instruction. I wasted a lot of time looking into this but all I could do was verify that all checks were in place.
Nonetheless, a fault injection is an attack and a lot of hackers resort to that when nothing else works. I was expecting that derrek would go into detail on his setup and the specifics of the attack, but that didn't happen. This confused me.
Why bother to include the Wii U in this talk when your most important achievement (and, actually, the only new thing to present) was going to be left out?
That made no sense to me, but that was still not the worst. Apparently, when analyzing boot1, the team found a potential bug in XML parsing. Interesting, right?
However, they got bored and didn't bother to look into it... Seriously? I get that the Wii U is not exactly popular but, again, why bring this up at all just to end with "we didn't care"?

At this point I was a bit revolted with their attitude. This talk started to sound more like a bragfest than anything useful.
Watching Ned Williamson's part caught my interest again, but then derrek proceeded to unveil how they cracked the 3DS bootROMs. Again, nothing groundbreaking, but still an incredible achievement. The bootROM was the last line of defense for the 3DS and no one had manage to break it.
I was very eager to see what kind of setup they used, since they had to resort to fault injection again, but, once more, they preferred to keep that in secret.
The last exploit presented was "sighax". Very interesting finding and somewhat hilarious to see that Nintendo had messed up RSA again.

The parting note about the Switch was completely unnecessary in my opinion and so was the remark about them being "nice" by not presenting this earlier considering they had achieved this back in the summer of 2015.

Also, after the talk was over, hacker plutoo released the group's notes on the Wii U:
Unfortunately, aside from a few tidbits, most of the documentation is very incomplete in comparison to the public documentation available at

It's great to achieve something against all odds, to break a system it's designer deemed "perfect" and learn from that experience. Unfortunately, I feel that this talk pushed things a bit too far and focused a lot on rubbing on Nintendo's face how much they suck.
I don't feel comfortable with this attitude at all. I believe there's room for healthy mockery, I mean come on, talented guys breaking a product that had millions of dollars invested in it (and in it's security) deserves some bragging.
However, we must not forget that hackers are not winning anything. Hacking consumer electronics IS illegal and it's up to these multimillionaire companies to decide the fate of perpetrators.
With that said, I really felt that this talk pushed the limits in an unhealthy way. By all means, that doesn't mean it was the only one doing that throughout the history, but after seeing something like HENkaku happening, I believe we hackers must drop the attitude a bit and start being more serious and professional in our activities.

Anyway, end of rant. I have nothing against these talented hackers and regardless of the means, they still achieved what others were unable to, so, congratulations to them all!

Moving on, I have a couple things I wish to achieve this year and I'm very happy with the results so far.
On the Wii U, I'm still going to work on hexFW, but right now my main focus is to attempt dumping boot1's key. While exploiting the Vita, I ended developing a XML fuzzing framework to look for bugs in the updatelist's parsing and I'm very eager to put it to good use in looking for that potential XML parsing bug in boot1.
For this task, I plan on attempting standard hardware fault injection techniques to replicate what derrek did. Unfortunately, while this kind of attacks aren't particularly difficult to deploy, they are very, very dangerous to the console.
What was presented during the talk relied on NAND readings to figure out the necessary timing for the attack. This requires the attacker to purposefully corrupt the Wii U's boot1 image in the NAND.
However, there might be another venue that was not explored by the group. The same size check is performed when reading a boot1 image from the SD card. This could potentially be a safer way of developing the attack, but I have yet to find out how to tell boot0 to load boot1 from the SD card (a specific event combo is needed).

As for the Vita, I have a bunch of tools I'll be releasing as necessary and tons of documentation that I'll be pushing to the HENkaku wiki. I have also recently managed to break TrustZone, but, unfortunately, the bug I've exploited was patched long ago. I suspect I stumbled upon the same bug Team molecule may have used in the past, but I plan on doing a proper write-up later on if they agree.

My next blog post will be a complete write-up on how I implemented the two public Wii U exploits to bring hexFW to life (IOS_CreateThread memset bug and uhshax). I was waiting for 33C3 just in case any of the hackers would present the IOS_CreateThread exploit, but since they decided to present "mqhax" instead and hykem is nowhere to be found, I'll just go ahead and detail my own experiences.
I believe these two exploits deserve a proper write-up and it would be a nice tribute to ex-hacker hykem who documented extensively and publicly the internals of the Wii U.

As always, stay tuned!

Monday, November 7, 2016

Anatomy of a Wii U: hexFW

As I mentioned in my last post, in parallel to researching the Vita's kernel I decided to research the Wii U and see what I could come up with.

For all this to make any sense, we must go back to the beginning and waste a couple minutes looking into the Wii U hacking scene's history.
It all began back in 2013 when team fail0verflow made a presentation at 30C3 describing their journey in hacking the Wii U.
For quite some time they became the reference in terms of research and documentation for the Wii U's internals and even set up a wiki for this purpose:
However, they had no intention to release their exploits or talk about any vulnerabilities. This led to a community-driven effort to recreate their steps and hack this system.

Attempts to exploit the vWii date from late 2013, but it wasn't until mid 2014 that Wii U userspace code execution was achieved. This was done originally by what would become the libwiiu team.
One year later, the same team achieved the first PowerPC kernel exploit (a TOCTOU involving the OSDriver structures) and opened the doors for homebrew (with some restrictions).
The libwiiu project became a very valuable framework to write, compile and execute code from within the Wii U's Web Browser and it kept being used across firmware changes.
Other projects were developed during this time frame and eventually branched away from libwiiu (e.g.: Loadiine, homebrew_launcher).

Later that year, the first reports of someone being able to break into the Wii U's secure processor (IOP, running a custom operating system called IOS and dubbed IOSU by the community) showed up. The hacker and developer hykem claimed that had defeated IOSU around December of 2015.
This was shortly followed by another team claiming the same feat. This time it came from smealum, plutoo, naehrwert, derrek and yellows8, all very well known video game console hackers from the 3DS (and PS3 in naehrwert's case) scene.
The 3DS group wasn't planning a release while hykem, on the other hand, revealed that was working on a CFW-like setup for a public release.
During the following weeks, hykem massively documented his findings on the wiiubrew wiki, but ended up disappearing before releasing his announced project.
Then came an awkward period of drama and mystery that marked the Wii U hacking scene for good.
Eventually, smealum announced he had no plans on developing further for the Wii U and released "iosuhax", a collection of patches for the IOSU that would, in theory, create a CFW-like environment (privileged memory access and direct communication with the IOSU in a RPC setup). However, no one released an actual exploit to take over the system and allow for firmware patching.
Earlier this year, someone documented two vulnerabilities found by hykem, naehrwert and plutoo in the wiiubrew wiki and yet again, a community-driven effort began to build an exploit based on these bugs.

This led us to today. The current state of the Wii U hacking scene is a fragmented playground with two dominant groups using this now public information to build an exploit chain and achieve the goal of building a CFW for the Wii U:
- Team SALT: a collective of hackers/developers mainly active on the 3DS scene that began working on a CFW solution quite early this year. They are developing everything in private and share a few details occasionally on their progress.
- Team wiiubru: formed under the public eye by early contributors and developers of the PowerPC homebrew scene that sparked after libwiiu. They develop everything in public and have achieved popularity among the community.

After learning about all this, I still felt motivated to research and work by myself for quite a few reasons:
 - The Wii U's security scheme is nowhere near the Vita's and is much easier to take down;
 - Public vulnerabilities already exist and there's plenty of documentation out there as well;
 - My vision conflicts with team SALT's and team wiiubru's.

That last point is crucial. Team SALT chose to work privately, which is understandable when dealing with something that can potentially brick your console, but it's not possible to evaluate what they have accomplished thus far. Also, one of their members was allegedly responsible for leaking team libwiiu's OSDriver exploit which doesn't inspire much trust in the group.
On the other hand, team wiiubru is doing everything in public, but using low standards in terms of code quality and organization, which is to be expected when working in large groups.

Not satisfied with either groups' approaches, I decided to come up with my own: hexFW.
The name may not be very original, but to be honest, I didn't put much effort into making it up.

So, in order to build a CFW of my own, I made two important decisions: use smealum's iosuhax as the base for IOSU patching and implement my own exploit chain.
In my opinion, iosuhax does the job fairly well. It's a set of patches and a script that replaces sections of a firmware image and re-encrypts it back to be run on the Wii U. The idea is to start with smealum's code base and evolve from there.

But that only covers the process of creating a CFW image, the hard part is to exploit the system and make it load this image.
I looked into wiiubru's public implementation of the two publicly disclosed bugs, but found many issues with it.
By far, what seemed to make less sense in their implementation was the fact that the exploit is launched using the "homebrew_launcher" (or HBL). This felt like an overkill: why exploit the PPC kernel and run userspace code to exploit the IOSU when the disclosed bugs can be used without kernel privileges?
After playing around with the bugs for a while I finally understood their point: it's really hard to pull this off solely from the browser.

Hacker yellows8 released a stagefright exploit compatible with the Wii U a long time ago which became the standard for userspace code execution under the most recent firmware versions (the bugs libwiiu had used in the past have all been patched). It's code is quite clean and does the job perfectly, so I decided to use it as the main entry point to achieve userspace code execution.
For compiling the code I resorted to libwiiu for it's simplicity and began writing the exploit chain from scratch. Soon enough I came across an issue that might have been why wiiubru decided to ditch direct code execution and resort to HBL and ELF loading: the userspace payload's size is limited due to the nature of the stagefright exploit.

Nonetheless, I came up with some creative ways of squeezing all the necessary steps into a single payload and managed to get it working.
This means hexFW is launched solely from the browser without the need for installing or using HBL!
Of course, this came with a small cost: it's very likely that running the exploit will crash once. This is due to how I'm locating a target thread inside the IOSU to modify it's stack pointer. However, if you reset the console it is guaranteed to launch the second time. After the launcher runs, the actual CFW will be booted into the system from the SD card.

I have released a preview version of hexFW on Github:
It contains my own exploit chain ("fwboot") and a copy of smealum's original iosuhax minus the filesystem patches (IOS-FS). This is merely to demonstrate it's usage, but the overall structure is very likely to stay the same. The following commits will consist in the actual firmware patches that make hexFW a CFW (SLC/MLC/OTP/SEEPROM dumping with/without compression, redNAND, USB read/write/install, coldboot, etc.).
If you're familiar with iosuhax, you can setup hexFW and it will generate a patched firmware image that contains smealum's wupserver. You can then communicate with it using the script and play around with it.

In the next days I'll be pushing several components of hexFW I've been working on. My next post will be a detailed write-up on the two vulnerabilities exploited and how I constructed the exploit chain from scratch.

Stay tuned!