WEBVTT 00:00:00.000 --> 00:00:18.264 36c3 prerol music 00:00:18.264 --> 00:00:26.160 Herald: So, Siemens recently decided to add some security feature to the PLC. And 00:00:26.160 --> 00:00:32.800 today we have Tobias and Ali and they will be sort of.. telling us what they managed 00:00:32.800 --> 00:00:40.720 to find. This PLC. They both come from Ruhr Universität Bochum. Tobias is a 00:00:40.720 --> 00:00:46.160 recent acquisition as a doctoral student. And Ali is a postdoc. So, uh, let's give 00:00:46.160 --> 00:00:48.358 them a hand. 00:00:48.358 --> 00:00:56.818 applause 00:00:59.648 --> 00:01:03.557 Ali: Hmm, where is our slide? Tobias: Presentation mode? 00:01:09.750 --> 00:01:17.210 Ali: Yes. OK. Welcome to our talk. A deep dive into on concentrate code execution in 00:01:17.210 --> 00:01:23.757 Siemens S7 PLCs. My name is Ali Abbasi and as mentioned before, I'm a postdoc at 00:01:23.757 --> 00:01:28.160 chair of System Security at Ruhr University Boch and here's my colleague. 00:01:28.160 --> 00:01:34.400 Tobias: I am Tobias or Tobi. I'm very glad to be here. It's my fifth time at the 00:01:34.400 --> 00:01:38.640 Congress and now finally able to give back in a way. So I'm very excited about that. 00:01:39.760 --> 00:01:46.880 So let's get into it. So first about the plan of the talk. We want to give you a 00:01:46.880 --> 00:01:51.360 little bit of a background of what PLCs, which is programmable logic controllers 00:01:51.360 --> 00:01:56.640 are all about, why we might want to use them and in what kind of setting. And then 00:01:56.640 --> 00:02:02.600 we want to go into the specifics of PLCs in the Siemens case. First we look a bit 00:02:02.600 --> 00:02:07.040 at the hardware and then at the software afterwards and the different findings that 00:02:07.040 --> 00:02:11.200 we had. At the end, we would show a demonstration of what we're able to 00:02:11.200 --> 00:02:18.960 achieve and conclude with some remarks. So first of all, process automation. So we 00:02:18.960 --> 00:02:25.280 all know it. Or maybe we do it ourselves or we know somebody who does it. We put in 00:02:25.280 --> 00:02:32.480 some devices in our smart home, if we call it smart already. And we try to automate 00:02:32.480 --> 00:02:38.720 different targets on different things to make our lives easier. Things like turning 00:02:38.720 --> 00:02:43.200 up and down the heat. We might not want to do that our own. We might not want to 00:02:43.200 --> 00:02:49.040 overheat or under heat. And what we do is basically have some sensory systems inside 00:02:49.040 --> 00:02:55.200 our homes, as well as some devices that interact with those sensors. In this case, 00:02:55.200 --> 00:03:00.560 we might have a thermostat and a heater and we want to adjust our temperature 00:03:00.560 --> 00:03:06.880 based on the thermostat. They're pretty simplistic solutions like this for a smart 00:03:06.880 --> 00:03:12.960 home. But what we do if we have very complex control loops for example. Here we 00:03:12.960 --> 00:03:20.240 can see on the left bottom corner a pretty complex looking picture, some operating 00:03:21.200 --> 00:03:26.640 operators sitting in front of what we call an HMI a human machine interface, which is 00:03:26.640 --> 00:03:30.320 basically an aggregation of all the information of things that go on in a 00:03:30.320 --> 00:03:36.560 factory, for example. We need different sensors and this factory and we need to 00:03:36.560 --> 00:03:41.040 steer different motors and stuff like this. So we need things in the middle to 00:03:41.040 --> 00:03:46.400 kind of control all of this. And we do this using PLCs and we can see a setup how 00:03:46.400 --> 00:03:50.260 it could look like. So basically have a set of inputs as we talked about and a set 00:03:50.260 --> 00:03:54.240 of outputs. And we have some logic going on in the middle. And what we typically 00:03:54.240 --> 00:03:59.840 deploy is a PLC a programable logic controller and some logic in the middle. 00:03:59.840 --> 00:04:04.880 There are different technologies that can be used, for example, structure, text or 00:04:04.880 --> 00:04:11.440 letter logic which gets downloaded onto the PLC and then which steers outputs 00:04:11.440 --> 00:04:16.160 based on the inputs that it gets. You can see some applications of this kind of 00:04:16.160 --> 00:04:21.666 thing. For example, a chemical power plant, chemical plant, an electric grid or 00:04:21.666 --> 00:04:28.482 some manufacturing. Some of those components are pretty critical to the 00:04:28.482 --> 00:04:33.194 workings. Even either we see it in the everyday lives and sometimes we don't 00:04:33.194 --> 00:04:39.563 really see it. But they are in the steering, everything in the background and 00:04:39.563 --> 00:04:44.217 we really don't want those systems to get compromised. For example, if you went onto 00:04:44.217 --> 00:04:48.451 Google and looked something about disasters and chemical plants, you could 00:04:48.451 --> 00:04:53.071 see melted down plants just because of some mis.. malfunction in the system or 00:04:53.071 --> 00:04:58.817 so. And we really don't want this to happen. Neither an accidental but also not 00:04:58.817 --> 00:05:03.531 a malicious basis. And this is why we want to secure all the processes going on in 00:05:03.531 --> 00:05:09.864 factories and the like. We've seen some of the recent attacks. So it started kind of 00:05:09.864 --> 00:05:16.984 in 1999 with a first initial reconnaissance based mainly. And then we 00:05:16.984 --> 00:05:22.037 had some more advanced attacks in 2010, for example, where we saw Stuxnet, which 00:05:22.037 --> 00:05:26.260 was very much really intricate operation. If you think about it on a technical 00:05:26.260 --> 00:05:31.688 level, what all went into it. What different skill sets were involved. It's 00:05:31.688 --> 00:05:38.048 pretty impressive. And then in the more recent time we had some issues in the 00:05:38.048 --> 00:05:45.400 Ukrainian power grid, which in 2015 and '16 just before Christmas, some lights 00:05:45.400 --> 00:05:51.747 went out for quite a while in some cities there. So quite a bit of impact. So to 00:05:51.747 --> 00:05:57.504 give you a bit of impact, a background on Siemens PLCs here when it comes to market 00:05:57.504 --> 00:06:01.908 shares. We can see that together with Rockwood Automation, Siemens actually has 00:06:01.908 --> 00:06:06.372 more than 50 percent market share in the market. And obviously, if we take out some 00:06:06.372 --> 00:06:10.422 devices that introduce some security, it would be interesting to look at those with 00:06:10.422 --> 00:06:15.560 the biggest market share. This is what we did here in the Siemens case. Here we can 00:06:15.560 --> 00:06:22.030 see the actual PLCs that we will focus on in this talk, which is the Siemens S7-1200 00:06:22.030 --> 00:06:26.721 PLC. It's one of the smaller PLCs, not quite the smallest, there is the logo as 00:06:26.721 --> 00:06:33.423 well, which is more of a playing around example, but this is the one that it's 00:06:33.423 --> 00:06:39.298 still pretty accessible to researchers in terms of costs. So it's like 250 for the 00:06:39.298 --> 00:06:44.560 PLC. Then if you need a power supply, it can add the same. So as long as you don't 00:06:44.560 --> 00:06:50.208 break too many, spoiler, we broke quite some or you don't drop them or something 00:06:50.208 --> 00:06:55.524 like this, then you're pretty fine so you can kind of get the resources to play with 00:06:55.524 --> 00:07:00.289 those devices. We have different applications and we talked about them 00:07:00.289 --> 00:07:08.186 before. So here is what an unboxing of a Siemens 7 1200 PLC would look like. We 00:07:08.186 --> 00:07:13.658 have the top view here on the left picture. It's only one of different PCBs 00:07:13.658 --> 00:07:19.360 which are layered on to each other in this case. But the real magic goes on in the 00:07:19.360 --> 00:07:25.717 top PCB, which is the green one that we see here. Looking at it a bit more in more 00:07:25.717 --> 00:07:31.200 detail. We have the top view on the left side, which shows the different components 00:07:31.200 --> 00:07:36.566 that really make the PLC. Take, for example, the ARM CPU that we have or 00:07:36.566 --> 00:07:41.675 different input outputs that we can connect to a PLC, as we talked about 00:07:41.675 --> 00:07:47.687 before, which they need in order to steer different parts of the system. And then we 00:07:47.687 --> 00:07:56.233 have the flash chip on the top side as well, which is a big flash chip holding 00:07:56.233 --> 00:08:04.169 the firmware off the actual PLCs, which we will talk about a bit more in detail 00:08:04.169 --> 00:08:09.841 later. On the flip side, we have on the right picture the bottom side of the first 00:08:09.841 --> 00:08:15.378 layer PCB. And as we can see here, this is where the bootloader chip resides, which 00:08:15.378 --> 00:08:21.870 is an SPI flashchip of four megabytes owning the code of the Siemens PLC 00:08:21.870 --> 00:08:29.040 bootloader. Here we wanted to have a detailed view on what the actual 00:08:29.040 --> 00:08:33.241 processing unit inside this board actually looks like and what you can do if you want 00:08:33.241 --> 00:08:38.861 really want to find out you can do some decapping. And that's what we see here. 00:08:38.861 --> 00:08:46.021 The result of this, we can see that at the core of it, it's a renaissance ARM 00:08:46.021 --> 00:08:52.712 Cortex-R4 for from 2010. And if you afterwards are more juggling with the 00:08:52.712 --> 00:08:58.079 software side of things, you may also want to find out the actual revision number, 00:08:58.079 --> 00:09:04.974 what it supports inside the ARM standard. And what you can do there is use a special 00:09:04.974 --> 00:09:13.442 instruction which resides in the ARM instruction set and you can decode the 00:09:13.442 --> 00:09:17.384 different bits on it, which we did here, which you can see here for reference. So 00:09:17.384 --> 00:09:22.787 if you really want to know what's going on, you can take apart those bits and make 00:09:22.787 --> 00:09:26.358 sure you're actually working with the hardware that you expect to be working 00:09:26.358 --> 00:09:32.349 with. So here's where we come to the memory part of the hardware and this is 00:09:32.349 --> 00:09:39.315 where I leave you over to Ali. Ali: Thanks. Now that Tobias like unboxed 00:09:39.315 --> 00:09:45.892 the PLC for us now I'm going to talk about quirks and features in the PLC. So as 00:09:45.892 --> 00:09:53.285 mentioned before, it's Cortex-R4 revision 3. It's a big endian instruction set and 00:09:53.285 --> 00:10:00.632 it's also only have MPU. So there is no visual memory basically, there are 00:10:00.632 --> 00:10:04.794 multiple ram sizes depending on which year you bought it or which variant of the S7 00:10:04.794 --> 00:10:10.991 1200 you buy and also multiple SPI flash and multiple different types of NAND 00:10:10.991 --> 00:10:15.416 flashes. The most significant one difference is like in the RAM, which 00:10:15.416 --> 00:10:20.198 sometimes they use Wingbond and sometimes they use Micron Technologies, recently 00:10:20.198 --> 00:10:30.818 Micron Technologies RAM. It is LPDDR1 RAM. We expect the SPI Flash for bootloader. So 00:10:30.818 --> 00:10:37.243 again, depending on the variance between one to four megabytes SPI flash, it 00:10:37.243 --> 00:10:43.840 contains different banks of each sized 512 kbytes. And basically what the bootloader 00:10:43.840 --> 00:10:48.797 does is that's beside the typical actions of the bootloader, which is like 00:10:48.797 --> 00:10:54.342 configuring your hardware is like verifying the integrity of the firmware 00:10:54.342 --> 00:11:01.835 before it being loaded. So we actually need some X-ray tomography of the PLC. So 00:11:01.835 --> 00:11:08.652 it's basically 3D. So the PCB is basically rotating here because we wanted to also do 00:11:08.652 --> 00:11:13.680 some hardware reverse engineering part. And somebody in university had something, 00:11:13.680 --> 00:11:20.414 so we didn't have to go to our dentist for X-ray. So here is like a quick 15 minutes 00:11:20.414 --> 00:11:26.400 X-ray, which is not that good. But once you go in deep, eventually what you will 00:11:26.400 --> 00:11:30.960 have is like this and you can actually just it's like a software animation. You 00:11:30.960 --> 00:11:36.320 can go inside PCB and see all the layers. It's like amazing. So it's up for PCB 00:11:36.320 --> 00:11:42.480 layer. And so besides, VCC and GND, you need two layers of PCB connection 00:11:42.480 --> 00:11:50.000 basically. So let's look at the start up process. Again. Start up as usual. Some 00:11:50.000 --> 00:11:53.840 hardware configuration happens. So vectoring trap controller, for example, 00:11:55.120 --> 00:12:01.600 like lots of this handlers for different modes in ARM and then CRC check some of 00:12:01.600 --> 00:12:06.240 the bootloader itself, which is easily bypassed over because you can just 00:12:06.240 --> 00:12:11.516 overwrite the CRC. Then the bootloader, especially in the 2017, 2018 variant of 00:12:11.516 --> 00:12:18.960 the Siemens PLC, allows you to overwrite the SPI flash. And also eventually we 00:12:18.960 --> 00:12:25.120 check the CRC checksum of the firmware before basically loading it. The size of 00:12:25.120 --> 00:12:28.960 the bootloader itself is like 128 kbyte, it is really even less than that because 00:12:28.960 --> 00:12:35.093 half of it is just like 0xff. Siemens multiple times changed, they had different 00:12:35.093 --> 00:12:39.368 version. I think in two years we saw three variants or four variants of the 00:12:39.368 --> 00:12:44.720 bootloader. So it was evolving. It was not something that's everybody forgotten about 00:12:44.720 --> 00:12:51.990 it. So generally as mentioned, so you have part this first stage of hardware 00:12:51.990 --> 00:12:59.760 initialization and then basically bringing the bootloader to the RAM and basically 00:12:59.760 --> 00:13:03.840 checking the bootloader CRC checksum. So make sure that it's not manipulated, which 00:13:03.840 --> 00:13:08.400 again is it can be bypassed. And then a second stage of the hardware 00:13:08.400 --> 00:13:12.827 initialization happens. And then at this moment, it waits for a specific command 00:13:12.827 --> 00:13:16.633 for half a second. And if it receives this command it goes to another mode, which 00:13:16.633 --> 00:13:22.101 we'll discuss later. Otherwise, it basically prepares some CRC checksum table 00:13:22.101 --> 00:13:25.727 for the firmware and then it tries to load the firmware and then eventually 00:13:25.727 --> 00:13:30.790 just removes the memory barrier the stage 1 instruction those who knows about ARM. 00:13:30.790 --> 00:13:34.846 And basically map the firmware to the memory. 00:13:34.846 --> 00:13:38.624 So the name of the operating system, it 00:13:38.624 --> 00:13:44.238 was not mentioned before, it's ADONIS. We know it from different from different 00:13:44.238 --> 00:13:49.995 ways, actually. So first in the references, in the firmware, we see lots 00:13:49.995 --> 00:13:54.552 of references to ADONIS, but that was not enough for us. So if we actually looked 00:13:54.552 --> 00:13:59.200 around to see if like there is any reference to it, and well linkedin is one 00:13:59.200 --> 00:14:04.917 good open source like reference. And he was like one employee actually talk about 00:14:04.917 --> 00:14:09.840 Siemens developer who talk about like working in ADONIS. I don't know why he put 00:14:09.840 --> 00:14:15.360 the Windows and Linux beside ADONIS, but I can say is that like you work on this. And 00:14:15.360 --> 00:14:20.560 so it was not enough for us. So maybe some some of us we don't know. And we look 00:14:20.560 --> 00:14:25.440 again further and further and we find this thing which was the best indicator. So 00:14:25.440 --> 00:14:30.240 Siemens developer engineer mentioned that he worked on kernel software 00:14:30.240 --> 00:14:34.480 development for ADONIS real time operating system, which is a good sign for us. It 00:14:34.480 --> 00:14:39.200 means that we are right. So now that we know about the naming and we sure about 00:14:39.200 --> 00:14:46.160 that. Let's look at the components. So it's actually a start in basically 00:14:46.160 --> 00:14:53.680 0x00040040 and basically then initializing the kernel and then lots of routines for 00:14:53.680 --> 00:14:57.535 initializing different components of the operating system. I don't think Siemens 00:14:57.535 --> 00:15:02.960 actually generalize it in this way. We don't have such thing in the firmware, 00:15:02.960 --> 00:15:07.680 but we actually did it like that. So we generalize it to two groups. Some of them 00:15:07.680 --> 00:15:11.360 are core services like ADONIS real time operating system services, and some of 00:15:11.360 --> 00:15:15.600 them are related to the like automation part. So those people who are like in the 00:15:15.600 --> 00:15:22.400 automation part, like writing ladder logic and stuff like that, those commands and on 00:15:22.400 --> 00:15:26.560 function codes which are relevant in Siemens, they actually know this are like 00:15:26.560 --> 00:15:32.480 more automated related services. So you have PROFINET, AWP or automated web 00:15:32.480 --> 00:15:39.920 programing MC7 JIT parser basically for the latter logic or different kind of SD 00:15:39.920 --> 00:15:46.400 like basically their own JIT compiler inside the PLC. And you also have the OMS 00:15:46.400 --> 00:15:51.120 this configuration system which is very related again to the automation part, core 00:15:51.120 --> 00:15:58.640 core part of the automation system and of course alarm central all your and stuff 00:15:58.640 --> 00:16:04.320 like that related to automation. In the operating system part, so lots of these 00:16:04.320 --> 00:16:11.040 usual things. So file system. So PDCFS, which Tobias talks later about, it. The 00:16:11.040 --> 00:16:18.480 TCP/IP stack, some C / C++ libraries, which is not from Siemens, it's from 00:16:18.480 --> 00:16:23.119 Dinkumware and MiniWeb Server and MWSL Parser 00:16:23.119 --> 00:16:25.470 or MiniWeb Scripting Language parser 00:16:25.470 --> 00:16:30.160 and lots of different subcomponents which is usual in operating system like any 00:16:30.160 --> 00:16:36.640 operating system you can find. Also, there are some references to CoreSight. I don't 00:16:36.640 --> 00:16:40.720 know how many of you know of CoreSight or how much you work on ARM, but the basic 00:16:40.720 --> 00:16:46.400 CoreSight is something similar to Intel process tracing or Intel PT for tracing 00:16:46.400 --> 00:16:52.640 applications and can be used for getting code-coverage, for example. And the 00:16:52.640 --> 00:16:58.720 hardware part is very well documented by Thomas Weber in this year, is not yet. 00:16:58.720 --> 00:17:04.000 This year or so. This year, Black Hat Asia, but I have to warn you, because I 00:17:04.000 --> 00:17:08.560 received some emails, some people ask about that. If you connect to it, the PLC 00:17:08.560 --> 00:17:12.880 have someone to debugging feature which detects that it's being debuged via JTAG 00:17:13.840 --> 00:17:18.960 and overwrite the NAND-Flash with random stuff. So you brick the PLC, so just 00:17:18.960 --> 00:17:23.838 connected it at your own risk. Next is let's look 00:17:23.838 --> 00:17:27.530 at the CoreSight just quickly, CoreSight basically have like 00:17:28.180 --> 00:17:30.880 before I go here, I have to mention that Ralf Philipp 00:17:30.880 --> 00:17:37.600 also have a good talk in 0 nights about CoreSight tracing. So I would recommend 00:17:37.600 --> 00:17:41.920 you guys go look at that as well. Generally, CoreSight have like 3 00:17:41.920 --> 00:17:46.800 major parts or components: sources, links and sinks and sinks is basically the part 00:17:46.800 --> 00:17:51.280 which you actually get the trace information and sources are the part which 00:17:51.280 --> 00:17:56.630 you tell is a featuring the CPU, which you ask what kind of sources you want to get 00:17:56.630 --> 00:18:03.200 the data from and then links basically convert these sources. I have to mention 00:18:03.200 --> 00:18:08.227 that like lots, it's very useful for Fuzzing as well too. I guess some people, 00:18:08.227 --> 00:18:12.560 very few, but some people are working on that things. On coverage guided fuzzing 00:18:12.560 --> 00:18:16.480 via CoreSight, ARM CoreSight. So it's possible similar implementation is 00:18:16.480 --> 00:18:25.680 happened in Intel PT for example KAFL, WinAFL or Hongfuzz. So sources, basically 00:18:25.680 --> 00:18:30.640 they have like three different components STM, PTM, ETM. ETM version 4 is the latest 00:18:30.640 --> 00:18:37.600 version of it. And basically you have also links which connects different sources to 00:18:37.600 --> 00:18:45.440 different like different or single sources to different or single basically sinks. 00:18:46.080 --> 00:18:52.198 And then you have funnels for CoreSight, sorry sinks, sorry. You have sinks, which 00:18:52.198 --> 00:18:56.144 is basically a different kind. So there are some integrity to the CPU which is 4 00:18:56.144 --> 00:19:02.560 kilobytes ring buffer SRAM or you have like system memory or even TPIU or just 00:19:02.560 --> 00:19:09.416 for example JTAG DP Port High Speed JTAG port. So now that cleared sink, 00:19:09.416 --> 00:19:14.800 like the CoreSight, we actually queried S7 for existence of CoreSight and as you can 00:19:14.800 --> 00:19:21.228 see, like in the software part is already implemented. So they actually have some 00:19:21.228 --> 00:19:26.960 references in their software that they are utilizing or configuring the CoreSight in 00:19:26.960 --> 00:19:32.720 the PLCs. And basically we can see that the ETM version is not the latest version 00:19:32.720 --> 00:19:39.520 it is ETM version 3. Now that I've talked to you about CoreSight, Tobi can talk 00:19:39.520 --> 00:19:43.200 about firmware dumps. Tobi: So let's get to something that I'm 00:19:43.200 --> 00:19:49.476 very much more familiar with and feel it's easier for me to handle it is firmware 00:19:49.476 --> 00:19:53.440 dumps or software in general, but firmware dumps, I think it's close as you can get 00:19:53.440 --> 00:19:59.840 to what I like when talking to a PLC or trying to understand a PLC. So in the 00:19:59.840 --> 00:20:06.960 Siemens case, we have a 13 megabytes binary and at the beginning it's not as 00:20:06.960 --> 00:20:14.800 many, but as if you twiddle around with a bit and apply some IDA python functions 00:20:14.800 --> 00:20:19.440 and stuff like this. You can get to like 84 000 functions, which is 00:20:19.440 --> 00:20:25.920 not something you want to really look at everything manually. Also, like 84 000 00:20:25.920 --> 00:20:31.840 function firmware image doesn't really get the sexiest firmware on planet, right? I 00:20:31.840 --> 00:20:38.000 guess so. But this is what I what I looked at and what we were looking a bit more in 00:20:38.000 --> 00:20:43.200 the next couple of minutes or so. As you can see, we have different names up there. 00:20:44.000 --> 00:20:48.800 We have one name which is called _some_get_some_max_size. So this is my 00:20:49.520 --> 00:20:53.760 internal way of saying I don't really have an idea of what's really going on in this 00:20:53.760 --> 00:20:58.400 function, but we can also see some more meaningful functions. So we understood 00:20:58.400 --> 00:21:03.920 some parts a bit more. Some parts of it less, but I gave it a cursory look in most 00:21:03.920 --> 00:21:11.360 places. So now let's get in to a lot of address related stuff, so we expected a 00:21:11.360 --> 00:21:16.880 lot of details, which are very interesting if you start looking at firmware code, and 00:21:16.880 --> 00:21:21.120 I will explain along the way why that might be interesting. So first of all, 00:21:21.120 --> 00:21:26.320 what you have to know is that coretex are for gives you bank registers. This is 00:21:26.320 --> 00:21:32.800 basically a feature that's implemented to lower software overhead and allow more 00:21:32.800 --> 00:21:40.560 seamless modes, which is for the internal CPU. And what we get is banks stacks per 00:21:41.120 --> 00:21:47.360 execution mode. So if we want to know what is kind of going on in the state of the 00:21:47.360 --> 00:21:51.200 filmware at a given point we may want to look at the different stacks of the 00:21:51.200 --> 00:21:56.880 different modes at any given point. And this is the addresses that we expected for 00:21:56.880 --> 00:22:02.640 this. And you could use that if you as a starting point, if you started reverse 00:22:02.640 --> 00:22:07.520 engineering, things like that. Now, we will have some address, some tables with 00:22:07.520 --> 00:22:16.080 addresses. And the first one is RAM mappings, which show you what kind of 00:22:16.080 --> 00:22:23.120 functionality or what you might expect when looking at firmware code, which is 00:22:23.120 --> 00:22:28.160 interfacing with different parts of memory. So if you initially go and look at 00:22:28.160 --> 00:22:33.120 some ARM code, you may just see a random access to some place in memory and you may 00:22:33.120 --> 00:22:39.040 want to know what it's actually doing. And it looks very uneventful of it's just an 00:22:39.040 --> 00:22:45.200 address and it gets gets queued and you don't really know what's going on. So, 00:22:45.200 --> 00:22:49.680 for example, if you looked at an address within the text section, you would expect 00:22:49.680 --> 00:22:55.120 there to reside code if you wanted to see some global static data, you would want to 00:22:55.120 --> 00:22:59.040 look at the data or the BSS section. And then finally, if you wanted to look at 00:22:59.040 --> 00:23:04.400 heap memory or how channels are set up there, you would look in the uninitialize 00:23:04.400 --> 00:23:09.760 section and it goes on like this for different sections. Another very 00:23:09.760 --> 00:23:14.480 interesting thing to look at, if you tried to reverse engineer firmware images is 00:23:14.480 --> 00:23:20.480 that you kind of want to know what the hardware is that a given piece of code is, 00:23:22.000 --> 00:23:29.760 is interfacing with. And in this case we dumped some regions or reverse engineered 00:23:29.760 --> 00:23:35.120 what some regions are for what is called memory mapped I/O. And the way ARM is 00:23:35.120 --> 00:23:39.360 talking to a firmware is basically to queue a magic value inside the address 00:23:39.360 --> 00:23:43.040 space and then it gets something back, which is not at all what it has been 00:23:43.040 --> 00:23:48.560 written there before. So it's basically an address which gets wired through to the 00:23:48.560 --> 00:23:53.600 periphery the hardware periphery on the same system on a chip. And here we can see 00:23:53.600 --> 00:23:57.360 that we have different hardware peripherals residing on it. For example, 00:23:58.000 --> 00:24:03.040 we can talk to the Siemens PLC via different serial protocols and those 00:24:03.040 --> 00:24:08.800 protocols might be SPI or I²C. And we have on the left side, kind of in the middle 00:24:08.800 --> 00:24:15.840 top what took part of it, have some region pertaining to that. And then if you saw 00:24:15.840 --> 00:24:21.920 some other code talking to timers, for example, you would know you are in timer 00:24:21.920 --> 00:24:26.288 land at the moment or like in the scheduler or whatever it would be. 00:24:26.288 --> 00:24:27.520 Finally, we have 00:24:27.520 --> 00:24:33.680 some MPU configurations which are memory protection unit configurations, as Ali 00:24:33.680 --> 00:24:38.880 introduced earlier. So what we can see is that Siemens is actually applying some of 00:24:38.880 --> 00:24:44.080 those configurations to protect parts of memory. What we can see, for example, is 00:24:44.080 --> 00:24:49.360 where whenever the XN so the execute never bit is set, code is not to be executed 00:24:49.360 --> 00:24:53.840 within this address region or we have a read only region. We really don't want to 00:24:53.840 --> 00:24:59.280 have it overwritten. So it's interesting that they started playing this in 00:24:59.280 --> 00:25:06.240 practice. Here we can see what actually happens when the firmware itself boots up. 00:25:06.240 --> 00:25:11.840 So it turns out the firmware doesn't really want to depend too much on what the 00:25:11.840 --> 00:25:16.720 bootloader did. Probably it's different teams doing different things. And to keep 00:25:16.720 --> 00:25:22.371 this interface as small as possible, they kind of redo some of the stuff that the 00:25:22.371 --> 00:25:27.040 bootloader code also does. It sets up the vector table for handling interrupts and 00:25:27.040 --> 00:25:31.680 similar things like that. Then if we get past this initial stage, we actually want 00:25:31.680 --> 00:25:36.960 to boot the ADONIS kernel which Ali talked about before. So first of all, there is an 00:25:36.960 --> 00:25:42.160 array of function pointers that gets called one for like every piece of 00:25:42.160 --> 00:25:47.200 functionality that we saw on this overview of the different components of ADONIS. So 00:25:47.200 --> 00:25:51.040 if you wanted to look at what kind of components are there or functional 00:25:51.040 --> 00:25:55.680 components are there. This is a very interesting list of functions, function 00:25:55.680 --> 00:26:01.520 handlers to... to examine and also sets up some management structures and stuff like 00:26:01.520 --> 00:26:07.840 this one a typical operating system would have to set up. So now we look at more of 00:26:07.840 --> 00:26:14.480 the different components of ADONIS. First one is the file system, so PLCs is part of 00:26:14.480 --> 00:26:20.240 the specifications. Sometimes it's how resilient is it against temperatures, how 00:26:20.240 --> 00:26:26.480 low of a temperature can I have this PLC reside in without losing functionality? 00:26:26.480 --> 00:26:33.360 And in this case, what they also want to provide is some safety against interrupts 00:26:33.360 --> 00:26:38.160 in power supply. So they developed a proprietary file system which is called 00:26:38.160 --> 00:26:42.640 "Powered Down Consistency Files System", which they implement in the firmware. And 00:26:44.080 --> 00:26:56.160 we can also see one of the work experience entries of one of the previous 00:26:56.160 --> 00:27:03.360 Siemens employees who stated that he or she worked on this file system. We have 00:27:03.360 --> 00:27:07.680 another part of a very critical part of the functionality, of course, we want to 00:27:07.680 --> 00:27:14.560 talk to the PLC, it wants to talk to us in.. and one of the ways is fiercely 00:27:14.560 --> 00:27:19.280 TCP/IP. And this is to expose the Web server, for example, and different other 00:27:19.280 --> 00:27:26.000 components. And in this case, it turns out that Siemens doesn't implement their own, 00:27:26.000 --> 00:27:31.150 which probably is a good idea not to do that. They use the 00:27:31.150 --> 00:27:34.944 InterNiche Technologies TCP/IP stack in version 3.1. 00:27:34.944 --> 00:27:37.760 If you are good at Googling you can find some source 00:27:37.760 --> 00:27:41.600 code and you can actually map this to the firmware and how it works. So it could 00:27:41.600 --> 00:27:48.880 give you some wrapper functions, something like creating sockets and stuff like this 00:27:48.880 --> 00:27:53.573 and could make it easier for you to find those in the firmware image. We also have 00:27:53.573 --> 00:28:00.666 one of the very critical components of each firmware is update. If it allows an 00:28:00.666 --> 00:28:06.647 update and the Siemens PLC allows updates, there are different modes. One of the 00:28:06.647 --> 00:28:12.248 modes is, just you drag and drop an UPD file, an update file to the web server and 00:28:12.248 --> 00:28:18.886 it will start checking firmware, integrity and signatures and so on. And the second 00:28:18.886 --> 00:28:24.714 way is doing it via an SD card, which has a great total of twenty four megabytes and 00:28:24.714 --> 00:28:30.807 it's for the low price of 250 euros. You can can get it. I think you can not really 00:28:30.807 --> 00:28:39.257 beat that, that ratio. If you actually decompress this kind of UPD file, you get 00:28:39.257 --> 00:28:43.142 another representation of it in memory. And we did some reverse engineering on 00:28:43.142 --> 00:28:47.389 that and we have different fields not sure if you can see them now, but you can 00:28:47.389 --> 00:28:53.711 expect what it is. It's different offsets into the actual binary file. It's it's an 00:28:53.711 --> 00:28:57.953 entry point into the firmware magic header to make sure something is not too screwed 00:28:57.953 --> 00:29:03.768 up and a CRC over the whole thing for example. We also extracted some of the 00:29:03.768 --> 00:29:11.704 addresses inside the firmware image, which helps you find a first foothold into what 00:29:11.704 --> 00:29:17.721 the logic is dealing with and give you some addresses for you to refer this to 00:29:17.721 --> 00:29:23.384 later. The next component that we want to touch on is Miniweb, which is the web 00:29:23.384 --> 00:29:30.040 server. It kind of exposes to you the different internal parts of the PLC and 00:29:30.040 --> 00:29:35.359 what the state of different GPIOs, general purpose input outputs, is. The inputs and 00:29:35.359 --> 00:29:41.827 the outputs and what the health of the PLC is itself and the way that it exposes this 00:29:41.827 --> 00:29:49.608 is using the MWSL language Miniweb scripting language. It's as we will see on 00:29:49.608 --> 00:29:55.129 the next over the next slide and we'll talk to them about that in a little bit 00:29:55.129 --> 00:30:01.890 more detail. We have a be started, has the service as well from one of the function 00:30:01.890 --> 00:30:08.585 handlers of the ADONIS initialization functions that I referred to a little bit 00:30:08.585 --> 00:30:13.727 before. So now let's get to some undocumented http handlers, which I think 00:30:13.727 --> 00:30:18.237 are very interesting. I think my favorites are "lilililili" and "lololololo".. 00:30:18.237 --> 00:30:20.391 laughter 00:30:20.391 --> 00:30:25.184 .. and if you should put those together in a clever way, maybe somebody is musically 00:30:25.184 --> 00:30:33.228 gifted and can make a song out of it. I would be very interested to hear that. So 00:30:33.228 --> 00:30:37.581 now let's get to the MWSL the Miniweb scripting language. So it basically 00:30:37.581 --> 00:30:42.676 exposes the internal functionality by allowing you to inject into an html page 00:30:42.676 --> 00:30:47.336 by a templating different configuration parameters and stuff like this. For 00:30:47.336 --> 00:30:53.920 example, as we can see here on the top right corner, you can see the CPU load of 00:30:53.920 --> 00:30:59.411 the system at a given time. It doesn't really seem to perform any output 00:30:59.411 --> 00:31:05.700 encoding, so it kind of trusting what comes out. So there may be clever ways 00:31:05.700 --> 00:31:12.902 to... to do some web related trickery with this and also the parsing of this 00:31:12.902 --> 00:31:19.429 tokenization is kind of complex. I looked into it a bit and this implementation 00:31:19.429 --> 00:31:24.753 could also be interesting to look at, but we will get to those kinds of 00:31:24.753 --> 00:31:30.407 aspects a bit later. With this, we're going to get to our actual findings and 00:31:30.407 --> 00:31:33.927 talk about those a bit more. And this is where Ali will take over. 00:31:34.605 --> 00:31:43.120 Ali: Thanks, Tobi. So. So now we talk about the capabilities which exist in the 00:31:43.120 --> 00:31:48.960 bootloader, which allows us to have unconstrained code execution. So basically 00:31:48.960 --> 00:31:54.640 this feature is available in the uart. So you need physical access to the device. 00:31:55.600 --> 00:32:00.880 But once you have this physical access, you can basically, as Tobias later 00:32:00.880 --> 00:32:05.120 describes, we can actually bypass the security ecosystem which developed by 00:32:05.120 --> 00:32:11.208 Siemens in their product. So you need uart access as it's documented here, you have 00:32:11.208 --> 00:32:20.240 TX, RX and GND in the PLC and the uart actually in previous research was 00:32:20.240 --> 00:32:25.840 documented as well. Every address which I am talking about here or mentioned in this 00:32:25.840 --> 00:32:31.440 presentation are for bootloader version 4 to 1. As I mentioned earlier, Siemens 00:32:31.440 --> 00:32:38.240 actively modified the bootloader. So I think in two years we saw like 2, 3 00:32:38.240 --> 00:32:44.640 modifications or different versions of their bootloader coming up. So this 00:32:44.640 --> 00:32:50.160 exactly is based on that's half a second waiting for a specific command after a 00:32:50.160 --> 00:32:56.320 second hardware configuration happens. It applies to Siemens S7-1200 including 00:32:56.320 --> 00:33:02.800 SiPLUS and S7-200 SMART. Actually, somebody from Kaspersky. IS security 00:33:02.800 --> 00:33:08.000 mentioned it. We didn't know even about it. We just investigated a S7-1200. But 00:33:08.000 --> 00:33:14.400 Siemens later updated that advisory that also applies to other products as well. So 00:33:14.400 --> 00:33:19.392 let's talk about this, a special access feature. So as you mentioned, one of the 00:33:19.392 --> 00:33:22.821 things the bootloader does is actually initialize the hardware after this 00:33:22.821 --> 00:33:27.360 hardware it's basically copy some of the contents of the bootloader itself to a 00:33:27.360 --> 00:33:36.000 memory segment called IRAM, basically. And then PLC basically waits half a second for 00:33:36.000 --> 00:33:39.680 a specific command. And once it's received, this specific command it 00:33:39.680 --> 00:33:44.160 responds with a specific string and it's all happening over the uart. So it's if 00:33:44.160 --> 00:33:50.348 you send a magic string, MFGT1, sorry for my broken German, but probably it means 00:33:50.348 --> 00:33:57.939 "Mit freundlichen Grüßen", I hope I did it right. And then the PLC responds with 00:33:57.939 --> 00:34:02.080 "-CPU" and says that now you are in this special access mode. I am waiting for your 00:34:02.080 --> 00:34:10.880 commands. And this address is also I believe 0xedf8 in the bootloader. So here 00:34:10.880 --> 00:34:16.480 is a decoding of our clients, which we will release later next year, actually, 00:34:16.480 --> 00:34:25.120 which you see that's 2d435055, which is the "-CPU" response from the PLC. So now 00:34:25.120 --> 00:34:30.560 we are in it. And also we also added some extra saying about your packet format. 00:34:30.560 --> 00:34:36.880 Somebody asked before. So once you send this command, you get lots of 00:34:37.600 --> 00:34:43.360 functionalities here in this presentation. We call them handlers and basically they 00:34:43.360 --> 00:34:49.840 are something we call primarily handler. It's like 128 entries and there are some 00:34:49.840 --> 00:34:57.600 three other separated handlers which are like 0x80 uart configuration and bye. So 00:34:57.600 --> 00:35:01.680 in the primary handler release, there are lots of things. So if you go back to the 2 00:35:01.680 --> 00:35:10.882 previous slides, I got the firmware version here, 4.2.3. And 00:35:10.882 --> 00:35:14.886 basically what is happening is that basically it's this command here, get 00:35:14.886 --> 00:35:19.724 bootloader version. We are just requesting the special access feature to tell us 00:35:19.724 --> 00:35:24.776 what is a bootloader version. And also you can do lots of low level diagnostic 00:35:24.776 --> 00:35:28.930 functionality is happening there. Also some functionalities related to firmware 00:35:28.930 --> 00:35:34.515 update happening there which bypasses the usual cryptographic verification of the 00:35:34.515 --> 00:35:42.540 firmware and doesn't need that. So let's look at them, because for this work, which 00:35:42.540 --> 00:35:46.632 we are talking about, we actually primarily only use two of the handlers. So 00:35:46.632 --> 00:35:51.515 we don't use.. we don't look at like or we don't discuss now all others hundred 00:35:51.515 --> 00:35:58.281 twenty eight handlers which exist in the PLC. So it works. One of the handlers, the 00:35:58.281 --> 00:36:05.907 interesting one for us was handler 0x80 which mentioned here, update function. So 00:36:05.907 --> 00:36:11.066 basically what it does is that it lets you allow you to write to a specific part of a 00:36:11.066 --> 00:36:17.259 memory IRAM, which previously copied some content of the bootloader. So basically 00:36:17.259 --> 00:36:21.731 you send this handler after this handshake, you have to do this MFGT1 and 00:36:21.731 --> 00:36:25.787 then -CPU. And then basically you are going to send this handler and then it 00:36:25.787 --> 00:36:29.713 basically checks because each handler might have different requirements. Check 00:36:29.713 --> 00:36:34.234 number of arguments, for example, and then you are in this update function mode. And 00:36:34.234 --> 00:36:38.840 then you have to provide target ID because there is 4 subfunctionality available. 00:36:38.840 --> 00:36:45.348 Once you enter this mode and some of them are like for IRAM, for SPI or IOC or for 00:36:45.348 --> 00:36:51.548 Flash, and then for each of them, you have to choose what kind of operation you want 00:36:51.548 --> 00:36:58.026 to do you want to configure, read, write or check. And so you can do all of these 00:36:58.026 --> 00:37:02.883 things so you can read and write to the IRAM. Basically, this is a function 00:37:02.883 --> 00:37:09.736 handler at 0x80. Next is a primary handler like 0x1c. This is listed in this handler 00:37:09.736 --> 00:37:19.869 list, here. So, so basically it allows you to call functions. So the basically this 00:37:19.869 --> 00:37:24.004 functions are listed in the IRAM. And basically what you do is that you send 00:37:24.004 --> 00:37:29.400 this handshake, you are and you are in this. Basically, this is what 0x1c handler 00:37:29.400 --> 00:37:34.520 and then you can call the ID number of the handlers which you want to use. So here 00:37:34.520 --> 00:37:41.920 you have like lots of handler available for 0x1c. So the question is, what we can 00:37:41.920 --> 00:37:50.845 do with it. And before I asked Tobias I want to ask anybody here, any idea? Trace, 00:37:50.845 --> 00:37:53.939 somebody said trace. I don't know what that means, but 00:37:53.939 --> 00:37:57.875 mumbling in the audience 00:37:57.875 --> 00:38:04.162 OK. You mean with JTAG? with the CoreSight? No, we are not going to use 00:38:04.162 --> 00:38:07.162 that. So let's ask Tobias what he can do. 00:38:07.162 --> 00:38:11.440 Tobias: Yeah. So looking at it dynamically and seeing what it does with the memory 00:38:11.440 --> 00:38:15.232 is, I guess, a good idea in general. If you if like static reverse engineering 00:38:15.232 --> 00:38:20.723 doesn't give you anything. In this case, we looked through different or I looked 00:38:20.723 --> 00:38:26.581 through different of those functions and tried to see, what can I do with it? So 00:38:26.581 --> 00:38:32.080 the base of where I started looking for this special access feature was basically 00:38:32.080 --> 00:38:37.475 that I saw there is too much in this code going on. I kind of feel like I understood 00:38:37.475 --> 00:38:42.418 what it should be doing. The bootloader what it should be doing, but it seemed 00:38:42.418 --> 00:38:50.171 just to be too much. And the way we can combine those two functions is basically 00:38:50.171 --> 00:39:01.672 to recap. Use this 0x1c handler, which gives us control over what kind of 00:39:01.672 --> 00:39:07.558 secondary list functions to be called, which, as we saw before, is copied during 00:39:07.558 --> 00:39:13.720 the the boot up process to a position in IRAM from external read-only memory. And 00:39:13.720 --> 00:39:19.862 this exposes this function handler table to anything that can write to IRAM. And as 00:39:19.862 --> 00:39:25.954 we learned before, the 0x80 handler is able to in a limited capacity, do just 00:39:25.954 --> 00:39:32.133 that. And here we can see what we can try to do with this. So we use in a first 00:39:32.133 --> 00:39:38.533 stage the 0x80 handler to write to IRAM. We can actually inject another function 00:39:38.533 --> 00:39:43.921 pointer together with some configuration values that allows us to pass different 00:39:43.921 --> 00:39:49.580 checks about argument sizes and stuff like this. We can inject this as an entry into 00:39:49.580 --> 00:39:56.286 this table and we can also write to this table a payload which we can use as a 00:39:56.286 --> 00:40:02.760 shell code. And then in a second stage we can use this previously injected index 00:40:02.760 --> 00:40:11.971 that we specified just as a trigger to call our own payload. So now we have code 00:40:11.971 --> 00:40:17.160 execution in the context of the bootloader. So which is as privileged as 00:40:17.160 --> 00:40:24.213 we can get at that point and we can see what we can play around with this. And as 00:40:24.213 --> 00:40:29.560 a little summary is that we chain all this together and we get code execution. And 00:40:29.560 --> 00:40:35.619 with Ali's words, with this technology, we're going to rocket the PLC. And before 00:40:35.619 --> 00:40:40.903 we go into what this actually allows us to do is a little word about the stager 00:40:40.903 --> 00:40:47.003 payload. So I wrote this this chain of different invocations and it turns out 00:40:47.003 --> 00:40:52.326 that this write to IRAM is somehow very slow in the first place, but then also 00:40:52.326 --> 00:40:56.736 error prone so the device can just error out and I'm not quite sure what this 00:40:56.736 --> 00:41:03.498 pertains to, but what may be interesting to know from the Siemens engineer, but it 00:41:03.498 --> 00:41:08.672 basically led to me having to inject a little encoded payload, which just has a 00:41:08.672 --> 00:41:16.345 subset of bytes which gives us an interface to do to perform 00:41:16.345 --> 00:41:20.124 reads and writes with an arbitrary write primitive and then use this to 00:41:20.124 --> 00:41:25.002 inject second stage payloads. And this is what we want to demonstrate here. 00:41:26.741 --> 00:41:32.796 Ali: Thanks. So now we would have our demo 4 demos, actually. So the first one is 00:41:32.796 --> 00:41:37.156 actually just seeing a communication, basically sending these requests and 00:41:37.156 --> 00:41:42.265 getting a response and basically sending this data payload. So the up is the raw 00:41:42.265 --> 00:41:48.493 UART communication. Don't worry, it's getting zoomed later and the down is like 00:41:48.493 --> 00:41:55.568 our client, which actually talking with the PLC and sending us comments. So we are 00:41:55.568 --> 00:42:01.134 just running our UART. And here is we are sending our command. And if you look at it 00:42:01.134 --> 00:42:07.048 up, you see the -CPU signal came from the PLC. And now we are sending our stager 00:42:07.048 --> 00:42:11.629 and our stager just sends us just one acknowledgement so we know that the stager 00:42:11.629 --> 00:42:16.014 runs successfully. This is for firmware version bootloader version 4.2.1, 00:42:16.014 --> 00:42:19.647 basically. So now we are going to do something else we are going to actually 00:42:19.647 --> 00:42:24.234 dump the firmware from a running PLC and compare it with the firmware downloaded 00:42:24.234 --> 00:42:30.913 from Siemens' website. So for us, we are going to actually unpack the firmware 00:42:30.913 --> 00:42:35.520 downloaded from Siemens website because it's a compressed with lzp3. So 00:42:38.080 --> 00:42:43.360 that's what we are going to do. Oh, we are actually setting up our SSL connection 00:42:43.360 --> 00:42:50.320 first. So SSL port forwarding, ssh port forwarding before and we are just checking 00:42:50.320 --> 00:42:56.952 that the PLC is running properly. So like this is not a broken PLC or something like 00:42:56.952 --> 00:43:02.107 that. We wrote something. So we just make sure that the web server is opening the 00:43:02.755 --> 00:43:12.640 open the server, it's open, it's good. And I also try to log in to the website, to 00:43:12.640 --> 00:43:16.720 the Web server of the PLC. Just again, make sure that the PLC is functional. So 00:43:16.720 --> 00:43:23.920 also enter the password. I guess everybody can guess it. And then so you see that we 00:43:23.920 --> 00:43:28.720 log in eventually and in the left side you see all the like functionalities which 00:43:28.720 --> 00:43:34.320 loads related to the PLC. So it's a working, running, functional PLC. And so 00:43:34.320 --> 00:43:39.680 now you're going to decompress the firmware downloaded from Siemens' website 00:43:39.680 --> 00:43:43.962 after checking for export license and stuff. So they want to make sure that 00:43:43.962 --> 00:43:51.664 people from Iran and North Korea don't get it. I'm from Iran, by the way. So here we 00:43:51.664 --> 00:43:55.485 have the unpacked firmware. But because the frame rate is very large, as Tobias 00:43:55.485 --> 00:43:59.415 mentioned earlier, what we are going to do is that we are just going to export 00:43:59.415 --> 00:44:05.049 256 kilobytes of the firmware from some part of the web server and into IDA. So 00:44:05.049 --> 00:44:10.358 you have to set the big endianess for the cpu. And also rebase the framwork. So as 00:44:10.358 --> 00:44:15.346 you can see, here is no function yet, but once we rebase it we have all the function 00:44:15.346 --> 00:44:24.538 as well and yeah, so then we gotta just go and export 256 kilo bytes from the 00:44:24.538 --> 00:44:29.406 firmware so we specifically slow down the UART because we want to make sure that we 00:44:29.406 --> 00:44:33.289 don't do it's too fast to overflow the buffer which we have internally in the 00:44:33.289 --> 00:44:41.896 PLC. So. So here, for example, in this address, 691e28 we are going to export 256 00:44:41.896 --> 00:44:45.876 kilobytes. This is from the firmware, Siemens firmware. Right. So we just 00:44:45.876 --> 00:45:00.737 export it. So, yeah, so it's now called fw-0x691E28 in the folder out. So now we 00:45:00.737 --> 00:45:05.645 are done with this part. We are going to dump the same address in the PLC. So from 00:45:05.645 --> 00:45:11.960 a running PLC, I have to mention again. So this is the top part is basically raw uart 00:45:11.960 --> 00:45:17.959 and this is basically our client part and we are dumping it with a cold boot style 00:45:17.959 --> 00:45:22.147 attack. So we are basically resetting the PLC. And before it's over, write the RAM, 00:45:22.147 --> 00:45:28.963 we are basically dumping the contents of the RAM. So this is the address, 0x691e28. 00:45:28.963 --> 00:45:34.991 This is about the same address, basically. And we are dumping 256 kilobytes. And here 00:45:34.991 --> 00:45:41.071 we send MFGT1 basically. And then got the /cpu and then the rest of the stager 00:45:41.071 --> 00:45:48.807 and stuff goes. So now basically we are sending packets and then eventually get a 00:45:48.807 --> 00:45:57.478 recive. So basically got all the payload like dumped in mem_dump_00691e28 00:45:57.478 --> 00:46:03.342 basically. So this is from the RAM of the PLC. This is not anymore from Siemens' 00:46:03.342 --> 00:46:17.300 websites. We are just scped to our own machine and then compare it. So now we 00:46:17.300 --> 00:46:21.887 have the memdump and original firmware 256 kilobytes each. And then we are going 00:46:21.887 --> 00:46:28.977 to compare them with each other. And as you can see, should look here like you 00:46:28.977 --> 00:46:32.755 have like hundred percent match. Meaning that it's exactly the same firmware, 00:46:32.755 --> 00:46:37.136 which is available on Siemens website. We dumped it directly from the Siemens PLC 00:46:37.136 --> 00:46:44.279 memory using this as special access feature. So let's do another one. So this 00:46:44.279 --> 00:46:47.896 time we all want to show that unconstrained code execution in just a 00:46:47.896 --> 00:46:53.474 very basic way. So we are actually just writing a custom payload to the PLC and 00:46:53.474 --> 00:46:57.960 get a hello or greetings from the PLC. So basically, basically we just asked the PLC 00:46:57.960 --> 00:47:04.922 to send us this message all the time. So again, so we are sending our custom 00:47:04.922 --> 00:47:13.449 payload here and say hello loop. And basically the PLC just sending this loop 00:47:13.449 --> 00:47:24.395 for us. So all of these things, again, are for bootloader 4.2.1. You have to readjust 00:47:24.395 --> 00:47:29.704 certain things because Siemens saying they updated again their bootloader in the 00:47:29.704 --> 00:47:36.458 recent 2019 December, which we bought new PLC, again, once again. And now here we 00:47:36.458 --> 00:47:42.997 get a response. That's the PLC is sending basically to us this our raw data, which 00:47:42.997 --> 00:47:46.894 is PLC is keep sending to us. That's showing that we are receiving this. But 00:47:46.894 --> 00:47:53.852 maybe this was too basic. These are the raw data which we are getting from the 00:47:53.852 --> 00:47:57.764 PLC. Let's actually do it a little more complex. Show something that is not from 00:47:57.764 --> 00:48:04.167 us. So let's play a game called tic tac toe inside the PLC. And I guess if you 00:48:04.167 --> 00:48:08.873 don't know, this is how tic tac toe is like this is I am playing and I just draw 00:48:08.873 --> 00:48:20.308 with the google. So. Now we are again are going to send our custom payload. But this 00:48:20.308 --> 00:48:25.364 time we are just use partial quotes from somebody else from the Internet and just 00:48:25.364 --> 00:48:30.091 upload, compile it and then upload it to the PLC. Obviously, you have to readjust 00:48:30.091 --> 00:48:38.726 lots of things. But so we are sending our payload, including a stager and these are 00:48:38.726 --> 00:48:44.956 the raw data. Again, these are our client. And eventually you will see a tic tac toe 00:48:44.956 --> 00:48:50.175 interface, which you have to enter. So Player 1 is actually playing with the X 00:48:50.175 --> 00:48:54.870 and player 2 is playing with like 0. So you see of any positioning, which you 00:48:54.870 --> 00:49:04.827 choose. You have X, X and hopefully a player one wins. Yes. So that was it. So 00:49:04.827 --> 00:49:15.680 that was a demo. applause 00:49:15.680 --> 00:49:19.891 Obviously, there are lots of other ideas which we can work on, on injecting other 00:49:19.891 --> 00:49:24.560 custom code, using the special access functionality, we are still working on 00:49:24.560 --> 00:49:30.320 this. Like lots of other things on Siemens, we are sorry Siemens we are just 00:49:30.320 --> 00:49:35.926 working on this, but there are more to come. But in the meantime, there are some 00:49:35.926 --> 00:49:40.881 ideas for other people in case they are looking into this and one to investigate 00:49:40.881 --> 00:49:45.860 security of Siemens PLCs. So using this as special access entry, you can do somewhat 00:49:45.860 --> 00:49:49.826 certain things. So, for example, you can use this prophylaxis functionality to 00:49:49.826 --> 00:49:54.607 write to the firmware. As we mentioned, this functionality is available and it 00:49:54.607 --> 00:49:59.320 doesn't require those cryptographic signature which normally during update 00:49:59.320 --> 00:50:03.917 process of the firmware available. So you can just bypass it and it's just CRC 00:50:03.917 --> 00:50:08.971 checksum. So what you can do is that, for example, adding entry to organize like 00:50:08.971 --> 00:50:13.446 initialization routine, which is available. And then also you can do it 00:50:13.446 --> 00:50:19.108 before organized initialization routine, which we call internal th_initial 00:50:19.698 --> 00:50:21.167 Another one which we can do, 00:50:21.167 --> 00:50:23.893 if you remember, Tobias talked about some undocumented and 00:50:23.893 --> 00:50:27.682 lots of creativity on creating music. li li li lo lo lo 00:50:27.682 --> 00:50:30.565 So what one person can do is 00:50:30.565 --> 00:50:35.871 like basically adding specific handler or overwriting existing handler. And what it 00:50:35.871 --> 00:50:39.757 makes actually is like something like triton. I don't know if anybody know her, 00:50:39.757 --> 00:50:42.660 but triton is malware which were attacking petrochemical plant 00:50:42.660 --> 00:50:44.339 in Saudi Arabia. So they were trying 00:50:44.339 --> 00:50:47.863 to do it in the TCP. But attacker here can maybe do it in http 00:50:47.863 --> 00:50:54.086 example and just listen and waiting for comments and also other alternatives like 00:50:54.086 --> 00:51:00.947 patching one of the jump tables in the AWP handlers, which can be also used for 00:51:00.947 --> 00:51:08.745 process a specific attack. So what else is out there? So what we looked is we looked 00:51:10.045 --> 00:51:10.919 We looked at 00:51:10.919 --> 00:51:15.774 at attack surface in the Siemens S7 PLCs. There are like for from prospective on 00:51:15.774 --> 00:51:19.838 local privilege attacks. What we can... what we looked was bootloader. We are 00:51:19.838 --> 00:51:25.351 still working on hardware attacks and some hardware software attacks on the edge. Is 00:51:25.351 --> 00:51:31.404 this still ongoing work, which we don't obviously discuss now? Also interesting 00:51:31.404 --> 00:51:35.022 thing, I think if somebody who is interested in security of PLCs and 00:51:35.022 --> 00:51:38.861 especially internals, I'm not talking about like just general segregation of 00:51:38.861 --> 00:51:43.058 network and stuff like that in ICS, I'm talking about more advanced low level 00:51:43.058 --> 00:51:51.252 stuff. We think like MWSL is interesting target. There probably are some like bugs 00:51:51.252 --> 00:51:55.677 in their implementations. Also, with respect to file system parsing and 00:51:55.677 --> 00:52:00.840 firmware signing, there are probably some stuff and also MC7 parser basically, 00:52:00.840 --> 00:52:06.601 which they have from privilege escalation perspective and also from remote code 00:52:06.601 --> 00:52:13.630 execution perspective, both MiniWeb webserver and also any network 00:52:13.630 --> 00:52:18.301 access of accessible services which they have might be interesting. You're actually 00:52:18.301 --> 00:52:27.577 also looking at this part right now. So as a conclusion. PLCs are becoming more 00:52:27.577 --> 00:52:31.354 complex. That's true, because they are actually providing more and more features 00:52:31.354 --> 00:52:34.969 and because of this more complexity, there will be more bugs. We can see, for 00:52:34.969 --> 00:52:41.676 example, in the MWSL, which we are looking at now, also bend or strike to basically 00:52:41.676 --> 00:52:47.037 more make it more complex. They have basically some anti debugging which we 00:52:47.037 --> 00:52:52.817 just discussed in Siemens PLCs, but also they have, for example, frame rate 00:52:52.817 --> 00:52:59.465 integrity verification so that the sign frame where like upload to the PLC and 00:52:59.465 --> 00:53:05.578 stuff like that. So they are making it more complex. But what you have to know is 00:53:05.578 --> 00:53:14.279 that if in their like thread model which like lots of people make or this security 00:53:14.279 --> 00:53:20.220 ecosystem which they built. If they have a feature which undermines the same security 00:53:20.220 --> 00:53:24.415 ecosystem which they designed. I mean, I think it's obvious that they have to 00:53:24.415 --> 00:53:28.427 remove like in the case of bootloader case in their special access features. One of 00:53:28.427 --> 00:53:32.340 the good examples. So. And of course, customers also have to know, because if 00:53:32.340 --> 00:53:36.428 they have such functionality and they need it, as long as customers know, it's fine. 00:53:36.428 --> 00:53:41.001 But when they don't, they can't risk calculate this risk in their strategy or 00:53:41.001 --> 00:53:46.809 in this threat model, which they have. So. And also they have to think or rethink 00:53:46.809 --> 00:53:51.054 about security by obscurity. Maybe they allow us, for example, as researchers to 00:53:51.054 --> 00:53:53.700 access the devices better and easier 00:53:53.700 --> 00:53:55.815 to investigate it more. We are still doing 00:53:55.815 --> 00:54:00.894 it, but it's just taking longer. And I believe that there are lots of seeing more 00:54:00.894 --> 00:54:08.464 to be done on like PLCs and Siemens will not be the last one which we are working 00:54:08.464 --> 00:54:13.844 on. So we have to thank some people Thorsten Holz our supervisor, he's not 00:54:13.844 --> 00:54:20.802 here. Thomas, Alexandre, Marina, Lucian, Nikita and Robin. For their help and 00:54:20.802 --> 00:54:26.902 their work. And now we are going to answer questions. 00:54:26.902 --> 00:54:27.881 Herald: Thank you. 00:54:27.881 --> 00:54:37.078 applause 00:54:38.944 --> 00:54:47.318 Herald: So, yeah, feel free to line up for the microphones or write your questions in 00:54:47.318 --> 00:54:54.941 the Elisa room. Ah, there you go. It's on right now I think. 00:55:02.043 --> 00:55:07.360 Signal Angel: Hello. Yeah. So there is one question from the Internet. Did you check 00:55:07.360 --> 00:55:15.789 the MC7 parser? If yes. Did you find any hidden unknown machine instruction 00:55:15.789 --> 00:55:21.760 on it or something? Ail: Do you want to answer? So just is it 00:55:21.760 --> 00:55:26.400 recorded or I have to repeat it again? So they ask that if we check the MC7 00:55:26.400 --> 00:55:32.097 parser. OK. So it's fine. So we didn't like truly investigate the MC7 parser, 00:55:32.097 --> 00:55:35.548 but we are working on it right now. 00:55:36.934 --> 00:55:40.640 Mic: Hello? How were you able to find the 00:55:40.640 --> 00:55:45.840 MFG security password? Ali: That's a very long story. First of 00:55:45.840 --> 00:55:50.236 all, like we had we had it in front of us for a long, long time until Siemens 00:55:50.236 --> 00:55:56.160 introduced this anti debugging feature. And after that, like we had to find other 00:55:56.160 --> 00:56:01.932 ways, other means to find it, to find a similar function, like similar ways that 00:56:01.932 --> 00:56:06.480 allow us because one thing which we didn't discuss here is that we didn't tell you 00:56:06.480 --> 00:56:11.920 about how we, for example, executed that instruction before in the PLC. It was 00:56:11.920 --> 00:56:18.240 involved some works which we received help from some researchers in Netherlands and 00:56:18.240 --> 00:56:24.560 in France. So this is this was something informed by Siemens in 2013. I think they 00:56:24.560 --> 00:56:31.280 knew about it. But until 2016, they patched it and then it became out like 00:56:31.280 --> 00:56:35.269 basically they tried to protect their PLCs from these kind of attack. It was never 00:56:35.269 --> 00:56:39.240 published before. So we were using it. And we don't want to talk about it, because 00:56:39.240 --> 00:56:42.939 the original author didn't want to talk about it. But we replicated what they 00:56:42.939 --> 00:56:49.360 were, what they were doing. And then once we really had to look for other ways, like 00:56:49.360 --> 00:56:53.760 then it opened our eyes that there are some other functionalities as well. There 00:56:53.760 --> 00:56:57.520 are so such as, for example, the bootloader. But before we before we need 00:56:57.520 --> 00:57:01.659 it, like we never actually looked at these things. So it was like in front of us for 00:57:01.659 --> 00:57:05.636 like two years. Tobias: Maybe one interesting piece of 00:57:05.636 --> 00:57:10.364 background story on this is that we actually in the previous technique that we 00:57:10.364 --> 00:57:16.240 used, we actually overrode the conditional jump that would lead to this special 00:57:16.240 --> 00:57:20.320 access feature being executed with an unconditional jump. So we basically cut 00:57:20.320 --> 00:57:25.680 out 60 percent of the whole code of the firmware image by accident. And then I 00:57:25.680 --> 00:57:30.320 just because of the hunch that I was talking about before that there is just 00:57:30.320 --> 00:57:35.040 too much functionality. I revisited it and actually realized that it was exactly the 00:57:35.040 --> 00:57:41.600 spot that we overrode before and we had to basically replace it and use it for our 00:57:41.600 --> 00:57:43.493 own sake. 00:57:44.113 --> 00:57:46.286 Mic: Is there any boot time security other 00:57:46.286 --> 00:57:51.470 than the CRC check? So you. Are you able to modify the contents of the SPI flash 00:57:51.470 --> 00:57:54.413 and get arbitrary code execution that way as well? 00:57:55.059 --> 00:58:01.911 Ali: So it depends in which year you are talking about 2017, 2016. So we are 00:58:01.911 --> 00:58:07.190 talking about the same models of the PLC, but in 2017 and 2018. No. So you could 00:58:07.190 --> 00:58:11.770 basically just take out SPI flash overwrite it. And that was fine. But if 00:58:11.770 --> 00:58:16.642 you were overwriting and it caused a halt in the CPU core, it would again trigger 00:58:16.642 --> 00:58:23.063 that anti debugging technology, which they have. This watchdog basically but from 00:58:23.063 --> 00:58:28.613 like frameware integrity verification. Well basically once you write to.. the 00:58:28.613 --> 00:58:33.347 firmware is written to the NAND flash, but it's just the CRC checksum. But during the 00:58:33.347 --> 00:58:37.189 update process? No. There are some cryptographic checks, but once it's 00:58:37.189 --> 00:58:41.920 written, no. There are some problems which there which again, it's a still ongoing 00:58:41.920 --> 00:58:45.456 work and we don't want to discuss about it, but nice catch. 00:58:45.456 --> 00:58:50.682 Mic: Thank you. Mic: Hi. Thanks for the talk. Could you 00:58:50.682 --> 00:58:54.937 elaborate on your communication with the vendor and the timeline? 00:58:54.937 --> 00:59:00.188 Ali: Yes. So, first of all, we know about this problem for like one year and half 00:59:00.188 --> 00:59:04.429 before we reported to the vendor. And the primary reason was that we were using it 00:59:04.429 --> 00:59:09.329 for some other project. This is actually this result is actually from a side 00:59:09.329 --> 00:59:12.867 project rather than the main project, because the main project is still 00:59:12.867 --> 00:59:18.083 something else and is still ongoing. But from a side of that projects, we had that 00:59:18.083 --> 00:59:21.888 access. And because we were worried that reporting to the vendor, they can fix it 00:59:21.888 --> 00:59:26.244 with software update and then do not allow all other CVEs which we find from this 00:59:26.244 --> 00:59:31.758 other project, we didn't want to eventually at 2019. Thomas Weber wanted to 00:59:31.758 --> 00:59:37.581 talk about his talk on like basically this JTAG interface with four CoreSight and 00:59:37.581 --> 00:59:42.776 then we decided to actually talk about it as well. But other than that, we actually 00:59:42.776 --> 00:59:48.512 talked in June I think with Siemens and they confirmed that there is this hardware 00:59:48.512 --> 00:59:53.209 base, a special access feature. And they are.. they say that they are going to 00:59:53.209 --> 00:59:58.460 remove it and that was it. We also send them a write up for them to read. 00:59:58.460 --> 01:00:02.644 Herald: So there is one last question from the signal angel over there. 01:00:04.173 --> 01:00:09.259 Signal Angel: So there's another question from the Internet. If tools like flashrom 01:00:09.259 --> 01:00:15.696 doesn't have support for unknown SPI flashrom chip, then how do you usually 01:00:15.696 --> 01:00:22.418 extract firmware if you don't want to decap a chip or use SOIC8 socket. 01:00:22.418 --> 01:00:26.538 Ali: Can you repeat it again? I didn't get the question, did you? 01:00:26.538 --> 01:00:32.419 Signal Angel: If tools like flashrom does not have support for unknown SPI flashrom 01:00:32.419 --> 01:00:38.640 chip, then how do you usually extract firmware if you don't want to decap chip 01:00:38.640 --> 01:00:42.262 and use SOIC8 socket. Ali: So first of all, we never actually 01:00:42.262 --> 01:00:49.030 decap the SPI flash. So that's just did it for the CPU. And just because we want we 01:00:49.030 --> 01:00:53.920 know that Siemens relabled their PLC, so it's not their own CPU, it's from 01:00:53.920 --> 01:00:58.755 Renesas, but that's why we did the decapping. So story of decapoing setting 01:00:58.755 --> 01:01:04.160 aside. But from other things all basically there are still this functionality, this 01:01:04.160 --> 01:01:08.068 bootloader functionality, which actually lets you read the content of the memory. 01:01:08.068 --> 01:01:11.621 So that's one thing you can read. Obviously you don't even need that thanks 01:01:11.621 --> 01:01:15.760 to one of my students. We now know one that's actually you don't even need to 01:01:15.760 --> 01:01:20.640 take out the bootloader, chip. We basically can just connect directly in the 01:01:20.640 --> 01:01:27.972 board and dump the firmware. Marcello, that's his name. He's here, actually. But 01:01:27.972 --> 01:01:34.110 anyway, so you can just directly read it. And yeah, I don't think the reading part, 01:01:34.110 --> 01:01:38.000 especially some part of it, is protected, especially in the recent versions, which 01:01:38.000 --> 01:01:43.200 you can't read everything. But besides that, I don't think there is any harder 01:01:43.200 --> 01:01:47.680 now yet. I am sure that they are working on that and we are working also on 01:01:47.680 --> 01:01:51.520 something to bypass that. So. Herald: Okay. That was our next talk is 01:01:51.520 --> 01:01:57.509 gonna be about delivery robots. Sasha in 20 minutes. So let's give you a hand. 01:01:57.509 --> 01:02:01.712 applause 01:02:01.712 --> 01:02:11.763 36c3 postrol music 01:02:11.763 --> 01:02:35.053 Subtitles created by c3subtitles.de in the year 2021. Join, and help us!