WEBVTT

00:01.870 --> 00:08.990
Hello, this is our talk from Blackbox to Automotive Ransomware.

00:10.290 --> 00:15.030
My name is Nius and I have Enrico with me.

00:15.490 --> 00:25.070
We are both PhD students on DOTH Regensburg and the University of West Bohemia.

00:25.070 --> 00:39.830
We are focusing on car hacking since 2016, I think, and today we're going to show how to reverse engineer a body controller and to run Automotive Ransomware.

00:40.050 --> 00:48.710
All right, in 2019 we gave a talk IoT backdoors in cars and basically this talk is volume two of it.

00:48.710 --> 01:00.670
In this talk we showed how to exploit an OBD GSM dongle over the air and how to obtain execution on the CAN bus.

01:00.790 --> 01:06.590
And basically during this talk we showed already how to flash stuff on a car.

01:06.770 --> 01:08.370
You can see it here in the picture.

01:08.370 --> 01:17.870
This is like a lock from the dongle where we get security access where we flash some payload and this was already our exploit but we couldn't show it at this time.

01:17.870 --> 01:20.390
So today we're gonna show the car part.

01:20.390 --> 01:25.570
So what we need to do to install a ransomware on the car itself.

01:25.630 --> 01:29.250
All right, so will Automotive Ransomware be a thing?

01:29.830 --> 01:41.330
We don't know but we made a proof of concept to show the difficulties and to see what you can do and what doesn't work.

01:41.330 --> 01:51.610
All right, so in order to make a ransomware we did some theory and thought about what we need for ransomware.

01:51.610 --> 01:54.550
We figured out some components.

01:54.650 --> 01:59.990
We also wrote a paper about that since we have to publish stuff sometimes.

01:59.990 --> 02:16.550
So details you can find in the paper but basically some of these components that we're going to show today are components for infection, for self-distribution, for persistency mechanism inside the car, for malicious activity.

02:16.550 --> 02:26.890
User injection is important and some how a revert mechanism that you can uninstall the ransomware after an infection.

02:27.110 --> 02:36.850
All right, today we're gonna show the initial infection through an OBD donor or a repressure tester.

02:36.850 --> 02:43.330
Both is possible 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:57.370
But the most likeliest for this ransomware to be distributed would be through repressure testers basically.

02:58.090 --> 03:07.270
All right, the persistency mechanism is done by writing to the flesh of the ECU which was not trivial which we show later.

03:07.350 --> 03:10.690
And malicious activity was pretty easy for us.

03:10.690 --> 03:20.430
We could use repressure tester jobs but we also analyzed the immobilizer system of this ECU in order to make the car run or not run at all.

03:20.730 --> 03:26.310
And the user injection which is very important for the ransomware since you want to frighten the user.

03:26.310 --> 03:31.610
We used the infotainment system and sent some messages to the car.

03:32.670 --> 03:36.290
All right, let's do a plan to action.

03:37.010 --> 03:40.790
We want to get ransomware on a black box ECU.

03:40.790 --> 03:44.270
First thing we need to do is we need to open security access.

03:44.270 --> 03:48.070
After that we have to figure out a way to get code execution.

03:48.130 --> 03:51.790
We need to extract the firmware and reverse engineer it.

03:51.790 --> 03:55.970
After that we're going to patch the firmware and run some malicious code on it.

03:55.990 --> 03:59.010
And last but not least we intimidate the user.

03:59.310 --> 04:03.290
Okay, first OBD.

04:03.850 --> 04:06.150
OBD is easy for us.

04:06.150 --> 04:08.710
It's available in almost every car.

04:08.750 --> 04:12.090
Soon or later every car connects to repressure tester.

04:12.090 --> 04:20.150
So if your repressure or your repressure test is infected you're gonna get the exploit or you're gonna get the ransomware.

04:20.530 --> 04:31.210
OBD gives us a direct access to all the CAN buses and especially to the diagnostic services of all ECUs even if you have a gateway for security measures and stuff.

04:31.750 --> 04:52.730
If you plug in an OBD dongle or an OBD-GSM dongle then you can get remotely exploited and if one founds a remote vulnerability inside the telematic unit of this car all we're going to show can also be done remotely and can be done over the air basically.

