1
00:00:00,000 --> 00:00:17,760
*33C3 preroll music*

2
00:00:17,760 --> 00:00:23,730
Herald: Good evening, everyone. In a few
minutes, the Nintendo Hacking 2016 talk

3
00:00:23,730 --> 00:00:28,470
will start. This talk will will be
translated into German, and there are

4
00:00:28,470 --> 00:00:34,300
English subtitles available. Anyway,
without much further ado. These are

5
00:00:34,300 --> 00:00:38,100
derrek, naehrwert and nedwill. They are
three students that have been working on

6
00:00:38,100 --> 00:00:42,499
hacking Nintendo platforms for a while
now, and please give them a warm applause.

7
00:00:42,499 --> 00:00:54,490
*applause*

8
00:00:54,490 --> 00:01:00,890
naehrwert: Hi guys. So, welcome to our
talk about Nintendo Hacking 2016. Let me

9
00:01:00,890 --> 00:01:06,280
quickly introduce the other guys. This is
derek, and that's ned, and I think I can

10
00:01:06,280 --> 00:01:11,210
speak for the three of us to say that I am
really happy that you guys are here today

11
00:01:11,210 --> 00:01:15,250
and we are happy that we can be here today
to tell you everything about what we did

12
00:01:15,250 --> 00:01:22,920
in the past one and a half years. I will
start with the state of the Wii U. I hope

13
00:01:22,920 --> 00:01:29,270
a lot of you guys have seen failOverflow's
talk in 2013 about hacking the Wii U. Not

14
00:01:29,270 --> 00:01:38,530
much happened afterwards, until 2015 there
is a public webkit exploit released and

15
00:01:38,530 --> 00:01:43,640
this time we started looking into the Wii
U. And, we wanted more access, right? Than

16
00:01:43,640 --> 00:01:48,430
just user mode and because there is also
the kernel running on a PowerPC and then

17
00:01:48,430 --> 00:01:54,320
there is this other ARM processor that
runs IOSU. Also user mode and kernel mode.

18
00:01:54,320 --> 00:01:58,470
I am not going to consider the user mode
today. Because I think there are currently

19
00:01:58,470 --> 00:02:05,970
exploits that are way more fun. So, let's
start with PowerPC kernel very quick. It

20
00:02:05,970 --> 00:02:10,139
has all standard basic security measures,
though it doesn't have any ASLR which

21
00:02:10,139 --> 00:02:20,110
makes our lives easier. It has about 140
syscalls. And we don't really.. We can't

22
00:02:20,110 --> 00:02:24,840
really name them from start, right? Kinda
need to reverse them. But there's a nice

23
00:02:24,840 --> 00:02:29,210
thing. So, the Wii U uses this RPL
mechanism for dynamic libraries. And

24
00:02:29,210 --> 00:02:33,500
there's this really nice library. It's
called coreinit.rpl and it contains a lot

25
00:02:33,500 --> 00:02:38,390
of syscalls, shims and symbol names. So we
can name all syscalls straight away

26
00:02:38,390 --> 00:02:44,420
without much hassle and, it is important
to know that all the syscalls use the safe

27
00:02:44,420 --> 00:02:50,120
copy in/copy out mechanism to get data
from the user space into the kernel space.

28
00:02:50,120 --> 00:02:56,330
So we start reversing each syscall and we
start looking for bugs And what we came

29
00:02:56,330 --> 00:03:01,750
out with, at first, this is what we call
I/O controlled VHAX Or, why indirections

30
00:03:01,750 --> 00:03:07,960
are hard. It's actually a bug in the
IPCKDriver_SubmitRequest syscall so what

31
00:03:07,960 --> 00:03:13,950
this syscall is used for is: you want to
submit requests from user mode to this

32
00:03:13,950 --> 00:03:20,220
other processor running which I'm going to
talk about later. And, so you submit this

33
00:03:20,220 --> 00:03:24,930
kind of request structures and the kernel
uses copy in to fetch the request

34
00:03:24,930 --> 00:03:29,260
structure from user mode into kernel mode
but there's a certain type of request

35
00:03:29,260 --> 00:03:35,380
structure which contains an indirection
like a second layer, right? And, well,

36
00:03:35,380 --> 00:03:41,060
they just ignore that for the second level
and hope for the best. So, let's look at

37
00:03:41,060 --> 00:03:45,220
the relevant part. I'm really sorry I'm
showing you this code here, but it's not

38
00:03:45,220 --> 00:03:49,430
much more than that. So, there is
something that is called ios packet in the

39
00:03:49,430 --> 00:03:53,599
second line which is kind of this request
that we submit from user mode into kernel

40
00:03:53,599 --> 00:03:58,351
mode And in the top line there's this
special request entry, so it contains a

41
00:03:58,351 --> 00:04:03,069
physical address, a buffer size and a
virtual address. And what we do from user

42
00:04:03,069 --> 00:04:07,510
mode is we submit it filled out with the
virtual address and the size. and the

43
00:04:07,510 --> 00:04:15,520
kernel does this convenient thing for us.
It kind of.. changes the virtual address

44
00:04:15,520 --> 00:04:21,019
to the physical address. So we can see, it
copies in these packets from user mode

45
00:04:21,019 --> 00:04:25,530
into kernel mode using the safe mechanism
and then it goes through all the entries

46
00:04:25,530 --> 00:04:29,840
and fixes up the physical addresses for us
but we can see in this line that it

47
00:04:29,840 --> 00:04:33,500
doesn't use to the safe mechanism at all
it doesn't care about whatever address we

48
00:04:33,500 --> 00:04:38,620
put in there so this gives us some kind of
right primitive to wherever we want

49
00:04:38,620 --> 00:04:45,780
basically and this looks hard to exploit,
right? Because the right kind of going

50
00:04:45,780 --> 00:04:54,630
through this conversation but we actually
only need one byte to exploit the kernel

51
00:04:54,630 --> 00:05:01,639
and we do this by noting that this
KIEffectiveToPhysical conversion function

52
00:05:01,639 --> 00:05:08,350
actually returns 0 for any garbage input
we get and there's a pretty high chance of

53
00:05:08,350 --> 00:05:14,320
the input to the function to being garbage
if we point to any part inside kernel data

54
00:05:14,320 --> 00:05:19,940
so the strategy here is that we go into
syscall handler address table and we

55
00:05:19,940 --> 00:05:25,020
overwrite the last byte for one particular
syscall handler and we hope that the new

56
00:05:25,020 --> 00:05:29,590
address actually points to some usable
gadget so we hope for the best basically

57
00:05:29,590 --> 00:05:33,910
and the other important thing to note here
is that our user mode code is running from

58
00:05:33,910 --> 00:05:38,230
what we call the JIT area and what's
really stupid is that the JIT area is

59
00:05:38,230 --> 00:05:44,050
actually executable from kernel mode for
some reason so that's nice too. Okay,

60
00:05:44,050 --> 00:05:49,720
let's look at the relevant structures so
this is the kernel and we should read this

61
00:05:49,720 --> 00:05:56,020
from the bottom to the top. Ok, like in
the last line the button we see this entry

62
00:05:56,020 --> 00:06:03,040
to KeLoaderCall and then we can look at
the last byte there it's hex F0. And what

63
00:06:03,040 --> 00:06:11,080
we will do now is overwrite this last byte
with 0 and what happens is that now this

64
00:06:11,080 --> 00:06:16,000
syscall will actually point to this
very usable gadget up there where it loads

65
00:06:16,000 --> 00:06:20,880
this register r28 into the link register
and just branches there the nice thing is

66
00:06:20,880 --> 00:06:28,120
that we control our 28 from user mode so
this gives us a way to just jump anywhere

67
00:06:28,120 --> 00:06:35,800
basically so how do we exploit this. Well,
we have our k-mode function there then we

68
00:06:35,800 --> 00:06:42,430
just call ioctlv to this shifted address
and from this point on we have this nice

69
00:06:42,430 --> 00:06:46,360
syscall that just comes to anywhere we
want and then we call it basically and

