Methodically Defeating Nintendo Switch Security
Methodically Defeating Nintendo Switch Security
Methodically Defeating Nintendo Switch Security
and whitelist, one by one, all the public Wi-Fi landing pages groups of pointers to functions and existing executable code
in the world. This empowers us to perform a simple server- fragments, based on our memory dumps, which we can use
side redirection to a web page of choice, one hosted locally to effect changes on the state of the system and test for more
and under our control, and begin to study the system. powerful vulnerabilities.
B. detachSecurity() C. PegaSwitch
Web browsers have long been a target for security re- That period of research was, unfortunately for us, short-
searchers, as many embedded devices use web features, and lived. Almost at the same time, an entire toolkit for browser-
most of those use WebKit for their browser engine, a program based exploitation on the Nintendo Switch was released by
mostly licensed under LGPL. This means that any commercial another independent team of researchers. The toolkit was
use of the WebKit engine must redistribute the source code called ”PegaSwitch”. [7]
of the software, including any modifications made to it. Not While this was frustrating, as most of our effort up to this
only does this allow us to reproduce an instrumentable test point had now seemed worthless, this was also an invaluable
environment for debugging outside of the system, but by research tool for us, as it implemented all the core ROP func-
its popularity and sheer pervasiveness in the desktop world, tions we cared about. Whereas we had planned on discovering
we can easily and quickly know which existing, public and an applicable WebKit browser vulnerability, with the expecta-
available security vulnerabilities haven’t been patched for our tion that we would have to engineer an exploit stack (including
target version of WebKit, and adapt/reimplement them as ROP, privilege escalation, arbitrary code execution, sandbox
needed for this system. escape, and shellcode to launch outside the browser sandbox),
PegaSwitch used an already available exploit, namely CVE-
A thing to note, however, is that the WebKit maintainers
2016-4657 [8], commonly known as ”Pegasus”, with the added
(Apple) don’t just hand us a neat, preformatted list of security
twist that this exploit stack was already implemented for
bugs for us to study, as security issues are considered protected
iOS systems on devices with the AArch64 architecture [9],
reports. They are removed from public view by the bug tracker,
explaining why they were able to get to ROP so quickly
as necessary to allow for mitigations to develop internally.
and reverse engineer so many things in so little time, as the
These reports permanently remain obscured by the bug tracker.
Nintendo Switch is also an AArch64 machine.
Although, as those bug reports are mentioned in the commits
Now that we have remote userland ROP code execution, our
which fix them, we can simply use the old trick [5] of making
next goal was then to reverse-engineer the inner workings of
a list of all commits linking to bug reports which we do not
the operating system, to identify potential targets for further
have access to, as those are presumably security-related issues
escalation. Horizon is the name of the Nintendo Switch’s
of particular interest to us.
operating system, the kernel, and its system services. Horizon
On our side, we settled for a use-after-free vulnerabil-
is also the OS on the Nintendo 3DS; the Switch version
ity in the FrameTree unload handlers [6] which we named
is a further development of this OS, with refinements and
detachSecurity(), as we could simply have a frame DOM
further progress towards being a full-fledged operating system
object, ”attached” to a detached tree. We then worked on
framework. The 3DS had been thoroughly researched and
getting some instrumentation in place, by setting up an RPC
documented by the time of our research, and understanding
server. This let us interact with our exploit remotely to, say,
that platform was a great help in understanding the rational of
dump current memory. Soon after, we realized one important
its successor, as will be explained later.
thing: the Switch does not have JIT in its browser.
To the effort of reverse-engineering the OS, we scanned
Since the user is not intended to be able to use a web
the addressable memory for executable formats in order to
browser at all, the lack of JIT surprisingly makes sense
gain useful insight on the fundamental details of the software
here. Traditionally, to exploit WebKit, the typical procedure
systems. One of the first things we realized, apart from the
involved creating some dummy function or functions, running
executables being in an apparently new, custom format —
it enough times so that it is selected to be optimized, wait
not uncommon for Nintendo [10] — is that due to dynamic
for it to be compiled and transferred into the JIT memory,
library linking and loading, we were able to retrieve a bunch
and then, since JIT memory is writable and executable by
of symbols which identified available services.
design, use a vulnerability that gives you a write in program
memory, in order to overwrite said function with our own
code, and execute it. The lack of JIT, and the subsequent lack D. Services, explained
of executable-and-writeable memory, completely prevented us What follows is in-depth information about the system ser-
from using this technique to gain arbitrary code execution. vice architecture of Nintendo’s Horizon operating system. This
We had to resort to the use of Return Oriented Programming section in particular is informative; it contains information
(ROP), by way of overwriting function pointers. While ROP is that we had to figure out after-the-fact, but is essential to
very powerful in its own right, by letting us redirect program understand the rationale behind our method, moving forward.
control flow, it does not let us redirect it to our own code. The userland API of the Nintendo Switch is comprised of
This primitive level of control, however, is enough for further services, provided by system service processes, or servers.
research that could lead to privilege escalation, so we went These are processes which run in the background, and pro-
and began to implement some ROP gadgets — essentially vide controlled-access, higher-privileged system functions to
3
userland applications as well as other servers, by way of an we want as an argument. Let’s assume for our example, the
IPC interface. service is ”bsd:u”. We now have a handle to our service and
Most of these services are limited as to what they can affect, are able to send commands via that handle, through IPC. A
and their servers load as a userland program would, and thus simpler comparison could be made that we interface with the
have restricted access to other services and hardware, as any system and its services through an address-and-port system,
application. in comparison to TCP/IP: the service name defines where the
Some of these services are especially privileged, and their command is to be addressed; meanwhile the handle, like a
servers load very early in the boot sequence. Because they TCP port, tells us where to send a command. The IPC header
are loaded so early, before the mechanisms are in place to defines the command format.
securely load and verify executable content from storage, the
first six of these servers are contained within the kernel binary,
and load into memory along with the kernel. These kernel-
initiated processes, or KIPs, are compressed and packaged
with a unique executable container format, and unpacked by
the kernel once it is loaded and running. Once spawned,
these six servers are sufficient for continuing the secure boot
process.
Access to services from userland applications, is coordi-
nated by a service manager (sm), which is itself a server, with
service endpoints. The sm reads the list of allowed services
for the application, registered to sm at launch. This list is
in the executable’s metadata on storage, which is signed by
Nintendo during their production-signing step, the same for all
applications, games, game cartridges, and system programs for
the Switch. That list’s signature is verified by the filesystem
server (fs), along with the executable code, to ensure that it
has not been tampered with after installation.
necessary. Through this effort, we were able to identify and • If the prior system is documented, its successor will be
reverse engineer a bunch of service related functions. However, easier to figure out. This can be used to the benefit of
unfortunately, most of the services’ names, functions and the both protecting, and exploiting, the system.
IPC command structure seemed to have been changed entirely, • Stripping executables of their debug strings and symbols
making us do the documentation effort and tooling all over makes the adversary’s job harder.
again. • A comprehensive audit strategy on privileged code’s API
Reversing the port system was trivial, as it was a simple endpoints is crucial.
syscall away — namely, poking at SVC 0x1f, ”svcConnect-
ToNamedPort” [11], was enough to verify that the named III. P RIVILEGE E SCALATION : S YSTEM S ERVICES
ports enumerated prior were correct, and to enable us to
A. Following a lead
further manipulate the services behind these ports. Gaining a
meaningful understanding of the IPC command structure was, All system service processes except for the kernel-initiated
to put it mildly, a fair bit more painful. By ”a fair bit”, of servers, are contained in ”sysmodules” in storage, like the
course, we regret to inform you, it had been head bangingly 3DS.
stupidly obfuscated, and blanketed in seemingly nonsensical By this point we had a huge attack surface, nothing short of
optimizations. The more dedicated (read: masochistic) reader unrestricted access to all system services, which we could take
may wish to consult the additional documentation about the advantage of to find flaws in privileged processes. However,
IPC buffer descriptors, and the bit shuffling hacks that happen there remained much mystery behind the workings of the
behind the scenes, to completely grasp the magnitude of the system. We had not dumped the sysmodules yet, and thus
topic at hand [12]. could not perform out-of-system analysis on these binaries.
Let us assume we somehow reverse engineered this protocol We began automating the process of fuzzing some services,
and reimplemented it. As we do not have any way to dump and then kind of got disinterested from research temporarily.
privileged code yet, our first reflex was to fuzz the services to In the meanwhile both Switchbrew and Reswitched indepen-
find any evicence of a crash thanks to an unexpected input, dently found an exploit called ”pl:utonium”. This exploit was
while documenting them... or I should say, it should have in the first commands of the service pl:u (which handles
been our first option. Remember how I mentioned the Service the system shared font in shared memory), initialized by the
Manager up above? If you follow the rules, you are supposed ns server, which read from an array using the user-input
to call an Initialize function, which sets the PID of the current arguments. That input was obviously not sanitized prior to
process to handle service permissions. It turns out, you can use, allowing them to dump the entire binary of the NS
just skip the initialize function. Doing that, leaves the PID sysmodule [14]. ReSwitched, on their side, created an emulator
field uninitialized. Uninitialized fields are set to 0. PID below to automate the findings of vulnerabilities through fuzzing [15]
8 have unrestricted service access, which we could also deduce [16]. Right after this, we had a surge of renewed interest into
at this point since the 3DS worked in a similar fashion [13]. the Switch which made us investigate some of the highest
It should suffice that the name given to this exploit, ”sm:h”, privileged sysmodules, as they would be the most useful to
need not be further explained. break.
Before telling you how we decided to look at entrypoints,
I would like to mention that we independently confirmed that
at least one research group was able to be aware of privileged
In brief:
services through internal leaks they shouldn’t have had access
• Features that are able to be abused, will be abused, even to, greatly helping their ability to document and research said
if they’re not ”supposed” to be. modules.
• Completely removing such a feature may not be the Moving on, we were aware that Plutoo was able to dump
easiest solution, and it may not be the best for all use- system modules [17] while excluding the possibility of a
cases, but it is the most secure. kernel hack [18]. This led us to believe that the flaw was
• Sometimes compromises are necessary to meet demands, present in some of the more privileged system servers, namely
but be sure to investigate all alternatives before settling the ones built-in that Plutoo mentioned. We were also curious
with the lesser-secure option. on why plutoo listed both the title id and the name of the
• Security through obscurity is not secure. Sometimes the modules in the post [17] mentioning the dump, and, while
very fact that something is hidden, is more than enough this could have been a coincidence, we decided to look at
information to formulate a plan of action. (This goes what this could lead us to.
to both the Wi-Fi browser access, and the WebKit bug As such we looked at the list of title ids that were currently
reports.) documented on switchbrew [19] and enumerated all the priv-
• Just because something can’t make code executable, ileged ones: fs, ldr, ncm, pm, sm and finally, boot. As the sm
doesn’t mean it can’t execute code. ROP is a very server’s services have a very small attack surface with very few
powerful tool. commands, and we had already bypassed it by way of sm:h,
• If you reuse common libraries, code and programs from we decided to not look at it. The boot server being a ”headless”
other platforms, you run the risk of importing existing server without any kind of service frontend, exploiting it was
vulnerabilities and exploits from those platforms, too. out of the question.
5
B. The FS services session services maintain only one connection with only
one other server.
After removing those two from the equation, we decided to
• Conditions which leave floating handles to privileged
look at everything filesystem related, because of the peculiar
resources should be avoided.
name listing in the post that plutoo made [17]. And so we
• Stating that an exploit exists is as good as publishing it;
began trying to work on fs, as it was numerically the first built-
if you don’t, someone else will.
in, fully-privileged module that was also related to filesystems.
We began looking at the FS documentation, and studying
IV. B EYOND P RIVILEGE E SCALATION : B OOT AND T RUST
and exploring every possible entrypoint in the service set
handled by the FS server. Coincidentally, the first service port A. Approaching the Tegra
listed was fsp-ldr, along with its first command (”OpenCode- The following section is written under the assumption that
FileSystem”, though it was referred to as ”MountCode” back we never did any work on the Tegra X1 hardware prior to
then, due to a lack of debugging symbols for naming internal beginning the research effort with the Nintendo Switch. We
things). had, however, already been working on the Tegra X1 platform,
Unfortunately, trying to bind to it directly, throws an error. since around August 2016. Unfortunately, we cannot discuss
We had somewhat anticipated this; building upon our experi- this prior research, as it is held under NDA until further notice.
ence with, and knowledge of, the 3DS, we figured that there We believe that such antagonistic NDA terms needlessly
was the likelihood that this service had a session limit, and that restrict innovation and hamper security for the company in
said limit was occupied at initialization time, something which question, as well as harming the professional security research
happened to the FS counterpart of the 3DS [20]. As the service community and vendors who implement Tegra-based solu-
name was fsp-ldr (which we presume stands for ”privileged tions. We will say that at least one major vendor that makes
filesystem service pertaining to the loader”), we figured out use of Tegra X1-based platforms, abuses these non-disclosure
that if we crashed the ldr service, which, one could infer, had terms to the detriment of their researchers.
an exclusive handle to fsp-ldr... we could get access to the Having a way to dump almost all of the system modules,
fsp-ldr handle instead! we began to look at our options to escalate privileges in a
And as a matter of fact, this is what happened: Any method more concrete, reproducible and persistent fashion. Having the
of crashing, killing, stopping, unloading, or otherwise causing binaries had helped a ton, and while we did get somewhere
a denial-of-service attack to ldr (of which there are several), with our newfound information, we were stopped dead in our
would cause the ldr server to release its handle on fsp-ldr, tracks by another research team, fail0verflow, who had shown
which we could hook up to, and then ask fsp-ldr nicely to off a cold-boot exploit [23], hinting at the fact that they were
dump all the code modules it had access to, since by virtue of able to dump the bootrom.
its function, it needs access to the binaries for applications and At this point we were aware that a development kit for the
sysmodules alike. Soon after we figured this out, a description Tegra X1, the System-on-Chip (SoC) used by the Nintendo
of the vulnerability, a minimal proof-of-concept exploit, and Switch, was publicly available for purchase... and that it
a functional ldr DoS were released to the public by other most likely had the same bootrom. Thus, the fun part began:
researchers [21]. We found out that they had left out enough glitching and hardware fault engineering was put into play. We
details so as to not completely trivialize the exploit. As we will mostly skip over this part, as Yifan Lu already explained
found, there was no reason to keep the full-featured exploit very well how glitching could be applied to embedded devices
private, and hoarding that exploit would only hurt the further- in the past [3] [24] and an entire talk had already been
developing public research effort, so we ported our unabridged given at the C4 OpenChaos event on glitching the Tegra X1,
fsp-ldr exploit code to the DoS framework that they had specifically. [25].
released and published it, including it into PegaSwitch [22]. Essentially, we took the path of least resistance, and voltage-
glitched a Tegra X1 development kit, and a second device
which we unfortunately cannot discuss here due to the afore-
In brief: mentioned NDA. As we are unable to discuss that project,
we will assume that our research is entirely unique and that
• While separating services from more privileged code
fail0verflow inspired us to look into the bootrom, for the
in the same program is a noble attempt at preventing
purposes of this paper. We will try to release the research
leakage, and marshalling the service domain and its
currently under NDA as soon as possible. We are sorry for any
endpoint away from the core program helps... again,
mandatory omissions we do in this paper, and are hopeful that
a comprehensive audit strategy can prevent faults in
the available literature will be more than sufficient to satiate
privileged code.
the curiosity of the dedicated reader.
• Just as parallellizing computation speeds results, so does
parallellizing research.
• While dependency chains are often hell on system de- B. Analyzing the boot ROM
signers, asserting a dependency such that, for example, So, we glitched our device and successfully acquired the
fsp-ldr can only operate when ldr is present, would have contents of the boot IROM. At this point, since we were aware
kept fsp-ldr from being exploited. Nintendo’s fix involved of fail0verflow’s tweet [23], we saw that they had, purposefully
adding semaphores, which ensures that privileged single- or not, hid the USB port of the console. Understanding that the
6
USB protocol — especially USB 3 and USB Type-C — has a the 90s, with no mitigation whatsoever, no memory protection
level of implementation complexity that often stretches beyond or isolation, as this is a bootrom, naturally, with no operating
the definition of ”acceptable”, and on the heels of several USB system or kernel to enforce it with. The memcpy occurs before
kernel flaws released a bit before this tweet [26], we surmised the stack, so you just overwrite the stack pointer, point it to
that it was fairly likely that the flaw was related to USB in the code you copied, and since there are no stack cookies, no
some way. At this point we had only gained a fairly minimal ASLR, and absent no-execute memory policy, you just watch
understanding of the Tegra boot firmware logic, and as such, it execute your code. It’s so easy, it almost feels like cheating.
decided to write an emulator for it, and employed dynamic
program analysis using that emulator, to aid the static analysis
C. God’s in his TrustZone, all’s right with the world
effort.
Building this emulator not only forced us to understand the Having access to an exploit in boot ROM, we had no real
boot flow of the Tegra X1, including its recovery mode (RCM) incentive to work on the switch again, but we were curious
which makes use of USB, but it also made us understand way about some known but private vulnerabilities nonetheless,
better how the boot ROM code worked. It had helped so much, especially one that the ReSwitched group called ”déjà vu”.
that we actually found the bug in a minimal amount of time, To put that into context: ReSwitched, early on, publicized a
with a minimal amount of effort, with our emulator still only write-up about a flaw they found called ”jamais vu”, which
operating in HLE (High Level Emulation)!. allowed code execution on the Secure Monitor of the Nintendo
The plan we had in mind for this emulator was to, first of Switch [28], while announcing déjà vu. As this is the type of
all, get an idea of the bootflow by implementing all the main exploit that really makes use of all the unexplored intricacies
cryptographic/USB functions in HLE, in order to develop a of the system, we will more thoroughly explain the overall
tool that would interface with the console’s RCM. We already technical architecture of the Nintendo Switch.
knew that, besides the RCM interface, there wasn’t a way to The Nintendo Switch is composed, first and foremost, of
interface to the console’s boot ROM to provide input, external a SoC called the Tegra X1, created by Nvidia. While it may
to the console. Once we had a better definition of the RCM sound unintuitive, this SoC is actually composed of several
interface over USB, we would then make a basic fuzzing tool processors with different architectures and different use-cases,
that would run in the background over a long time, while we out of which some are particularly notable.
ported our emulator to full Low Level Emulation (LLE), to The main CPU core complex, that we will henceforth
allow us to more completely simulate the processor and its call the CCPLEX, is the primary applications processor. The
devices, to thoroughly fuzz out any trivial bugs we may have ”Boot and Power Management Processor”, referred to in this
missed up to this point. paper as BPMP or BPMP-Lite, handles system bringup, power
While we were working on the HLE part of our emulator, management, and is technically the ”root processor” of a Tegra
we decided to perform a quick audit. The USB and crypto- system. (The Reference Manual calls it ”BPMP-Lite”, as it
graphic functions, being prime targets, were the first items lacks some features that more advanced versions of the SoC
of interest to us, with some focus on cryptographic fails. will apparently get.) The boot ROM that we dumped before,
Fortunately for us, the bug occured at a point in the RCM is referred to by Nvidia as the BPMP-FW, the ”firmware” for
program flow before any kind of cryptographic verification this subsystem, because it is the first program loaded and the
was performed. As such we discovered it naturally when trying first processor to initialize on power-up. There is also a third
to understand the RCM. processor, the Tegra Security Co-Processor (TSEC), that we
will talk more in depth about in the following section. For
the purpose of this section, knowing that the BPMP is meant
to handle power-on bringup, initial bootloader, and low-level
tasks is more than enough.
The CCPLEX is a somewhat recent ARM processor, which
means it is capable of a feature that ARM calls TrustZone. For
those unfamiliar with the concept, TrustZone is a hardware-
enforced virtualized system-separated enclave on the proces-
sor, used to isolate security-critical parts of the operating
system as much as possible (in the case of the Nintendo
Switch, its internal cryptographic engine). This introduces a
notion of ”Secure World” and ”Normal World”, both running
their own OS and having their own separate resources. For
example, the Secure World has its own secure RAM space,
”TZRAM”.
Fig. 2. The bug, courtesy of ktemkin’s fusée gelée report [27] In our case, the ”Normal World” is the Horizon kernel,
with its servers and userland applications, and the ”Secure
The flaw was fairly simple actually: in some functions of World” contains the ”Secure Monitor” of the Nintendo Switch,
the USB protocol, we could arbitrarily control the size of a which is just its cryptographic engine, as mentioned above,
memcpy, allowing us a good, simple buffer overflow, just like alongside some rudimentary power management services. The
7
normal world interacts with this secure world by using Secure would not be able to modify the Secure Monitor whatsoever,
Monitor Calls (SMC), roughly analogous to kernel syscalls, keeping it secure and encrypted, so that no information leaks
or ”Supervisor Calls” (SVC). This is an important part of from Secure World can happen.
Nintendo’s security scheme, as this allows them to seal keys, There was, unfortunately for Nintendo, a small omission
even in the case of complete kernel takeover, so that: in that trust logic: userland could modify the PMC registers,
1) We cannot replicate their cryptographic engine outside breaking entirely the ”trust” in TrustZone. We could simply
of the device, and replace the copy of the TZRAM with our own, change the
2) They can always patch known vulnerabilities, update the MAC result to verify against ours and, thanks to another bug
keys and we would have no way to break the DRM of within the boot ROM, because it fails to correctly verify the
newer games. state of the Security Engine (SE) it restores, we can simply
replace the keys used to decrypt the TZRAM by ones we
control, to make it decrypt and verify our own TZRAM.
On top of all of that, we could have modified BPMP
exception vectors to point at code we owned, leading to pre-
sleep code execution on the BPMP. We could have rewritten
the RESET vector to execute our code at startup and, as such,
be able to control the Secure World like before. This didn’t last
long, though, as all of this would be fixed with a launch-day
firmware update, 2.0.0.
Or at least this is what Nintendo thought: Indeed, while
PMC was effectively made Secure-Mode only as far as we
can tell, the BPMP exception vectors checks haven’t been
thoroughly reviewed: a high speed internal bus of the Tegra
Fig. 3. TrustZone illustration
X1, the AHB, has a DMA interface, conveniently named AHB-
Unfortunately for them, having bootrom code execution DMA. AHB-DMA is supposedly ”deprecated”, but it still
kind of spoils the fun... but let’s just forget that for a moment. exists in the X1. Because this DMA hadn’t been otherwise
Continuing on what we mentioned above, we know that disabled or limited to specific memory ranges, we could
ReSwitched managed to get code execution on the Secure overwrite the exception vectors of the BPMP, leading to a
Monitor which they called ”déjà vu”, on top of ”jamais vu”, full compromise once again. The good news, is that the AHB-
which pointed us in the right direction, especially thanks to DMA interface is only accessible to the kernel, running on
the amazing write-up for the latter. CCPLEX. The bad news, is that it is available to the CCPLEX,
We were still pretty dormant up until firmware revision 6.0.0 let alone non-Secure World kernel code, in the first place.
of the Nintendo Switch. The founder of, and a former lead There is also another exploit available for code execution
of the ReSwitched group had independently discovered and that was fixed in firmware 6.0.0, that we have not found, hav-
privately disclosed a vulnerability to Nintendo that was part ing studied firmwares newer than this version while looking
of the exploit chain that formed déjà vu [29], and as of 6.0, for this bug. For the sake of completeness, though, we will
Nintendo had also mitigated the exploit itself! [30] This was describe it: While TrustZone is writing its wake up firmware
more than enough to bring back interest to this bug, even (”Warmboot”) to the BPMP, you could replace it with your
though we would have no real use for it. own, gaining code execution on the BPMP. This was fixed
by further validating the state of the BPMP, to make sure the
BPMP was not compromised before starting the warmboot
D. Waking up in another world payload.
So, after all this fuss, what is Jamais Vu all about? Essen-
tially, it deals with deep sleep — a mode which ”shuts down”
all hardware, except for the minimal power draw necessary In brief:
for sustaining the Power Management Controller (PMC), and • Glitch attacks, fault injection, power analysis, and other
persisting the contents of DRAM. When resuming from deep hardware-level attacks, will violate your preconceptions
sleep, the BPMP will begin as if being cold-booted, but it of software/hardware validity at the lowest level, unless
instead resumes the system state in RAM. you proactively protect against unexpected code or reg-
As mentioned in the excellent write-up cited above [28], in ister data injection.
earlier firmwares, before entering deep sleep, the Secure Mon- • Complexity (such as, full implementations of bus and
itor would save its state from its TZRAM, to the CCPLEX’s network stacks, RSA cryptosystems, complex implemen-
”main” DRAM. It saves the contents encrypted, along with a tations of storage interfaces, filesystems and other device
Message authentication code (MAC) to ensure that it had not driver code) increases the potential vulnerability surface.
been modified or tampered with. The MAC is saved to a set Paradoxically, the more complex the program, the easier
of hardware registers in the Power Management Controller it becomes to exploit, in general.
(PMC), which persist through deep-sleep. The idea is that, • Low-level boot-time resources are a very high focus for
when rebooted, unless you had bootrom code execution, you researchers to audit. Not only the bootloader, but recovery
8
modes, factory modes, download modes, whatever they applications. Trojan/DSBrick.A, one such piece of malware,
may be called, if it’s loading code into the system from simply displays a brick-wall texture on the displays of the DS
an external source, it is going to be thoroughly studied system, while it overwrites the system firmware, rendering
for any possible flaws. the console entirely useless (a ”brick”), requiring risky or
• Moving data between security domains (TZRAM to costly repairs to return the system to a usable state. As well,
DRAM, for instance) is another high-focus area to audit. earlier Nintendo Wii homebrew methods involved replacing
Anything that depends on securely saving and restoring IOS packages (essentially, system drivers) with custom ones
such data should not depend on an unsecured system enabling homebrew to have access to more hardware that only
(PMC registers, for instance) to protect them. few games had taken advantage of. These ”cIOS”, custom
• ”Undocumented” features aren’t... or won’t be for long, IOS packages, were high-risk modifications, and often led
in the context of security research. to bricked Wii systems, especially if modified IOSes were
• Further, ”Deprecated” means nothing to a security re- installed before accepting a system update from Nintendo.
searcher, until the ”deprecated” feature is removed. Because of the risk of these and other modifications to
• Validating the state of privileged boot services goes a the system potentially leading to damage, customer support
long way to enforcing secure boot. Payload signatures headaches, and in the case of DSBrick, media attention,
aren’t enough; further boot-time measurements of code console manufacturers had to make a compromise to further
and state are necessary. secure against system modifications, while still allowing up-
grades to firmware, system software, bundled applications,
V. B EYOND T RUST: FROM TSEC TO 0 X DEAD5EC1 downloaded applications and content.
Having bootrom-level code execution, we thought we were Because of the heightened protections on firmware mod-
pretty much done with the security challenges of this console... ifications, homebrew methods on later consoles have given
And yet, Nintendo still managed to surprise us. rise to live, in-memory patching, rather than modifying the
Before we touch on how Nintendo revamped their trust necessary code in storage, either through modified bootloaders
chain, we’ll take a look at some background on console (such as Enso [31], for the PlayStation Vita) or through custom
security. kernel modules or system programs which patch memory
as well as add features (Prometheus/Pro-CFW [32], for the
PlayStation Portable), or a combination of the two (Luma3DS
A. How Homebrew Works [33], for the Nintendo 3DS). By tradition, these pre-loaders,
The community of developers and users making and us- in-memory patchers, modified or reimplemented components
ing unlicensed homebrew software for game consoles, de- continue to be called ”CFW”, despite often being neither
pends on the ability to run arbitrary, unauthorized code in custom, nor firmware. These CFW environments almost uni-
a convenient way (e.g., without physically modifying the versally disable or work around code-signature enforcement.
device or installing aftermarket or replacement components
through high-risk hardware modifications). In order to run
unauthorized code, the strict code-signature enforcement on B. Switching gears
applications needs to be relaxed, if not removed entirely. On Earlier on, Nintendo Switch homebrew was rudimentary.
older consoles and handheld systems, there was no code- The limited homebrew entrypoints available had placed many
signature enforcement; running homebrew applications de- restrictions on the capabilities of such software, when com-
pended entirely on gaining any arbitrary code execution, most pared to native, signed applications. The first public homebrew
commonly through specially-crafted user-generated data or user and development environment, ReSwitched’s PegaSwitch,
savedata. On later consoles, cryptographical measures had which ran on system software 3.0.0, was used to launch the
taken place to simultaneously enable game data to be stored on Homebrew Menu, or hbmenu, an alternative launcher, loader
removable, user-accessible memory, as well as to protect the and host for homebrew applications compiled as relocatable
game data from tampering, reverse-engineering, and outright code objects (.nro files). This menu was intended to be boot-
replacement, and prevent unauthorized applications from being strapped from an existing application that had been exploited
able to run on users’ systems. Needless to say, these measures to run arbitrary code, which either had, or had escalated to
are often defeated by security researchers, and made available obtain, the necessary permissions to read content from storage,
to homebrew developers and users. In past systems with code- and dynamically load executable code.
signature enforcement, these workarounds had been achieved The application from which homebrew was bootstrapped,
through gaining code execution, and once running on the in this early environment, was the WiFiWebAuthApplet, or
target, installing modified or patched versions of the firmware the captive-portal landing page web browser applet. As such,
or operating system, typically called ”custom firmware”, or being an applet, the programs were extremely restricted with
CFW. For instance, installing FlashMe on the Nintendo DS the amount of memory they could allocate, as applets ran in the
allows running unsigned code directly over the Download Play foreground, while an application (such as a video game) was
feature, through a protocol termed ”Wireless Multiboot”. either running or suspended, in the background. As well, the
However, the ability to modify the system firmware or OS web browser had only very minimal permissions, and while
contents, had given rise to a handful of malware programs, of- this limited environment would more than suffice for testing
ten disguised as pirated games or highly anticipated homebrew new toolchains and enabling homebrew development on the
9
what good would a security co-processor be, right? We can use the hardware level, before granting it the HS privileges. Those
the BPMP’s control over the internal I/O memory management pages are then marked secret and cannot be read anymore
unit, the System Memory Management Unit (SMMU) as the until CPU halt, where trying to read from it would return
ARM architecture calls it, to redirect all reads and writes 0xDEAD5EC1.
to pages of memory we control, and fool it into thinking it Now that we’ve covered that, let’s assume we are working
effectively redirected code flow from our own control, while with earlier TSEC firmwares, for brevity. Those are easier
it just handed over the keys. That sure is a foolproof way to to work with, while maintaining, thanks to the nature of our
go about in-depth platform security. exploit, the exact same level of control.
But Nintendo was not done with TSEC, or at least not yet. Keygenldr, during normal operation, reads that blob of data,
As it turns out, the TSEC had a feature that was not well- so that it can parse it and check the first stage size and CMAC
documented (some would argue that it isn’t documented at hash, in our case Boot. This is done in order to retroactively
all, for our usecase), that came in handy for securing the boot verify that it hadn’t been tampered with. The thing is, this
flow and giving us yet another new challenge. An SMMU blob of data is not authenticated. We can control both the size
Bypass function is available to the TSEC, which forces the and content of data being copied over, hence, we can control
TSEC to simply consider all memory as linear, and avoid the a rudimentary stack smash. To go about that, we can have
memory virtualization that SMMU can perform. That’s quite a KeygenLdr copy our modified boot payload, fail verification,
useful feature for a security coprocessor, we must admit. This and return. Fortunately for us the verified MAC has not been
time around, in firmware update 7.0.0, they enabled it, while cleared from memory, so we can restart the process along
doing a bunch of checks to detect virtualization, updating yet with this MAC, pass verification and return to our crafted ROP
again their TSEC root key so as not to let us use older ones. gadgets, allowing us to get code execution in the Heavy Secure
mode of the TSEC.
The exploit described above is used to get code execution af-
E. In-”sept”-tion
ter Keygen has been decrypted, but its pages have been marked
Since 7.0.0 had yet again changed the security playing field, secret. We could optionally get ROP after the verification has
we needed to find another approach to attack TSEC. To explain failed, but we would be unable to decrypt Keygen. We would
our findings, we will discuss how this firmware authenticates also like to note that the same result could have been replicated
its payloads in depth. thanks to design flaws of the TSEC that we shall not further
TSEC is based around a Falcon microcontroller. This pro- discuss here.
cessor has three ”modes” in a security context: Non-Secure
(NS), which typically restricts the microprogram from reading
In brief:
most registers and memory; Light Secure (LS), which is
rarely used outside of debugging and development; and Heavy • The community behind developing homebrew software
Secure (HS), which enables full access to the cryptographical is pervasive; methods to gain homebrew access are often
hardware, and protected or secret registers and memory. invasive, and often co-opted by software pirates.
A small blob of unauthenticated data is present in the • It is very difficult to secure a system where the boot chain
firmware uploaded to the TSEC. That data contains the size of of trust has been compromised.
each payload, and a hash of the AES CMAC (!) that should be • Adding a new cryptographically-secure system may seem
calculated for the payload to pass boot-safety measurements. like a good protection against such a compromise moving
Now, if you understand even elementary cryptographical forward, but keep in mind that added complexity makes
theory, that seems counter-intuitive. Why AES-CMAC, and for a larger attack surface.
not an asymmetric cypher like RSA? If you get the AES key • Understand that using symmetric algorithms (such as
used for decryption (and the one necessary for verification), AES) where asymmetric crypto would typically be em-
you can effectively sign your own MAC... and completely ployed, means that a compromise of the key or keystream
substitute the expected payload for one you have control will allow forging the data in question.
of! Well, Nintendo has a reason. Falcon is a rather limited • If you’re depending on unauthenticated data from within
microcontroller environment. For one, there’s not enough a high-security domain, even if it is only accessible by
memory headroom to (securely) implement RSA in software. highly-privileged code, exercise due diligence on ensur-
Falcon has separate data and instruction memory, DMEM and ing that the data is valid — e.g., employ bounds-checking
IMEM, and together they measure in the dozens of kilobytes. on structures in the data.
For another, one would have to implement RSA from scratch As a side note, we would like to warn the interested reader
to the Falcon microarchitecture, and Nintendo seems to have that, should they decide to further attempt to understand the
since learned not to roll their own crypto... However, the TSEC secure boot process of the Switch by reading the publicly
does include hardware AES acceleration, which is expected to available Atmosphère [34] reference code, take note that the
be reasonably secure. key-generation is not done for 7.0.0 firmwares in the same
Those checks also execute in reverse order, so that way that it is done on the original bootloader.
KeygenLdr can ensure that Boot has not been tampered with, Sept [35], is a payload they designed to bypass checks
for example. On top of this CMAC, TSEC verifies page by implemented in SecureBoot. It does so by loading the original
page that any signed payload the payload is indeed signed, at 7.0.0 TSEC firmware, unmodified. The TSEC firmware is
11
designed to verify the AES CMAC of the PK11 binary, Any code implementing any cryptography primitive, espe-
before returning execution to the bootloader there. Sept works cially if it’s considered secure and crucial to the chain of trust
because the CMAC was forged on the custom PK11, passing in a system, should not only be audited in order to avoid
the code authentication routines in SecureBoot. Sept, now in basic security issues, but also be hardened against side-channel
PK11, derives keys in place in package1Ldr and scrambles the attacks, such as power analysis and fault injection [39], at the
TSEC and TSEC root key, making it impossible whatsoever to very least, to avoid any early breakage of the trust chain.
use the original Secure Monitor firmware, as it doesn’t have Ultimately, security is defined by failures thereof. Software
the keys necessary to further perform key generation. Engineering should learn from traditional engineering in that
point, as software and software systems CAN fail, and we
should accordingly plan for even a slim margin of error in that
VI. C ONCLUSION
regard. As such, mitigations against common faults in software
We completely broke the security system of one of the most security should be graciously applied whenever possible, and
secure embedded consumer devices on the market with no a clear list of everything a user could potentially control, must
prior knowledge of its hardware nor software. be set.
Unlike most of the existing literature on computer science A sad thing about security, is that it is mostly decided
security, we decided to focus on the inductive process of by your budget. Even if you have a state-level intelligence
finding security flaws and fixing them, rather than explaining threat the smaller your budget is, the less you’ll invest in
how they work and implementing exploits for them. This security, if this isn’t one of your unique selling points. This
decision was motivated by having most of the security flaws shows in IoT devices and, in some cases, forced hackers to
we independently found already published online, some being exploit vulnerabilities, in order to patch them. Our approach
released before or even during [36] the writing of this paper! to security should change altogether.
Our inability to talk about some potentially damaging non- We must focus on putting the best practices at the forefront,
public security vulnerabilities related to the Tegra X1 did not to the point that they are the easiest to implement, otherwise
help either. We also think finding flaws in embedded devices we will continue to be trapped in the conspiracy against trust.
is much more interesting to write about, as a whole.
We would also like to stress that this paper’s ultimate goal ACKNOWLEDGMENTS
is not to expose Nintendo’s flaws, but rather to help computer We would like to thank the tremendous work of the re-
security research be aware of such possible flaws, and as such search groups that worked on the security and making of the
would like to give our point of view on what could have been homebrew community on the Nintendo Switch: Switchbrew
improved by Nintendo to avoid those exploits. ReSwitched and, to a lesser extent, fail0verflow. We acknowl-
Firstly, exploits such as sm:h and pl:utonium seem to present edge the time and effort investment to make such a community
a crucial lack of auditing. While we are aware that auditing exist. While we were only interested on the security side of
the entire runtime code of the Switch firmware would be the subject, the entire SDKs, CFW reimplementations and
impractical, serious security audits must be done on every homebrews are invaluable for such a community. The entire
privileged bit of code that could be harmful and are a prime documentation provided by Switchbrew contributors was also
attack target, which is indeed the case of the NS and SM immensely helpful at several points during this research. We
servers. Optionally, switching to safer languages (such as would also like to thank 3DBrew, which community is shared
Rust [37]) or formally-verified coding paradigms, would have by Switchbrew, who were a building block for Switchbrew
altogether avoided both of those flaws. If some code has to research.
be privileged and yet not trusted, such as a blob of third
party code, then it is good practice to try to isolate it as R EFERENCES
much as possible. Positioning services such as pl:u separately [1] Wiibrew Contributors. Signing bug. [Online]. Available: https://wiibrew.
from the main NS services is also a good idea, even though org/wiki/Signing bug
such separation should have been more pronounced in that [2] Console Hacking 2010, PS3 Epic Fail, Dec. 2010. [Online]. Available:
https://media.ccc.de/v/27c3-4087-en-console hacking 2010
particular case. [3] Viva la Vita Vida, Hacking the most secure handheld console, Dec.
Moving on to any secure code attacks and secure key 2018. [Online]. Available: https://media.ccc.de/v/c4.openchaos.2018.06.
retrieval: it is crucial to add anti glitch measures to make glitching-the-switch
[4] 3dbrew Contributors. Browserhax. [Online]. Available: https://www.
glitching with low-cost, low-complexity equipment as hard 3dbrew.org/wiki/Browserhax
as possible. Depending on your threat model, it might also [5] Console Hacking 2013, WiiU, Dec. 2013. [Online]. Available:
be a good idea to encrypt the ROM stored inside the SoC. https://media.ccc.de/v/30C3 - 5290 - en - saal 2 - 201312272030
- console hacking 2013 - sven - marcan - nicholas allegra comex
While a powerful attacker could, ultimately, decap the SoC, [6] C. Dumez. Changeset 213311 in webkit. [Online].
reverse engineer cryptography primitives used to decrypt the Available: https://trac.webkit.org/browser/webkit/trunk/LayoutTests/fast/
boot ROM [38], and laser glitch his way around the program, frames/insert-frame-unload-handler.html?rev=213311
[7] ReSwitched Contributors. Pegaswitch. [Online]. Available: https:
the process should be as arduous as possible if we want any //github.com/reswitched/PegaSwitch
cryptographically secure software boot on devices at all. Decap [8] MITRE by virtue of Apple Inc. Cve-2016-4657. [Online]. Available:
and laser glitching will most likely always be possible, but https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-4657
[9] qwertyuiop. jbme. [Online]. Available: https://jbme.qwertyoruiop.com
when this becomes part of the least effort approach then we [10] 3dbrew Contributors. File formats. [Online]. Available: https://www.
might have some chance at protecting secrets. 3dbrew.org/wiki/Category:File formats
12