04:53.770 --> 04:56.650
Okay, this is our target.

04:56.650 --> 04:58.530
It's a body controller.

04:58.890 --> 05:03.610
It acts as a gateway inside the CAN, a gateway for the CAN networks.

05:03.610 --> 05:12.790
So the car we attack has two CAN networks and it runs the immobilizer code and has a direct connection to OBD2.

05:13.470 --> 05:27.130
The processor is a UPD70F3558 from Renesas with a V852E2M instruction set and two megabytes of code flash.

05:27.310 --> 05:30.930
Also we have 144 kilobytes of RAM.

05:30.930 --> 05:36.210
We have two CAN transceivers, a single wire CAN and a high speed CAN.

05:36.210 --> 05:51.010
A high speed CAN is running with 500 kilobits per second and a single wire CAN has 33.3 kilobits and besides that we have many transistors and relays for body control stuff on that ECU.

05:51.410 --> 05:55.210
Okay, how to communicate with that ECU?

05:55.210 --> 06:04.430
This ECU uses GMLAN and this is a combination of ISOTP and normal CAN messages.

06:04.710 --> 06:12.790
It's very similar to UDS but there's some differences and the documentation for the GMLAN protocol is available.

06:12.790 --> 06:26.190
And finally we wrote a SCPI module for GMLAN and we also wrote an ISOTP module, a CAN module, a CCP, OBD2, a UDS, ENET and some IP for SCPI.

06:26.190 --> 06:28.230
So check this out if you like SCPI.

06:28.230 --> 06:31.690
We try to support as much automotive stuff as possible here.

06:33.930 --> 06:37.350
Okay, to get security access let's look into the documentation.

06:37.810 --> 06:39.450
It's quite easy.

06:39.450 --> 06:44.190
We have a sub function where you can specify to get a seat or to send a key.

06:44.930 --> 06:55.510
An even number is requesting a seat, an odd number is sending a key and then we have two bytes like a high and a low byte for the key.

06:55.590 --> 06:57.430
Again two bytes of key.

06:57.430 --> 07:04.050
This is 16 bits of entropy so not that much for this car.

07:05.070 --> 07:11.270
To get security access the tester has to send a request to get a seat.

07:11.270 --> 07:20.410
Then ECU sends back a 16-bit seat and the tester calculates the corresponding key in order to obtain security access.

07:20.410 --> 07:24.910
Here's an example how security access routine might look like.

07:24.910 --> 07:33.890
You have a secret which then gets shifted and moved around with some magic numbers and at the end you obtain the key.

07:34.530 --> 07:42.770
It's important to mention here that the key is constant so we get the same seat every time.

07:43.390 --> 07:59.310
And security access takes 10 seconds after reboot until we can ask for a seat and if we fuck up and the key is wrong security access is disabled until the next reboot.

07:59.310 --> 08:04.130
So we have to power cycle and we can try infinite times.

08:05.850 --> 08:23.770
Every ECU sends different but constant seats and the whole cracking took us roughly eight days so we had 10 to 10 times to the power of 16 possibilities for sorry seconds to test every possible key.

08:23.790 --> 08:43.530
This is our setup in our laboratory where we have a power supply connected to a car battery and a big relay here on the side next to the cat which is turning on and off the car every 10 seconds and the Raspberry Pi which is then brute forcing every possible seat key combination.

08:44.650 --> 08:52.250
All right after we have security access we can start with the enumeration of services to see what kind of attack surface we have on the ECU.

08:52.610 --> 08:55.050
Again we use SCEPI for this.

08:55.670 --> 09:02.350
We are pretty interested in the programming mode and after security access we can enter this programming mode.

09:02.350 --> 09:07.710
Here's a screenshot of SCEPI of the results from enumeration.

09:07.710 --> 09:16.430
On the left side you see all possible GMLAN services and on top you see different states where the ECU is in.

09:17.130 --> 09:27.090
Most important the state on the most right side the programming session with security access and request download entered.

09:27.090 --> 09:37.890
As you can see this one gives us a positive response on the request download job if we enter that.