70
00:06:46,360 --> 00:06:53,310
this calls our k-mode function. So, the
Wii U starts out with full four hearts and

71
00:06:53,310 --> 00:06:59,710
this gives us PowerPC kernel mode code
execution so we subtract one hard and it's

72
00:06:59,710 --> 00:07:05,570
quite nice but we can and need to go
deeper and for that let's look at the IOSU

73
00:07:05,570 --> 00:07:12,430
architecture. So IOSU is present as one
big ELF file and this includes the kernel

74
00:07:12,430 --> 00:07:18,110
and all the services and it's running on
the Starbuck it, has a hardware way to

75
00:07:18,110 --> 00:07:24,479
enforce no execute and again no ASLR,
making our lives easier and it's a

76
00:07:24,479 --> 00:07:30,590
microkernel design that has about a 140
syscalls so another thing to notice that

77
00:07:30,590 --> 00:07:35,790
the kernel spawns all these services as
user mode processes so before we can

78
00:07:35,790 --> 00:07:40,139
exploit the kernel we actually have to
exploit one of these user mode processes

79
00:07:40,139 --> 00:07:46,280
which we did but i'm not going to talk
about and to look into the kernel, we

80
00:07:46,280 --> 00:07:51,639
began by reversing all of the syscalls and
search for bugs and what we came up with

81
00:07:51,639 --> 00:07:56,400
is called MQHAX or message queue hax it
contains another nice bug class that

82
00:07:56,400 --> 00:08:05,249
apparently never dies. Integer overflows.
And let's look at the code again so

83
00:08:05,249 --> 00:08:09,610
there's this syscall, it's called create
message queue you pass it a buffer and a

84
00:08:09,610 --> 00:08:14,050
number of buffer entries and what they
assumed was that each buffer entry is four

85
00:08:14,050 --> 00:08:18,410
bytes so when they check the address range
to just multiply the number of entries

86
00:08:18,410 --> 00:08:24,361
with four bytes so does anyone see the
integer overflow here and then a nice

87
00:08:24,361 --> 00:08:28,110
thing is that it just to use the number of
entries for the maximum number of entries

88
00:08:28,110 --> 00:08:33,718
for the message queue and our right
primitive again is the send message

89
00:08:33,718 --> 00:08:40,669
syscall. So, I told you about this
hardware NX right? So IOSU should be

90
00:08:40,669 --> 00:08:47,759
enforcing that no executable memory is
writeable and if you look at the kernel

91
00:08:47,759 --> 00:08:52,180
section flags we actually see that
KERNEL_TEXT is read execute and

92
00:08:52,180 --> 00:08:58,789
KERNEL_DATA is read-write but these
permissions are all lies. Ok so our

93
00:08:58,789 --> 00:09:05,199
exploit strategy: well, let's look at the
relevant part of the IOSU kernel so we see

94
00:09:05,199 --> 00:09:10,230
that KERNEL_TEXT starts at this lower
address, at hex 0x08120000 and

95
00:09:10,230 --> 00:09:15,170
conveniently for us there is a syscall
there and the addresses before that are

96
00:09:15,170 --> 00:09:21,089
all valid so we create a message queue,
I'm starting at minus eight bytes and this

97
00:09:21,089 --> 00:09:27,629
magic hex 0x400- whatever-2 number and
from this point on we just push two

98
00:09:27,629 --> 00:09:32,529
messages and then ARM instruction to
branch out three and what this does is it

99
00:09:32,529 --> 00:09:38,499
actually causes the start of text section
to be overwritten with branch R3 and let's

100
00:09:38,499 --> 00:09:43,619
just look at the integer overflow right
four times this value truncated to 4 bytes

101
00:09:43,619 --> 00:09:48,200
gives 8 bytes so what kind of things is
that the message queues is only bytes but

102
00:09:48,200 --> 00:09:54,509
we can just push any messages we want ok
so this gives us IOSU kernel-mode

103
00:09:54,509 --> 00:09:59,560
execution and the nice thing about this is
that we actually have full control over

104
00:09:59,560 --> 00:10:03,871
the console unit now right so we can dump
the console's OTP which contains all the

105
00:10:03,871 --> 00:10:10,209
keys except for boot1 which we will come
back to later because unfortunately the

106
00:10:10,209 --> 00:10:15,869
pieces for boot1 are locked out as we have
already seen. And now we want to make

107
00:10:15,869 --> 00:10:22,199
everything persistent so how do we do
that? We find that title content is only

108
00:10:22,199 --> 00:10:27,179
verified at title install time but never
at boot time because at boot time they

109
00:10:27,179 --> 00:10:31,790
only verify the title binary so what you
can do is you can actually start to mess

110
00:10:31,790 --> 00:10:39,499
with the metadata of titles and overwrite
it and what we did was to overwrite the

111
00:10:39,499 --> 00:10:44,769
ROM for a DS game, exploited the emulator
and got user mode code

112
00:10:44,769 --> 00:10:50,170
execution again and another thing is that
the console contains this config file

113
00:10:50,170 --> 00:10:55,100
which tells it to boot into which
title to boot so what you can do is you

114
00:10:55,100 --> 00:11:00,869
overwrite the title ID with your modified
DS emulator title and the next time you

115
00:11:00,869 --> 00:11:06,970
start up the console it actually boots
into the exploited game and yeah so just

116
00:11:06,970 --> 00:11:11,060
gives us persistent code execution and
cold boot with full control over to

117
00:11:11,060 --> 00:11:17,570
console whatsoever so
game over

118
00:11:17,570 --> 00:11:26,339
*applause*

119
00:11:26,339 --> 00:11:33,959
derrek: So, as we just saw, the kernel
it's like pretty broken, right? So, what

120
00:11:33,959 --> 00:11:41,420
is missing and I just copied this slide from
failoverflow's talk as you can see we are

121
00:11:41,420 --> 00:11:49,309
using the same d14 thing for our slides
and basically the boot1 key which is the

122
00:11:49,309 --> 00:11:57,060
second stage bootloader on Wii U and this
key is still unknown and they tried to get

123
00:11:57,060 --> 00:12:05,129
it somehow with some side-channel attacks
thing but I think it never worked

124
00:12:05,129 --> 00:12:12,889
so it would be nice to get this key and
the first thing we did was to make a NAND

125
00:12:12,889 --> 00:12:22,139
tracer so we can basically sniff all the
traffic between NAND and boot1 to see what

126
00:12:22,139 --> 00:12:33,069
boot1 reads from flash and so we get some
nice addresses and we could compare this

127
00:12:33,069 --> 00:12:40,319
with the file system on the / to see what
file it is reading and we also kind of

128
00:12:40,319 --> 00:12:46,740
mess around with some files on this file
system and we found out that boot1

129
00:12:46,740 --> 00:12:53,360
actually parses a file that is called
system.xml and I don't know, it doesn't

130
00:12:53,360 --> 00:13:03,290
really feel safe to parse an XML file in
such a really early boot process I mean

131
00:13:03,290 --> 00:13:11,860
there's a lot of stuff that could go
wrong. So, we tried to attack this and we

132
00:13:11,860 --> 00:13:18,350
tried some blind exploitation stuff but
yeah unfortunately it didn't really work

133
00:13:18,350 --> 00:13:28,899
so let's try something else. So, there's
boot1, which of course boots this.. Sorry

134
00:13:28,899 --> 00:13:37,290
we've got boot0 and this boots boot1 and
failoverflow found out that this boot0

135
00:13:37,290 --> 00:13:42,629
which is a bootrom of the security
processor can be re-enabled again in

136
00:13:42,629 --> 00:13:49,339
virtual Wii mode and you can just dump it
so let's look at boot1... boot0 I'm sorry

137
00:13:49,339 --> 00:13:59,029
and we can see that it reads boot1 key
from OTP and then it locks out boot1 key

138
00:13:59,029 --> 00:14:05,769
forever and this happens really early but
it's basically kept in memory all the time

139
00:14:05,769 --> 00:14:14,790
until it's done until it has launched
boot1 or just panicked. So, this means

