Boot Flow and You
---
What?
The First Turnabout: checkm8
- checkm8 is a bug in Apple's BootROM in its A-series chips, up to A11.
- The BootROM is the first code that runs after boot.
- This means BootROM compromise directly compromises the root-of-trust model for these devices.
- checkm8 results in BootROM compromise, resulting in an un-patchable root-of-trust compromise in millions of Apple devices.
Typical Boot
DFU?
- DFU is the Device Firmware Upgrade mode.
- DFU is typically used for recovery purposes: New (signed!) firmware can be uploaded via DFU.
- Note that the BootROM is burned-in, so DFU cannot be used to upgrade BootROM itself.
Consider an Attack
Take a moment: what sort of attacks could be mounted against the BootROM, given that we cannot directly modify it?
Sources & Sinks
- A source is something that you, the attacker, controls.
- A sink is some interesting target: perhaps, for example, some vulnerable code.
- Reasoning about code in this way, trying to connect sources and sinks, is useful.
Use-After-Free
- When USB is started, a buffer is allocated.
- When you send data, it sets a pointer to the buffer.
- Global variables are used to keep track length and the number of bytes received.
- If all data is received, it is copied elsewhere for later verification and booting.
- Global variables are reset.
- Once DFU exits the buffer is free'd.
What's wrong here?
- By interrupting this transaction, the program enters some bad state: a state not considered by the programmer.
- In this state, a buffer is both free'd but also used. This is a use-after-free.
Initial State
Post-Free
The Use-Aftermath
What went wrong?
Lessons Learned
How could Apple have prevented an unpatchable root-of-trust bypass across millions of devices?
BootROM is Unpatchable
All code has bugs!
BootROM is Complex
Complex code increases the risk of bugs!
BootROM Fell Victim to Memory Unsafety
Isolated Case?
Wait, this keeps happening?
The Turnabout Sisters: The 3DS
- Contains two processors, the main ARM11 chip and the ARM9 coprocessor
- The root-of-trust lies in the ARM9 boot ROM, called Boot9.
- Boot9 is burned-in.
- Boot9 performs signature verification.
3DS Boot Flow
- ARM9 wakes up.
- ARM9 begins executing Boot9.
- Boot9 exports AES and RSA keys to the hardware AES and RSA engines.
- Boot9 will attempt to boot from NAND.
- It will parse the partition header to determine available firmware images.
- For each image, it will attempt to verify its signature.
- The first valid image is copied into memory as its header instructs.
- The loaded firmware is executed on both ARM9 and ARM11.
Boot9: In Summary
- Contains RSA keys to which Nintendo holds the private keys.
- Does some platform initialisation.
- Validates and executes later-stage firmware.
Let's attack Boot9: from where?
- No communication over, say, USB.
- We know that Boot9 does take one input: firmware images and signature blocks.
- Can we craft one of these to bypass the signature checks in Boot9?
Signature Verification
- Recall that to sign data, we cryptographically operate on its hash.
- To verify a signature, we compare hashes.
Firmware Signatures
- Some length values are not validated when they are read, resulting in insufficient bounds checking.
- An additional block type, intended for encryption - not signing - is permitted. This means that padding data can be any data, rather than just a repeated 0xFF byte.
- Padding is permitted to be too short for the signature block.
Flaw 1
- We can determine the location on the stack that the embedded hash is read from.
- If only there was a correct hash on the stack.
- The 3DS computes the hash to compare against! Can we make the parser compare the computed hash against itself?
What's wrong here?
Just like that?
Almost! With the second two flaws also, the requirements for forging a signature are now well within the computable range for brute-forcing. Game over!
Fakesigning
Boot9 will now consider any image with this crafted signature block to be valid. Oh no!
What went wrong?
- Implementation bugs significantly weakened the cryptographic soundness of an otherwise well-designed system.
- This was a mix of classical cryptographic issues and a really nasty case of spatial memory unsafety.
Boot9 is Unpatchable
All code has bugs!
Boot9 Fell Victim to Memory Unsafety
Boot9 used a Custom Signature Parser
Consider if this was necessary, or if a robustly tested alternative would have sufficed.
How were both of these discovered?
- The boot ROMs are inaccessible.
- How can you exploit them without even seeing them?
- In these cases, code reuse!
Uncovering Boot9
- Had been done once before privately, so existence of the bug was known.
- Buggy firmware was reconstructed from un-erased NAND fragments.
- This was enough to construct an attack against the BootROM, which shared code.
So don't reuse code?
Not really! This wasn't the real issue with these systems.
Why Bother?
- It is essentially impossible to prevent a user with full physical access from breaking your security mechanism with enough time.
- These systems are trying to solve an impossible problem.
- But they are excellent mechanisms to delay attackers.
- And are also useful as part of a defence-in-depth strategy.
- These attacks are hard!
Sources & Further Reading
- https://habr.com/en/companies/dsec/articles/472762/
- Attacking the Nintendo 3DS Boot ROMs, Scire et al., 2018
- https://www.copetti.org/writings/consoles/nintendo-3ds/