09:37.950 --> 09:41.330
So this is a good sign for us and a very good attack surface.

09:42.450 --> 09:45.330
Let's look into request download and transfer data.

09:45.330 --> 09:46.730
How does that work?

09:47.450 --> 09:49.530
On this ECU we were unlucky.

09:49.530 --> 09:57.770
Read memory address was not supported so we could not just say give me an arbitrary address and give me a memory for it.

09:57.770 --> 10:04.730
So firmware extraction was not possible through that but request download was possible and transfer data as well.

10:04.970 --> 10:11.510
Another feature of transfer data is in this specification the download and execute sub-function.

10:11.510 --> 10:13.250
Let's look in the specification.

10:13.250 --> 10:23.950
Here we have the GMLAN transfer data function and the sub-function can be two different things download and download and execute or execute.

10:24.150 --> 10:28.070
Then you have to give a starting address and a data record.

10:28.070 --> 10:32.810
This is how we will basically transfer data to this ECU.

10:33.990 --> 10:38.010
And download and execute is really execute.

10:38.010 --> 10:40.950
Later we reverse-engineered the bootloader.

10:40.950 --> 10:44.110
This is an IDA picture of it.

10:44.110 --> 10:54.110
So here you can see the service 36 which is transfer data and the sub-function 80 which then gives us download and execute or execute.

10:54.110 --> 10:59.990
And if we enter here we have the four bytes to int which is the starting address.

11:00.290 --> 11:12.090
This function gives us the starting address back into R10 and then it's moved into R29 and after that we directly jump to R29.

11:12.090 --> 11:17.290
So code execution by design is not a big deal for us.

11:17.450 --> 11:20.530
To exploit that you can use scapy again.

11:20.530 --> 11:22.230
This is an exploit function.

11:22.230 --> 11:42.990
We have two sockets here for communicating with the vehicle and then we have a couple of gmlan functions for initiate diagnostic operations, getting security access and then finally transfer payload transfers our exploit payload to the entry we give it.

11:42.990 --> 11:55.290
And then after all this went through you can just send gmlan transfer data with the sub-function download and execute or execute and the starting address you want to jump to.

11:56.030 --> 11:56.870
That's it.

11:56.870 --> 12:00.330
So Enrico, how do we move forward from here?

12:00.630 --> 12:16.150
So first of all we want to show that we really have a code execution and for doing that the simplest way is downloading some garbage into the memory and trying to execute it.

12:16.150 --> 12:31.970
So for example if I just transfer a 000 which in this instruction set is a NOP, then the ECU will execute this NOP and then start executing whatever is after it in the memory which might be uninitialized.

12:32.070 --> 12:41.490
And in fact if we do this, if we call the previous scapy exploit function with 000 as data, the ECU will crash.

12:42.270 --> 13:01.590
Now if instead I terminate the function with 7f00 which in this instruction set is a jump to the link pointer which is how a return from a function is encoded, then the ECU will not crash because we are correctly returning to the caller.

13:01.630 --> 13:18.350
Now we were lucky in this case because the function that called our exploit call did not create some stack frame, so we did not have to pop to the stack frame and restore the registers for the caller.

13:18.350 --> 13:31.170
But in case that was the case, we would have needed to brute force all the possible shapes of the stack frame which is not really a big issue.

13:31.170 --> 13:43.170
But in this case we were lucky, so just sending out these four bytes will let the ECU execute this NOP and then jump back to the normal execution.

13:43.190 --> 13:48.510
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:06.010
So we want to build a small exploit, a small software that dumps the firmware for us over KEM.

14:06.010 --> 14:16.630
We were able to find an IDE for the V850 family of processor for the V850 architecture, but no tool specific for our processor.

14:17.050 --> 14:26.690
We assume that the tools for our version of this processor are only available to automotive OEMs.

14:27.390 --> 14:35.810
So in the beginning for us it was easier to write small chunks of V850 assembly to dump the entire firmware over KEM.

14:36.650 --> 14:46.790
So this is an example of how we figured out how to send messages over KEM with our small assembly pieces of code.