140
00:14:14,790 --> 00:14:22,740
that we have to exploit boot0 to get the
boot1 key and unfortunately, boot0 is

141
00:14:22,740 --> 00:14:30,389
pretty safe it's kind of surprising
because this is Wii U and basically this

142
00:14:30,389 --> 00:14:37,649
gives us this question: How can you
exploit something that has no bugs? So,

143
00:14:37,649 --> 00:14:43,860
the answer is we have to introduce our own
bugs - *laughter* - and we're doing this

144
00:14:43,860 --> 00:14:50,230
by using fault injection and maybe you
have heard of it already it's basically

145
00:14:50,230 --> 00:14:58,410
you introduce an error into device by a
glitching the clock, voltage, the reset

146
00:14:58,410 --> 00:15:04,790
line you can also do electromagnetic
injections. There are many ways. But

147
00:15:04,790 --> 00:15:12,049
basically what you want to get is a
mutated instruction, or instruction skip

148
00:15:12,049 --> 00:15:18,579
or some corrupted registers and what you
don't want is just a stupid lock up where

149
00:15:18,579 --> 00:15:27,790
it just crashes and yeah that's all really
useful so we want to glitch boot0 and to

150
00:15:27,790 --> 00:15:37,069
do this we have to find a nice target like
the weak spot of boot0 so let's take a

151
00:15:37,069 --> 00:15:44,829
look what boot0 does first thing it does
is it copies itself to ram for some

152
00:15:44,829 --> 00:15:49,129
unknown reason I mean there's no good
reason to do this but it's nice for us

153
00:15:49,129 --> 00:15:58,029
because it copies itself to RAM and just
executes from there and then it copies the

154
00:15:58,029 --> 00:16:04,519
boot1 key to memory it locks out the auto
key slot initializes some other stuff and

155
00:16:04,519 --> 00:16:11,579
flash controller and then it starts
reading the boot1 image and it does that

156
00:16:11,579 --> 00:16:22,559
by just reading its header to this address
and then they read the size from the

157
00:16:22,559 --> 00:16:30,639
header field and they also do some max
size check on this and please note that

158
00:16:30,639 --> 00:16:37,990
the header itself is not encrypted and
they also don't do any signature

159
00:16:37,990 --> 00:16:49,869
verification here at this step so they use
the size and reads the whole boot1 image

160
00:16:49,869 --> 00:16:54,939
using size and then they do a real
signature verification to make sure that

161
00:16:54,939 --> 00:17:00,230
the image is not corrupted it then
decrypts the boot1 code using the key from

162
00:17:00,230 --> 00:17:09,010
RAM and then it clears the key and jumps
to boot1entry point ok so what is the weak

163
00:17:09,010 --> 00:17:14,680
spot here and I mean if you look at this
you can pretty much already tell what it

164
00:17:14,680 --> 00:17:24,940
is and of course it's this size check so
what we can do is we can write our own

165
00:17:24,940 --> 00:17:31,500
modified version of boot1 into flash with
some really really large size in the

166
00:17:31,500 --> 00:17:43,660
header so it reads the header and then
it's supposed to do a size check and this

167
00:17:43,660 --> 00:17:50,830
is exactly where we wanted to glitch it
and eventually it will just skip the

168
00:17:50,830 --> 00:17:57,560
instruction or something else happens and
then basically the size check is bypassed

169
00:17:57,560 --> 00:18:03,300
so when it's reading the boot1 image using
this size it will actually overflow the

170
00:18:03,300 --> 00:18:09,180
buffer and we have some jump instructions
at the end so when it returns from the

171
00:18:09,180 --> 00:18:16,730
flash read function it will eventually
jump to our code and this is actually

172
00:18:16,730 --> 00:18:19,820
boot0 code execution

173
00:18:19,820 --> 00:18:29,680
*applause*

174
00:18:29,680 --> 00:18:35,450
ok so we have boot0 code execution and you
know we can just dump the boot1 key from

175
00:18:35,450 --> 00:18:43,430
RAM and we didn't even need an exploit for
this right so it's just boot0 is actually

176
00:18:43,430 --> 00:18:49,600
pretty safe right but when it comes to
pitching it's kind of fragile

177
00:18:49,600 --> 00:18:58,350
because boot0 code is writeable and also
the boot1 image buffer is in front of boot0

178
00:18:58,350 --> 00:19:04,810
buffer so we can just overflow it and also
the setup that I had was also surprisingly

179
00:19:04,810 --> 00:19:11,600
stable so it works like fifty percent of
the entire time so let's finally look at

180
00:19:11,600 --> 00:19:19,490
boot1 and boot1 is able to understand the
Wii U file system it uses real file path

181
00:19:19,490 --> 00:19:24,670
strings to load the firmware image
and of course the first

182
00:19:24,670 --> 00:19:33,370
thing we did was to look at the xml parser
and well unfortunately it seems pretty

183
00:19:33,370 --> 00:19:44,160
safe and yeah but maybe we found a bug
we're not really sure and we haven't

184
00:19:44,160 --> 00:19:49,750
really tried to exploit it. Interest kind
of faded out because you know it's after

185
00:19:49,750 --> 00:20:00,290
all it's just the Wii U so that's it for
Wii U and now I will hand over to nedwill.

186
00:20:00,290 --> 00:20:03,250
He's talking about 3DS

187
00:20:03,250 --> 00:20:12,020
*applause*

188
00:20:12,020 --> 00:20:17,820
nedwill: Hi, everyone, I'm ned. I started 3DS
this year and I'm basically a software

189
00:20:17,820 --> 00:20:22,860
person so I'm going to be showing some of
the homebrew side of 3DS where that's at

190
00:20:22,860 --> 00:20:29,701
right now so just to reiterate from last
year these guys broke userland, kernel and

191
00:20:29,701 --> 00:20:37,060
the security processor they also broke the
secret hardware key scrambler and since

192
00:20:37,060 --> 00:20:44,130
then Nintendo has been kind of mad about
this they released a lot of system updates

193
00:20:44,130 --> 00:20:50,940
and they started a bug bounty program so
there's a lot of bugs getting patched but

194
00:20:50,940 --> 00:20:56,360
because of the amount of the level of
exploitation we got last year it's

195
00:20:56,360 --> 00:21:01,740
actually really easy to find new bugs and
exploits so what I want to emphasize here

196
00:21:01,740 --> 00:21:05,860
is that even though it's like a
cat-and-mouse game because we have so much

197
00:21:05,860 --> 00:21:13,310
control we can exploit more difficult
books on the latest firmware so starting

198
00:21:13,310 --> 00:21:19,480
with user space. This is where all
homebrew comes from so already it's pretty

199
00:21:19,480 --> 00:21:25,040
good like this has always been a huge
focus for the homebrew community because

200
00:21:25,040 --> 00:21:29,190
it's kind of where you know user space is
where you want to be running your own

201
00:21:29,190 --> 00:21:37,380
custom games you know modifying stuff so
we have a bunch of game entry points and a

202
00:21:37,380 --> 00:21:41,930
bunch of browser exploits but there's a
couple limitations to leads and that's

203
00:21:41,930 --> 00:21:50,800
that game carts cost money and they
frequently are.. like the games that are

204
00:21:50,800 --> 00:21:56,600
exploited are usually somewhat rare and
unusual and so the price goes way up as

205
00:21:56,600 --> 00:22:03,870
demand soars and for the browser every
time we release a new browser exploit,

206
00:22:03,870 --> 00:22:10,280
Nintendo can actually enforce that you're
on the latest firmware, because before we

207
00:22:10,280 --> 00:22:16,490
fetch any web page it will check that the
system is on the latest version. So, they

208
00:22:16,490 --> 00:22:23,731
can kind of remotely cut off web browser
exploits. So looking at this I thought it

209
00:22:23,731 --> 00:22:27,570
might be fun to look at if any of the
system titles can be exploitable as

210
00:22:27,570 --> 00:22:36,960
primary entry points and I found something
called SOUNDHAX so just the basic like the

