0:00:00.000,0:00:19.781
36C3 preroll music
0:00:22.710,0:00:26.439
Herald: The following talk is titled "It's[br]Not Safe in the Streets, especially for
0:00:26.439,0:00:31.430
your 3DS" and it's about exploring a new[br]attack surface on the 3DS. And the speaker
0:00:31.430,0:00:36.270
is nba::yoh. The show is yours.
0:00:36.270,0:00:42.190
applause
0:00:43.297,0:00:49.879
nba::yoh: Hi, everyone. I'm nba::yoh and[br]today I'm going to talk about 3DS hacking
0:00:49.879,0:01:01.109
and especially about a protocol, an[br]undocumented protocol. And we're gonna see
0:01:01.109,0:01:10.580
how I attacked the protocol and got remote[br]code execution on the system. But before
0:01:10.580,0:01:18.229
before saying, oh, I did that, I'd like to[br]do a quick recap of the state of 3DS
0:01:18.229,0:01:27.100
hacking in 2019, because there have been a[br]lot of userland exploits, a lot of patched
0:01:27.100,0:01:33.030
kernel flaws and there's a lot of[br]documentation online about the system. And
0:01:33.030,0:01:41.420
during the last few years, people have[br]been working on it and broke the hardware
0:01:41.420,0:01:49.509
keyscambler. And they managed to dump the[br]bootroms. And as a result, anyone who now
0:01:49.509,0:01:57.899
have the bootrom can derive all the secret[br]keys of the system. And as a bonus, they
0:01:57.899,0:02:03.700
were able to find a permanent unpatchable[br]bootrom exploit. So at that point, you
0:02:03.700,0:02:11.040
might be wondering what's left to do in[br]the system. And actually, I wonder if it
0:02:11.040,0:02:16.620
would be possible to use those keys to[br]attack features that were protected until
0:02:16.620,0:02:22.475
then by encryption. So that's why today[br]I'm going to talk about StreetPass.
0:02:25.059,0:02:30.650
First, I'm going to do a quick introduction about[br]the feature and then we'll see how I
0:02:30.650,0:02:39.240
expoited it and see what's possible to do[br]once you get code execution. So what is
0:02:39.240,0:02:45.790
StreetPass? This is a local and wireless[br]communication feature. The basic idea
0:02:45.790,0:02:51.980
behind StreetPass was that users would[br]take their 3DS with them and go out and it
0:02:51.980,0:02:59.989
would automatically communicate with other[br]people's systems. The point of the feature
0:02:59.989,0:03:07.180
was to share data between applications[br]like custom levels for your games or
0:03:07.180,0:03:14.800
messages, avatars, et cetera. So this is[br]quite an interesting feature for players,
0:03:14.800,0:03:21.930
but also for hackers. So this is the[br]player point of view so you can send your
0:03:21.930,0:03:29.209
messages and other people will be able to[br]receive them. But we'd like to - from an
0:03:29.209,0:03:34.510
hacker point of view - we'd like to[br]replace one of these systems with a PC to
0:03:34.510,0:03:40.629
tamper with the protocol, for example. And[br]eventually it would be nice if we could
0:03:40.629,0:03:48.021
send some corrupted messages and see if we[br]can get code execution on foreign systems.
0:03:49.621,0:03:54.663
But for doing that, you need to know how[br]the street the StreetPass feature works.
0:03:55.845,0:04:01.319
So it's quite simple. It acts like a mailbox.[br]So you have CECD, which is a system
0:04:01.319,0:04:10.829
module, and it's the only one that manages[br]all this StreetPass feature. So all your
0:04:10.829,0:04:18.370
applications have an inbox and an[br]associated outbox in the CECD file system
0:04:18.370,0:04:27.320
and they can put and get messages from and[br]to these boxes via IPC. Then messages in
0:04:27.320,0:04:32.390
these boxes are used to craft packets[br]which are then sent using the StreetPass
0:04:32.390,0:04:40.610
protocol. And we can already see on this[br]diagram which path we could try to attack.
0:04:40.610,0:04:47.220
The first one you might think about are[br]our application boxes because it's very
0:04:47.220,0:04:53.750
likely that you'll be able to find some kind[br]of game or application that have a float
0:04:53.750,0:05:02.890
parser. So we might take and get remote[br]code execution in such an application. But
0:05:02.890,0:05:10.960
the most interesting one would be to try[br]to attack CECDs parser. And this would
0:05:10.960,0:05:19.290
give us remote code execution in a system[br]module, which would be nice. But for doing
0:05:19.290,0:05:25.060
that, we need to figure out how the[br]StreetPass protocol works and nobody
0:05:25.060,0:05:31.069
really knows how it works. There is a bit[br]of documentation online about the
0:05:31.069,0:05:36.419
pairings, so "oh both our systems are[br]seeing a hand here. Would like would you
0:05:36.419,0:05:42.410
like to communicate with me?" But it has[br]never been successfully reproduced, at
0:05:42.410,0:05:49.600
least publicly. And we know that it's[br]using an unknown and encrypted protocol
0:05:49.600,0:05:58.900
that uses the secret AES key that we can[br]now get. So let's reverse the protocol.
0:05:58.900,0:06:08.100
First, well, let's reverse the pairing and[br]replicate it. So it's fairly easy to
0:06:08.100,0:06:15.360
understand: You have both peers, the[br]client and the master and before
0:06:15.360,0:06:23.169
communicating they randomize their console[br]ID and their MAC address. Then the client
0:06:23.169,0:06:32.460
sends a bunch of probe requests with our[br]bundle specific tag, containing a list of
0:06:32.460,0:06:37.940
the applications that have StreetPass[br]activated. And then eventually the master
0:06:37.940,0:06:45.110
received that public list and analyzes it.[br]It's checked if an application from the
0:06:45.110,0:06:50.419
client that has StreetPass activated[br]matches one of it's own applications with
0:06:50.419,0:06:55.680
StreetPass activated. If it's the case, it[br]sends the probe response to the client,
0:06:55.680,0:07:02.160
which will do the same. And if both peers[br]agree that they can exchange data, they
0:07:02.160,0:07:11.430
will start communicating after deriving a[br]common key. So replicating the pairing is
0:07:11.430,0:07:20.810
not super odd if you know what tool to[br]use. I tried to reproduce the pairing
0:07:20.810,0:07:28.470
using a monitor mode, but it's really hard[br]because you have to deal with all the
0:07:28.470,0:07:38.009
action item frames et cetera. So I used[br]nl80211 which lets you register some
0:07:38.009,0:07:44.470
specific callback for some specific frames[br]and send custom frames and everything is
0:07:44.470,0:07:53.590
handled by your wifi adapter driver. So at[br]that point the 3DS starts sending
0:07:53.590,0:08:00.827
encrypted data and we have to decrypt[br]them. So let's review the encryption. They
0:08:00.827,0:08:09.979
do this in two passes, the first one they[br]use an HMAC-SHA1 over both consoles CIDs
0:08:09.979,0:08:18.270
and both MAC addresses and the output of[br]this pass is used as an input counter for
0:08:18.270,0:08:28.659
on AES-CTR using the AES key slot we can[br]now get. And the output of this encryption
0:08:28.659,0:08:37.570
is used as a session key for the[br]communication. So nl80211 lets you
0:08:37.570,0:08:45.530
register CCMP keys so it's quite easy to[br]send and receive encrypted packets using
0:08:45.530,0:08:56.470
it. So now we can start reversing the[br]protocol. Let's take a look at the
0:08:56.470,0:09:04.100
structure of packets before doing any[br]reverse engineering. So I put some packets
0:09:04.100,0:09:09.544
I was able to receive and the first one is[br]one of the smallest one you can actually
0:09:09.544,0:09:19.450
observe. So first you have a header and[br]then you have some data and you can spot
0:09:19.450,0:09:26.830
some magic values here. Actually, it's[br]easy to spot them because CECD is using
0:09:26.830,0:09:35.890
really recognizable magic values. It's[br]always the same byte repeated twice. Once
0:09:35.890,0:09:40.520
you know the structure of the packets, you[br]can view that there are actually
0:09:40.520,0:09:49.340
two protocols. The first one is SPTCP.[br]It's an equivalent of TCP, but for local
0:09:49.340,0:09:55.380
communication. It's mainly designed to[br]ensure reliability and data segmentation.
0:09:55.380,0:10:03.790
And then you have SPMTP which is built[br]over SPTCP and handles all the exchange of
0:10:03.790,0:10:11.060
stricter data and StreetPass messages. So[br]we have two protocols and we need to
0:10:11.060,0:10:18.290
review both of them. Let's start with[br]SPTCP. Actually, there is not much to say
0:10:18.290,0:10:29.090
because you only basically have to reverse[br]and understand the header. You have a
0:10:29.090,0:10:33.570
magic value and some constants. But the[br]most important field here is the flag
0:10:33.570,0:10:39.100
field because if you can understand what[br]are the flags, you can understand the
0:10:39.100,0:10:45.760
meaning of the packets you are sending and[br]receiving. And so you can basically
0:10:45.760,0:10:53.710
understand the protocol. And fortunately,[br]in this case, they're using the same flags
0:10:53.710,0:11:01.950
as TCP, so it was really easy to[br]understand the protocol and how it worked.
0:11:01.950,0:11:13.590
And what about SPTCP security? Actually,[br]it's OK. I did not find any bug. But the
0:11:13.590,0:11:19.140
attack surface is really small. We can[br]basically only tamper with the header and
0:11:19.140,0:11:31.460
that's it. So SPMTP should be much more[br]interesting. Let's take a look at the
0:11:31.460,0:11:40.420
structure of SPMTP packets, because there[br]are actually two different packet types.
0:11:40.420,0:11:49.900
The first one is an info packet. It's[br]basically used in the handshake and it's
0:11:49.900,0:11:56.920
only here to share information between[br]both peers. And then you have message box
0:11:56.920,0:12:03.120
packets which are much more interesting[br]because they contain actual StreetPass
0:12:03.120,0:12:11.360
data and you can even spot the CECD[br]message via magic value, which means that
0:12:11.360,0:12:17.650
we actually reach actual game data and[br]SPMTP is the last layer of encapsulation
0:12:17.650,0:12:26.050
of the whole protocol. So once you figure[br]out how SPMTP works, you can reimplement
0:12:26.050,0:12:33.660
the protocol. So let's first review info[br]packets. There's a bunch of things in
0:12:33.660,0:12:40.440
here. Many fixed size data like friend[br]codes, MAC addresses, et cetera. It's not
0:12:40.440,0:12:46.750
much interesting when you're looking for[br]vulnerabilities. There are variable size
0:12:46.750,0:12:51.560
data, which are much more interesting.[br]They are sending application lists,
0:12:51.560,0:12:59.450
metadata lists, and it's much more[br]interesting because when you process them,
0:12:59.450,0:13:06.260
you can fail your parser. And if there is[br]some vulnerability here, we might exploit
0:13:06.260,0:13:14.720
them to get remote execution. So let's[br]take a look at one of this parser. This is
0:13:14.720,0:13:23.700
a function that parses meta data lists. So[br]let's focus on the for-loop. They are
0:13:23.700,0:13:33.740
actually copying a list of entries to the[br]stack. The destination is on the stack and
0:13:33.740,0:13:41.110
they do not check the number of entries in[br]the list. So this is clearly a buffer
0:13:41.110,0:13:48.420
overflow, but is it exploitable? Let's[br]illustrate this with a diagram. So this is
0:13:48.420,0:13:57.130
a regular copy. So you have your packet[br]buffer. And you have memcopy called on
0:13:57.130,0:14:08.770
each entry and everything's is all right[br]here. But if you had more entries, you
0:14:08.770,0:14:15.690
have a bunch of entries, compete on the[br]stack, that overwrite a bunch of things.
0:14:15.690,0:14:21.810
But there's a problem here, because the[br]packet buffer is not large enough for us
0:14:21.810,0:14:32.680
to reach the return address on the stack.[br]So we are probably copying uncontrol data.
0:14:32.680,0:14:39.430
So I was like, it's too bad, we can't do[br]anything with this, but let's check the
0:14:39.430,0:14:44.900
buffer next to our packet buffer. Maybe[br]there are some control data in there. And
0:14:44.900,0:14:54.260
actually, yes, it's this buffer just[br]next to the packet buffer, dedicated to a
0:14:54.260,0:15:03.240
list that we sent just before. So actually[br]we can rewrite the return address. So, how
0:15:03.240,0:15:09.940
do we exploit it now? On the 3DS, you have[br]the NX bit, but there is no stack cookies
0:15:09.940,0:15:15.500
or no ASLR, so it's pretty[br]straightforward. You can just embed a ROP-
0:15:15.500,0:15:22.790
chain, a small ROP-chain, and then send[br]another one in some kind of packets and
0:15:22.790,0:15:31.230
stack-pivot to it. And then you get remote[br]code execution in CECD. So this one was
0:15:31.230,0:15:40.350
quite easy. Let's move on to message box[br]packets. Message box packets are packets
0:15:40.350,0:15:48.290
to send a list of StreetPass messages for[br]some specific applications. They are
0:15:48.290,0:15:55.010
actually stored in some temporary files[br]for avoiding delays and they are parsed
0:15:55.010,0:16:02.080
once the communication is over. So they[br]are parsed. So let's take a look at the
0:16:02.080,0:16:15.370
parser. This is the function that actually[br]loads a temp file into an associated
0:16:15.370,0:16:24.290
structure on the stack and whoops, they do[br]not check the number of messages in the
0:16:24.290,0:16:35.010
box. So this is another buffer overflow.[br]You are basically overflowing the message
0:16:35.010,0:16:43.050
pointers array and the message sizes[br]array. So let's treat this with another
0:16:43.050,0:16:55.430
diagram. So you have on the right the temp[br]file and on the left the stack and you see
0:16:55.430,0:17:02.001
that you have this structure on the stack[br]we can see that there is the message
0:17:02.001,0:17:08.311
pointers with pointer pointing to your[br]temp file buffer and you have the message
0:17:08.311,0:17:17.520
sizes. And if you add another message in[br]the temporary file, you overflow both
0:17:17.520,0:17:26.980
arrays and start overwriting some data on[br]the stack. We are a bit concerned because
0:17:26.980,0:17:31.830
we are writing partially or uncontrolled[br]data on the stack. Obviously you cannot
0:17:31.830,0:17:39.440
control the message pointers and you can[br]not still control message size because you
0:17:39.440,0:17:44.910
can not put some arbitrary values in[br]there. You'd have to send gigabytes of
0:17:44.910,0:17:56.510
messages and you can not do that. So what[br]can we do? What you can see here is that
0:17:56.510,0:18:02.490
you can actually set the last message size[br]to an arbitrary value because they are
0:18:02.490,0:18:10.790
checking if the current message being[br]parsed is actually inside of the temporary
0:18:10.790,0:18:15.810
file, a buffer. And if the current message[br]pointer goes out of the buffer,
0:18:15.810,0:18:17.250
they break the loop
0:18:17.250,0:18:24.110
without returning an error. So what you[br]can do is set the last message size to an
0:18:24.110,0:18:30.200
arbitrary value and then the pointer will[br]go out of the buffer and you will write
0:18:30.200,0:18:39.920
one 32-bit value on the stack. But we[br]need to know what to write. You cannot,
0:18:39.920,0:18:44.990
unfortunately, you cannot directly[br]overwrite the return address because
0:18:44.990,0:18:51.810
remember that we are writing mainly[br]uncontrolled data and reaching the return
0:18:51.810,0:18:59.100
address would require you to overwrite the[br]whole stack frame with uncontrolled or
0:18:59.100,0:19:07.890
partially uncontrolled data. So the only[br]thing I was able to rewrite without
0:19:07.890,0:19:17.350
crashing the system is this particular[br]variable. It's a pointer to a critical
0:19:17.350,0:19:26.150
section and it's used for signed[br]synchronization and mutual exclusion. And
0:19:26.150,0:19:31.690
you can see it's used after the temporary[br]file has been parsed. So maybe we can do
0:19:31.690,0:19:36.870
something with it. This is the leave_critical_section[br]call at the end of the loop
0:19:36.870,0:19:42.910
iteration. And you can see that they're[br]using the pointer to decrement some kind
0:19:42.910,0:19:49.320
of count. So it's basically the number of[br]threads that are using the critical
0:19:49.320,0:19:55.970
section and we can override the lock[br]pointer. So by overwriting it, we can
0:19:55.970,0:20:03.000
decrement an arbitrary value in memory,[br]but we need to find what to overwrite,
0:20:03.000,0:20:12.860
that would give us more control of the[br]memory and control the execution flow. So
0:20:12.860,0:20:18.690
I've been looking for something like this[br]and I found something interesting in the
0:20:18.690,0:20:26.610
function that deinitialized the structure[br]associated to temporary files. This is the
0:20:26.610,0:20:34.900
function for the structure[br]deinitialization. And you can spot this
0:20:34.900,0:20:42.920
variable. They actually implemented[br]some kind of allocation mode. And if it's
0:20:42.920,0:20:49.820
equal to pointer mode, it will not try to[br]free the pointer. The pointers in the
0:20:49.820,0:20:58.480
message pointers array. But if it's not[br]pointer mode, they will free all of them.
0:20:58.480,0:21:04.390
And while this value should be pointer[br]mode in any case. But we can decrement it
0:21:04.390,0:21:13.850
using the the vulnerability we've seen[br]before. So we can get some pointer freed.
0:21:13.850,0:21:22.380
And since we control everything at the[br]location pointed by message pointers, we can
0:21:22.380,0:21:31.030
try to make it free some crafted and fake[br]chunks. But there is another problem
0:21:31.030,0:21:38.950
because they're actually resetting the[br]allocation mode each time a temporary box
0:21:38.950,0:21:48.290
is passed. So we have to find a solution[br]to this. And what you can do is try to
0:21:48.290,0:21:55.410
make that function return early before the[br]allocation mode is restored. But this
0:21:55.410,0:22:06.200
implies making it return an invalid return[br]code. But actually, it's not a problem
0:22:06.200,0:22:15.690
because they're not checking the return[br]code. So what can we do so far with
0:22:15.690,0:22:23.510
this? So you can send a first temporary[br]box. This will overwrite the lock variable
0:22:23.510,0:22:29.920
in the stack and decrement the[br]allocation mode. Then you can send your
0:22:29.920,0:22:38.460
invalid second temorary box and the[br]parser will return early and the
0:22:38.460,0:22:43.090
message pointers array will not be[br]updated. And in the end, all the pointers
0:22:43.090,0:22:51.370
in that particular array will be freed.[br]But since the message pointers array is
0:22:51.370,0:22:57.750
not updated, the pointer in that[br]particular array are still pointing to the
0:22:57.750,0:23:05.850
first temporary file buffer[br]which has been freed. That's not a
0:23:05.850,0:23:11.580
problem. If you send a xecond temporary[br]box with the same size, the buffer will be
0:23:11.580,0:23:15.760
re-allocated for that second[br]temporary file and we eventually free
0:23:15.760,0:23:25.930
up pointers to control the buffer. So[br]what's next? We can craft some fake heap
0:23:25.930,0:23:32.920
chunks. We can have the application free[br]them. What do we do? The free, yes, it is
0:23:32.920,0:23:39.070
actually really insecure. You can exploit[br]the classic unsafe linker vulnerability,
0:23:39.070,0:23:47.650
so you get one arbitrary write for each[br]chunk you can free. And you still need to
0:23:47.650,0:23:56.730
know what to overwrite. But you can just[br]rewrite the heap free list head pointer. So the
0:23:56.730,0:24:04.350
next malloc call will return a pointer to[br]wherever you want, and you can especially
0:24:04.350,0:24:10.470
put a pointer to the stack in there. So[br]the next malloc call will return a
0:24:10.470,0:24:20.990
pointer to the stack and it will be used[br]to store your third temporary file. So
0:24:20.990,0:24:29.460
it's a bit hard to understand. So let's[br]again illustrate this with a diagram. So
0:24:29.460,0:24:35.670
first you have your first temporary file[br]loaded in memory. So on the right it's
0:24:35.670,0:24:49.440
parsed and the associated structure is[br]written in stack and it overwrites the
0:24:49.440,0:24:57.510
lock pointer to make it point to the alloc[br]mode in memory. In the end,
0:24:57.510,0:25:05.070
leave_critical_section is called. So you have[br]your temporary buffer freed and your location
0:25:05.070,0:25:13.540
mode decremented. Then your second[br]temporary file is loaded in memory. The
0:25:13.540,0:25:19.160
buffer used for the first[br]file is relocated and the pointers in the
0:25:19.160,0:25:26.180
structure still point to our[br]controlled data and especially our fake
0:25:26.180,0:25:39.480
chunks. So your second temporary file is[br]loaded and parsed. Then all the chunks are
0:25:39.480,0:25:49.100
freed and the field it is at is moved to[br]point on the stack. And finally, you can
0:25:49.100,0:25:54.360
see that your last temporary file is[br]read in on the stack so we can overwrite
0:25:54.360,0:26:00.890
the return address and put a ROP-chain in[br]there. So this gives us a second remote
0:26:00.890,0:26:10.070
code execution vulnerability in CECD. And[br]this one this one was quite trickier. So
0:26:10.070,0:26:18.650
what's next? Another one. Yeah. Again,[br]there is another vulnerability in the
0:26:18.650,0:26:29.880
message parser. It's actually an SDK[br]function. So any application that uses
0:26:29.880,0:26:33.970
SteetPass is vulnerable, not only CECD but[br]all application and games that use
0:26:33.970,0:26:36.360
StreetPass are vulnerable for this one.
0:26:36.360,0:26:41.010
But I'm not going[br]to talk about it and explain everything.
0:26:41.010,0:26:50.590
It's up to you to exploit it. So this[br]gives us a third Remote Code Execution in
0:26:50.590,0:26:57.450
CECD and you can get Code Execution in any[br]application using StreetPass. And this
0:26:57.450,0:27:06.260
also give us a persistent backdoor in CECD[br]because of CECD usually parses all the
0:27:06.260,0:27:15.260
messages in the in and out boxes at startup.[br]So you can trigger the vulnerability
0:27:15.260,0:27:25.270
once the system boots. So we've got a[br]Remote Code Execution in CECD, what can we
0:27:25.270,0:27:34.730
do? No, actually, CECD does not have much[br]privileges. It's only a userspace
0:27:34.730,0:27:41.090
application. And it's pretty well[br]sandboxed. You can not access the
0:27:41.090,0:27:49.230
internet, for example or not the SD card.[br]So if you want more privileges and we
0:27:49.230,0:27:57.131
want more privileges, you need to take[br]care of something else. And your
0:27:57.131,0:28:04.980
best choice would be trying to take over[br]ARM11 Kernel, which is the kernel for the
0:28:04.980,0:28:13.590
userland processor. This this would give[br]you total control over this processor.
0:28:13.590,0:28:18.490
And if you want really full system[br]control, you'd like to also take over the
0:28:18.490,0:28:25.600
ARM9 security processor. So this is the[br]processor that do all the encryption and
0:28:25.600,0:28:34.590
signature stuff. And we will see this[br]later. So let's first try to take over the
0:28:34.590,0:28:46.470
ARM11 kernel. But first, I need to[br]talk about IPC and especially
0:28:46.470,0:28:55.640
what are called static buffers. So when[br]you are doing IPC, you need to sometimes
0:28:55.640,0:29:03.460
send data from a sender process to a[br]receiver process and on the 3DS, you can
0:29:03.460,0:29:12.170
do this in multiple ways. The first one is[br]if you want to send large regular
0:29:12.170,0:29:20.020
buffers, you can map parts of the sender's[br]memory into the receivers, but you can
0:29:20.020,0:29:27.020
also use what are called static buffers.[br]If you want to send some small buffers,
0:29:27.020,0:29:34.670
the receiver can register static buffers[br]and the ARM11 kernel will do the copy for
0:29:34.670,0:29:42.010
you to that particular buffer. And[br]sometimes you need some buffers
0:29:42.010,0:29:51.870
to be sent to the ARM9[br]processor. So the ARM11 kernel need to
0:29:51.870,0:29:59.000
write some pairs of[br]physical addresses and size to the static
0:29:59.000,0:30:05.560
buffers because the ARM9 does not have an[br]MMU so it's only using physical addresses
0:30:05.560,0:30:14.970
and the copy of data is eventually done by[br]the Process9, which is the only process
0:30:14.970,0:30:23.760
running on the ARM9 side. So let's talk[br]about a vulnerability now. So it's called
0:30:23.760,0:30:32.997
LazyPixie and it has been found by TuxSH.[br]So it's not me. How does the kernel handle the
0:30:32.997,0:30:44.604
PXI buffers case because it[br]seems a bit complicated. So first
0:30:44.604,0:30:48.790
they check the alignment of the[br]destination state buffer, they check the
0:30:48.790,0:30:54.250
size of the destination static buffer.[br]They check the permissions for the source
0:30:54.250,0:31:01.100
buffers. Then they do cache operations, they[br]copy metadata. So the physical address and
0:31:01.100,0:31:09.480
the size of the static buffer[br]to the destination and then the copy is
0:31:09.480,0:31:15.830
done by the ARM9 side. But I think[br]there is something missing here because
0:31:15.830,0:31:23.870
they do not check the permissions for the[br]destination buffer. So what you can do is
0:31:23.870,0:31:30.440
use an arbitrary address as a destination.[br]And so you can just overwrite the MMU
0:31:30.440,0:31:37.860
table and make your kernnel read, write and[br]execute, which is obviously enough to take
0:31:37.860,0:31:48.890
it over. So at that point, the ARM11[br]Kernel has fallen and we have
0:31:48.890,0:31:58.740
the full control of that processor. But we[br]would like a bit more privileges because
0:31:58.740,0:32:07.640
why not? We want the full system control.[br]So let's take the road to full system
0:32:07.640,0:32:15.770
control and see why taking over CECD was[br]one of the best ideas ever. So I am going
0:32:15.770,0:32:22.410
to talk about SAFEHAX. Maybe some of you[br]know what SAFEHAX is because it's a really
0:32:22.410,0:32:31.870
cool vulnerability. It's actually race a[br]condition in the firmware header parsing
0:32:31.870,0:32:38.410
you can take over the ARM9 side if you[br]control the ARM11 kernel. It has
0:32:38.410,0:32:47.170
been fixed in the system version 9.5 for[br]the regular native firmware
0:32:47.170,0:32:52.020
and fixed in the safe mode firmware, which[br]is basically the recovery firmware if
0:32:52.020,0:32:58.330
something went wrong for your console. So[br]people have been exploiting it both on the
0:32:58.330,0:33:04.780
native firmware and the[br]safe mode firmware and it has been
0:33:04.780,0:33:12.960
mitigated in version 11.3 and 11.4. So it[br]does not work anymore, but it has only
0:33:12.960,0:33:19.800
been mitigated and not patched. So let's[br]take a look at that mitigation because
0:33:19.800,0:33:26.559
how do they prevent us to exploit that[br]vulnerability? So this so-called
0:33:26.559,0:33:36.820
mitigation is a boolean flag that has been[br]added on the ARM9 side and when it's set to
0:33:36.820,0:33:48.559
1 the system just panics. When you try to[br]launch the safe mode firmware. So this
0:33:48.559,0:33:53.140
flag is actually set to 1 whenever you try[br]to launch an application, so this was the
0:33:53.140,0:33:59.490
usual way to exploit it, you were[br]launching the homebrew menu through an
0:33:59.490,0:34:07.070
application and then exploiting the ARM11[br]kernel and then running SAFEHAX. So they
0:34:07.070,0:34:13.549
set the flag to 1 whenever you try to[br]launch a specific application, except some
0:34:13.549,0:34:22.240
of them because your reconnection ARMs needs some[br]applications to run. So this is there is
0:34:22.240,0:34:29.270
an exception for the home menu and the[br]system modules. And guess what? We are
0:34:29.270,0:34:35.270
exploiting CCD, which is a system module[br]and we are getting Remote Code Execution
0:34:35.270,0:34:43.090
in CCD. So the the flag is never set to 1[br]when we are getting code executing on the
0:34:43.090,0:34:52.630
CCD. So with that kind of exploit. You can[br]easily replicate the initial SAFEHAX
0:34:52.630,0:35:02.830
exploit. So then you get a full control,[br]remote code execution without any user
0:35:02.830,0:35:10.130
interaction. And it's StreetPass and it's[br]doing all of this thing in the background
0:35:10.130,0:35:16.320
and on any firmwre version at the time[br]this was developed because Nintendo
0:35:16.320,0:35:28.520
patched it with firmware version 11.12. So[br]I guess it's time for a little demo. I'm
0:35:28.520,0:35:37.550
not going to do it live because I don't[br]want to some exploits in the air. So I
0:35:37.550,0:35:46.300
have a little video. So I'm running my[br]exploit on my laptop and you can see the
0:35:46.300,0:35:52.850
LED is turned on to see that the exploit[br]is running in CCD. And then you once
0:35:52.850,0:35:59.700
you're you can exploit and you can launch[br]the installer for the Boot ROM exploit,
0:35:59.700,0:36:10.460
for example.[br]applause
0:36:10.460,0:36:24.140
Thanks. So now, some some takeaways. Well,[br]you'd better check your return value,
0:36:24.140,0:36:28.960
really, because there's a second[br]vulnerability would have been really,
0:36:28.960,0:36:41.800
really out to exploit without that[br]mistake. And really, you should not hide
0:36:41.800,0:36:47.910
behind cryptography because one day your[br]encryption will be broken and this might
0:36:47.910,0:36:59.650
come sooner than you think. And for this[br]specific case, there was a bunch of dumb
0:36:59.650,0:37:09.190
mistakes and basically all vulnerabilities[br]were only buffer overflows. Then,
0:37:09.190,0:37:16.900
assessing hard-to-reach features is really[br]arduous. I spent a lot of time doing this,
0:37:16.900,0:37:26.480
especially figuring out how to replicate[br]all the features, parts and all the
0:37:26.480,0:37:32.830
different protocols involved. But[br]eventually, you can get some really
0:37:32.830,0:37:41.090
interesting results like this. Then, I'd[br]say please fix your flows, and do not
0:37:41.090,0:37:50.760
implement some poor mitigation, like for[br]SAFEHAX. And there's things still to do on
0:37:50.760,0:37:57.340
the 3DS. I think I was able to show this[br]today. There is, this is an amazing system
0:37:57.340,0:38:03.830
you can start to work on and do some[br]practical things. And there's still things
0:38:03.830,0:38:13.490
to document on the open source wiki, so[br]feel free to contribute. So, in the end, I
0:38:13.490,0:38:25.220
would like to thank @TuxSH for the[br]LazyPixie and helping me getting this full
0:38:25.220,0:38:39.270
chain exploit done, and @hedgeberg for[br]recurring support with a lot of things. So
0:38:39.270,0:38:45.230
now, if you have some questions, feel free[br]to ask.
0:38:45.230,0:38:50.930
Herald: Thank you very much.
0:38:50.930,0:38:54.640
applause
0:38:54.640,0:39:02.080
Herald: We are very, very much on time. So[br]ask any questions, but please do ask them
0:39:02.080,0:39:13.609
at a microphone. Go ahead. No, I thought[br]there was going to ask a question. No
0:39:13.609,0:39:21.200
questions? Oh, the Internet has one.[br]Great.
0:39:21.200,0:39:29.230
Signal angel: So, yes, we have two[br]questions. The first one is what tools and
0:39:29.230,0:39:34.220
environments do you use for your research?[br]For example, someone mentioned how do you
0:39:34.220,0:39:40.970
get all the source code?[br]nba::yoh: Oh, everything on the 3DS is
0:39:40.970,0:39:50.410
closed source. So you have to reverse[br]engineer everything. I used IDA and Ghidra
0:39:50.410,0:39:57.390
to reverse the binaries of CCD and, yeah,[br]that, that's it.
0:39:57.390,0:40:08.320
Signal angel: OK. Thank you. We have a[br]second question: Is there any procedure
0:40:08.320,0:40:13.200
for the Switch that is compatible with all[br]what you've done?
0:40:13.200,0:40:16.109
nba::yoh: Sorry, could you repeat that[br]question?
0:40:16.109,0:40:23.330
Signal angel: Well, all the things you[br]have done, all the code. Is there anything
0:40:23.330,0:40:28.430
similar for the Switch?[br]nba::yoh: I don't think there is something
0:40:28.430,0:40:37.420
similar on the Switch, at least something[br]that looks like the StreetPass feature.
0:40:37.420,0:40:44.420
But I don't really know how the Switch[br]works, I've only done things on the 3DS.
0:40:44.420,0:40:51.930
Herald: OK, first question for the room.[br]Microphone: Thanks for the talk, great.
0:40:51.930,0:40:57.800
Did you really need all the three[br]exploits? And which one did you use in the
0:40:57.800,0:41:03.450
end for the full chain? Thanks.[br]nba::yoh: Could you repeat the question?
0:41:03.450,0:41:07.870
Microphone: Did you need all the three[br]exploits that you had or could you just
0:41:07.870,0:41:11.990
use the easiest one? And which one did you[br]use in the end?
0:41:11.990,0:41:19.650
nba::yoh: Well, no, you do not need all[br]three exploits, at least in CCD. You only
0:41:19.650,0:41:30.369
need one basically to get remote code[br]execution. But I found it fun to just show
0:41:30.369,0:41:35.570
all the exploits for CCD.[br]Herald: Next question.
0:41:35.570,0:41:40.080
Microphone: Are the StreetPass messages[br]passed to the applications even when those
0:41:40.080,0:41:44.030
applications are not running? So, for[br]example, when you have like Pokémon or
0:41:44.030,0:41:46.670
something installed...[br]nba::yoh: Could you speak louder, please?
0:41:46.670,0:41:51.260
Microphone: Okay. Are the applications[br]parsing the messages even if they are not
0:41:51.260,0:41:55.450
running? Like, is there some sort of a[br]handler being run by the OS even if you
0:41:55.450,0:41:59.930
don't have an application running, just[br]installed? So that if you have a
0:41:59.930,0:42:06.150
vulnerable application with the old SDK[br]built in there, will it automatically
0:42:06.150,0:42:15.050
parse the corrupted message?[br]nba::yoh: Could you reformulate your
0:42:15.050,0:42:19.050
question? I don't understand.[br]Microphone: Okay. In your tree
0:42:19.050,0:42:24.930
exploitation method, you mentioned the[br]third method that mentions the SDK being
0:42:24.930,0:42:26.930
broken.[br]nba::yoh: Yeah.
0:42:26.930,0:42:31.490
Microphone: And if you have an application[br]built with that old SDK, does it
0:42:31.490,0:42:36.280
automatically parse the message even if[br]it's not running, so that even if you have
0:42:36.280,0:42:41.390
a patched OS, but not patched[br]applications, it will still get exploited?
0:42:41.390,0:42:49.001
nba::yoh: Yeah, all the applications using[br]the SDK should be updated to fix the
0:42:49.001,0:42:59.950
vulnerability. So the exploit is triggered[br]when the application parsed the messages.
0:42:59.950,0:43:10.541
So you have to run the application to[br]exploit it. CCD has been patched, so there
0:43:10.541,0:43:20.930
is no more remote code execution in CCD,[br]nor a permanent backdoor in CCD, that
0:43:20.930,0:43:29.160
automatically runs, when the system is[br]started. But you can probably still
0:43:29.160,0:43:34.430
exploit games and applications that use[br]the old SDK.
0:43:34.430,0:43:39.160
Microphone: Okay, thanks.[br]Herald: There's a question over there.
0:43:39.160,0:43:44.099
Microphone: Yes. Can you go back to the[br]slide where you showed how the encryption
0:43:44.099,0:43:46.610
for the packets worked?[br]nba::yoh: The encryption?
0:43:46.610,0:44:12.359
Microphone: Yes, the encryption. Yeah.[br]Yeah. That one. So my question is, if all
0:44:12.359,0:44:18.720
you're, if the only thing that you're[br]changing is the counter, and the data is
0:44:18.720,0:44:24.160
constant and the key is constant, and it's[br]CTR, then you're basically just XOring a
0:44:24.160,0:44:33.770
known block with your HMAC output. So why[br]do you even need the key here?
0:44:33.770,0:44:42.910
nba::yoh: Well, the counter changed every[br]time you start a new StreetPass
0:44:42.910,0:44:50.440
communication, because the CID's are[br]randomized and the MAC address is, the MAC
0:44:50.440,0:44:55.560
address is also randomized before starting[br]a new communication.
0:44:55.560,0:45:01.270
Microphone: Right. But I guess what I'm[br]asking is, why do you need key slot 2E? In
0:45:01.270,0:45:08.310
my mind, having the CCD HMAC key would be[br]enough, because you can just XOR the, you
0:45:08.310,0:45:13.920
know, output of that with the final[br]output, and that removes, you know, the
0:45:13.920,0:45:20.280
CTR part, and now you have the raw output[br]of the null block encrypted with key slot
0:45:20.280,0:45:27.109
2E, which is always going to be constant,[br]and then you can just XOR whatever output
0:45:27.109,0:45:32.600
to get the final result, right?[br]nba::yoh: Yeah, well I'm not super
0:45:32.600,0:45:41.560
familiar with all the cryptography, but[br]maybe we could talk about it. I was just
0:45:41.560,0:45:50.770
putting this for, for people to reproduce[br]it if they want.
0:45:50.770,0:46:01.580
Herald: Okay. Are there any more[br]questions? Thank you so much.
0:46:01.580,0:46:03.550
nba::yoh: Thanks.
0:46:03.550,0:46:04.550
applause
0:46:04.550,0:46:07.635
postroll music
0:46:07.635,0:46:29.000
subtitles created by c3subtitles.de[br]in the year 2020. Join, and help us!