14:46.790 --> 15:03.010
First of all, we have to set the register IP with the address of the KEM interface where we want to send the IP, where we want to send the KEM message from.

15:03.010 --> 15:06.790
In this case it is FCN3.

15:07.050 --> 15:14.570
We figured this out by reverse engineering the PCB and trying out all the different KEM interfaces.

15:14.770 --> 15:29.050
And then we just have to write 300 in hexadecimal to that address in order to let the KEM interface send whatever was in the buffer at that moment in time.

15:29.510 --> 15:35.970
Now doing this, the last KEM frame that the issue sent will be sent again.

15:35.970 --> 15:48.290
And by seeing the same KEM frame twice we knew that we were successful in sending something over with our assembly code.

15:48.890 --> 15:55.530
So the next step was sending some custom data over KEM.

15:55.970 --> 16:03.770
This is a bit more complicated because it requires unlocking the message buffer for writing it and then locking it again when sending the message.

16:03.770 --> 16:11.190
So this took quite a long time to blindly run code, reading the manual and figuring out how to do this.

16:11.190 --> 16:13.810
But in the end we figured it out.

16:13.810 --> 16:19.670
It's just a matter of writing 17 in hexadecimal in the same address as before.

16:20.250 --> 16:24.270
This unlocks the message buffer for writing.

16:24.270 --> 16:28.110
Now we can write the KEM ID.

16:28.370 --> 16:31.050
This needs to be multiplied by 4 for some reason.

16:31.770 --> 16:32.970
And we can write it.

16:32.970 --> 16:37.110
This is written to a different address in the same peripheral.

16:37.370 --> 16:42.550
Then we have to write the length of the message.

16:42.550 --> 16:55.770
For some reason this CPU has a bit... has a curve where different sizes of registers need to be written at different addresses in the memory map.

16:55.770 --> 16:59.810
So before we were writing half words, 16 bits at a time.

17:00.670 --> 17:04.430
And now we're writing something in a register which is a single byte.

17:04.430 --> 17:09.330
So we have to change the register, change the address of the memory map to register.

17:10.130 --> 17:20.030
But after reading the manual enough and figuring out what we were doing wrong, we were able to change the size of the sent KEM message finally, in this case to 4.

17:20.670 --> 17:26.390
And finally we can change the data by writing to this address right here.

17:26.430 --> 17:28.770
In this case I'm writing dead beef.

17:28.850 --> 17:34.010
I have to write it in Lithuanian, so A-D-D-E-E-F-B-E.

17:34.170 --> 17:41.970
Also here it was quite confusing the fact that the registers for the buffer are not contiguous.

17:42.630 --> 17:49.570
So the first two bytes are stored at offset 0 and the next two bytes are stored at offset 8 and so on.

17:50.130 --> 17:59.290
Finally we have to send the buffer that we prepared and this time I have to write 700 hexadecimal instead of 300.

17:59.290 --> 18:04.270
This was because I also had to lock the message and cause the buffer to refresh.

18:04.270 --> 18:10.810
Now all of these required a lot of effort and trying, but in the end we were able to send the custom messages.

18:10.810 --> 18:15.990
So at this point nothing stops us from dumping the entire firmware.

18:16.250 --> 18:41.730
So for example, if we want to dump address 1-2-3-4-0, what we have to do is prepare the address that we want to dump into register 2 for example, point the NTP pointer, which is another register, to the CAN interface like before and then read two bytes at a time from R2 and write them into the EP.

18:41.990 --> 18:48.530
And this way we were able to dump the entire firmware, one request at a time.

18:48.830 --> 18:52.750
So now we have the firmware and it's time for some reverse engineering.

18:53.750 --> 19:07.850
This work was made a few years ago and at that point in time there wasn't really a choice for tools to use for reverse engineering these architectures.

19:07.850 --> 19:09.950
First we tried with AIDA.

19:09.950 --> 19:23.230
We actually have a license at our university, but our license is only for a very old version and it did not support the V850-E2 instruction set.

19:23.410 --> 19:26.110
And a new license is super expensive.

19:26.850 --> 19:35.650
We tried RADAR, same thing, didn't support the V850-E2 extension of the instruction set.