211
00:22:36,960 --> 00:22:42,370
two probably most obvious things to look
at are the image loader because it's got

212
00:22:42,370 --> 00:22:48,020
JPEG parsing and also the music player.
But, when I looked at the music player I

213
00:22:48,020 --> 00:22:52,330
saw that they're parsing actually a lot of
formats and maybe even have their own

214
00:22:52,330 --> 00:23:00,200
custom playlists format and if they make a
single mistake anywhere it's it's over so

215
00:23:00,200 --> 00:23:03,450
then I was trying to compare with like
open source implementations I didn't find

216
00:23:03,450 --> 00:23:10,610
any overlap. It seemed like everything was
custom. So that was pretty promising. So,

217
00:23:10,610 --> 00:23:14,980
over the course of about a month, I found
a bunch of bugs and I was trying to like

218
00:23:14,980 --> 00:23:20,070
chain together little like logical bugs
and it wasn't really working and then I

219
00:23:20,070 --> 00:23:25,860
just found one that was really critical.
So, I'm going to demonstrate that here.

220
00:23:25,860 --> 00:23:29,240
So, actually studied mp3 for the whole
month MPEG was like the

221
00:23:29,240 --> 00:23:36,260
last day so I looked at it and they
actually malloc 256 byte buffer for the

222
00:23:36,260 --> 00:23:43,000
song name and then when they go to load it
if they see a unicode BOM marker they just

223
00:23:43,000 --> 00:23:49,750
memcpy the thing and that tag size is
totally controlled so you know that's

224
00:23:49,750 --> 00:23:56,060
that's it so this is like it was pretty
great but it's a few pics place that's a

225
00:23:56,060 --> 00:24:01,910
little tricky but this is what it looks
like so we have our name chunk that we're

226
00:24:01,910 --> 00:24:08,900
about to overflow and then like I'm a CTF
player, so I put A's there and then the

227
00:24:08,900 --> 00:24:15,210
next thing that happens is this gets freed
and so this victim chunk that we have

228
00:24:15,210 --> 00:24:21,720
overridden it's actually the way the 3DS
heap works they actually track they have a

229
00:24:21,720 --> 00:24:25,880
linked list of what things are currently
allocated so this gives us the classical

230
00:24:25,880 --> 00:24:32,611
heap unlink arbitrary write and so at this
point we have a 4-byte write and we want

231
00:24:32,611 --> 00:24:40,120
to get ROP out of it so we'll probably do
a stack pivot so I looked at the binary

232
00:24:40,120 --> 00:24:47,230
and there's only one pivot gadget and then
i looked at the the thumb pivots, there

233
00:24:47,230 --> 00:24:51,410
are actually a lot but because this CPU
was too old didn't support the wide

234
00:24:51,410 --> 00:24:58,710
instructions where all the pivots come up
so unfortunately that one pivot

235
00:24:58,710 --> 00:25:07,750
instruction has some arithmetic conditions
on it specifically it was that in order to

236
00:25:07,750 --> 00:25:12,170
you know load all your registers from
memory the condition flags had to satisfy

237
00:25:12,170 --> 00:25:18,800
less than and everywhere where we return
from the function it had just checked that

238
00:25:18,800 --> 00:25:23,240
like if this pointer is not null free it
and so the comparisons wouldn't ever be

239
00:25:23,240 --> 00:25:29,980
satisfied because nothing is mapped up in
the negative area so of course CTF

240
00:25:29,980 --> 00:25:38,230
workarounds. We can still do this so I
overwrite the heap freelist head with the

241
00:25:38,230 --> 00:25:43,420
stack address and so on the next malloc we
just return that stack address and read

242
00:25:43,420 --> 00:25:50,820
into it so there's a couple of constraints
on this and the first one is really normal

243
00:25:50,820 --> 00:25:56,151
like this is every pivot to stack heap
thing you have to make sure that you have

244
00:25:56,151 --> 00:26:01,670
a heap chunk on the stack and luckily this
is actually pretty easy because all you

245
00:26:01,670 --> 00:26:07,450
need is a size followed by two null
pointers representing next and previous so

246
00:26:07,450 --> 00:26:11,640
when malloc goes to look there it seems
like the size is big enough and then

247
00:26:11,640 --> 00:26:18,610
nothing else is in the queue so just
return this and then this worked so we

248
00:26:18,610 --> 00:26:24,080
memcpy the next tag to the stack and like
we just specify that size and malloc some

249
00:26:24,080 --> 00:26:31,320
*unintelligible* for us and then from
there we're done because we can just do a

250
00:26:31,320 --> 00:26:35,430
little little ROP chain, we memcpy the
shellcode to the heap and then use an

251
00:26:35,430 --> 00:26:41,900
existing exploit gspwn which has been
around for a long time to override the

252
00:26:41,900 --> 00:26:52,410
text section and jump there so there's the
first heart so you can't really talk about

253
00:26:52,410 --> 00:26:58,430
homebrew without also talking about kernel
because we want to get access to more

254
00:26:58,430 --> 00:27:03,060
syscalls like the 3DS actually sandboxes a
lot of the syscalls away from you and so

255
00:27:03,060 --> 00:27:09,170
as an attacker, your goal is to call some
syscalls that are restricted a really nice

256
00:27:09,170 --> 00:27:14,060
example would be you want to map some
executable memory for like a JIT emulator

257
00:27:14,060 --> 00:27:20,590
so it's kind of a tricky situation because
you're inside the sandbox you want to

258
00:27:20,590 --> 00:27:26,380
break out you have to find bugs in like
pretty restricted syscalls so I looked at

259
00:27:26,380 --> 00:27:32,240
last year's talk here and like what had
been done so far and it seemed like there

260
00:27:32,240 --> 00:27:36,740
are a lot of attacks on that memory
mapping but I didn't see much about the

261
00:27:36,740 --> 00:27:42,750
sync primitives or anything related to use
after free and i had just got a pretty bad

262
00:27:42,750 --> 00:27:46,640
grade on my OS project because i had a lot
of those so I knew this is a good place to

263
00:27:46,640 --> 00:27:56,090
look so I noticed the design flaw when I
was reversing the ref counting so it's not

264
00:27:56,090 --> 00:28:00,920
so much that they couldn't possibly get
this right but generally when you're

265
00:28:00,920 --> 00:28:05,740
designing an API you want to make it
really hard to abuse and this is just not

266
00:28:05,740 --> 00:28:10,800
really true for how they do ref counting
so I'll go ahead and bring these up yeah

267
00:28:10,800 --> 00:28:18,910
so basically they whenever the user
fetches a kernel object to perform some

268
00:28:18,910 --> 00:28:23,310
operation on it meaning you call this
syscall that does something using the

269
00:28:23,310 --> 00:28:30,150
current object it does the correct inc ref
and then dec ref for you but I was looking

270
00:28:30,150 --> 00:28:33,059
at it and thinking well like a lot of
times the kernel actually is using these

271
00:28:33,059 --> 00:28:38,090
objects internally to do stuff so I mean
I spelled it but like I mean I was like a

272
00:28:38,090 --> 00:28:42,380
week I found like 3 use after frees and
they're all following the same pattern.

273
00:28:42,380 --> 00:28:47,640
The kernel's using an object internally
without maintaining the reference count

274
00:28:47,640 --> 00:28:53,510
correctly and then some people ask me like
advice on kernel hacking maybe like at

275
00:28:53,510 --> 00:28:58,630
home I definitely recommend looking here
I'm sure that there's plenty more so the

276
00:28:58,630 --> 00:29:06,360
one going to talk about today is the the
timer object so this is a pretty simple

277
00:29:06,360 --> 00:29:11,950
API with the kernel you can have it create
a timer for you you can set the timer you

278
00:29:11,950 --> 00:29:18,300
can wait on it it's like a normal
synchronization primitive so like I said I

279
00:29:18,300 --> 00:29:21,020
was looking for these use after frees
I saw this I thought it's kind of

