Table of Contents
Sighax: How Hackers Broke the Most Protected Part of Nintendo 3DS
Friends, AliExpress now has:
Cool metal labels for Game Boy Advance consoles.
Cool eXtremeRate cases for GBA SP.
Friends, help me buy (if you have) various old stuff: Help me buy.
In the history of Nintendo 3DS, there was a moment when it seemed completely hacked.
The A9LH (Arm9LoaderHax) exploit allowed running custom firmware and gave almost full control over the console. A powerful tool, but finicky and risky to install. It's like putting a sports engine and a straight pipe in an old Lada: you can go fast, but controlling such a car is difficult — and there's always a chance to miss a turn.
B9S (Boot9Strap), created based on the Sighax vulnerability, became the complete opposite. This was no longer garage tuning, but a Mercedes — fast, reliable, and comfortable. It launches earlier, works more stable, and does everything the same, but without unnecessary risk. What once seemed like a fragile DIY project now became a complete, engineered system.
Sighax is a hack that allows signing custom firmware correctly at the lowest level.
This is what the Sighax exploit looks like
Before Sighax, pirates had one big problem: all their hacks worked on an already running console. That is, to play a pirated game, you had to first turn on the console, manually activate the exploit, and only then launch the game. After turning it off, the whole process had to be repeated.
Why did this happen? Because every time it was turned on, the ARM9 processor performed a cryptographic check of the firmware. If the signature wasn't genuine — the console simply wouldn't boot. And since custom firmware is by definition modified, it couldn't pass the check.
This was exactly the problem Sighax solved. It allowed bypassing the signature verification system and loading modified firmware — as if it were official. Moreover, this happened even before the system itself launched.
But if Sighax itself fit into a couple of lines of code, searching for it was like looking for a needle in a haystack.
The Hunt for Sighax: The Story of Finding the Deepest Breach in the System
On May 6, 2014, the U.S. Federal Communications Commission (FCC), which regulates, among other things, the release of gaming consoles, published Nintendo's technical documentation.
The documents stated that there were no hardware differences between models FTR-001 (the first revision of Nintendo 2DS) and FTR-001(-01) (the updated version) — the only difference was in the security functions of the processor and bootloader firmware.
Derrek noticed this. He assumed that if Nintendo suddenly changed the bootloader, something must have been wrong with the previous one — possibly a vulnerability. He started digging — and indeed found holes in the firmware signature system.
Nintendo used a custom ASN.1 parser to verify the RSA-2048 signature, which contained a SHA-256 hash of the firmware. And while cracking the signature itself was practically impossible (it would have required years of computation), the parser turned out to be surprisingly fragile: full of flaws, oversights, and dangerous assumptions.
Later, Derrek went even further — he managed to obtain the Boot ROM — the hidden part of memory that contained the implementation of the signature verification. The main difficulty was that this code was automatically disabled by the system immediately after boot and couldn't be read during normal operation.
On December 27, 2016, Derrek spoke at the hacker conference Chaos Communication Congress (33C3). He publicly talked about the found vulnerability in Nintendo 3DS and showed that he had managed to download the Boot ROM — something that was considered impossible.
However, he only showed that there was a breach but left no code or details — just a lot of questions. And Boot ROM isn't just a technical component; it's a real treasure trove of Nintendo's secrets, containing encryption keys, internal protocols, and security mechanisms of the entire 3DS system. Such a hint, especially around the most critical part of the system, couldn't go unnoticed by the community. SciresM, Myriachan, Normmatt, TuxSH, and Hedgeberg joined the game.
The problem was that they only knew the general direction but had no idea what exactly needed to be done or where to start. They understood: Boot ROM (Boot9) is hardwired into the console's chip forever and can't be changed after leaving the factory. So if the vulnerability was indeed in Boot9 — as Derrek claimed — it must have remained there forever. And if a way to reproduce it could be found, it could be used.
So the team made an important assumption: Nintendo, as it had done many times before, might have reused the same code in different parts of the system. This was especially true for security functions, such as the RSA signature parser in ASN.1 format.
They began studying publicly available firmware and indeed found similar code there. However, starting from version 1.0.0 (kernel 0.14), this code already contained additional checks of the signature structure, including strict verification of the so-called padding area. These checks eliminated the very weaknesses that could be exploited to bypass protection. This meant that analyzing new firmware no longer made sense because they no longer contained vulnerable code similar to Boot9. And thus, constructing a working signature became impossible, as to create it, one needed to precisely reproduce the behavior of the vulnerable Boot9 parser.
Then the researchers decided to go further and tried to find out what was before version 1.0.0 — in the so-called factory firmware installed on consoles before leaving the factory.
They started buying consoles with the lowest possible firmware version, hoping that using NAND memory features would allow them to recover fragments of the factory firmware. The thing is, NAND, like most non-volatile storage, doesn't delete information completely but only marks blocks as "erased," and they can remain in raw form until overwritten.
By analyzing dozens of such consoles, they managed to recover an early firmware version with kernel 0.13 — the predecessor of the public 1.0.0. It indeed contained the vulnerable signature parser, without the fixes added later. This became the first real way to explore and attack the Boot9 vulnerability without direct access to it.
Using the recovered firmware, the team assembled the first fake signature that successfully bypassed the factory firmware check. However, when testing on the real Boot9, the console didn't show the usual blue error screen but simply froze with a black screen. This black screen, rather than the familiar blue error screen, made it clear: the vulnerability worked, but Boot9 tried to access inaccessible memory, and execution stopped before the error could be processed.
The path to a universal exploit turned out to be more complicated. Now they needed to create a signature that perfectly matched Boot9's behavior. The brute-force phase began.
Imagine a huge maze with 128 rooms scattered throughout. The researchers knew that the one they needed was among these 128. But there was a catch: they couldn't simply open the doors one by one. Instead, they had to find the single correct path leading to the desired room — a path encoded within a special RSA signature.
Everything was complicated by the fact that there were about 323 undecillion possible paths. And this wasn't just a list of routes — each had to be traversed completely, as the door would only open if the path was followed strictly according to the rules: from start to finish. At this scale, even the Sun would burn out before a complete brute-force search of all possible routes could be completed.
Of course, theoretically, they could have gotten lucky — and the right path might have been, say, the tenth one. But the probability of this was vanishingly small. So they had to look for patterns and "tricks" that could simplify the search. For example, each attempt required 17 multiplications and 17 modulo operations, but they could calculate the value once — and immediately check its negative counterpart as well. This already halved the search volume. Additionally, they used mathematical features of RSA, combined intermediate results, and ran everything on GPUs with optimized algorithms.
To traverse these millions of digital routes, ingenuity alone wasn't enough — computational power was also needed. The researchers gathered everything they could: powerful gaming GPUs like the GTX 1080 Ti and 980 Ti ran around the clock at home, but for a task of this scale, it wasn't enough.
Then they turned to Amazon's cloud servers. One such instance — p2.8xlarge — contained eight Tesla K80 GPUs and 32 CPU cores, providing 230 million checks per second. The machines ran for nine days without stopping, with rental costing about $7 per hour.
As a result, instead of the theoretical hundreds of trillions of paths, the actual search volume was reduced to about 80 trillion. And on the eight-trillionth attempt, the right path was found — the very signature that fooled the system.
But simply finding the signature wasn't enough. Here it's worth pausing for a moment and asking the main question: what exactly did SciresM, Myriachan, Normmatt, TuxSH, and Hedgeberg want? The answer is simple and ambitious — complete control over the device.
They weren't satisfied with just tricking Boot9 and loading custom firmware. Yes, that was already a victory — but not the one they'd invested hundreds of hours of work, cloud computing, and thousands of dollars for. Their real goal was deeper — to reach that secret half of Boot ROM where everything begins: cryptographic keys, protection mechanisms, internal protocols. Exactly where, according to Derrek, he had managed to peek.
The main problem was that Boot9 closed itself before handing control to the firmware. It was a vicious circle: yes, the fake signature allowed loading firmware, but when the firmware code began executing — access to Boot9 was already closed.
So the team came up with an elegant and daring plan. Boot9, besides protection, had another important task — it copied the firmware code into RAM. This meant the desired code could be inserted there in advance — the main thing was that it had to launch before access was closed.
After loading the firmware into memory, they needed to deliberately trigger an error. Then the console itself would call the error handler. And there, the modified code would be waiting. A very elegant solution.
And all their efforts weren't in vain. Breaking through the most impenetrable wall of protection, the researchers finally reached that forbidden zone of Boot9, where not only the keys were stored but also secrets Nintendo never planned to reveal. And among it all, they found what could be called the perfect ending to this story.
In one of Boot9's functions, there was a quiet, undocumented check. If the console's lid was closed during startup and the user held the START + SELECT + X combination, Boot9 checked — was a Nintendo DS cartridge inserted? And if so — instead of normal booting, it tried to load alternative firmware directly from that cartridge.
And so, what seemed like an ordinary bureaucratic step — filing a patent — became the first crack in armor Nintendo considered impregnable. One technical document and Derrek's silence, who chose not to share his developments, fueled other researchers' interest so much that they literally couldn't stop: factory firmware, trillions of attempts, breaking protections, and their own code executing before the system even launched.
And all this led to a console built around encryption and distrust completely revealing all its secrets. Not by force. Not by chance. But through persistence, intelligence, and the desire to understand what seemed securely hidden.
How does the exploit work?
All Nintendo 3DS consoles have identical Boot ROMs, hardwired into their chips at the factory. When you press the power button, the console's boot process is initialized by Boot9.
The console boot process looks like this:
1. AES key slots are initialized with secret keys from Boot9;
2. RSA key slots are initialized with public keys for the 3DS firmware;
3. The boot device is selected (usually the NAND chip where the firmware is stored);
4. The firmware header is read from the NAND chip into the console's memory (if it was selected in the previous step);
4.1. The firmware header contains a series of data necessary for booting (ARM9 and ARM11 entry points, an RSA-2048 signature encrypted with Nintendo's private key, which contains a SHA-256 hash);
4.2. At this stage, two processes occur:
4.2.1. A SHA-256 hash of the header is created and written to a specific memory location;
4.2.2. The RSA-2048 signature is copied right before the created SHA-256 hash;
5. A parser is launched that examines the contents of the encrypted signature, finds the SHA-256 hash of the header there, and compares it with the SHA-256 hash created in step 4.2.1.;
6. The firmware sections are read into memory according to the parameters from the header;
7. Access to the protected halves of Boot9 and Boot11 is closed (they initiate the work of the ARM9 and ARM11 processors, but for protection, this is interrupted before the next step);
8. The ARM9 and ARM11 processors jump to the entry points specified in the firmware header.
This is what the standard console boot process looks like. In theory, this startup phase is the most protected stage of operation. Yes, once the firmware is running, certain exploits can be used to execute custom code. But these exploits need to be activated anew each time. Because the console's RAM is cleared after shutdown. And modifying the firmware so that it always remains altered isn't possible (or rather, in exceptional cases it is, but it's dangerous and can lead to bricking), as the firmware is checked every time the console is turned on.
Let's focus in more detail on steps 4 and 5, as this is where the magic of the Sighax hack happens.
When Boot9 reaches step 4, it essentially creates new code in memory (steps 4.2.1. and 4.2.2.):
It might seem like perfect protection. We calculate the hash of the header's beginning, encrypt it with Nintendo's private key, and place the resulting signature at the end of the header. If you change something in the header (and you'll have to if you're making custom firmware), the header's hash won't match the encrypted hash. We can't take the header hash from our custom firmware and place it in the RSA-2048 signature because we don't know Nintendo's private key, and the public key (which Boot9 obtains in step 2) isn't suitable for this. At first glance, it seems like a vicious circle, but it's not.
The RSA PKCS#1v1.5 signature with the encrypted SHA-256 hash is encoded in ASN.1 format. Such data represents a sequence of bytes that follow one after another without breaks (such a sequence of data in ASN.1 format can be seen in the image below).
To decrypt this hash from the RSA-2048 signature, Nintendo wrote their own parser. In an ideal scenario, it moves through the signature from left to right and top to bottom (essentially like reading a book).
It reaches byte 01 (purple color — padding type) and understands that empty FF bytes will follow. It skips them. Then it skips bytes 30 31 30 (red, pink, green colors — outer block id, outer block size, and inner block id respectively) and finally moves to the most important byte (light green color — inner block size), which indicates the distance to the block where the signature hash begins. Accordingly, the parser skips this space (pale green) and moves to values 04 (light brown — SHA256 block id) and 20 (yellow — SHA256 block size), which indicate that the SHA256 signature will follow in a certain size. It skips these values again and finally reaches the signature itself, which was originally encoded with RSA-2048.
As a result, the hash from the RSA-2048 signature (green color) is compared with the SHA256 hash calculated by Boot9 independently (blue color).
But this parser has many weaknesses:
1. It doesn't check field boundaries;
2. It allows block type PKCS#1v1.5 2 (intended for encrypted messages, not signatures; ideally, Nintendo uses PKCS#1v1.5 1);
3. It doesn't require the signature block padding to be complete (allowing for a less strict signature scheme).
The first error creates a vulnerability that allows comparing the hash with itself. The second and third errors allow brute-forcing signatures to find the one that will pass the parser and enable the first error.
The problem is that a simple brute-force search of signatures is a very intensive procedure, requiring 17 multiplication operations and 17 modulo operations per attempt. Even in a simplified scenario, using errors 2 and 3, the needed signature was one of two to the forty-third power.
That is, in the worst-case scenario, about EIGHTY TRILLION attempts would be needed to find the perfect signature. And such a signature was found after nine days and more than eight trillion attempts. As you can imagine, in the worst-case scenario, it would have taken ninety days. And this is a simplified search due to Nintendo's errors. Can you imagine if these errors hadn't existed?
Now let's return to that "perfect signature" obtained after nine days. What is it for? Primarily, to pass the custom parser. But its main purpose is to make Boot9 always return a positive response when checking both hashes (step 5).
Literally at the first step, differences are visible. The value 01 was changed to 02 (purple color). This is exactly error two we talked about earlier. Next are not empty FF blocks but an encrypted message skipped by the parser. Then come standard values 30 30 30 and a new number 5e, indicating that much unnecessary information will follow (much more than in the normal version). And at the end — two values 6a and 2c, indicating that the decrypted hash will follow. But due to the extended light green block, the decrypted hash ends up in the zone where the calculated hash was originally written (step 4.2.1.). The parser reaches this point and reads the first hash. Then it goes to the address where the created hash was written and compares the two values.
So it turns out that it reads the hash from the same place and then compares them. As you can imagine, such a check will always pass.