19:35.710 --> 19:46.280
And finally JITRA didn't exist yet, well it wasn't published yet, but when it was published it also didn't support the V850-E2 architecture.

19:46.710 --> 19:53.810
So at this point we were really sad because we could not reverse engineer the firmware, we did not have the tools.

19:54.190 --> 20:08.050
However you don't need to be sad anymore because recently JITRA started supporting this instruction set and this extension thanks to this pull request here from Alex Lasso, which is one of our students.

20:08.590 --> 20:13.390
And he just finished his bachelor writing this plugin as his thesis.

20:14.270 --> 20:25.970
So what I ended up doing at the moment for getting to work fast was writing an AIDA plugin for V850-E2 processors.

20:25.970 --> 20:34.410
I started from this already existing plugin called Necromancer which supported some instructions but was incomplete.

20:34.470 --> 20:46.710
And then I wrote a small parser that from the PDF manual generated the Python arrays, Python code for the AIDA plugin.

20:46.710 --> 20:51.770
So this is the manual, this is how an instruction is encoded.

20:51.770 --> 21:03.150
There are a bunch of static constant zeros and one and some bits which are representing the registers that this instruction can access and these are variable.

21:03.710 --> 21:17.250
And yeah this parser will parse this PDF and output these tables, these arrays which then could be fed into the plugin for AIDA.

21:17.410 --> 21:21.550
And this is a screenshot showing it working.

21:21.550 --> 21:33.850
So all the instructions that are uppercase here were disassembled from the plugin and they were not already existing in AIDA.

21:33.850 --> 21:35.690
They were not supported by AIDA.

21:38.580 --> 21:44.040
Now that we can reverse engineer the firmware, we should look at how it is structured.

21:44.240 --> 21:49.960
There is a bootloader in the beginning which is 32 kilobytes.

21:50.380 --> 21:54.960
This bootloader contains the code that is executing during the programming mode.

21:54.960 --> 21:59.280
So when we switch to programming mode with security access, this is what is getting executed.

21:59.700 --> 22:07.520
After that there is the firmware, the program for the rest of the application on this issue.

22:07.520 --> 22:13.200
This is 1.3 megabytes and this contains everything that runs while you're driving the car.

22:14.280 --> 22:18.400
Then there is around 700 kilobytes of empty program flash.

22:18.400 --> 22:25.040
So this is great for us because this is where we can write our persistent malware.

22:25.420 --> 22:29.180
And finally there is a few kilobytes of configuration.

22:31.120 --> 22:35.160
So we have a lot of space to write a persistent malware.

22:35.160 --> 22:36.640
So let's try doing that.

22:36.640 --> 22:38.560
Let's see how difficult this is.

22:41.640 --> 22:49.720
Of course we cannot write simply with the security 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:09.780
So it is clear that for flashing, for updates on this issue, they were relying on the execution of external data from the RAM, this programming mode.

23:10.920 --> 23:20.480
And also the reference manual for the processor does not give any information about how to write to the flash and it only says that you should be using this FSL library.

23:21.460 --> 23:34.100
So we managed to find this library, download it, and again it didn't work for our specific V850 processor, but we found one that worked for a very similar one.

23:35.020 --> 23:37.100
And it's a binary.

23:37.100 --> 23:38.400
It's already compiled.

23:38.620 --> 23:40.760
There is no source code.

23:40.760 --> 23:48.460
There is some example source code, but the examples use the compiled library.

23:49.800 --> 23:51.820
So we had to reverse engineer this.

23:52.080 --> 24:06.260
And what we could gather from reverse engineering is that first, the flashing code can only run from RAM because the entire flash, which normally contains the program, is disabled during the write and erase operations.

24:06.760 --> 24:27.480
So also when we disable the write protection on the flash, the entire address space of the flash gets replaced by some other code, which was confusing, but it looks like some kind of internal ROM or maybe a BIOS.

24:27.880 --> 24:50.640
And write and erase operations are simply executed by preparing the command and the parameters like addresses and the new data into registers from R7 to R10, and then jumping to a very specific address here, FEDFFFF0, which performs the flashing operation for us.