280
00:29:21,020 --> 00:29:27,470
interesting that this one called pulse is
here because what's happening with this

281
00:29:27,470 --> 00:29:35,390
one is when you set the timer to pulse
like every period it's signaling

282
00:29:35,390 --> 00:29:38,660
everything that's waiting on it and then
it like resets itself and then if you wait

283
00:29:38,660 --> 00:29:42,559
on it the next period comes around you get
a signal again and so was thinking like

284
00:29:42,559 --> 00:29:47,990
it's definitely doing some stuff with this
object internally that's like a bit more

285
00:29:47,990 --> 00:29:53,890
complicated than some of the other modes
and the other kernel objects so i looked

286
00:29:53,890 --> 00:29:59,810
at how they did the pulse like you know
every every second whatever, when it

287
00:29:59,810 --> 00:30:06,610
pulses like what's actually getting
executed and if you look here they do some

288
00:30:06,610 --> 00:30:11,370
pretty good locking and then they signal
and then what happens here is basically

289
00:30:11,370 --> 00:30:16,299
when they signal they go through and
everyone that was waiting gets rescheduled

290
00:30:16,299 --> 00:30:22,420
- made runnable - and then at the end they
reset the timer state and just say like

291
00:30:22,420 --> 00:30:28,470
okay everyone that waits on this again has
to wait for the next cycle so and then

292
00:30:28,470 --> 00:30:32,790
this also looks pretty good like they
they're locking the scheduler here this

293
00:30:32,790 --> 00:30:38,670
would work but nothing is preventing you
from just closing this from another call

294
00:30:38,670 --> 00:30:46,809
so I have FASTHAX which is just 3 syscalls
and that's it. That's the entire exploit

295
00:30:46,809 --> 00:30:51,440
there's a lot of setup which we will get
to but you just create the timer set it to

296
00:30:51,440 --> 00:30:57,760
run really fast and then close the handle
and then if it was pulsing and you closed

297
00:30:57,760 --> 00:31:03,950
it it will use after free so what's nice
about this is if you lose the race it's

298
00:31:03,950 --> 00:31:09,510
just the timer is just on schedule you're
fine and then it actually happens quite

299
00:31:09,510 --> 00:31:14,340
often and I didn't even really
specifically try to win this to like I

300
00:31:14,340 --> 00:31:18,740
just.. Once it was within a second I don't
worry about those parameters are probably

301
00:31:18,740 --> 00:31:28,610
not optimal so we should look at how do we
exploit this basically this is a little

302
00:31:28,610 --> 00:31:32,450
bit of a more complicated view of it. I'll
show a diagram in a second but this is

303
00:31:32,450 --> 00:31:37,559
like where the use after free actually
happens so like r7 is pointing to my timer

304
00:31:37,559 --> 00:31:42,760
object and then it was freed before we
reach this chunk here and then it's

305
00:31:42,760 --> 00:31:48,510
loading r7 to r0, loading something from
that and then branching to it so that's

306
00:31:48,510 --> 00:31:54,730
like calling a use after free object. So,
this is pretty exploitable on the 3DS

307
00:31:54,730 --> 00:32:03,970
kernel because they use a slab heap to deal
with allocating objects so this is the

308
00:32:03,970 --> 00:32:09,050
normal situation when that first timer is
allocated the vtable is pointing to the

309
00:32:09,050 --> 00:32:12,930
you know the real KTimer vtable and then
it wants to call that timer reset

310
00:32:12,930 --> 00:32:21,460
function. It's totally fine but when we
free it actually, that vtable pointer goes

311
00:32:21,460 --> 00:32:25,320
to the next free timer object in the
kernel so it's actually interpreting that

312
00:32:25,320 --> 00:32:31,730
struct as a vtable and what's nice is it
actually overlaps with the initial timer

313
00:32:31,730 --> 00:32:38,970
value that we totally control and so it
looks like okay we can just set the

314
00:32:38,970 --> 00:32:44,590
initial timer value you know do this use
after free, we're just calling user space

315
00:32:44,590 --> 00:32:52,580
that's what I thought and then realized it
wasn't that easy so because the race like

316
00:32:52,580 --> 00:32:56,820
it because I was actually calling this is
in a kernel thread we actually can't

317
00:32:56,820 --> 00:33:01,420
guarantee that our user process is
actually mapped in memory and in fact it's

318
00:33:01,420 --> 00:33:07,380
on a different core so even if you open a
process in the other core like ran a

319
00:33:07,380 --> 00:33:12,980
thread there you can't get more than
twenty-five percent of the time I think so

320
00:33:12,980 --> 00:33:17,840
that's just super unstable also because
it's a kernel thread we don't necessarily

321
00:33:17,840 --> 00:33:21,900
want to crash it and we don't like crashes
in general but this will just totally

322
00:33:21,900 --> 00:33:27,760
break everything if the timer like sync
thread dies so as long as we return to a

323
00:33:27,760 --> 00:33:33,860
function do something cleanly, return it
will be fine so it sounds like okay all we

324
00:33:33,860 --> 00:33:38,290
have to do is find some kernel function we
can call and we're done but there's

325
00:33:38,290 --> 00:33:44,070
actually another issue and that's that
kernel code is mapped at high addresses

326
00:33:44,070 --> 00:33:49,370
and these are actually negative and that
the set timer syscall actually checks if

327
00:33:49,370 --> 00:33:57,250
your timer is negative so there's a pretty
funny trick I found and that's that when

328
00:33:57,250 --> 00:34:00,510
you set the timer you're saying like you
know start I like one second from now

329
00:34:00,510 --> 00:34:06,730
start pulsing obviously it's adding like
the current time to the one second to know

330
00:34:06,730 --> 00:34:11,730
like when do i trigger this timer so so
SetTimer is the one that does that add for

331
00:34:11,730 --> 00:34:18,359
you they don't check for overflow when
installing it and timer schedule values

332
00:34:18,359 --> 00:34:26,210
are signed which is also a bit weird so we
can overflow and schedule into the past so

333
00:34:26,210 --> 00:34:32,739
how this looks is that's my like
disgusting set up call so what's happening

334
00:34:32,739 --> 00:34:38,789
is like in the middle that's the start of
the 3DS boot and then that range on the

335
00:34:38,789 --> 00:34:46,129
right is what the 3DS will allow you to
pass for your values for the initial and

336
00:34:46,129 --> 00:34:54,329
like pulse period time and so what I do is
I just put it right there at the end and

337
00:34:54,329 --> 00:35:00,230
then it overflows and then on the next
pulse I also control that and that's also

338
00:35:00,230 --> 00:35:05,509
less than that range so then we can get it
to line up on the kernel address we want

339
00:35:05,509 --> 00:35:13,130
and so that's pretty good. Unfortunately,
we're at the end like at this point is

340
00:35:13,130 --> 00:35:19,309
pretty solid but there isn't like an
obvious single thing we can call and it

341
00:35:19,309 --> 00:35:22,269
seems like maybe you could race a bunch of
times and call a bunch of different things

342
00:35:22,269 --> 00:35:26,359
in the kernel and like you know that's a
decent amount of control but because of

343
00:35:26,359 --> 00:35:32,739
all this weird negative scheduling stuff
it's actually pretty hard to do multiple

344
00:35:32,739 --> 00:35:37,150
calls so I was trying to look for one
thing that I can call that will give me

345
00:35:37,150 --> 00:35:47,049
control and this is where it gets really
tricky so if we look at how the memory

346
00:35:47,049 --> 00:35:54,489
mapping on 3DS works in userspace you can
access the FCRAM which is that first range

347
00:35:54,489 --> 00:36:00,599
up there that's just where you know your
heap goes there and then the kernel also

348
00:36:00,599 --> 00:36:09,039
has a view of this heap it's you know a
shared mapping so if we can write one of

349
00:36:09,039 --> 00:36:13,190
those something in that range into the
free pointer and allocate it, it actually

350
00:36:13,190 --> 00:36:20,160
ends up in something we can see as the
user so then I noticed this.. This is

