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