24:51.960 --> 24:56.900
Of course, the first flash writes were very scary.

24:56.900 --> 25:02.560
So I first started writing... as I said, it's scary.

25:03.000 --> 25:08.160
So I first started writing on empty places in the flash.

25:08.560 --> 25:12.700
And this is just to verify that the flashing was working.

25:12.700 --> 25:15.820
And after a few attempts, it was able to write the flash.

25:16.500 --> 25:24.500
And then the next step was patching the bootloader in a way that we didn't have to wait 10 seconds before switching to the programming mode.

25:24.500 --> 25:26.100
We could do it instantly.

25:26.280 --> 25:34.260
So yeah, I patched the bootloader in a way that the issue would always start in the bootloader, so in the programming mode.

25:35.840 --> 25:40.900
So now the requirement for writing a complex ransomware here.

25:41.200 --> 25:44.200
First, we don't want to write the entire thing in assembly.

25:44.420 --> 25:48.320
We imagine we have to write a lot of code, so we want to write it in C.

25:49.580 --> 25:57.900
Secondly, we don't want to break the functionality of the body control module, because it's an essential component when you're driving the car.

25:58.660 --> 26:04.580
And because of this, it will be very practical to have code running in your own thread.

26:05.180 --> 26:06.860
So a thread is just for us.

26:06.860 --> 26:09.460
But this issue did not implement threads at all.

26:09.460 --> 26:15.540
This issue just has a single program cooperating with the tasking, not even parallel tasks.

26:15.980 --> 26:19.040
One function executes after the other one.

26:20.020 --> 26:21.600
Other problems.

26:21.960 --> 26:25.860
There is a hardware watchdog and a software watchdog.

26:25.860 --> 26:30.400
Both are going to reset the CPU when it doesn't respond in time.

26:30.540 --> 26:40.980
And this is another reason why we need to write a parallel thread with a yield function, because otherwise we cannot run a long-running program.

26:42.140 --> 26:45.520
And also, we did not have the linker.

26:45.520 --> 26:54.480
We had a linker that supported a very similar processor, and we could only compile C that ran from RAM, basically.

26:54.480 --> 26:55.520
No flash.

26:55.520 --> 26:58.780
We could only run our C code from RAM.

26:59.200 --> 27:01.300
And finally, another issue.

27:01.300 --> 27:11.080
There are these two registers, R5 and GP, which get set statically to a constant value by the compiler.

27:11.080 --> 27:17.260
And then for doing the whole execution of the program, they will preserve the same value.

27:17.260 --> 27:21.480
And this value is going to be different depending on what the compiler decides.

27:21.480 --> 27:38.020
So when executing our code, it was necessary to preserve the original values of these two registers and then restore them back before passing control back to the original code of this VCU.

27:38.060 --> 27:46.320
And this makes return-oriented programming very hard, of course, because we cannot just jump to already existing code to let it do our stuff.

27:46.640 --> 27:49.680
We have to be careful about these two registers.

27:50.460 --> 27:57.220
So let's look at how we ended up implementing our exploits, given all of these limitations.

27:57.820 --> 28:07.560
First, we used transfer data to load our code into the empty portion of the RAM, where we can execute it from.

28:08.040 --> 28:19.060
And then we execute it, and this one will patch some exploit into the empty flash, which is this large part of flash which is not used, 700 kilobytes.

28:19.780 --> 28:23.260
Then we also patched two interrupt service routines.

28:23.260 --> 28:38.760
So the interrupt handlers for both a timer, which gets called periodically, where we will execute our thread, and the interrupt service routine for canReceive, so that we can receive can frames for the rest of the car.

28:38.760 --> 28:47.240
And if we are interested in them, save them in a message box in a buffer for our thread to pick them up later.

28:48.840 --> 29:05.670
After this patching occurs, during the first execution of the timer ISR, our patch will jump to our code in the empty part of the flash, which is now not empty anymore.

29:05.790 --> 29:12.750
And this code is written in assembly, because we cannot compile code to the flash.

29:13.390 --> 29:26.350
And what this piece of code does, it just copies the rest of the code from flash to the empty position in the RAM, where code normally is downloaded.