351
00:36:20,160 --> 00:36:30,099
actually a common instruction prefix in
ARM so I jumped here and at this point

352
00:36:30,099 --> 00:36:35,559
like we just did in C++, a vtable call on
the use after free thing with one argument

353
00:36:35,559 --> 00:36:41,009
so this means that r0 contains the address
of the object and r1 contains the address

354
00:36:41,009 --> 00:36:49,519
of where we just jumped to so that uh like
B65C [0xFFF1B65C] is where r1 is pointing

355
00:36:49,519 --> 00:36:53,290
so this is actually like some random
linked lists lookup function but it's

356
00:36:53,290 --> 00:36:57,829
actually looking down to the add
instruction and loading it to r1 and then

357
00:36:57,829 --> 00:37:05,720
we write that to the object and so at this
point it looks like this it's pointing to

358
00:37:05,720 --> 00:37:11,190
something in user space and then we just
alloc two times we can look in user space

359
00:37:11,190 --> 00:37:16,579
so they put the object there you control
the vtable and from there it's pretty much

360
00:37:16,579 --> 00:37:25,970
standard straightforward thing. So, there
we go *unintelligible* userspace in kernel

361
00:37:25,970 --> 00:37:31,210
and this is almost game over one more time

362
00:37:31,210 --> 00:37:39,450
*applause*

363
00:37:39,450 --> 00:37:42,000
derrek: So we've broken several parts of

364
00:37:42,000 --> 00:37:48,920
the 3DS firmware including 3DS kernel and
all software that's running on the

365
00:37:48,920 --> 00:37:55,390
security processor what we haven't looked
at yet are the 3DS bootroms and I'm

366
00:37:55,390 --> 00:38:04,470
basically there's one bootrom for each
processor for the ARM 11 and for the ARM 9

367
00:38:04,470 --> 00:38:10,869
and I think there's probably, there are
more bootroms in 3DS system-on-a-chip used

368
00:38:10,869 --> 00:38:18,220
to for old Nintendo DS mode but we will
focus on the 3DS bootroms here and what we

369
00:38:18,220 --> 00:38:27,670
know is 3DS is somehow loading the
firmware image from NAND flash and we also

370
00:38:27,670 --> 00:38:34,640
know that the ARM9 bootrom does all the
interesting stuff because only the ARM9

371
00:38:34,640 --> 00:38:43,549
has access to the whole crypto hardware
like the AES engine, RSA engine we also

372
00:38:43,549 --> 00:38:53,279
know that the bootrom will initialize the
secret keys for the AES key slots and yes

373
00:38:53,279 --> 00:39:00,769
we would like to get those keys but um
unfortunately the bootrom is disabled, it

374
00:39:00,769 --> 00:39:08,789
disables itself before its launching of
the firmware and 3DS bootroms also print

375
00:39:08,789 --> 00:39:16,330
nice error screens like when the NAND is
corrupted or something, it shows an error

376
00:39:16,330 --> 00:39:23,580
screen so let's look how the bootroms are
protected in detail and basically there

377
00:39:23,580 --> 00:39:30,730
are two registers that we call
CFG_SYSPROT9 and CFG_SYSPROT11 and the

378
00:39:30,730 --> 00:39:37,089
bootrom writes to those registers and of
course they are one shot you cannot

379
00:39:37,089 --> 00:39:44,490
re-enable bootroms again because this is
not the Wii U and basically when it's

380
00:39:44,490 --> 00:39:53,029
disables the bootrom it only disables one
half of it so what you get are two parts

381
00:39:53,029 --> 00:40:01,190
of bootrom there's the unprotected part
and protected part you can just dump the

382
00:40:01,190 --> 00:40:07,739
unprotected part by taking over ARM9 from
firmware but you can never see the

383
00:40:07,739 --> 00:40:14,030
protected part and they were really clever
and basically they put all the interesting

384
00:40:14,030 --> 00:40:20,249
code in the protected part and if you look
at the reset vector it just jumps directly

385
00:40:20,249 --> 00:40:25,680
to protected part of the boot room so as
you can't really figure out what is going

386
00:40:25,680 --> 00:40:32,499
on when the 3DS is starting up but what
you can do is you can look at the code

387
00:40:32,499 --> 00:40:40,989
from the unprotected bootrom and who knows
maybe we can find a bug so let's do this.

388
00:40:40,989 --> 00:40:47,190
First of all of course there are no keys
in in the unprotected bootrom, they put

389
00:40:47,190 --> 00:40:53,989
all the keys in the protected part it's
also mainly it's a lot of driver code.

390
00:40:53,989 --> 00:41:00,059
Talks to some hardware like NAND flash,
MMC, AES engine and also to SPI flash

391
00:41:00,059 --> 00:41:07,539
which is kind of interesting because the
SPI flash is some really tiny chip that is

392
00:41:07,539 --> 00:41:14,509
soldered on the Wi-Fi socket and it's
actually used for some Wi-Fi settings and

393
00:41:14,509 --> 00:41:21,430
other user settings us by old Nintendo DS
mode and yeah that's kind of interesting

394
00:41:21,430 --> 00:41:28,170
uses the SPI flash and it also includes
the ARM exception vector table and this is

395
00:41:28,170 --> 00:41:32,769
actually just design that they have
adopted from previous generations of the

396
00:41:32,769 --> 00:41:41,299
Nintendo DS such as the DSi if you don't
know ARM basically, you have something

397
00:41:41,299 --> 00:41:48,089
that is called an exception vector table
and this is located at this hardcoded

398
00:41:48,089 --> 00:41:55,769
address in bootrom and basically every
time when something weird happens or

399
00:41:55,769 --> 00:42:03,249
something special on the CPU it will jump
to those exception vectors like the reset

400
00:42:03,249 --> 00:42:09,000
vector as we just so or when you're trying
to read from an invalid address, it

401
00:42:09,000 --> 00:42:16,160
returns to the prefetch abort or data
abort vector and also when you receive an

402
00:42:16,160 --> 00:42:25,160
interrupt it will jump to interrupt
request vector so those are the exception

403
00:42:25,160 --> 00:42:29,580
vectors and they're hardcoded in the
bootrom and there's kind of a problem with

404
00:42:29,580 --> 00:42:37,700
that because as a developer you don't want
to put the exception in the routines in

405
00:42:37,700 --> 00:42:45,480
the boot rom, you want to it'd be able to
change the code right? So, what they do is

406
00:42:45,480 --> 00:42:53,839
they just redirect all the exception
execution flow from bootrom to another

407
00:42:53,839 --> 00:43:01,699
jumptable that is located in ARM9 memory
so it looks like this. What you can see

408
00:43:01,699 --> 00:43:06,539
here are the bootrom vectors and it's
basically just a jump instruction to the

409
00:43:06,539 --> 00:43:12,239
RAM vectors and the RAM vectors are also
just another jump instruction to the

410
00:43:12,239 --> 00:43:16,980
actual firmware handler and this is so
things look like when the firmware is

411
00:43:16,980 --> 00:43:26,200
running but what about cold boot well on
cold boot you get this and this looks

412
00:43:26,200 --> 00:43:33,339
kinda interesting because you have the
bootrom vectors that still point to ARM9

413
00:43:33,339 --> 00:43:39,930
memory but since this is cold boot, the
RAM is not initialized so this is

414
00:43:39,930 --> 00:43:45,050
interesting but it is it's not really a
bug because at some point the bootrom will

415
00:43:45,050 --> 00:43:53,700
initialize those RAM vectors so but let's
cheat a little bit here and say let's just

416
00:43:53,700 --> 00:43:59,130
assume we could somehow trigger a really
early exception even before the bootrom is

417
00:43:59,130 --> 00:44:08,729
able to initialize the RAM vectors well
probably it was just crash because on

418
00:44:08,729 --> 00:44:13,519
exception it will just jump to
uninitialized memory and there's probably

419
00:44:13,519 --> 00:44:22,190
no valid instruction there so this is not
very useful but there's a really nice

420
00:44:22,190 --> 00:44:27,960
hardware flaw and we found this by just
writing to some memory reboot, and see

