[00:01.870 --> 00:08.990] Hello, this is our talk from Blackbox to Automotive Ransomware. [00:10.290 --> 00:21.590] My name is Nius and I have Enrico with me. We are both PhD students on DOTH Regensburg [00:22.430 --> 00:30.550] and the University of West Bohemia. We are focusing on car hacking since 2016, I think, [00:30.550 --> 00:37.370] and today we're going to show how to reverse engineer a body controller and to run [00:37.910 --> 00:46.330] Automotive Ransomware. All right, in 2019 we gave a talk IoT backdoors in cars and basically this [00:46.330 --> 00:55.690] talk is volume two of it. In this talk we showed how to exploit an OBD GSM dongle over the air and [00:55.690 --> 01:03.650] how to obtain execution on the CAN bus. And basically during this talk we showed already [01:03.650 --> 01:09.670] how to flash stuff on a car. You can see it here in the picture. This is like a lock from [01:09.670 --> 01:15.490] the dongle where we get security access where we flash some payload and this was already our [01:15.490 --> 01:20.950] exploit but we couldn't show it at this time. So today we're gonna show the car part. So what [01:20.950 --> 01:28.330] we need to do to install a ransomware on the car itself. All right, so will Automotive Ransomware [01:28.330 --> 01:38.050] be a thing? We don't know but we made a proof of concept to show the difficulties and to see [01:38.050 --> 01:46.250] what you can do and what doesn't work. All right, so in order to make a ransomware we [01:47.030 --> 01:54.550] did some theory and thought about what we need for ransomware. We figured out some components. [01:54.650 --> 02:00.990] We also wrote a paper about that since we have to publish stuff sometimes. So details you can [02:00.990 --> 02:07.110] find in the paper but basically some of these components that we're going to show today [02:07.110 --> 02:14.470] are components for infection, for self-distribution, for persistency mechanism inside the car, [02:14.470 --> 02:20.990] for malicious activity. User injection is important and some how a revert mechanism [02:20.990 --> 02:30.330] that you can uninstall the ransomware after an infection. All right, today we're gonna show [02:30.830 --> 02:37.510] the initial infection through an OBD donor or a repressure tester. Both is possible [02:38.710 --> 02:43.330] and we chose OBD since it was the easiest way for us. [02:43.330 --> 02:50.450] The self-distribution inside the car is possible but it's not part of the proof of concept. [02:50.710 --> 02:55.750] But the most likeliest for this ransomware to be distributed would be through repressure [02:55.750 --> 03:03.210] testers basically. All right, the persistency mechanism is done by writing to the flesh of [03:03.210 --> 03:10.690] the ECU which was not trivial which we show later. And malicious activity was pretty easy for us. [03:10.690 --> 03:16.270] We could use repressure tester jobs but we also analyzed the immobilizer system of this ECU [03:16.270 --> 03:22.850] in order to make the car run or not run at all. And the user injection which is very important [03:22.850 --> 03:28.250] for the ransomware since you want to frighten the user. We used the infotainment system [03:28.250 --> 03:36.290] and sent some messages to the car. All right, let's do a plan to action. [03:37.010 --> 03:42.910] We want to get ransomware on a black box ECU. First thing we need to do is we need to open [03:42.910 --> 03:49.170] security access. After that we have to figure out a way to get code execution. We need to extract [03:49.170 --> 03:54.450] the firmware and reverse engineer it. After that we're going to patch the firmware and run some [03:54.450 --> 04:03.290] malicious code on it. And last but not least we intimidate the user. Okay, first OBD. [04:03.850 --> 04:11.070] OBD is easy for us. It's available in almost every car. Soon or later every car connects to [04:11.070 --> 04:16.670] repressure tester. So if your repressure or your repressure test is infected you're gonna get [04:16.670 --> 04:23.110] the exploit or you're gonna get the ransomware. OBD gives us a direct access to all the CAN buses [04:23.110 --> 04:29.270] and especially to the diagnostic services of all ECUs even if you have a gateway for security [04:29.270 --> 04:37.590] measures and stuff. If you plug in an OBD dongle or an OBD-GSM dongle then you can get remotely [04:37.590 --> 04:46.590] exploited and if one founds a remote vulnerability inside the telematic unit of this car all we're [04:46.590 --> 04:52.730] going to show can also be done remotely and can be done over the air basically. [04:53.770 --> 05:02.730] Okay, this is our target. It's a body controller. It acts as a gateway inside the CAN, a gateway for [05:02.730 --> 05:09.590] the CAN networks. So the car we attack has two CAN networks and it runs the immobilizer code [05:09.590 --> 05:21.250] and has a direct connection to OBD2. The processor is a UPD70F3558 from Renesas with a [05:22.750 --> 05:30.930] V852E2M instruction set and two megabytes of code flash. Also we have 144 kilobytes of RAM. [05:30.930 --> 05:37.250] We have two CAN transceivers, a single wire CAN and a high speed CAN. A high speed CAN is running [05:37.250 --> 05:45.770] with 500 kilobits per second and a single wire CAN has 33.3 kilobits and besides that we have [05:45.770 --> 05:54.550] many transistors and relays for body control stuff on that ECU. Okay, how to communicate with [05:54.550 --> 06:04.430] that ECU? This ECU uses GMLAN and this is a combination of ISOTP and normal CAN messages. [06:04.710 --> 06:10.910] It's very similar to UDS but there's some differences and the documentation for the [06:10.910 --> 06:18.710] GMLAN protocol is available. And finally we wrote a SCPI module for GMLAN and we also wrote [06:18.710 --> 06:27.210] an ISOTP module, a CAN module, a CCP, OBD2, a UDS, ENET and some IP for SCPI. So check this out if [06:27.210 --> 06:35.070] you like SCPI. We try to support as much automotive stuff as possible here. Okay, to get security [06:35.070 --> 06:41.390] access let's look into the documentation. It's quite easy. We have a sub function where you can [06:41.390 --> 06:48.910] specify to get a seat or to send a key. An even number is requesting a seat, an odd number is [06:48.910 --> 06:56.510] sending a key and then we have two bytes like a high and a low byte for the key. Again two [06:56.510 --> 07:06.630] bytes of key. This is 16 bits of entropy so not that much for this car. To get security access [07:06.630 --> 07:14.350] the tester has to send a request to get a seat. Then ECU sends back a 16-bit seat and the tester [07:14.350 --> 07:22.110] calculates the corresponding key in order to obtain security access. Here's an example how [07:22.110 --> 07:29.230] security access routine might look like. You have a secret which then gets shifted and moved [07:29.230 --> 07:36.190] around with some magic numbers and at the end you obtain the key. It's important to mention here [07:36.190 --> 07:45.170] that the key is constant so we get the same seat every time. And security access [07:45.730 --> 07:55.690] takes 10 seconds after reboot until we can ask for a seat and if we fuck up and the key is wrong [07:55.690 --> 08:02.930] security access is disabled until the next reboot. So we have to power cycle and we can try infinite [08:02.930 --> 08:11.570] times. Every ECU sends different but constant seats and the whole cracking took us roughly [08:11.570 --> 08:21.730] eight days so we had 10 to 10 times to the power of 16 possibilities for sorry seconds to test [08:21.730 --> 08:28.850] every possible key. This is our setup in our laboratory where we have a power supply connected [08:28.850 --> 08:35.870] to a car battery and a big relay here on the side next to the cat which is turning on and off the [08:35.870 --> 08:42.050] car every 10 seconds and the Raspberry Pi which is then brute forcing every possible seat key [08:42.050 --> 08:47.910] combination. All right after we have security access we can start with the enumeration of [08:47.910 --> 08:55.050] services to see what kind of attack surface we have on the ECU. Again we use SCEPI for this. [08:55.670 --> 09:01.150] We are pretty interested in the programming mode and after security access we can enter [09:01.150 --> 09:08.210] this programming mode. Here's a screenshot of SCEPI of the results from enumeration. On the left [09:08.210 --> 09:16.430] side you see all possible GMLAN services and on top you see different states where the ECU is in. [09:17.130 --> 09:24.430] Most important the state on the most right side the programming session with security access and [09:24.430 --> 09:33.350] request download entered. As you can see this one gives us a positive response on the request [09:33.350 --> 09:41.330] download job if we enter that. So this is a good sign for us and a very good attack surface. [09:42.450 --> 09:48.730] Let's look into request download and transfer data. How does that work? On this ECU we were [09:48.730 --> 09:55.950] unlucky. Read memory address was not supported so we could not just say give me an arbitrary address [09:55.950 --> 10:00.810] and give me a memory for it. So firmware extraction was not possible through that [10:00.810 --> 10:07.250] but request download was possible and transfer data as well. Another feature of transfer data [10:07.250 --> 10:13.250] is in this specification the download and execute sub-function. Let's look in the specification. [10:13.250 --> 10:19.690] Here we have the GMLAN transfer data function and the sub-function can be two different things [10:19.690 --> 10:26.570] download and download and execute or execute. Then you have to give a starting address [10:26.570 --> 10:32.810] and a data record. This is how we will basically transfer data to this ECU. [10:33.990 --> 10:40.950] And download and execute is really execute. Later we reverse-engineered the bootloader. [10:40.950 --> 10:48.150] This is an IDA picture of it. So here you can see the service 36 which is transfer data [10:48.790 --> 10:54.790] and the sub-function 80 which then gives us download and execute or execute. And if we enter [10:54.790 --> 11:02.570] here we have the four bytes to int which is the starting address. This function gives us the [11:02.570 --> 11:12.090] starting address back into R10 and then it's moved into R29 and after that we directly jump to R29. [11:12.090 --> 11:19.250] So code execution by design is not a big deal for us. To exploit that you can use [11:19.250 --> 11:25.310] scapy again. This is an exploit function. We have two sockets here for communicating with the vehicle [11:26.050 --> 11:33.350] and then we have a couple of gmlan functions for initiate diagnostic operations, [11:33.350 --> 11:41.630] getting security access and then finally transfer payload transfers our exploit payload to the entry [11:41.630 --> 11:49.890] we give it. And then after all this went through you can just send gmlan transfer data with the [11:49.890 --> 11:55.290] sub-function download and execute or execute and the starting address you want to jump to. [11:56.030 --> 12:04.450] That's it. So Enrico, how do we move forward from here? So first of all we want to show that we [12:04.450 --> 12:13.710] really have a code execution and for doing that the simplest way is downloading some garbage into [12:13.710 --> 12:20.350] the memory and trying to execute it. So for example if I just transfer a 000 which in this [12:20.350 --> 12:27.230] instruction set is a NOP, then the ECU will execute this NOP and then start executing whatever [12:27.230 --> 12:34.030] is after it in the memory which might be uninitialized. And in fact if we do this, [12:34.030 --> 12:41.490] if we call the previous scapy exploit function with 000 as data, the ECU will crash. [12:42.270 --> 12:49.110] Now if instead I terminate the function with 7f00 which in this instruction set [12:49.110 --> 12:56.210] is a jump to the link pointer which is how a return from a function is encoded, then the [12:56.910 --> 13:01.590] ECU will not crash because we are correctly returning to the caller. [13:01.630 --> 13:09.050] Now we were lucky in this case because the function that called our exploit call did not [13:09.050 --> 13:15.190] create some stack frame, so we did not have to pop to the stack frame and restore the [13:16.150 --> 13:22.970] registers for the caller. But in case that was the case, we would have needed to brute force [13:22.970 --> 13:31.790] all the possible shapes of the stack frame which is not really a big issue. But in this case we [13:31.790 --> 13:40.450] were lucky, so just sending out these four bytes will let the ECU execute this NOP and then [13:40.450 --> 13:48.510] jump back to the normal execution. And yeah, this shows that we can execute code on this ECU. [13:49.590 --> 13:57.630] Now we want to dump the firmware because we could not read it out with read memory by address. [13:59.390 --> 14:05.050] So we want to build a small exploit, a small software that dumps the firmware for us over [14:05.050 --> 14:12.750] KEM. We were able to find an IDE for the V850 family of processor for the V850 architecture, [14:12.750 --> 14:21.050] but no tool specific for our processor. We assume that the tools for our [14:21.670 --> 14:26.690] version of this processor are only available to automotive OEMs. [14:27.390 --> 14:32.290] So in the beginning for us it was easier to write small chunks of V850 assembly [14:32.290 --> 14:40.950] to dump the entire firmware over KEM. So this is an example of how we figured out how to send [14:40.950 --> 14:50.610] messages over KEM with our small assembly pieces of code. First of all, we have to set the register [14:51.350 --> 15:01.310] IP with the address of the KEM interface where we want to send the IP, where we want to send [15:01.310 --> 15:09.810] the KEM message from. In this case it is FCN3. We figured this out by reverse engineering the PCB [15:09.810 --> 15:17.890] and trying out all the different KEM interfaces. And then we just have to write 300 in hexadecimal [15:17.890 --> 15:26.830] to that address in order to let the KEM interface send whatever was in the buffer [15:26.830 --> 15:35.970] at that moment in time. Now doing this, the last KEM frame that the issue sent will be sent again. [15:35.970 --> 15:43.850] And by seeing the same KEM frame twice we knew that we were successful in sending something [15:45.310 --> 15:52.130] over with our assembly code. So the next step was sending some custom [15:53.810 --> 15:59.570] data over KEM. This is a bit more complicated because it requires unlocking the message [15:59.570 --> 16:04.790] buffer for writing it and then locking it again when sending the message. So this took quite a [16:04.790 --> 16:11.390] long time to blindly run code, reading the manual and figuring out how to do this. But [16:11.390 --> 16:17.350] in the end we figured it out. It's just a matter of writing 17 in hexadecimal in the same [16:17.870 --> 16:25.870] address as before. This unlocks the message buffer for writing. Now we can write the [16:26.510 --> 16:33.750] KEM ID. This needs to be multiplied by 4 for some reason. And we can write it. This is written to [16:33.850 --> 16:42.550] a different address in the same peripheral. Then we have to write the length of the message. [16:42.550 --> 16:51.470] For some reason this CPU has a bit... has a curve where different sizes of registers need to be [16:51.470 --> 16:58.910] written at different addresses in the memory map. So before we were writing half words, 16 bits at [16:59.010 --> 17:04.870] a time. And now we're writing something in a register which is a single byte. So we have to [17:04.870 --> 17:11.890] change the register, change the address of the memory map to register. But after reading the [17:11.890 --> 17:17.070] manual enough and figuring out what we were doing wrong, we were able to change the size of the [17:17.070 --> 17:24.850] sent KEM message finally, in this case to 4. And finally we can change the data by writing to this [17:24.850 --> 17:31.150] address right here. In this case I'm writing dead beef. I have to write it in Lithuanian, so [17:31.150 --> 17:38.890] A-D-D-E-E-F-B-E. Also here it was quite confusing the fact that the registers for the buffer [17:39.690 --> 17:47.270] are not contiguous. So the first two bytes are stored at offset 0 and the next two bytes are [17:47.270 --> 17:53.750] stored at offset 8 and so on. Finally we have to send the buffer that we prepared [17:54.350 --> 18:01.010] and this time I have to write 700 hexadecimal instead of 300. This was because I also had to [18:01.010 --> 18:07.230] lock the message and cause the buffer to refresh. Now all of these required a lot of effort and [18:07.230 --> 18:13.990] trying, but in the end we were able to send the custom messages. So at this point nothing stops [18:13.990 --> 18:21.170] us from dumping the entire firmware. So for example, if we want to dump address 1-2-3-4-0, [18:21.170 --> 18:26.930] what we have to do is prepare the address that we want to dump into register 2 for example, [18:27.970 --> 18:35.150] point the NTP pointer, which is another register, to the CAN interface like before and then [18:35.890 --> 18:44.530] read two bytes at a time from R2 and write them into the EP. And this way we were able to dump [18:44.530 --> 18:51.670] the entire firmware, one request at a time. So now we have the firmware and it's time for some [18:51.670 --> 19:01.750] reverse engineering. This work was made a few years ago and at that point in time there wasn't [19:02.250 --> 19:07.850] really a choice for tools to use for reverse engineering these architectures. [19:07.850 --> 19:17.730] First we tried with AIDA. We actually have a license at our university, but our license is [19:17.730 --> 19:23.230] only for a very old version and it did not support the V850-E2 instruction set. [19:23.410 --> 19:31.450] And a new license is super expensive. We tried RADAR, same thing, didn't support the [19:32.150 --> 19:39.370] V850-E2 extension of the instruction set. And finally JITRA didn't exist yet, well it wasn't [19:39.370 --> 19:46.280] published yet, but when it was published it also didn't support the V850-E2 architecture. [19:46.710 --> 19:52.310] So at this point we were really sad because we could not reverse engineer the firmware, [19:52.310 --> 19:58.270] we did not have the tools. However you don't need to be sad anymore because recently JITRA [19:58.270 --> 20:03.450] started supporting this instruction set and this extension thanks to this pull request here [20:04.190 --> 20:11.850] from Alex Lasso, which is one of our students. And he just finished his bachelor writing this [20:11.850 --> 20:20.410] plugin as his thesis. So what I ended up doing at the moment for getting to work fast was writing [20:20.410 --> 20:29.810] an AIDA plugin for V850-E2 processors. I started from this already existing plugin called Necromancer [20:30.530 --> 20:38.730] which supported some instructions but was incomplete. And then I wrote a small parser [20:38.730 --> 20:47.710] that from the PDF manual generated the Python arrays, Python code for the AIDA plugin. So this [20:47.710 --> 20:53.490] is the manual, this is how an instruction is encoded. There are a bunch of static constant [20:53.490 --> 21:00.950] zeros and one and some bits which are representing the registers that this instruction can access [21:00.950 --> 21:10.150] and these are variable. And yeah this parser will parse this PDF and output these tables, [21:10.150 --> 21:20.290] these arrays which then could be fed into the plugin for AIDA. And this is a screenshot showing [21:20.290 --> 21:29.450] it working. So all the instructions that are uppercase here were disassembled from the plugin [21:29.870 --> 21:35.690] and they were not already existing in AIDA. They were not supported by AIDA. [21:38.580 --> 21:47.300] Now that we can reverse engineer the firmware, we should look at how it is structured. There is a [21:47.300 --> 21:54.140] bootloader in the beginning which is 32 kilobytes. This bootloader contains the code that is executing [21:54.140 --> 21:58.380] during the programming mode. So when we switch to programming mode with security access, this is [21:58.380 --> 22:05.600] what is getting executed. After that there is the firmware, the program for the rest of the [22:05.600 --> 22:11.680] application on this issue. This is 1.3 megabytes and this contains everything that runs while [22:11.680 --> 22:19.560] you're driving the car. Then there is around 700 kilobytes of empty program flash. So this is [22:19.560 --> 22:27.360] great for us because this is where we can write our persistent malware. And finally there is a few [22:27.360 --> 22:35.500] kilobytes of configuration. So we have a lot of space to write a persistent malware. So let's [22:35.500 --> 22:44.260] try doing that. Let's see how difficult this is. Of course we cannot write simply with the security [22:44.260 --> 22:49.720] access and transfer data because those can only write to a very specific portion of the RAM. [22:52.340 --> 22:56.980] There is no code in the entire firmware that performs writes to the flashing. [22:56.980 --> 23:03.180] So it is clear that for flashing, for updates on this issue, they were relying on the [23:04.820 --> 23:09.780] execution of external data from the RAM, this programming mode. [23:10.920 --> 23:14.300] And also the reference manual for the processor does not give any information [23:14.300 --> 23:20.480] about how to write to the flash and it only says that you should be using this FSL library. [23:21.460 --> 23:27.880] So we managed to find this library, download it, and again it didn't work for our specific [23:27.880 --> 23:34.100] V850 processor, but we found one that worked for a very similar one. [23:35.020 --> 23:41.920] And it's a binary. It's already compiled. There is no source code. There is some example [23:42.760 --> 23:48.460] source code, but the examples use the compiled library. [23:49.800 --> 23:55.320] So we had to reverse engineer this. And what we could gather from reverse engineering is that [23:55.320 --> 24:01.120] first, the flashing code can only run from RAM because the entire flash, [24:01.120 --> 24:06.260] which normally contains the program, is disabled during the write and erase operations. [24:06.760 --> 24:17.460] So also when we disable the write protection on the flash, the entire address space of the [24:17.460 --> 24:24.360] flash gets replaced by some other code, which was confusing, but it looks like some kind of [24:24.360 --> 24:31.000] internal ROM or maybe a BIOS. And write and erase operations are simply executed by [24:31.000 --> 24:37.900] preparing the command and the parameters like addresses and the new data into registers from [24:37.900 --> 24:48.500] R7 to R10, and then jumping to a very specific address here, FEDFFFF0, which performs the [24:48.500 --> 24:58.740] flashing operation for us. Of course, the first flash writes were very scary. So I first started [25:00.180 --> 25:08.160] writing... as I said, it's scary. So I first started writing on empty places in the flash. [25:08.560 --> 25:13.900] And this is just to verify that the flashing was working. And after a few attempts, [25:13.900 --> 25:19.540] it was able to write the flash. And then the next step was patching the bootloader [25:19.540 --> 25:24.500] in a way that we didn't have to wait 10 seconds before switching to the programming mode. [25:24.500 --> 25:28.940] We could do it instantly. So yeah, I patched the bootloader in a way that [25:28.940 --> 25:34.260] the issue would always start in the bootloader, so in the programming mode. [25:35.840 --> 25:42.640] So now the requirement for writing a complex ransomware here. First, we don't want to write [25:42.640 --> 25:47.700] the entire thing in assembly. We imagine we have to write a lot of code, so we want to write it in [25:47.700 --> 25:54.320] C. Secondly, we don't want to break the functionality of the body control module, [25:54.320 --> 26:00.700] because it's an essential component when you're driving the car. And because of this, [26:00.700 --> 26:06.860] it will be very practical to have code running in your own thread. So a thread is just for us. [26:06.860 --> 26:11.180] But this issue did not implement threads at all. This issue just has a single program [26:11.180 --> 26:19.040] cooperating with the tasking, not even parallel tasks. One function executes after the other one. [26:20.020 --> 26:25.860] Other problems. There is a hardware watchdog and a software watchdog. [26:25.860 --> 26:32.540] Both are going to reset the CPU when it doesn't respond in time. And this is another reason why [26:32.540 --> 26:39.060] we need to write a parallel thread with a yield function, because otherwise we cannot run a [26:39.060 --> 26:47.120] long-running program. And also, we did not have the linker. We had a linker that supported [26:48.020 --> 26:55.520] a very similar processor, and we could only compile C that ran from RAM, basically. No flash. [26:55.520 --> 27:02.620] We could only run our C code from RAM. And finally, another issue. There are these two [27:02.620 --> 27:11.080] registers, R5 and GP, which get set statically to a constant value by the compiler. [27:11.080 --> 27:14.840] And then for doing the whole execution of the program, they will preserve the same [27:16.080 --> 27:21.600] value. And this value is going to be different depending on what the compiler decides. So [27:22.420 --> 27:30.120] when executing our code, it was necessary to preserve the original values of these two [27:30.120 --> 27:36.920] registers and then restore them back before passing control back to the original code of [27:36.920 --> 27:41.080] this VCU. And this makes return-oriented programming very hard, of course, because [27:41.080 --> 27:47.460] we cannot just jump to already existing code to let it do our stuff. We have to [27:47.460 --> 27:53.700] be careful about these two registers. So let's look at how we ended up implementing [27:53.700 --> 28:02.740] our exploits, given all of these limitations. First, we used transfer data to load our code [28:02.740 --> 28:09.260] into the empty portion of the RAM, where we can execute it from. And then we execute it, [28:09.260 --> 28:16.760] and this one will patch some exploit into the empty flash, which is this large part of flash [28:16.760 --> 28:23.560] which is not used, 700 kilobytes. Then we also patched two interrupt service routines. So the [28:23.560 --> 28:29.980] interrupt handlers for both a timer, which gets called periodically, where we will execute our [28:29.980 --> 28:37.820] thread, and the interrupt service routine for canReceive, so that we can receive can frames [28:37.820 --> 28:43.640] for the rest of the car. And if we are interested in them, save them in a message box in a buffer [28:44.360 --> 28:52.540] for our thread to pick them up later. After this patching occurs, during the first execution [28:52.540 --> 29:03.870] of the timer ISR, our patch will jump to our code in the empty part of the flash, [29:03.870 --> 29:10.410] which is now not empty anymore. And this code is written in assembly, because we cannot compile [29:10.410 --> 29:20.230] code to the flash. And what this piece of code does, it just copies the rest of the code [29:20.230 --> 29:27.730] from flash to the empty position in the RAM, where code normally is downloaded. And then, [29:27.730 --> 29:33.870] after the code is copied there, on the next time the timer, interrupt service routine, or [29:33.870 --> 29:43.130] canRoutine are called, we are jumping to the RAM exploit, so the code we have placed in the RAM. [29:43.130 --> 29:45.970] Also, we have a small [29:47.990 --> 29:53.690] signature at the beginning of our RAM exploit to verify that we prepared the exploit there, [29:53.690 --> 29:59.710] and that it didn't crash last time. So, we put some safety measures there to ensure that [30:00.170 --> 30:06.690] we didn't get locked out of our only ECU. We only had one ECU to do all of this. [30:07.490 --> 30:12.110] And finally, to inject the parallel process, this thread, [30:13.050 --> 30:18.810] we changed the timer interrupt, as I said before, and then implemented a small yield function, [30:18.810 --> 30:24.690] which saves the entire state of the execution of our exploit. [30:25.730 --> 30:33.370] Basically, in its own stack, we have a stack for our thread, and this allows us to do stuff like [30:33.370 --> 30:41.010] yield or sleep in between our program, and it works like an Arduino where [30:42.310 --> 30:50.810] we can keep running the rest of the code of the car and make sure the watchdog doesn't kick us out. [30:52.610 --> 30:58.470] So, this is all regarding patching of the firmware. Now, Nils will explain the features [30:58.470 --> 31:07.510] that we implemented in our ransomware. So, now after we have basically our own thread in an [31:07.510 --> 31:13.990] unknown operating system where we can inject our code. So, all this portion that we showed, [31:13.990 --> 31:21.810] which lives in RAM, has all code written in C, and we can write our ransomware completely in C, [31:21.810 --> 31:29.330] we have a yield and a time or sleep function in order to wait for certain events, [31:29.330 --> 31:34.950] and we can also receive CAN messages, as Enrico said, through the CAN interrupt service routine. [31:34.950 --> 31:43.470] We can store incoming CAN messages into our own ring buffer in our ransomware and can then [31:43.470 --> 31:50.710] give this message back to the normal operating system. And this is very handy for us since the [31:50.710 --> 31:56.110] car acts completely normal. We can still drive the car, we can do everything with the car, [31:56.110 --> 32:03.810] and have our ransomware running independently. Okay, to implement these features, we need a [32:03.810 --> 32:13.230] couple of things. So, we want still to interact with the user. We wanted to lock and unlock the [32:13.230 --> 32:18.150] immobilizer. So, we implemented a way that we can start the car without key, and we can also [32:18.150 --> 32:26.870] not start the car with key, basically, in order to really put pressure onto our ransomware. [32:27.630 --> 32:36.190] And then we also need to send ICTP messages to make the car behave badly, in order to [32:36.950 --> 32:43.410] scare the driver. And we want to use some extracted rehearsal tester jobs [32:44.350 --> 32:51.650] to run these actions, basically. Okay, talking to the user. This is very important for the [32:51.650 --> 32:57.690] ransomware, because if you cannot tell someone that the car is owned by the ransomware, no one [32:57.690 --> 33:05.450] will pay. But yeah, how can we do this? The multimedia ECU of this car has a screen connected. [33:05.450 --> 33:12.790] The radio has its screen, and also this car has a Wi-Fi hotspot. So, the car owner can [33:12.790 --> 33:19.730] open up a hotspot and connect with its smartphone to the Wi-Fi hotspot. In order to connect the [33:19.730 --> 33:28.530] access points from the car, the car driver needs login credentials. And these login credentials [33:28.530 --> 33:35.590] need to be transferred from the telematic ECU to the multimedia ECU. And obviously, [33:35.590 --> 33:41.010] they get transferred over CAN. And luckily, over the same CAN as our body control module is [33:41.010 --> 33:47.390] connected to. So, the module that we own now is connected on the same CAN bus, where also the [33:47.390 --> 33:54.150] multimedia and telematic ECU do their job and their message exchange. Here is an example of [33:54.150 --> 34:01.150] some SCEPI code, where we analyzed the ICT communication. We see a first frame here, [34:01.150 --> 34:09.190] some flow control, and then some data. And if you defragment all of this data, you can see [34:09.780 --> 34:17.090] some strings here. So, there's... it's Italian, since we put the car to Italian language. [34:17.090 --> 34:24.160] You can see here Imposizioni Wi-Fi and Anula, which means Wi-Fi settings and abort. [34:24.730 --> 34:31.010] And these are basically the text fields for the button on the screen in the car. And we can [34:31.010 --> 34:39.270] send our own text strings here in order to show any message we want. Okay, so how does this look [34:39.270 --> 34:51.190] like? So, here we see the car and it takes roughly 30 seconds to start. We can let you run, [34:51.190 --> 34:56.810] the expert basically run on every event. You can wait for a year after the car got infected. [34:56.850 --> 35:03.550] You can wait until the car does more than 100 kilometers per hour, whatever. So, it's completely [35:03.550 --> 35:12.990] free. So, and this time, here the ransomware starts. We can see the screen, we can have the [35:12.990 --> 35:23.650] buttons, and can talk to the user. Here we are playing around with the dashboard to behave badly, [35:23.650 --> 35:43.090] basically. We disable GPS. We also spin up the engine van. So, you will hear it now. [35:51.860 --> 35:59.740] And we attack again the dashboard to do some stuff. Let some LEDs blink. [36:00.880 --> 36:06.100] So, as soon as you want to pay, the expert is over. [36:07.100 --> 36:16.360] All right, this was the live demonstration. We also investigated if you can spread the infection [36:16.360 --> 36:23.920] to other ECUs. So, during our time that we worked on this car, we investigated the EPIC ECU. We [36:23.920 --> 36:32.140] investigated the telematic ECU and the engine control unit. And security access and code [36:32.140 --> 36:39.000] execution on the EPIC ECU were trivial. So, theoretically, it would be very likely and [36:39.000 --> 36:47.060] possible that you can infect also other ECUs in that car and that this one ransomware spreads [36:47.060 --> 36:59.110] around over all the ECUs in the car. There are some limitations since to do this, basically, [36:59.610 --> 37:07.390] our ransomware would be prepared with expert codes for all the individual ECUs. And this is [37:07.390 --> 37:13.550] also one of the things which is still, in our opinion, the most limiting factor for writing [37:13.550 --> 37:22.170] malware or ransomware for cars nowadays. So, lessons learned from here. In this car, [37:22.170 --> 37:28.110] we didn't have any cryptographic challenges and the flashing of the body control unit was easy. [37:29.530 --> 37:37.090] The most problems we had were by the obscurity. So, the flashing library was locked down [37:37.950 --> 37:44.050] only for the OEMs. So, only if you sign NDAs, you get these tools, you get the hardware. [37:44.450 --> 37:52.330] The hardware was proprietary. We didn't got any compiler for this processor. So, this is really [37:52.330 --> 38:00.190] limiting factor. And also, in total for malware, the most limiting factor is the heterogonous [38:00.190 --> 38:06.370] systems in the car. So, that every ECU has a different chip set, has different instruction [38:06.370 --> 38:12.750] set, has different bootloaders, of course, which need to be exploited in a different way. [38:12.750 --> 38:18.190] And this is, yeah, in our opinion, the most secure, in fact, at the moment. [38:20.370 --> 38:25.970] Yeah, and this, as I said, the problems are common for all ECUs. In the future, we expect [38:25.970 --> 38:31.870] more Linux in cars and less obscurity and more homogeneous systems and platforms [38:32.510 --> 38:38.730] and probably more server-based. So, yeah, the architecture will probably completely change. [38:40.130 --> 38:48.450] Some facts about our proof of concept. This proof of concept was released on a car in 2016. [38:49.370 --> 39:01.610] We was made for a car released in 2016. We think almost all cars with a lower price range [39:01.610 --> 39:08.710] will have similar bad security at the moment, or let's say a little bit older cars also, [39:08.710 --> 39:13.570] you can affect even a not connected car as soon as it connects to the repair shop tester [39:13.570 --> 39:19.610] and this repair shop tester has a malware, then you have it. And these cars will still [39:19.610 --> 39:26.350] drive around for 5 to 10 more years. So, for example, in Germany, the average age is 9.5 years [39:27.650 --> 39:33.670] and all cars will frequently connect to a repair shop tester. So, this is a very easy way for [39:33.670 --> 39:43.070] infecting this insecure cars. All right, yeah, you can follow us on Twitter if you like and [39:43.750 --> 39:46.730] thanks for listening. Thanks for listening.