29:26.750 --> 29:43.130
And then, after the code is copied there, on the next time the timer, interrupt service routine, or canRoutine are called, we are jumping to the RAM exploit, so the code we have placed in the RAM.

29:43.130 --> 29:56.090
Also, we have a small signature at the beginning of our RAM exploit to verify that we prepared the exploit there, and that it didn't crash last time.

29:56.090 --> 30:03.710
So, we put some safety measures there to ensure that we didn't get locked out of our only ECU.

30:03.710 --> 30:06.690
We only had one ECU to do all of this.

30:07.490 --> 30:24.690
And finally, to inject the parallel process, this thread, we changed the timer interrupt, as I said before, and then implemented a small yield function, which saves the entire state of the execution of our exploit.

30:25.730 --> 30:50.810
Basically, in its own stack, we have a stack for our thread, and this allows us to do stuff like yield or sleep in between our program, and it works like an Arduino where 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:55.690
So, this is all regarding patching of the firmware.

30:55.690 --> 31:00.890
Now, Nils will explain the features that we implemented in our ransomware.

31:01.050 --> 31:11.430
So, now after we have basically our own thread in an unknown operating system where we can inject our code.

31:11.430 --> 31:31.450
So, all this portion that we showed, which lives in RAM, has all code written in C, and we can write our ransomware completely in C, we have a yield and a time or sleep function in order to wait for certain events, and we can also receive CAN messages,

31:31.450 --> 31:34.950
as Enrico said, through the CAN interrupt service routine.

31:34.950 --> 31:47.350
We can store incoming CAN messages into our own ring buffer in our ransomware and can then give this message back to the normal operating system.

31:47.350 --> 31:52.890
And this is very handy for us since the car acts completely normal.

31:52.890 --> 31:58.970
We can still drive the car, we can do everything with the car, and have our ransomware running independently.

31:59.350 --> 32:04.490
Okay, to implement these features, we need a couple of things.

32:04.490 --> 32:08.650
So, we want still to interact with the user.

32:09.750 --> 32:13.470
We wanted to lock and unlock the immobilizer .

32:13.470 --> 32:26.870
So, we implemented a way that we can start the car without key, and we can also not start the car with key, basically, in order to really put pressure onto our ransomware.

32:27.630 --> 32:38.510
And then we also need to send ICTP messages to make the car behave badly, in order to scare the driver.

32:38.510 --> 32:47.150
And we want to use some extracted rehearsal tester jobs to run these actions, basically.

32:47.590 --> 32:50.450
Okay, talking to the user.

32:50.450 --> 32:58.610
This is very important for the ransomware, because if you cannot tell someone that the car is owned by the ransomware, no one will pay.

32:59.790 --> 33:01.810
But yeah, how can we do this?

33:01.810 --> 33:05.450
The multimedia ECU of this car has a screen connected.

33:05.450 --> 33:11.030
The radio has its screen, and also this car has a Wi-Fi hotspot.

33:11.030 --> 33:18.330
So, the car owner can open up a hotspot and connect with its smartphone to the Wi-Fi hotspot.

33:18.330 --> 33:26.910
In order to connect the access points from the car, the car driver needs login credentials.

33:27.130 --> 33:34.350
And these login credentials need to be transferred from the telematic ECU to the multimedia ECU.

33:34.350 --> 33:37.250
And obviously, they get transferred over CAN.

33:37.250 --> 33:41.970
And luckily, over the same CAN as our body control module is connected to.

33:41.970 --> 33:52.170
So, the module that we own now is connected on the same CAN bus, where also the multimedia and telematic ECU do their job and their message exchange.

33:52.170 --> 33:59.690
Here is an example of some SCEPI code, where we analyzed the ICT communication.

33:59.690 --> 34:04.190
We see a first frame here, some flow control, and then some data.

34:04.370 --> 34:11.270
And if you defragment all of this data, you can see some strings here.

34:11.270 --> 34:17.090
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:30.050
And these are basically the text fields for the button on the screen in the car.

34:30.050 --> 34:36.910
And we can send our own text strings here in order to show any message we want.