421
00:44:27,960 --> 00:44:35,010
what what happened basically we found out
that some RAM is actually not cleared on

422
00:44:35,010 --> 00:44:42,410
reboot and this also includes ARM9 so the
basic idea is we can set up some custom

423
00:44:42,410 --> 00:44:49,650
exception vectors in RAM that regenerate
execution flow to some dumper code so when

424
00:44:49,650 --> 00:44:55,579
we reboot we get this and this is really
interesting because if you look at this

425
00:44:55,579 --> 00:45:01,469
this means all we need to do now is
trigger a really early exception and then

426
00:45:01,469 --> 00:45:10,039
the bootrom will jump to our dumper code
so, how can we trigger an exception? Well

427
00:45:10,039 --> 00:45:14,489
if you look at here, the exception vector
table again there are some exceptions that

428
00:45:14,489 --> 00:45:20,261
we can trigger like because they are
hardcoded like reset and they won't jump

429
00:45:20,261 --> 00:45:29,200
to ARM9 memory and you also can't use the
interrupt vector because interrupts are

430
00:45:29,200 --> 00:45:39,190
disabled on reset and yeah this won't work
so what's left is these 3 here interesting

431
00:45:39,190 --> 00:45:45,150
exceptions and if you look at those and
they normally don't happen right undefined

432
00:45:45,150 --> 00:45:50,970
instruction is pretty rare and it
shouldn't happen so I don't know about

433
00:45:50,970 --> 00:45:57,839
this reminds me kind of like it's a really
nice use case for doing for injection

434
00:45:57,839 --> 00:46:04,759
again because you can corrupt registers
and getting mutated instruction so it's

435
00:46:04,759 --> 00:46:10,950
really likely that it will trigger an
exception so this is the vector glitch

436
00:46:10,950 --> 00:46:17,200
hack and basically we set up some vectors
in RAM, trigger reboot then do some

437
00:46:17,200 --> 00:46:24,930
glitching magic and then we reset again
and let it boot up normally and hopefully

438
00:46:24,930 --> 00:46:32,170
our dumper code got executed and just
wrote a copy of the bootrom in memory so

439
00:46:32,170 --> 00:46:38,299
we can just dump it. All this stuff is not
very stable but it works for me.

440
00:46:38,299 --> 00:46:48,549
*applause*

441
00:46:48,549 --> 00:46:57,990
Wo okay we got the bootrom and Nintendo is
losing a life there so before we look at

442
00:46:57,990 --> 00:47:08,889
the bootrom I have a little problem for
you and basically in early 2014 an FCC

443
00:47:08,889 --> 00:47:15,629
document became public. There it is, and
basically it says that Nintendo has changed

444
00:47:15,629 --> 00:47:21,400
the CPU of the Nintendo 2DS and there's
one really interesting sentence that

445
00:47:21,400 --> 00:47:26,819
basically says, they have changed security
function of the initial program loader

446
00:47:26,819 --> 00:47:33,300
that is installed in each model so the
initial program loader is probably bootrom

447
00:47:33,300 --> 00:47:42,180
so obviously there must be some really
huge bug in the bootrom, right? So so

448
00:47:42,180 --> 00:47:48,680
that's it let's look at the bootrom.
Basically there are some boot methods and

449
00:47:48,680 --> 00:47:52,721
you can boot from NAND, that's what it
normally does but alternatively you can

450
00:47:52,721 --> 00:48:00,839
also boot from SPI flash which is the
Wi-Fi flash and it will only boot firmware

451
00:48:00,839 --> 00:48:08,050
images that are signed and encrypted
there's no freaky development backdoor

452
00:48:08,050 --> 00:48:15,420
that we can exploit it also uses two
different sets of keys for NAND and non

453
00:48:15,420 --> 00:48:21,390
NAND boot methods and also for our retail
and dev mode so even when stuff gets

454
00:48:21,390 --> 00:48:28,150
leaked you cannot use it on your retail
console so let's do a small boot walk

455
00:48:28,150 --> 00:48:34,469
through and it's pretty straightforward
actually so the first thing it does is it

456
00:48:34,469 --> 00:48:41,869
selects a boot device then it loads the
firmware header and RSA signature from it

457
00:48:41,869 --> 00:48:50,959
it's just one block and then it hashes the
header and extract the hash from the

458
00:48:50,959 --> 00:48:58,170
signature and compares it, so basically a
basic signature verification header

459
00:48:58,170 --> 00:49:04,859
verification and then assumes yeah the
header is safe and then it starts loading

460
00:49:04,859 --> 00:49:12,789
the firmware sections and the firmware
images are pretty simple format and like

461
00:49:12,789 --> 00:49:19,930
you have some entries in the header that
tells you okay take the data from this

462
00:49:19,930 --> 00:49:26,849
offset and there there's a section with
the size load it to that address. It's

463
00:49:26,849 --> 00:49:32,729
pretty simple so we know from Nintendos
past that they like to mess up RSA

464
00:49:32,729 --> 00:49:42,220
signature checks so let's look as how RSA
is done on 3DS so for the 3DS firmware

465
00:49:42,220 --> 00:49:51,630
they're using RSA signatures in the PKCS
standard PKCS is basically a bunch of

466
00:49:51,630 --> 00:49:57,500
standards that tell you how your
signatures have to look like and they are

467
00:49:57,500 --> 00:50:11,269
using the 2048-bit version of RSA which is
safe and in the signature you have a SHA-2

468
00:50:11,269 --> 00:50:19,870
hash and this is encoded using ASN.1 and
ASN.1 it's some really complex structure

469
00:50:19,870 --> 00:50:26,009
it's basically it's similar to the mp3
structure so you have little chunks of

470
00:50:26,009 --> 00:50:31,490
data and those chunks have little headers
and the headers have tag bytes and length

471
00:50:31,490 --> 00:50:40,900
bytes and basically this ASN.1 stuff is
used to tell the parser which hashing

472
00:50:40,900 --> 00:50:51,311
algorithm is used and well since the SHA-2
hash is only 20 hex [0x20] bytes in size

473
00:50:51,311 --> 00:50:57,050
you have some remaining space in the
signature that you have to fill and PKCS

474
00:50:57,050 --> 00:51:01,959
says you need a padding and this padding
should be deterministic it should only

475
00:51:01,959 --> 00:51:07,950
contain FF bytes so when you're trying to
forge signatures it's it's really

476
00:51:07,950 --> 00:51:14,489
difficult because of this padding that
really long and when you compare the

477
00:51:14,489 --> 00:51:22,019
signatures of different firmware images
you'll actually notice that only the hash

478
00:51:22,019 --> 00:51:28,269
will change and the rest of the data is
always the same for all signatures but

479
00:51:28,269 --> 00:51:34,729
well for some reason they decided to write
a signature parser for this stuff so what

480
00:51:34,729 --> 00:51:45,860
you get now is RSA the Nintendo way again
so the first thing it does is it tries to

481
00:51:45,860 --> 00:51:53,129
parse the padding and this part is totally
messed up like there is a flag byte that

482
00:51:53,129 --> 00:51:59,129
tells you if the padding should be checked
and if it's one then it is checked it

483
00:51:59,129 --> 00:52:06,910
should be all FF but but if it's two then
it will just skip the padding and it also

484
00:52:06,910 --> 00:52:12,809
has some really weak bounds checking it
make sure that it will not when it's

485
00:52:12,809 --> 00:52:18,859
passing the padding it make sure that it
will not go out of bounds but they forget

486
00:52:18,859 --> 00:52:28,489
to verify that the hash will actually fit
in there as well so next thing they do is

487
00:52:28,489 --> 00:52:35,000
parsing this really complicated ASN.1
structure and this process is also really

488
00:52:35,000 --> 00:52:42,770
simplified so we know ASN.1 has some
length fields and there's no bounds

489
00:52:42,770 --> 00:52:52,800
checking so eventually it will add the
length to the current pointer in the

490
00:52:52,800 --> 00:53:02,300
signature and then they stop parsing and
say okay we parsed all the data and now

