1
00:00:00,000 --> 00:00:19,781
36C3 preroll music
2
00:00:22,710 --> 00:00:26,439
Herald: The following talk is titled "It's
Not Safe in the Streets, especially for
3
00:00:26,439 --> 00:00:31,430
your 3DS" and it's about exploring a new
attack surface on the 3DS. And the speaker
4
00:00:31,430 --> 00:00:36,270
is nba::yoh. The show is yours.
5
00:00:36,270 --> 00:00:42,190
applause
6
00:00:43,297 --> 00:00:49,879
nba::yoh: Hi, everyone. I'm nba::yoh and
today I'm going to talk about 3DS hacking
7
00:00:49,879 --> 00:01:01,109
and especially about a protocol, an
undocumented protocol. And we're gonna see
8
00:01:01,109 --> 00:01:10,580
how I attacked the protocol and got remote
code execution on the system. But before
9
00:01:10,580 --> 00:01:18,229
before saying, oh, I did that, I'd like to
do a quick recap of the state of 3DS
10
00:01:18,229 --> 00:01:27,100
hacking in 2019, because there have been a
lot of userland exploits, a lot of patched
11
00:01:27,100 --> 00:01:33,030
kernel flaws and there's a lot of
documentation online about the system. And
12
00:01:33,030 --> 00:01:41,420
during the last few years, people have
been working on it and broke the hardware
13
00:01:41,420 --> 00:01:49,509
keyscambler. And they managed to dump the
bootroms. And as a result, anyone who now
14
00:01:49,509 --> 00:01:57,899
have the bootrom can derive all the secret
keys of the system. And as a bonus, they
15
00:01:57,899 --> 00:02:03,700
were able to find a permanent unpatchable
bootrom exploit. So at that point, you
16
00:02:03,700 --> 00:02:11,040
might be wondering what's left to do in
the system. And actually, I wonder if it
17
00:02:11,040 --> 00:02:16,620
would be possible to use those keys to
attack features that were protected until
18
00:02:16,620 --> 00:02:22,475
then by encryption. So that's why today
I'm going to talk about StreetPass.
19
00:02:25,059 --> 00:02:30,650
First, I'm going to do a quick introduction about
the feature and then we'll see how I
20
00:02:30,650 --> 00:02:39,240
expoited it and see what's possible to do
once you get code execution. So what is
21
00:02:39,240 --> 00:02:45,790
StreetPass? This is a local and wireless
communication feature. The basic idea
22
00:02:45,790 --> 00:02:51,980
behind StreetPass was that users would
take their 3DS with them and go out and it
23
00:02:51,980 --> 00:02:59,989
would automatically communicate with other
people's systems. The point of the feature
24
00:02:59,989 --> 00:03:07,180
was to share data between applications
like custom levels for your games or
25
00:03:07,180 --> 00:03:14,800
messages, avatars, et cetera. So this is
quite an interesting feature for players,
26
00:03:14,800 --> 00:03:21,930
but also for hackers. So this is the
player point of view so you can send your
27
00:03:21,930 --> 00:03:29,209
messages and other people will be able to
receive them. But we'd like to - from an
28
00:03:29,209 --> 00:03:34,510
hacker point of view - we'd like to
replace one of these systems with a PC to
29
00:03:34,510 --> 00:03:40,629
tamper with the protocol, for example. And
eventually it would be nice if we could
30
00:03:40,629 --> 00:03:48,021
send some corrupted messages and see if we
can get code execution on foreign systems.
31
00:03:49,621 --> 00:03:54,663
But for doing that, you need to know how
the street the StreetPass feature works.
32
00:03:55,845 --> 00:04:01,319
So it's quite simple. It acts like a mailbox.
So you have CECD, which is a system
33
00:04:01,319 --> 00:04:10,829
module, and it's the only one that manages
all this StreetPass feature. So all your
34
00:04:10,829 --> 00:04:18,370
applications have an inbox and an
associated outbox in the CECD file system
35
00:04:18,370 --> 00:04:27,320
and they can put and get messages from and
to these boxes via IPC. Then messages in
36
00:04:27,320 --> 00:04:32,390
these boxes are used to craft packets
which are then sent using the StreetPass
37
00:04:32,390 --> 00:04:40,610
protocol. And we can already see on this
diagram which path we could try to attack.
38
00:04:40,610 --> 00:04:47,220
The first one you might think about are
our application boxes because it's very
39
00:04:47,220 --> 00:04:53,750
likely that you'll be able to find some kind
of game or application that have a float
40
00:04:53,750 --> 00:05:02,890
parser. So we might take and get remote
code execution in such an application. But
41
00:05:02,890 --> 00:05:10,960
the most interesting one would be to try
to attack CECDs parser. And this would
42
00:05:10,960 --> 00:05:19,290
give us remote code execution in a system
module, which would be nice. But for doing
43
00:05:19,290 --> 00:05:25,060
that, we need to figure out how the
StreetPass protocol works and nobody
44
00:05:25,060 --> 00:05:31,069
really knows how it works. There is a bit
of documentation online about the
45
00:05:31,069 --> 00:05:36,419
pairings, so "oh both our systems are
seeing a hand here. Would like would you
46
00:05:36,419 --> 00:05:42,410
like to communicate with me?" But it has
never been successfully reproduced, at
47
00:05:42,410 --> 00:05:49,600
least publicly. And we know that it's
using an unknown and encrypted protocol
48
00:05:49,600 --> 00:05:58,900
that uses the secret AES key that we can
now get. So let's reverse the protocol.
49
00:05:58,900 --> 00:06:08,100
First, well, let's reverse the pairing and
replicate it. So it's fairly easy to
50
00:06:08,100 --> 00:06:15,360
understand: You have both peers, the
client and the master and before
51
00:06:15,360 --> 00:06:23,169
communicating they randomize their console
ID and their MAC address. Then the client
52
00:06:23,169 --> 00:06:32,460
sends a bunch of probe requests with our
bundle specific tag, containing a list of
53
00:06:32,460 --> 00:06:37,940
the applications that have StreetPass
activated. And then eventually the master
54
00:06:37,940 --> 00:06:45,110
received that public list and analyzes it.
It's checked if an application from the
55
00:06:45,110 --> 00:06:50,419
client that has StreetPass activated
matches one of it's own applications with
56
00:06:50,419 --> 00:06:55,680
StreetPass activated. If it's the case, it
sends the probe response to the client,
57
00:06:55,680 --> 00:07:02,160
which will do the same. And if both peers
agree that they can exchange data, they
58
00:07:02,160 --> 00:07:11,430
will start communicating after deriving a
common key. So replicating the pairing is
59
00:07:11,430 --> 00:07:20,810
not super odd if you know what tool to
use. I tried to reproduce the pairing
60
00:07:20,810 --> 00:07:28,470
using a monitor mode, but it's really hard
because you have to deal with all the
61
00:07:28,470 --> 00:07:38,009
action item frames et cetera. So I used
nl80211 which lets you register some
62
00:07:38,009 --> 00:07:44,470
specific callback for some specific frames
and send custom frames and everything is
63
00:07:44,470 --> 00:07:53,590
handled by your wifi adapter driver. So at
that point the 3DS starts sending
64
00:07:53,590 --> 00:08:00,827
encrypted data and we have to decrypt
them. So let's review the encryption. They
65
00:08:00,827 --> 00:08:09,979
do this in two passes, the first one they
use an HMAC-SHA1 over both consoles CIDs
66
00:08:09,979 --> 00:08:18,270
and both MAC addresses and the output of
this pass is used as an input counter for
67
00:08:18,270 --> 00:08:28,659
on AES-CTR using the AES key slot we can
now get. And the output of this encryption
68
00:08:28,659 --> 00:08:37,570
is used as a session key for the
communication. So nl80211 lets you
69
00:08:37,570 --> 00:08:45,530
register CCMP keys so it's quite easy to
send and receive encrypted packets using
70
00:08:45,530 --> 00:08:56,470
it. So now we can start reversing the
protocol. Let's take a look at the
71
00:08:56,470 --> 00:09:04,100
structure of packets before doing any
reverse engineering. So I put some packets
72
00:09:04,100 --> 00:09:09,544
I was able to receive and the first one is
one of the smallest one you can actually
73
00:09:09,544 --> 00:09:19,450
observe. So first you have a header and
then you have some data and you can spot
74
00:09:19,450 --> 00:09:26,830
some magic values here. Actually, it's
easy to spot them because CECD is using
75
00:09:26,830 --> 00:09:35,890
really recognizable magic values. It's
always the same byte repeated twice. Once
76
00:09:35,890 --> 00:09:40,520
you know the structure of the packets, you
can view that there are actually
77
00:09:40,520 --> 00:09:49,340
two protocols. The first one is SPTCP.
It's an equivalent of TCP, but for local
78
00:09:49,340 --> 00:09:55,380
communication. It's mainly designed to
ensure reliability and data segmentation.
79
00:09:55,380 --> 00:10:03,790
And then you have SPMTP which is built
over SPTCP and handles all the exchange of
80
00:10:03,790 --> 00:10:11,060
stricter data and StreetPass messages. So
we have two protocols and we need to
81
00:10:11,060 --> 00:10:18,290
review both of them. Let's start with
SPTCP. Actually, there is not much to say
82
00:10:18,290 --> 00:10:29,090
because you only basically have to reverse
and understand the header. You have a
83
00:10:29,090 --> 00:10:33,570
magic value and some constants. But the
most important field here is the flag
84
00:10:33,570 --> 00:10:39,100
field because if you can understand what
are the flags, you can understand the
85
00:10:39,100 --> 00:10:45,760
meaning of the packets you are sending and
receiving. And so you can basically
86
00:10:45,760 --> 00:10:53,710
understand the protocol. And fortunately,
in this case, they're using the same flags
87
00:10:53,710 --> 00:11:01,950
as TCP, so it was really easy to
understand the protocol and how it worked.
88
00:11:01,950 --> 00:11:13,590
And what about SPTCP security? Actually,
it's OK. I did not find any bug. But the
89
00:11:13,590 --> 00:11:19,140
attack surface is really small. We can
basically only tamper with the header and
90
00:11:19,140 --> 00:11:31,460
that's it. So SPMTP should be much more
interesting. Let's take a look at the
91
00:11:31,460 --> 00:11:40,420
structure of SPMTP packets, because there
are actually two different packet types.
92
00:11:40,420 --> 00:11:49,900
The first one is an info packet. It's
basically used in the handshake and it's
93
00:11:49,900 --> 00:11:56,920
only here to share information between
both peers. And then you have message box
94
00:11:56,920 --> 00:12:03,120
packets which are much more interesting
because they contain actual StreetPass
95
00:12:03,120 --> 00:12:11,360
data and you can even spot the CECD
message via magic value, which means that
96
00:12:11,360 --> 00:12:17,650
we actually reach actual game data and
SPMTP is the last layer of encapsulation
97
00:12:17,650 --> 00:12:26,050
of the whole protocol. So once you figure
out how SPMTP works, you can reimplement
98
00:12:26,050 --> 00:12:33,660
the protocol. So let's first review info
packets. There's a bunch of things in
99
00:12:33,660 --> 00:12:40,440
here. Many fixed size data like friend
codes, MAC addresses, et cetera. It's not
100
00:12:40,440 --> 00:12:46,750
much interesting when you're looking for
vulnerabilities. There are variable size
101
00:12:46,750 --> 00:12:51,560
data, which are much more interesting.
They are sending application lists,
102
00:12:51,560 --> 00:12:59,450
metadata lists, and it's much more
interesting because when you process them,
103
00:12:59,450 --> 00:13:06,260
you can fail your parser. And if there is
some vulnerability here, we might exploit
104
00:13:06,260 --> 00:13:14,720
them to get remote execution. So let's
take a look at one of this parser. This is
105
00:13:14,720 --> 00:13:23,700
a function that parses meta data lists. So
let's focus on the for-loop. They are
106
00:13:23,700 --> 00:13:33,740
actually copying a list of entries to the
stack. The destination is on the stack and
107
00:13:33,740 --> 00:13:41,110
they do not check the number of entries in
the list. So this is clearly a buffer
108
00:13:41,110 --> 00:13:48,420
overflow, but is it exploitable? Let's
illustrate this with a diagram. So this is
109
00:13:48,420 --> 00:13:57,130
a regular copy. So you have your packet
buffer. And you have memcopy called on
110
00:13:57,130 --> 00:14:08,770
each entry and everything's is all right
here. But if you had more entries, you
111
00:14:08,770 --> 00:14:15,690
have a bunch of entries, compete on the
stack, that overwrite a bunch of things.
112
00:14:15,690 --> 00:14:21,810
But there's a problem here, because the
packet buffer is not large enough for us
113
00:14:21,810 --> 00:14:32,680
to reach the return address on the stack.
So we are probably copying uncontrol data.
114
00:14:32,680 --> 00:14:39,430
So I was like, it's too bad, we can't do
anything with this, but let's check the
115
00:14:39,430 --> 00:14:44,900
buffer next to our packet buffer. Maybe
there are some control data in there. And
116
00:14:44,900 --> 00:14:54,260
actually, yes, it's this buffer just
next to the packet buffer, dedicated to a
117
00:14:54,260 --> 00:15:03,240
list that we sent just before. So actually
we can rewrite the return address. So, how
118
00:15:03,240 --> 00:15:09,940
do we exploit it now? On the 3DS, you have
the NX bit, but there is no stack cookies
119
00:15:09,940 --> 00:15:15,500
or no ASLR, so it's pretty
straightforward. You can just embed a ROP-
120
00:15:15,500 --> 00:15:22,790
chain, a small ROP-chain, and then send
another one in some kind of packets and
121
00:15:22,790 --> 00:15:31,230
stack-pivot to it. And then you get remote
code execution in CECD. So this one was
122
00:15:31,230 --> 00:15:40,350
quite easy. Let's move on to message box
packets. Message box packets are packets
123
00:15:40,350 --> 00:15:48,290
to send a list of StreetPass messages for
some specific applications. They are
124
00:15:48,290 --> 00:15:55,010
actually stored in some temporary files
for avoiding delays and they are parsed
125
00:15:55,010 --> 00:16:02,080
once the communication is over. So they
are parsed. So let's take a look at the
126
00:16:02,080 --> 00:16:15,370
parser. This is the function that actually
loads a temp file into an associated
127
00:16:15,370 --> 00:16:24,290
structure on the stack and whoops, they do
not check the number of messages in the
128
00:16:24,290 --> 00:16:35,010
box. So this is another buffer overflow.
You are basically overflowing the message
129
00:16:35,010 --> 00:16:43,050
pointers array and the message sizes
array. So let's treat this with another
130
00:16:43,050 --> 00:16:55,430
diagram. So you have on the right the temp
file and on the left the stack and you see
131
00:16:55,430 --> 00:17:02,001
that you have this structure on the stack
we can see that there is the message
132
00:17:02,001 --> 00:17:08,311
pointers with pointer pointing to your
temp file buffer and you have the message
133
00:17:08,311 --> 00:17:17,520
sizes. And if you add another message in
the temporary file, you overflow both
134
00:17:17,520 --> 00:17:26,980
arrays and start overwriting some data on
the stack. We are a bit concerned because
135
00:17:26,980 --> 00:17:31,830
we are writing partially or uncontrolled
data on the stack. Obviously you cannot
136
00:17:31,830 --> 00:17:39,440
control the message pointers and you can
not still control message size because you
137
00:17:39,440 --> 00:17:44,910
can not put some arbitrary values in
there. You'd have to send gigabytes of
138
00:17:44,910 --> 00:17:56,510
messages and you can not do that. So what
can we do? What you can see here is that
139
00:17:56,510 --> 00:18:02,490
you can actually set the last message size
to an arbitrary value because they are
140
00:18:02,490 --> 00:18:10,790
checking if the current message being
parsed is actually inside of the temporary
141
00:18:10,790 --> 00:18:15,810
file, a buffer. And if the current message
pointer goes out of the buffer,
142
00:18:15,810 --> 00:18:17,250
they break the loop
143
00:18:17,250 --> 00:18:24,110
without returning an error. So what you
can do is set the last message size to an
144
00:18:24,110 --> 00:18:30,200
arbitrary value and then the pointer will
go out of the buffer and you will write
145
00:18:30,200 --> 00:18:39,920
one 32-bit value on the stack. But we
need to know what to write. You cannot,
146
00:18:39,920 --> 00:18:44,990
unfortunately, you cannot directly
overwrite the return address because
147
00:18:44,990 --> 00:18:51,810
remember that we are writing mainly
uncontrolled data and reaching the return
148
00:18:51,810 --> 00:18:59,100
address would require you to overwrite the
whole stack frame with uncontrolled or
149
00:18:59,100 --> 00:19:07,890
partially uncontrolled data. So the only
thing I was able to rewrite without
150
00:19:07,890 --> 00:19:17,350
crashing the system is this particular
variable. It's a pointer to a critical
151
00:19:17,350 --> 00:19:26,150
section and it's used for signed
synchronization and mutual exclusion. And
152
00:19:26,150 --> 00:19:31,690
you can see it's used after the temporary
file has been parsed. So maybe we can do
153
00:19:31,690 --> 00:19:36,870
something with it. This is the leave_critical_section
call at the end of the loop
154
00:19:36,870 --> 00:19:42,910
iteration. And you can see that they're
using the pointer to decrement some kind
155
00:19:42,910 --> 00:19:49,320
of count. So it's basically the number of
threads that are using the critical
156
00:19:49,320 --> 00:19:55,970
section and we can override the lock
pointer. So by overwriting it, we can
157
00:19:55,970 --> 00:20:03,000
decrement an arbitrary value in memory,
but we need to find what to overwrite,
158
00:20:03,000 --> 00:20:12,860
that would give us more control of the
memory and control the execution flow. So
159
00:20:12,860 --> 00:20:18,690
I've been looking for something like this
and I found something interesting in the
160
00:20:18,690 --> 00:20:26,610
function that deinitialized the structure
associated to temporary files. This is the
161
00:20:26,610 --> 00:20:34,900
function for the structure
deinitialization. And you can spot this
162
00:20:34,900 --> 00:20:42,920
variable. They actually implemented
some kind of allocation mode. And if it's
163
00:20:42,920 --> 00:20:49,820
equal to pointer mode, it will not try to
free the pointer. The pointers in the
164
00:20:49,820 --> 00:20:58,480
message pointers array. But if it's not
pointer mode, they will free all of them.
165
00:20:58,480 --> 00:21:04,390
And while this value should be pointer
mode in any case. But we can decrement it
166
00:21:04,390 --> 00:21:13,850
using the the vulnerability we've seen
before. So we can get some pointer freed.
167
00:21:13,850 --> 00:21:22,380
And since we control everything at the
location pointed by message pointers, we can
168
00:21:22,380 --> 00:21:31,030
try to make it free some crafted and fake
chunks. But there is another problem
169
00:21:31,030 --> 00:21:38,950
because they're actually resetting the
allocation mode each time a temporary box
170
00:21:38,950 --> 00:21:48,290
is passed. So we have to find a solution
to this. And what you can do is try to
171
00:21:48,290 --> 00:21:55,410
make that function return early before the
allocation mode is restored. But this
172
00:21:55,410 --> 00:22:06,200
implies making it return an invalid return
code. But actually, it's not a problem
173
00:22:06,200 --> 00:22:15,690
because they're not checking the return
code. So what can we do so far with
174
00:22:15,690 --> 00:22:23,510
this? So you can send a first temporary
box. This will overwrite the lock variable
175
00:22:23,510 --> 00:22:29,920
in the stack and decrement the
allocation mode. Then you can send your
176
00:22:29,920 --> 00:22:38,460
invalid second temorary box and the
parser will return early and the
177
00:22:38,460 --> 00:22:43,090
message pointers array will not be
updated. And in the end, all the pointers
178
00:22:43,090 --> 00:22:51,370
in that particular array will be freed.
But since the message pointers array is
179
00:22:51,370 --> 00:22:57,750
not updated, the pointer in that
particular array are still pointing to the
180
00:22:57,750 --> 00:23:05,850
first temporary file buffer
which has been freed. That's not a
181
00:23:05,850 --> 00:23:11,580
problem. If you send a xecond temporary
box with the same size, the buffer will be
182
00:23:11,580 --> 00:23:15,760
re-allocated for that second
temporary file and we eventually free
183
00:23:15,760 --> 00:23:25,930
up pointers to control the buffer. So
what's next? We can craft some fake heap
184
00:23:25,930 --> 00:23:32,920
chunks. We can have the application free
them. What do we do? The free, yes, it is
185
00:23:32,920 --> 00:23:39,070
actually really insecure. You can exploit
the classic unsafe linker vulnerability,
186
00:23:39,070 --> 00:23:47,650
so you get one arbitrary write for each
chunk you can free. And you still need to
187
00:23:47,650 --> 00:23:56,730
know what to overwrite. But you can just
rewrite the heap free list head pointer. So the
188
00:23:56,730 --> 00:24:04,350
next malloc call will return a pointer to
wherever you want, and you can especially
189
00:24:04,350 --> 00:24:10,470
put a pointer to the stack in there. So
the next malloc call will return a
190
00:24:10,470 --> 00:24:20,990
pointer to the stack and it will be used
to store your third temporary file. So
191
00:24:20,990 --> 00:24:29,460
it's a bit hard to understand. So let's
again illustrate this with a diagram. So
192
00:24:29,460 --> 00:24:35,670
first you have your first temporary file
loaded in memory. So on the right it's
193
00:24:35,670 --> 00:24:49,440
parsed and the associated structure is
written in stack and it overwrites the
194
00:24:49,440 --> 00:24:57,510
lock pointer to make it point to the alloc
mode in memory. In the end,
195
00:24:57,510 --> 00:25:05,070
leave_critical_section is called. So you have
your temporary buffer freed and your location
196
00:25:05,070 --> 00:25:13,540
mode decremented. Then your second
temporary file is loaded in memory. The
197
00:25:13,540 --> 00:25:19,160
buffer used for the first
file is relocated and the pointers in the
198
00:25:19,160 --> 00:25:26,180
structure still point to our
controlled data and especially our fake
199
00:25:26,180 --> 00:25:39,480
chunks. So your second temporary file is
loaded and parsed. Then all the chunks are
200
00:25:39,480 --> 00:25:49,100
freed and the field it is at is moved to
point on the stack. And finally, you can
201
00:25:49,100 --> 00:25:54,360
see that your last temporary file is
read in on the stack so we can overwrite
202
00:25:54,360 --> 00:26:00,890
the return address and put a ROP-chain in
there. So this gives us a second remote
203
00:26:00,890 --> 00:26:10,070
code execution vulnerability in CECD. And
this one this one was quite trickier. So
204
00:26:10,070 --> 00:26:18,650
what's next? Another one. Yeah. Again,
there is another vulnerability in the
205
00:26:18,650 --> 00:26:29,880
message parser. It's actually an SDK
function. So any application that uses
206
00:26:29,880 --> 00:26:33,970
SteetPass is vulnerable, not only CECD but
all application and games that use
207
00:26:33,970 --> 00:26:36,360
StreetPass are vulnerable for this one.
208
00:26:36,360 --> 00:26:41,010
But I'm not going
to talk about it and explain everything.
209
00:26:41,010 --> 00:26:50,590
It's up to you to exploit it. So this
gives us a third Remote Code Execution in
210
00:26:50,590 --> 00:26:57,450
CECD and you can get Code Execution in any
application using StreetPass. And this
211
00:26:57,450 --> 00:27:06,260
also give us a persistent backdoor in CECD
because of CECD usually parses all the
212
00:27:06,260 --> 00:27:15,260
messages in the in and out boxes at startup.
So you can trigger the vulnerability
213
00:27:15,260 --> 00:27:25,270
once the system boots. So we've got a
Remote Code Execution in CECD, what can we
214
00:27:25,270 --> 00:27:34,730
do? No, actually, CECD does not have much
privileges. It's only a userspace
215
00:27:34,730 --> 00:27:41,090
application. And it's pretty well
sandboxed. You can not access the
216
00:27:41,090 --> 00:27:49,230
internet, for example or not the SD card.
So if you want more privileges and we
217
00:27:49,230 --> 00:27:57,131
want more privileges, you need to take
care of something else. And your
218
00:27:57,131 --> 00:28:04,980
best choice would be trying to take over
ARM11 Kernel, which is the kernel for the
219
00:28:04,980 --> 00:28:13,590
userland processor. This this would give
you total control over this processor.
220
00:28:13,590 --> 00:28:18,490
And if you want really full system
control, you'd like to also take over the
221
00:28:18,490 --> 00:28:25,600
ARM9 security processor. So this is the
processor that do all the encryption and
222
00:28:25,600 --> 00:28:34,590
signature stuff. And we will see this
later. So let's first try to take over the
223
00:28:34,590 --> 00:28:46,470
ARM11 kernel. But first, I need to
talk about IPC and especially
224
00:28:46,470 --> 00:28:55,640
what are called static buffers. So when
you are doing IPC, you need to sometimes
225
00:28:55,640 --> 00:29:03,460
send data from a sender process to a
receiver process and on the 3DS, you can
226
00:29:03,460 --> 00:29:12,170
do this in multiple ways. The first one is
if you want to send large regular
227
00:29:12,170 --> 00:29:20,020
buffers, you can map parts of the sender's
memory into the receivers, but you can
228
00:29:20,020 --> 00:29:27,020
also use what are called static buffers.
If you want to send some small buffers,
229
00:29:27,020 --> 00:29:34,670
the receiver can register static buffers
and the ARM11 kernel will do the copy for
230
00:29:34,670 --> 00:29:42,010
you to that particular buffer. And
sometimes you need some buffers
231
00:29:42,010 --> 00:29:51,870
to be sent to the ARM9
processor. So the ARM11 kernel need to
232
00:29:51,870 --> 00:29:59,000
write some pairs of
physical addresses and size to the static
233
00:29:59,000 --> 00:30:05,560
buffers because the ARM9 does not have an
MMU so it's only using physical addresses
234
00:30:05,560 --> 00:30:14,970
and the copy of data is eventually done by
the Process9, which is the only process
235
00:30:14,970 --> 00:30:23,760
running on the ARM9 side. So let's talk
about a vulnerability now. So it's called
236
00:30:23,760 --> 00:30:32,997
LazyPixie and it has been found by TuxSH.
So it's not me. How does the kernel handle the
237
00:30:32,997 --> 00:30:44,604
PXI buffers case because it
seems a bit complicated. So first
238
00:30:44,604 --> 00:30:48,790
they check the alignment of the
destination state buffer, they check the
239
00:30:48,790 --> 00:30:54,250
size of the destination static buffer.
They check the permissions for the source
240
00:30:54,250 --> 00:31:01,100
buffers. Then they do cache operations, they
copy metadata. So the physical address and
241
00:31:01,100 --> 00:31:09,480
the size of the static buffer
to the destination and then the copy is
242
00:31:09,480 --> 00:31:15,830
done by the ARM9 side. But I think
there is something missing here because
243
00:31:15,830 --> 00:31:23,870
they do not check the permissions for the
destination buffer. So what you can do is
244
00:31:23,870 --> 00:31:30,440
use an arbitrary address as a destination.
And so you can just overwrite the MMU
245
00:31:30,440 --> 00:31:37,860
table and make your kernnel read, write and
execute, which is obviously enough to take
246
00:31:37,860 --> 00:31:48,890
it over. So at that point, the ARM11
Kernel has fallen and we have
247
00:31:48,890 --> 00:31:58,740
the full control of that processor. But we
would like a bit more privileges because
248
00:31:58,740 --> 00:32:07,640
why not? We want the full system control.
So let's take the road to full system
249
00:32:07,640 --> 00:32:15,770
control and see why taking over CECD was
one of the best ideas ever. So I am going
250
00:32:15,770 --> 00:32:22,410
to talk about SAFEHAX. Maybe some of you
know what SAFEHAX is because it's a really
251
00:32:22,410 --> 00:32:31,870
cool vulnerability. It's actually race a
condition in the firmware header parsing
252
00:32:31,870 --> 00:32:38,410
you can take over the ARM9 side if you
control the ARM11 kernel. It has
253
00:32:38,410 --> 00:32:47,170
been fixed in the system version 9.5 for
the regular native firmware
254
00:32:47,170 --> 00:32:52,020
and fixed in the safe mode firmware, which
is basically the recovery firmware if
255
00:32:52,020 --> 00:32:58,330
something went wrong for your console. So
people have been exploiting it both on the
256
00:32:58,330 --> 00:33:04,780
native firmware and the
safe mode firmware and it has been
257
00:33:04,780 --> 00:33:12,960
mitigated in version 11.3 and 11.4. So it
does not work anymore, but it has only
258
00:33:12,960 --> 00:33:19,800
been mitigated and not patched. So let's
take a look at that mitigation because
259
00:33:19,800 --> 00:33:26,559
how do they prevent us to exploit that
vulnerability? So this so-called
260
00:33:26,559 --> 00:33:36,820
mitigation is a boolean flag that has been
added on the ARM9 side and when it's set to
261
00:33:36,820 --> 00:33:48,559
1 the system just panics. When you try to
launch the safe mode firmware. So this
262
00:33:48,559 --> 00:33:53,140
flag is actually set to 1 whenever you try
to launch an application, so this was the
263
00:33:53,140 --> 00:33:59,490
usual way to exploit it, you were
launching the homebrew menu through an
264
00:33:59,490 --> 00:34:07,070
application and then exploiting the ARM11
kernel and then running SAFEHAX. So they
265
00:34:07,070 --> 00:34:13,549
set the flag to 1 whenever you try to
launch a specific application, except some
266
00:34:13,549 --> 00:34:22,240
of them because your reconnection ARMs needs some
applications to run. So this is there is
267
00:34:22,240 --> 00:34:29,270
an exception for the home menu and the
system modules. And guess what? We are
268
00:34:29,270 --> 00:34:35,270
exploiting CCD, which is a system module
and we are getting Remote Code Execution
269
00:34:35,270 --> 00:34:43,090
in CCD. So the the flag is never set to 1
when we are getting code executing on the
270
00:34:43,090 --> 00:34:52,630
CCD. So with that kind of exploit. You can
easily replicate the initial SAFEHAX
271
00:34:52,630 --> 00:35:02,830
exploit. So then you get a full control,
remote code execution without any user
272
00:35:02,830 --> 00:35:10,130
interaction. And it's StreetPass and it's
doing all of this thing in the background
273
00:35:10,130 --> 00:35:16,320
and on any firmwre version at the time
this was developed because Nintendo
274
00:35:16,320 --> 00:35:28,520
patched it with firmware version 11.12. So
I guess it's time for a little demo. I'm
275
00:35:28,520 --> 00:35:37,550
not going to do it live because I don't
want to some exploits in the air. So I
276
00:35:37,550 --> 00:35:46,300
have a little video. So I'm running my
exploit on my laptop and you can see the
277
00:35:46,300 --> 00:35:52,850
LED is turned on to see that the exploit
is running in CCD. And then you once
278
00:35:52,850 --> 00:35:59,700
you're you can exploit and you can launch
the installer for the Boot ROM exploit,
279
00:35:59,700 --> 00:36:10,460
for example.
applause
280
00:36:10,460 --> 00:36:24,140
Thanks. So now, some some takeaways. Well,
you'd better check your return value,
281
00:36:24,140 --> 00:36:28,960
really, because there's a second
vulnerability would have been really,
282
00:36:28,960 --> 00:36:41,800
really out to exploit without that
mistake. And really, you should not hide
283
00:36:41,800 --> 00:36:47,910
behind cryptography because one day your
encryption will be broken and this might
284
00:36:47,910 --> 00:36:59,650
come sooner than you think. And for this
specific case, there was a bunch of dumb
285
00:36:59,650 --> 00:37:09,190
mistakes and basically all vulnerabilities
were only buffer overflows. Then,
286
00:37:09,190 --> 00:37:16,900
assessing hard-to-reach features is really
arduous. I spent a lot of time doing this,
287
00:37:16,900 --> 00:37:26,480
especially figuring out how to replicate
all the features, parts and all the
288
00:37:26,480 --> 00:37:32,830
different protocols involved. But
eventually, you can get some really
289
00:37:32,830 --> 00:37:41,090
interesting results like this. Then, I'd
say please fix your flows, and do not
290
00:37:41,090 --> 00:37:50,760
implement some poor mitigation, like for
SAFEHAX. And there's things still to do on
291
00:37:50,760 --> 00:37:57,340
the 3DS. I think I was able to show this
today. There is, this is an amazing system
292
00:37:57,340 --> 00:38:03,830
you can start to work on and do some
practical things. And there's still things
293
00:38:03,830 --> 00:38:13,490
to document on the open source wiki, so
feel free to contribute. So, in the end, I
294
00:38:13,490 --> 00:38:25,220
would like to thank @TuxSH for the
LazyPixie and helping me getting this full
295
00:38:25,220 --> 00:38:39,270
chain exploit done, and @hedgeberg for
recurring support with a lot of things. So
296
00:38:39,270 --> 00:38:45,230
now, if you have some questions, feel free
to ask.
297
00:38:45,230 --> 00:38:50,930
Herald: Thank you very much.
298
00:38:50,930 --> 00:38:54,640
applause
299
00:38:54,640 --> 00:39:02,080
Herald: We are very, very much on time. So
ask any questions, but please do ask them
300
00:39:02,080 --> 00:39:13,609
at a microphone. Go ahead. No, I thought
there was going to ask a question. No
301
00:39:13,609 --> 00:39:21,200
questions? Oh, the Internet has one.
Great.
302
00:39:21,200 --> 00:39:29,230
Signal angel: So, yes, we have two
questions. The first one is what tools and
303
00:39:29,230 --> 00:39:34,220
environments do you use for your research?
For example, someone mentioned how do you
304
00:39:34,220 --> 00:39:40,970
get all the source code?
nba::yoh: Oh, everything on the 3DS is
305
00:39:40,970 --> 00:39:50,410
closed source. So you have to reverse
engineer everything. I used IDA and Ghidra
306
00:39:50,410 --> 00:39:57,390
to reverse the binaries of CCD and, yeah,
that, that's it.
307
00:39:57,390 --> 00:40:08,320
Signal angel: OK. Thank you. We have a
second question: Is there any procedure
308
00:40:08,320 --> 00:40:13,200
for the Switch that is compatible with all
what you've done?
309
00:40:13,200 --> 00:40:16,109
nba::yoh: Sorry, could you repeat that
question?
310
00:40:16,109 --> 00:40:23,330
Signal angel: Well, all the things you
have done, all the code. Is there anything
311
00:40:23,330 --> 00:40:28,430
similar for the Switch?
nba::yoh: I don't think there is something
312
00:40:28,430 --> 00:40:37,420
similar on the Switch, at least something
that looks like the StreetPass feature.
313
00:40:37,420 --> 00:40:44,420
But I don't really know how the Switch
works, I've only done things on the 3DS.
314
00:40:44,420 --> 00:40:51,930
Herald: OK, first question for the room.
Microphone: Thanks for the talk, great.
315
00:40:51,930 --> 00:40:57,800
Did you really need all the three
exploits? And which one did you use in the
316
00:40:57,800 --> 00:41:03,450
end for the full chain? Thanks.
nba::yoh: Could you repeat the question?
317
00:41:03,450 --> 00:41:07,870
Microphone: Did you need all the three
exploits that you had or could you just
318
00:41:07,870 --> 00:41:11,990
use the easiest one? And which one did you
use in the end?
319
00:41:11,990 --> 00:41:19,650
nba::yoh: Well, no, you do not need all
three exploits, at least in CCD. You only
320
00:41:19,650 --> 00:41:30,369
need one basically to get remote code
execution. But I found it fun to just show
321
00:41:30,369 --> 00:41:35,570
all the exploits for CCD.
Herald: Next question.
322
00:41:35,570 --> 00:41:40,080
Microphone: Are the StreetPass messages
passed to the applications even when those
323
00:41:40,080 --> 00:41:44,030
applications are not running? So, for
example, when you have like Pokémon or
324
00:41:44,030 --> 00:41:46,670
something installed...
nba::yoh: Could you speak louder, please?
325
00:41:46,670 --> 00:41:51,260
Microphone: Okay. Are the applications
parsing the messages even if they are not
326
00:41:51,260 --> 00:41:55,450
running? Like, is there some sort of a
handler being run by the OS even if you
327
00:41:55,450 --> 00:41:59,930
don't have an application running, just
installed? So that if you have a
328
00:41:59,930 --> 00:42:06,150
vulnerable application with the old SDK
built in there, will it automatically
329
00:42:06,150 --> 00:42:15,050
parse the corrupted message?
nba::yoh: Could you reformulate your
330
00:42:15,050 --> 00:42:19,050
question? I don't understand.
Microphone: Okay. In your tree
331
00:42:19,050 --> 00:42:24,930
exploitation method, you mentioned the
third method that mentions the SDK being
332
00:42:24,930 --> 00:42:26,930
broken.
nba::yoh: Yeah.
333
00:42:26,930 --> 00:42:31,490
Microphone: And if you have an application
built with that old SDK, does it
334
00:42:31,490 --> 00:42:36,280
automatically parse the message even if
it's not running, so that even if you have
335
00:42:36,280 --> 00:42:41,390
a patched OS, but not patched
applications, it will still get exploited?
336
00:42:41,390 --> 00:42:49,001
nba::yoh: Yeah, all the applications using
the SDK should be updated to fix the
337
00:42:49,001 --> 00:42:59,950
vulnerability. So the exploit is triggered
when the application parsed the messages.
338
00:42:59,950 --> 00:43:10,541
So you have to run the application to
exploit it. CCD has been patched, so there
339
00:43:10,541 --> 00:43:20,930
is no more remote code execution in CCD,
nor a permanent backdoor in CCD, that
340
00:43:20,930 --> 00:43:29,160
automatically runs, when the system is
started. But you can probably still
341
00:43:29,160 --> 00:43:34,430
exploit games and applications that use
the old SDK.
342
00:43:34,430 --> 00:43:39,160
Microphone: Okay, thanks.
Herald: There's a question over there.
343
00:43:39,160 --> 00:43:44,099
Microphone: Yes. Can you go back to the
slide where you showed how the encryption
344
00:43:44,099 --> 00:43:46,610
for the packets worked?
nba::yoh: The encryption?
345
00:43:46,610 --> 00:44:12,359
Microphone: Yes, the encryption. Yeah.
Yeah. That one. So my question is, if all
346
00:44:12,359 --> 00:44:18,720
you're, if the only thing that you're
changing is the counter, and the data is
347
00:44:18,720 --> 00:44:24,160
constant and the key is constant, and it's
CTR, then you're basically just XOring a
348
00:44:24,160 --> 00:44:33,770
known block with your HMAC output. So why
do you even need the key here?
349
00:44:33,770 --> 00:44:42,910
nba::yoh: Well, the counter changed every
time you start a new StreetPass
350
00:44:42,910 --> 00:44:50,440
communication, because the CID's are
randomized and the MAC address is, the MAC
351
00:44:50,440 --> 00:44:55,560
address is also randomized before starting
a new communication.
352
00:44:55,560 --> 00:45:01,270
Microphone: Right. But I guess what I'm
asking is, why do you need key slot 2E? In
353
00:45:01,270 --> 00:45:08,310
my mind, having the CCD HMAC key would be
enough, because you can just XOR the, you
354
00:45:08,310 --> 00:45:13,920
know, output of that with the final
output, and that removes, you know, the
355
00:45:13,920 --> 00:45:20,280
CTR part, and now you have the raw output
of the null block encrypted with key slot
356
00:45:20,280 --> 00:45:27,109
2E, which is always going to be constant,
and then you can just XOR whatever output
357
00:45:27,109 --> 00:45:32,600
to get the final result, right?
nba::yoh: Yeah, well I'm not super
358
00:45:32,600 --> 00:45:41,560
familiar with all the cryptography, but
maybe we could talk about it. I was just
359
00:45:41,560 --> 00:45:50,770
putting this for, for people to reproduce
it if they want.
360
00:45:50,770 --> 00:46:01,580
Herald: Okay. Are there any more
questions? Thank you so much.
361
00:46:01,580 --> 00:46:03,550
nba::yoh: Thanks.
362
00:46:03,550 --> 00:46:04,550
applause
363
00:46:04,550 --> 00:46:07,635
postroll music
364
00:46:07,635 --> 00:46:29,000
subtitles created by c3subtitles.de
in the year 2020. Join, and help us!