34:37.690 --> 34:40.350
Okay, so how does this look like?

34:42.570 --> 34:50.070
So, here we see the car and it takes roughly 30 seconds to start.

34:50.070 --> 34:53.330
We can let you run, the expert basically run on every event.

34:53.330 --> 34:56.810
You can wait for a year after the car got infected.

34:56.850 --> 35:02.410
You can wait until the car does more than 100 kilometers per hour, whatever.

35:02.410 --> 35:04.430
So, it's completely free.

35:05.930 --> 35:10.110
So, and this time, here the ransomware starts.

35:10.110 --> 35:15.730
We can see the screen, we can have the buttons, and can talk to the user.

35:18.050 --> 35:24.870
Here we are playing around with the dashboard to behave badly, basically.

35:25.130 --> 35:27.990
We disable GPS.

35:35.910 --> 35:39.710
We also spin up the engine van.

35:40.250 --> 35:43.090
So, you will hear it now.

35:51.860 --> 35:57.900
And we attack again the dashboard to do some stuff.

35:57.900 --> 35:59.740
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:12.520
All right, this was the live demonstration.

36:12.520 --> 36:17.960
We also investigated if you can spread the infection to other ECUs.

36:17.960 --> 36:23.780
So, during our time that we worked on this car, we investigated the EPIC ECU.

36:23.780 --> 36:29.020
We investigated the telematic ECU and the engine control unit.

36:30.180 --> 36:35.420
And security access and code execution on the EPIC ECU were trivial.

36:35.420 --> 36:51.160
So, theoretically, it would be very likely and possible that you can infect also other ECUs in that car and that this one ransomware spreads around over all the ECUs in the car.

36:51.160 --> 37:07.030
There are some limitations since to do this, basically, our ransomware would be prepared with expert codes for all the individual ECUs.

37:07.030 --> 37:16.870
And this is also one of the things which is still, in our opinion, the most limiting factor for writing malware or ransomware for cars nowadays.

37:17.010 --> 37:19.870
So, lessons learned from here.

37:20.830 --> 37:28.110
In this car, we didn't have any cryptographic challenges and the flashing of the body control unit was easy.

37:29.530 --> 37:34.310
The most problems we had were by the obscurity.

37:34.310 --> 37:39.810
So, the flashing library was locked down only for the OEMs.

37:39.810 --> 37:44.050
So, only if you sign NDAs, you get these tools, you get the hardware.

37:44.450 --> 37:46.830
The hardware was proprietary.

37:46.830 --> 37:50.750
We didn't got any compiler for this processor.

37:51.230 --> 37:53.810
So, this is really limiting factor.

37:54.470 --> 38:01.930
And also, in total for malware, the most limiting factor is the heterogonous systems in the car.

38:01.930 --> 38:12.750
So, that every ECU has a different chip set, has different instruction 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:24.710
Yeah, and this, as I said, the problems are common for all ECUs.

38:24.710 --> 38:34.750
In the future, we expect more Linux in cars and less obscurity and more homogeneous systems and platforms and probably more server-based.

38:34.750 --> 38:38.730
So, yeah, the architecture will probably completely change.

38:40.130 --> 38:42.950
Some facts about our proof of concept.

38:43.390 --> 38:48.450
This proof of concept was released on a car in 2016.

38:49.370 --> 38:54.050
We was made for a car released in 2016.

38:55.630 --> 39:15.910
We think almost all cars with a lower price range will have similar bad security at the moment, or let's say a little bit older cars also, you can affect even a not connected car as soon as it connects to the repair shop tester and this repair shop tester has a malware,

39:15.910 --> 39:17.590
then you have it.

39:18.110 --> 39:22.650
And these cars will still drive around for 5 to 10 more years.

39:22.650 --> 39:31.750
So, for example, in Germany, the average age is 9.5 years and all cars will frequently connect to a repair shop tester.

39:31.750 --> 39:37.570
So, this is a very easy way for infecting this insecure cars.

39:38.210 --> 39:45.170
All right, yeah, you can follow us on Twitter if you like and thanks for listening.

39:45.210 --> 39:46.730
Thanks for listening.