491
00:53:02,300 --> 00:53:08,950
there should be the hash and yet they are
not checking this length and this pointer

492
00:53:08,950 --> 00:53:18,430
is used to do the hash comparison so all
in all you can say it only checks a few

493
00:53:18,430 --> 00:53:23,410
bytes in the signature because the padding
parser is messed up and also the ASN.1

494
00:53:23,410 --> 00:53:29,249
parser is really simplified so what we can
do is we can bruteforce the perfect

495
00:53:29,249 --> 00:53:36,909
signature where the final pointer when
it's done parsing the padding and the

496
00:53:36,909 --> 00:53:45,779
ASN.1 data that this final pointer matches
the pointer of the calculated hash of

497
00:53:45,779 --> 00:53:57,359
bootrom so what it does then this it does
a mem compare [memory compare] with the

498
00:53:57,359 --> 00:54:05,481
calculated hash and the calculated hash
like and this never fails, right? So it

499
00:54:05,481 --> 00:54:10,009
will always succeed and this is SIGHAX.

500
00:54:10,009 --> 00:54:18,210
*applause*

501
00:54:18,210 --> 00:54:24,450
So the SIGHAX is a bootrom exploit for 3DS
and basically we can sign our own

502
00:54:24,450 --> 00:54:31,279
firmwares and there are over 60 million
vulnerable devices and basically in new

503
00:54:31,279 --> 00:54:37,259
3DS and 2DS basically all models are
affected and of course since this is the

504
00:54:37,259 --> 00:54:45,709
bootrom, Nintendo can't fix it so that's
very nice but that's one heart remaining

505
00:54:45,709 --> 00:54:54,960
so something is missing what we haven't
done yet is we haven't dumped the ARM11

506
00:54:54,960 --> 00:55:00,019
bootrom. It's probably not really
interesting but for sake of completeness

507
00:55:00,019 --> 00:55:07,759
you would like to get it and in theory we
can just do a vector glitch hack again

508
00:55:07,759 --> 00:55:13,369
because it has the same flaw but know that
we can sign our own firmwares let's try

509
00:55:13,369 --> 00:55:21,450
something else so if you look at the
unprotected part of the ARM11 bootrom you

510
00:55:21,450 --> 00:55:29,059
can see there are a lot of references to
ARM11 memory so maybe now that we can sign

511
00:55:29,059 --> 00:55:33,880
our own firmwares and we can set up our
own firmware sections maybe we can

512
00:55:33,880 --> 00:55:41,979
overwrite some bootrom data so but they're
the bootrom developers were kind of clever

513
00:55:41,979 --> 00:55:49,059
and the ARM9 bootrom checks the firmware
sections and they have some kind of

514
00:55:49,059 --> 00:55:58,359
blacklist and unfortunately you can't just
overwrite boot9 data sections sections but

515
00:55:58,359 --> 00:56:03,709
for some reason they forgot to blacklist
all the boot11 data regions so we can just

516
00:56:03,709 --> 00:56:11,770
overwrite boot11 stack or the exception
vectors and well you can dump the ARM11

517
00:56:11,770 --> 00:56:12,990
bootrom.

518
00:56:12,990 --> 00:56:21,989
*applause*

519
00:56:21,989 --> 00:56:29,520
yeah that was pretty easy and now I get to
tell you something, all this stuff about

520
00:56:29,520 --> 00:56:38,829
the bootrom we did this in summer 2015 so
we could have talked about this already

521
00:56:38,829 --> 00:56:45,880
last year but since we are kind of
friendly hackers we held this bug so long

522
00:56:45,880 --> 00:56:56,660
so yeah Nintendo should be thankful and ok
so that's it 3DS is pretty game over and

523
00:56:56,660 --> 00:57:02,209
here's a picture of Nintendo Switch and
our body is ready *laughter*

524
00:57:02,209 --> 00:57:16,429
*applause*

525
00:57:16,429 --> 00:57:21,499
Herald: Thank you very much there's about
five minutes left for questions and are

526
00:57:21,499 --> 00:57:26,749
there any questions from the internet?
No no no okay?

527
00:57:26,749 --> 00:57:32,069
Signal Angel: Yes there's actually one
question from the internet and that is the

528
00:57:32,069 --> 00:57:41,519
internet wants to know if we can get DSP
code execution maybe sometime soon

529
00:57:41,519 --> 00:57:43,000
Herald: Can you repeat the question?

530
00:57:43,000 --> 00:57:44,780
yeah very hard to understand here

531
00:57:44,780 --> 00:57:51,049
Signal Angel: Ok I'm the internet wants to
know if we can get a DSP code execution?

532
00:57:51,049 --> 00:58:02,259
derrek: Yes well the DSP of the 3DS runs
its own firmware and that is included in

533
00:58:02,259 --> 00:58:10,440
some kernel module and basically when you
can sign your own firmware you can also

534
00:58:10,440 --> 00:58:21,519
make it load another DSP firmware
so yes you can do this

535
00:58:21,519 --> 00:58:25,369
Herald: Ok people who are leaving please
do so quietly and people entering please

536
00:58:25,369 --> 00:58:35,369
do so quietly. There was a question on
microphone 3 I think but no longer okay.

537
00:58:35,369 --> 00:58:38,260
Does the internet have more questions?

538
00:58:38,260 --> 00:58:44,009
Signal Angel: Yes it does. The internet
wants to know if you or how you glitch the

539
00:58:44,009 --> 00:58:48,599
Wii U to get execution

540
00:58:48,599 --> 00:58:56,729
derrek: Well I don't want to worry how I
did it in detail but there are some basic

541
00:58:56,729 --> 00:59:04,660
fault injection attacks and my setup was
I think kind of complicated you had to

542
00:59:04,660 --> 00:59:11,490
modify a lot of stuff on the Wii U
mainboard to get it to work so I guess you

543
00:59:11,490 --> 00:59:17,260
have to figure out yourself, sorry.

544
00:59:17,260 --> 00:59:21,109
Herald: Ok there's a question
upstairs microphone five I think?

545
00:59:21,109 --> 00:59:29,920
Mic 7: Seven but it's okay. Yeah well you
said that you broke all the 2DS but

546
00:59:29,920 --> 00:59:36,880
actually you showed that the 2DS changed
in the boot process so did you verify that

547
00:59:36,880 --> 00:59:40,500
that work for the first version as well

548
00:59:40,500 --> 00:59:47,160
derrek: Yes so the new 3DS was released
after the 2DS and the new 3DS is also

549
00:59:47,160 --> 00:59:54,900
vulnerable and basically all the Nintendo
2DS consoles are also also vulnerable as

550
00:59:54,900 --> 01:00:01,140
well. Yes we did verify this and we don't
really know what this FCC document is

551
01:00:01,140 --> 01:00:12,019
about we got some really new 2DS from
store and and basically yes, no difference

552
01:00:12,019 --> 01:00:16,179
for the bootrom at all,
so yes everything is vulnerable.

553
01:00:16,179 --> 01:00:18,169
Mic 7: Nice to know, thanks.

554
01:00:18,169 --> 01:00:23,470
derrek: ok
*applause*

555
01:00:23,470 --> 01:00:25,650
Herald: Final question from microphone 3?

556
01:00:25,650 --> 01:00:29,390
Mic 3: Yeah just a fun question out of
interest when you're going to buy such a

557
01:00:29,390 --> 01:00:33,880
device do you also plan to play games on
it? Or is it just going to check if the

558
01:00:33,880 --> 01:00:38,730
other kernel works?

559
01:00:38,730 --> 01:00:42,549
naehrwert: Personally for the
Wii U, I own 0 games so

560
01:00:42,549 --> 01:00:44,199
Mic 3: Great, thanks.

561
01:00:44,199 --> 01:00:49,519
*applause*

562
01:00:49,519 --> 01:00:55,979
I also didn't pirate any so i never
played a game on my Wii U.

563
01:00:55,979 --> 01:01:19,701
*33c3 postroll music*
