*36c3 prerol music*
Herald: So, Siemens recently decided to add some security feature to the PLC. And
today we have Tobias and Ali and they will be sort of.. telling us what they managed
to find. This PLC. They both come from Ruhr Universität Bochum. Tobias is a
recent acquisition as a doctoral student. And Ali is a postdoc. So, uh, let's give
them a hand.
*applause*
Ali: Hmm, where is our slide? Tobias: Presentation mode?
Ali: Yes. OK. Welcome to our talk. A deep dive into on concentrate code execution in
Siemens S7 PLCs. My name is Ali Abbasi and as mentioned before, I'm a postdoc at
chair of System Security at Ruhr University Boch and here's my colleague.
Tobias: I am Tobias or Tobi. I'm very glad to be here. It's my fifth time at the
Congress and now finally able to give back in a way. So I'm very excited about that.
So let's get into it. So first about the plan of the talk. We want to give you a
little bit of a background of what PLCs, which is programmable logic controllers
are all about, why we might want to use them and in what kind of setting. And then
we want to go into the specifics of PLCs in the Siemens case. First we look a bit
at the hardware and then at the software afterwards and the different findings that
we had. At the end, we would show a demonstration of what we're able to
achieve and conclude with some remarks. So first of all, process automation. So we
all know it. Or maybe we do it ourselves or we know somebody who does it. We put in
some devices in our smart home, if we call it smart already. And we try to automate
different targets on different things to make our lives easier. Things like turning
up and down the heat. We might not want to do that our own. We might not want to
overheat or under heat. And what we do is basically have some sensory systems inside
our homes, as well as some devices that interact with those sensors. In this case,
we might have a thermostat and a heater and we want to adjust our temperature
based on the thermostat. They're pretty simplistic solutions like this for a smart
home. But what we do if we have very complex control loops for example. Here we
can see on the left bottom corner a pretty complex looking picture, some operating
operators sitting in front of what we call an HMI a human machine interface, which is
basically an aggregation of all the information of things that go on in a
factory, for example. We need different sensors and this factory and we need to
steer different motors and stuff like this. So we need things in the middle to
kind of control all of this. And we do this using PLCs and we can see a setup how
it could look like. So basically have a set of inputs as we talked about and a set
of outputs. And we have some logic going on in the middle. And what we typically
deploy is a PLC a programable logic controller and some logic in the middle.
There are different technologies that can be used, for example, structure, text or
letter logic which gets downloaded onto the PLC and then which steers outputs
based on the inputs that it gets. You can see some applications of this kind of
thing. For example, a chemical power plant, chemical plant, an electric grid or
some manufacturing. Some of those components are pretty critical to the
workings. Even either we see it in the everyday lives and sometimes we don't
really see it. But they are in the steering, everything in the background and
we really don't want those systems to get compromised. For example, if you went onto
Google and looked something about disasters and chemical plants, you could
see melted down plants just because of some mis.. malfunction in the system or
so. And we really don't want this to happen. Neither an accidental but also not
a malicious basis. And this is why we want to secure all the processes going on in
factories and the like. We've seen some of the recent attacks. So it started kind of
in 1999 with a first initial reconnaissance based mainly. And then we
had some more advanced attacks in 2010, for example, where we saw Stuxnet, which
was very much really intricate operation. If you think about it on a technical
level, what all went into it. What different skill sets were involved. It's
pretty impressive. And then in the more recent time we had some issues in the
Ukrainian power grid, which in 2015 and '16 just before Christmas, some lights
went out for quite a while in some cities there. So quite a bit of impact. So to
give you a bit of impact, a background on Siemens PLCs here when it comes to market
shares. We can see that together with Rockwood Automation, Siemens actually has
more than 50 percent market share in the market. And obviously, if we take out some
devices that introduce some security, it would be interesting to look at those with
the biggest market share. This is what we did here in the Siemens case. Here we can
see the actual PLCs that we will focus on in this talk, which is the Siemens S7-1200
PLC. It's one of the smaller PLCs, not quite the smallest, there is the logo as
well, which is more of a playing around example, but this is the one that it's
still pretty accessible to researchers in terms of costs. So it's like 250 for the
PLC. Then if you need a power supply, it can add the same. So as long as you don't
break too many, spoiler, we broke quite some or you don't drop them or something
like this, then you're pretty fine so you can kind of get the resources to play with
those devices. We have different applications and we talked about them
before. So here is what an unboxing of a Siemens 7 1200 PLC would look like. We
have the top view here on the left picture. It's only one of different PCBs
which are layered on to each other in this case. But the real magic goes on in the
top PCB, which is the green one that we see here. Looking at it a bit more in more
detail. We have the top view on the left side, which shows the different components
that really make the PLC. Take, for example, the ARM CPU that we have or
different input outputs that we can connect to a PLC, as we talked about
before, which they need in order to steer different parts of the system. And then we
have the flash chip on the top side as well, which is a big flash chip holding
the firmware off the actual PLCs, which we will talk about a bit more in detail
later. On the flip side, we have on the right picture the bottom side of the first
layer PCB. And as we can see here, this is where the bootloader chip resides, which
is an SPI flashchip of four megabytes owning the code of the Siemens PLC
bootloader. Here we wanted to have a detailed view on what the actual
processing unit inside this board actually looks like and what you can do if you want
really want to find out you can do some decapping. And that's what we see here.
The result of this, we can see that at the core of it, it's a renaissance ARM
Cortex-R4 for from 2010. And if you afterwards are more juggling with the
software side of things, you may also want to find out the actual revision number,
what it supports inside the ARM standard. And what you can do there is use a special
instruction which resides in the ARM instruction set and you can decode the
different bits on it, which we did here, which you can see here for reference. So
if you really want to know what's going on, you can take apart those bits and make
sure you're actually working with the hardware that you expect to be working
with. So here's where we come to the memory part of the hardware and this is
where I leave you over to Ali. Ali: Thanks. Now that Tobias like unboxed
the PLC for us now I'm going to talk about quirks and features in the PLC. So as
mentioned before, it's Cortex-R4 revision 3. It's a big endian instruction set and
it's also only have MPU. So there is no visual memory basically, there are
multiple ram sizes depending on which year you bought it or which variant of the S7
1200 you buy and also multiple SPI flash and multiple different types of NAND
flashes. The most significant one difference is like in the RAM, which
sometimes they use Wingbond and sometimes they use Micron Technologies, recently
Micron Technologies RAM. It is LPDDR1 RAM. We expect the SPI Flash for bootloader. So
again, depending on the variance between one to four megabytes SPI flash, it
contains different banks of each sized 512 kbytes. And basically what the bootloader
does is that's beside the typical actions of the bootloader, which is like
configuring your hardware is like verifying the integrity of the firmware
before it being loaded. So we actually need some X-ray tomography of the PLC. So
it's basically 3D. So the PCB is basically rotating here because we wanted to also do
some hardware reverse engineering part. And somebody in university had something,
so we didn't have to go to our dentist for X-ray. So here is like a quick 15 minutes
X-ray, which is not that good. But once you go in deep, eventually what you will
have is like this and you can actually just it's like a software animation. You
can go inside PCB and see all the layers. It's like amazing. So it's up for PCB
layer. And so besides, VCC and GND, you need two layers of PCB connection
basically. So let's look at the start up process. Again. Start up as usual. Some
hardware configuration happens. So vectoring trap controller, for example,
like lots of this handlers for different modes in ARM and then CRC check some of
the bootloader itself, which is easily bypassed over because you can just
overwrite the CRC. Then the bootloader, especially in the 2017, 2018 variant of
the Siemens PLC, allows you to overwrite the SPI flash. And also eventually we
check the CRC checksum of the firmware before basically loading it. The size of
the bootloader itself is like 128 kbyte, it is really even less than that because
half of it is just like 0xff. Siemens multiple times changed, they had different
version. I think in two years we saw three variants or four variants of the
bootloader. So it was evolving. It was not something that's everybody forgotten about
it. So generally as mentioned, so you have part this first stage of hardware
initialization and then basically bringing the bootloader to the RAM and basically
checking the bootloader CRC checksum. So make sure that it's not manipulated, which
again is it can be bypassed. And then a second stage of the hardware
initialization happens. And then at this moment, it waits for a specific command
for half a second. And if it receives this command it goes to another mode, which
we'll discuss later. Otherwise, it basically prepares some CRC checksum table
for the firmware and then it tries to load the firmware and then eventually
just removes the memory barrier the stage 1 instruction those who knows about ARM.
And basically map the firmware to the memory.
So the name of the operating system, it
was not mentioned before, it's ADONIS. We know it from different from different
ways, actually. So first in the references, in the firmware, we see lots
of references to ADONIS, but that was not enough for us. So if we actually looked
around to see if like there is any reference to it, and well linkedin is one
good open source like reference. And he was like one employee actually talk about
Siemens developer who talk about like working in ADONIS. I don't know why he put
the Windows and Linux beside ADONIS, but I can say is that like you work on this. And
so it was not enough for us. So maybe some some of us we don't know. And we look
again further and further and we find this thing which was the best indicator. So
Siemens developer engineer mentioned that he worked on kernel software
development for ADONIS real time operating system, which is a good sign for us. It
means that we are right. So now that we know about the naming and we sure about
that. Let's look at the components. So it's actually a start in basically
0x00040040 and basically then initializing the kernel and then lots of routines for
initializing different components of the operating system. I don't think Siemens
actually generalize it in this way. We don't have such thing in the firmware,
but we actually did it like that. So we generalize it to two groups. Some of them
are core services like ADONIS real time operating system services, and some of
them are related to the like automation part. So those people who are like in the
automation part, like writing ladder logic and stuff like that, those commands and on
function codes which are relevant in Siemens, they actually know this are like
more automated related services. So you have PROFINET, AWP or automated web
programing MC7 JIT parser basically for the latter logic or different kind of SD
like basically their own JIT compiler inside the PLC. And you also have the OMS
this configuration system which is very related again to the automation part, core
core part of the automation system and of course alarm central all your and stuff
like that related to automation. In the operating system part, so lots of these
usual things. So file system. So PDCFS, which Tobias talks later about, it. The
TCP/IP stack, some C / C++ libraries, which is not from Siemens, it's from
Dinkumware and MiniWeb Server and MWSL Parser
or MiniWeb Scripting Language parser
and lots of different subcomponents which is usual in operating system like any
operating system you can find. Also, there are some references to CoreSight. I don't
know how many of you know of CoreSight or how much you work on ARM, but the basic
CoreSight is something similar to Intel process tracing or Intel PT for tracing
applications and can be used for getting code-coverage, for example. And the
hardware part is very well documented by Thomas Weber in this year, is not yet.
This year or so. This year, Black Hat Asia, but I have to warn you, because I
received some emails, some people ask about that. If you connect to it, the PLC
have someone to debugging feature which detects that it's being debuged via JTAG
and overwrite the NAND-Flash with random stuff. So you brick the PLC, so just
connected it at your own risk. Next is let's look
at the CoreSight just quickly, CoreSight basically have like
before I go here, I have to mention that Ralf Philipp
also have a good talk in 0 nights about CoreSight tracing. So I would recommend
you guys go look at that as well. Generally, CoreSight have like 3
major parts or components: sources, links and sinks and sinks is basically the part
which you actually get the trace information and sources are the part which
you tell is a featuring the CPU, which you ask what kind of sources you want to get
the data from and then links basically convert these sources. I have to mention
that like lots, it's very useful for Fuzzing as well too. I guess some people,
very few, but some people are working on that things. On coverage guided fuzzing
via CoreSight, ARM CoreSight. So it's possible similar implementation is
happened in Intel PT for example KAFL, WinAFL or Hongfuzz. So sources, basically
they have like three different components STM, PTM, ETM. ETM version 4 is the latest
version of it. And basically you have also links which connects different sources to
different like different or single sources to different or single basically sinks.
And then you have funnels for CoreSight, sorry sinks, sorry. You have sinks, which
is basically a different kind. So there are some integrity to the CPU which is 4
kilobytes ring buffer SRAM or you have like system memory or even TPIU or just
for example JTAG DP Port High Speed JTAG port. So now that cleared sink,
like the CoreSight, we actually queried S7 for existence of CoreSight and as you can
see, like in the software part is already implemented. So they actually have some
references in their software that they are utilizing or configuring the CoreSight in
the PLCs. And basically we can see that the ETM version is not the latest version
it is ETM version 3. Now that I've talked to you about CoreSight, Tobi can talk
about firmware dumps. Tobi: So let's get to something that I'm
very much more familiar with and feel it's easier for me to handle it is firmware
dumps or software in general, but firmware dumps, I think it's close as you can get
to what I like when talking to a PLC or trying to understand a PLC. So in the
Siemens case, we have a 13 megabytes binary and at the beginning it's not as
many, but as if you twiddle around with a bit and apply some IDA python functions
and stuff like this. You can get to like 84 000 functions, which is
not something you want to really look at everything manually. Also, like 84 000
function firmware image doesn't really get the sexiest firmware on planet, right? I
guess so. But this is what I what I looked at and what we were looking a bit more in
the next couple of minutes or so. As you can see, we have different names up there.
We have one name which is called _some_get_some_max_size. So this is my
internal way of saying I don't really have an idea of what's really going on in this
function, but we can also see some more meaningful functions. So we understood
some parts a bit more. Some parts of it less, but I gave it a cursory look in most
places. So now let's get in to a lot of address related stuff, so we expected a
lot of details, which are very interesting if you start looking at firmware code, and
I will explain along the way why that might be interesting. So first of all,
what you have to know is that coretex are for gives you bank registers. This is
basically a feature that's implemented to lower software overhead and allow more
seamless modes, which is for the internal CPU. And what we get is banks stacks per
execution mode. So if we want to know what is kind of going on in the state of the
filmware at a given point we may want to look at the different stacks of the
different modes at any given point. And this is the addresses that we expected for
this. And you could use that if you as a starting point, if you started reverse
engineering, things like that. Now, we will have some address, some tables with
addresses. And the first one is RAM mappings, which show you what kind of
functionality or what you might expect when looking at firmware code, which is
interfacing with different parts of memory. So if you initially go and look at
some ARM code, you may just see a random access to some place in memory and you may
want to know what it's actually doing. And it looks very uneventful of it's just an
address and it gets gets queued and you don't really know what's going on. So,
for example, if you looked at an address within the text section, you would expect
there to reside code if you wanted to see some global static data, you would want to
look at the data or the BSS section. And then finally, if you wanted to look at
heap memory or how channels are set up there, you would look in the uninitialize
section and it goes on like this for different sections. Another very
interesting thing to look at, if you tried to reverse engineer firmware images is
that you kind of want to know what the hardware is that a given piece of code is,
is interfacing with. And in this case we dumped some regions or reverse engineered
what some regions are for what is called memory mapped I/O. And the way ARM is
talking to a firmware is basically to queue a magic value inside the address
space and then it gets something back, which is not at all what it has been
written there before. So it's basically an address which gets wired through to the
periphery the hardware periphery on the same system on a chip. And here we can see
that we have different hardware peripherals residing on it. For example,
we can talk to the Siemens PLC via different serial protocols and those
protocols might be SPI or I²C. And we have on the left side, kind of in the middle
top what took part of it, have some region pertaining to that. And then if you saw
some other code talking to timers, for example, you would know you are in timer
land at the moment or like in the scheduler or whatever it would be.
Finally, we have
some MPU configurations which are memory protection unit configurations, as Ali
introduced earlier. So what we can see is that Siemens is actually applying some of
those configurations to protect parts of memory. What we can see, for example, is
where whenever the XN so the execute never bit is set, code is not to be executed
within this address region or we have a read only region. We really don't want to
have it overwritten. So it's interesting that they started playing this in
practice. Here we can see what actually happens when the firmware itself boots up.
So it turns out the firmware doesn't really want to depend too much on what the
bootloader did. Probably it's different teams doing different things. And to keep
this interface as small as possible, they kind of redo some of the stuff that the
bootloader code also does. It sets up the vector table for handling interrupts and
similar things like that. Then if we get past this initial stage, we actually want
to boot the ADONIS kernel which Ali talked about before. So first of all, there is an
array of function pointers that gets called one for like every piece of
functionality that we saw on this overview of the different components of ADONIS. So
if you wanted to look at what kind of components are there or functional
components are there. This is a very interesting list of functions, function
handlers to... to examine and also sets up some management structures and stuff like
this one a typical operating system would have to set up. So now we look at more of
the different components of ADONIS. First one is the file system, so PLCs is part of
the specifications. Sometimes it's how resilient is it against temperatures, how
low of a temperature can I have this PLC reside in without losing functionality?
And in this case, what they also want to provide is some safety against interrupts
in power supply. So they developed a proprietary file system which is called
"Powered Down Consistency Files System", which they implement in the firmware. And
we can also see one of the work experience entries of one of the previous
Siemens employees who stated that he or she worked on this file system. We have
another part of a very critical part of the functionality, of course, we want to
talk to the PLC, it wants to talk to us in.. and one of the ways is fiercely
TCP/IP. And this is to expose the Web server, for example, and different other
components. And in this case, it turns out that Siemens doesn't implement their own,
which probably is a good idea not to do that. They use the
InterNiche Technologies TCP/IP stack in version 3.1.
If you are good at Googling you can find some source
code and you can actually map this to the firmware and how it works. So it could
give you some wrapper functions, something like creating sockets and stuff like this
and could make it easier for you to find those in the firmware image. We also have
one of the very critical components of each firmware is update. If it allows an
update and the Siemens PLC allows updates, there are different modes. One of the
modes is, just you drag and drop an UPD file, an update file to the web server and
it will start checking firmware, integrity and signatures and so on. And the second
way is doing it via an SD card, which has a great total of twenty four megabytes and
it's for the low price of 250 euros. You can can get it. I think you can not really
beat that, that ratio. If you actually decompress this kind of UPD file, you get
another representation of it in memory. And we did some reverse engineering on
that and we have different fields not sure if you can see them now, but you can
expect what it is. It's different offsets into the actual binary file. It's it's an
entry point into the firmware magic header to make sure something is not too screwed
up and a CRC over the whole thing for example. We also extracted some of the
addresses inside the firmware image, which helps you find a first foothold into what
the logic is dealing with and give you some addresses for you to refer this to
later. The next component that we want to touch on is Miniweb, which is the web
server. It kind of exposes to you the different internal parts of the PLC and
what the state of different GPIOs, general purpose input outputs, is. The inputs and
the outputs and what the health of the PLC is itself and the way that it exposes this
is using the MWSL language Miniweb scripting language. It's as we will see on
the next over the next slide and we'll talk to them about that in a little bit
more detail. We have a be started, has the service as well from one of the function
handlers of the ADONIS initialization functions that I referred to a little bit
before. So now let's get to some undocumented http handlers, which I think
are very interesting. I think my favorites are "lilililili" and "lololololo"..
*laughter*
.. and if you should put those together in a clever way, maybe somebody is musically
gifted and can make a song out of it. I would be very interested to hear that. So
now let's get to the MWSL the Miniweb scripting language. So it basically
exposes the internal functionality by allowing you to inject into an html page
by a templating different configuration parameters and stuff like this. For
example, as we can see here on the top right corner, you can see the CPU load of
the system at a given time. It doesn't really seem to perform any output
encoding, so it kind of trusting what comes out. So there may be clever ways
to... to do some web related trickery with this and also the parsing of this
tokenization is kind of complex. I looked into it a bit and this implementation
could also be interesting to look at, but we will get to those kinds of
aspects a bit later. With this, we're going to get to our actual findings and
talk about those a bit more. And this is where Ali will take over.
Ali: Thanks, Tobi. So. So now we talk about the capabilities which exist in the
bootloader, which allows us to have unconstrained code execution. So basically
this feature is available in the uart. So you need physical access to the device.
But once you have this physical access, you can basically, as Tobias later
describes, we can actually bypass the security ecosystem which developed by
Siemens in their product. So you need uart access as it's documented here, you have
TX, RX and GND in the PLC and the uart actually in previous research was
documented as well. Every address which I am talking about here or mentioned in this
presentation are for bootloader version 4 to 1. As I mentioned earlier, Siemens
actively modified the bootloader. So I think in two years we saw like 2, 3
modifications or different versions of their bootloader coming up. So this
exactly is based on that's half a second waiting for a specific command after a
second hardware configuration happens. It applies to Siemens S7-1200 including
SiPLUS and S7-200 SMART. Actually, somebody from Kaspersky. IS security
mentioned it. We didn't know even about it. We just investigated a S7-1200. But
Siemens later updated that advisory that also applies to other products as well. So
let's talk about this, a special access feature. So as you mentioned, one of the
things the bootloader does is actually initialize the hardware after this
hardware it's basically copy some of the contents of the bootloader itself to a
memory segment called IRAM, basically. And then PLC basically waits half a second for
a specific command. And once it's received, this specific command it
responds with a specific string and it's all happening over the uart. So it's if
you send a magic string, MFGT1, sorry for my broken German, but probably it means
"Mit freundlichen Grüßen", I hope I did it right. And then the PLC responds with
"-CPU" and says that now you are in this special access mode. I am waiting for your
commands. And this address is also I believe 0xedf8 in the bootloader. So here
is a decoding of our clients, which we will release later next year, actually,
which you see that's 2d435055, which is the "-CPU" response from the PLC. So now
we are in it. And also we also added some extra saying about your packet format.
Somebody asked before. So once you send this command, you get lots of
functionalities here in this presentation. We call them handlers and basically they
are something we call primarily handler. It's like 128 entries and there are some
three other separated handlers which are like 0x80 uart configuration and bye. So
in the primary handler release, there are lots of things. So if you go back to the 2
previous slides, I got the firmware version here, 4.2.3. And
basically what is happening is that basically it's this command here, get
bootloader version. We are just requesting the special access feature to tell us
what is a bootloader version. And also you can do lots of low level diagnostic
functionality is happening there. Also some functionalities related to firmware
update happening there which bypasses the usual cryptographic verification of the
firmware and doesn't need that. So let's look at them, because for this work, which
we are talking about, we actually primarily only use two of the handlers. So
we don't use.. we don't look at like or we don't discuss now all others hundred
twenty eight handlers which exist in the PLC. So it works. One of the handlers, the
interesting one for us was handler 0x80 which mentioned here, update function. So
basically what it does is that it lets you allow you to write to a specific part of a
memory IRAM, which previously copied some content of the bootloader. So basically
you send this handler after this handshake, you have to do this MFGT1 and
then -CPU. And then basically you are going to send this handler and then it
basically checks because each handler might have different requirements. Check
number of arguments, for example, and then you are in this update function mode. And
then you have to provide target ID because there is 4 subfunctionality available.
Once you enter this mode and some of them are like for IRAM, for SPI or IOC or for
Flash, and then for each of them, you have to choose what kind of operation you want
to do you want to configure, read, write or check. And so you can do all of these
things so you can read and write to the IRAM. Basically, this is a function
handler at 0x80. Next is a primary handler like 0x1c. This is listed in this handler
list, here. So, so basically it allows you to call functions. So the basically this
functions are listed in the IRAM. And basically what you do is that you send
this handshake, you are and you are in this. Basically, this is what 0x1c handler
and then you can call the ID number of the handlers which you want to use. So here
you have like lots of handler available for 0x1c. So the question is, what we can
do with it. And before I asked Tobias I want to ask anybody here, any idea? Trace,
somebody said trace. I don't know what that means, but
*mumbling in the audience*
OK. You mean with JTAG? with the CoreSight? No, we are not going to use
that. So let's ask Tobias what he can do.
Tobias: Yeah. So looking at it dynamically and seeing what it does with the memory
is, I guess, a good idea in general. If you if like static reverse engineering
doesn't give you anything. In this case, we looked through different or I looked
through different of those functions and tried to see, what can I do with it? So
the base of where I started looking for this special access feature was basically
that I saw there is too much in this code going on. I kind of feel like I understood
what it should be doing. The bootloader what it should be doing, but it seemed
just to be too much. And the way we can combine those two functions is basically
to recap. Use this 0x1c handler, which gives us control over what kind of
secondary list functions to be called, which, as we saw before, is copied during
the the boot up process to a position in IRAM from external read-only memory. And
this exposes this function handler table to anything that can write to IRAM. And as
we learned before, the 0x80 handler is able to in a limited capacity, do just
that. And here we can see what we can try to do with this. So we use in a first
stage the 0x80 handler to write to IRAM. We can actually inject another function
pointer together with some configuration values that allows us to pass different
checks about argument sizes and stuff like this. We can inject this as an entry into
this table and we can also write to this table a payload which we can use as a
shell code. And then in a second stage we can use this previously injected index
that we specified just as a trigger to call our own payload. So now we have code
execution in the context of the bootloader. So which is as privileged as
we can get at that point and we can see what we can play around with this. And as
a little summary is that we chain all this together and we get code execution. And
with Ali's words, with this technology, we're going to rocket the PLC. And before
we go into what this actually allows us to do is a little word about the stager
payload. So I wrote this this chain of different invocations and it turns out
that this write to IRAM is somehow very slow in the first place, but then also
error prone so the device can just error out and I'm not quite sure what this
pertains to, but what may be interesting to know from the Siemens engineer, but it
basically led to me having to inject a little encoded payload, which just has a
subset of bytes which gives us an interface to do to perform
reads and writes with an arbitrary write primitive and then use this to
inject second stage payloads. And this is what we want to demonstrate here.
Ali: Thanks. So now we would have our demo 4 demos, actually. So the first one is
actually just seeing a communication, basically sending these requests and
getting a response and basically sending this data payload. So the up is the raw
UART communication. Don't worry, it's getting zoomed later and the down is like
our client, which actually talking with the PLC and sending us comments. So we are
just running our UART. And here is we are sending our command. And if you look at it
up, you see the -CPU signal came from the PLC. And now we are sending our stager
and our stager just sends us just one acknowledgement so we know that the stager
runs successfully. This is for firmware version bootloader version 4.2.1,
basically. So now we are going to do something else we are going to actually
dump the firmware from a running PLC and compare it with the firmware downloaded
from Siemens' website. So for us, we are going to actually unpack the firmware
downloaded from Siemens website because it's a compressed with lzp3. So
that's what we are going to do. Oh, we are actually setting up our SSL connection
first. So SSL port forwarding, ssh port forwarding before and we are just checking
that the PLC is running properly. So like this is not a broken PLC or something like
that. We wrote something. So we just make sure that the web server is opening the
open the server, it's open, it's good. And I also try to log in to the website, to
the Web server of the PLC. Just again, make sure that the PLC is functional. So
also enter the password. I guess everybody can guess it. And then so you see that we
log in eventually and in the left side you see all the like functionalities which
loads related to the PLC. So it's a working, running, functional PLC. And so
now you're going to decompress the firmware downloaded from Siemens' website
after checking for export license and stuff. So they want to make sure that
people from Iran and North Korea don't get it. I'm from Iran, by the way. So here we
have the unpacked firmware. But because the frame rate is very large, as Tobias
mentioned earlier, what we are going to do is that we are just going to export
256 kilobytes of the firmware from some part of the web server and into IDA. So
you have to set the big endianess for the cpu. And also rebase the framwork. So as
you can see, here is no function yet, but once we rebase it we have all the function
as well and yeah, so then we gotta just go and export 256 kilo bytes from the
firmware so we specifically slow down the UART because we want to make sure that we
don't do it's too fast to overflow the buffer which we have internally in the
PLC. So. So here, for example, in this address, 691e28 we are going to export 256
kilobytes. This is from the firmware, Siemens firmware. Right. So we just
export it. So, yeah, so it's now called fw-0x691E28 in the folder out. So now we
are done with this part. We are going to dump the same address in the PLC. So from
a running PLC, I have to mention again. So this is the top part is basically raw uart
and this is basically our client part and we are dumping it with a cold boot style
attack. So we are basically resetting the PLC. And before it's over, write the RAM,
we are basically dumping the contents of the RAM. So this is the address, 0x691e28.
This is about the same address, basically. And we are dumping 256 kilobytes. And here
we send MFGT1 basically. And then got the /cpu and then the rest of the stager
and stuff goes. So now basically we are sending packets and then eventually get a
recive. So basically got all the payload like dumped in mem_dump_00691e28
basically. So this is from the RAM of the PLC. This is not anymore from Siemens'
websites. We are just scped to our own machine and then compare it. So now we
have the memdump and original firmware 256 kilobytes each. And then we are going
to compare them with each other. And as you can see, should look here like you
have like hundred percent match. Meaning that it's exactly the same firmware,
which is available on Siemens website. We dumped it directly from the Siemens PLC
memory using this as special access feature. So let's do another one. So this
time we all want to show that unconstrained code execution in just a
very basic way. So we are actually just writing a custom payload to the PLC and
get a hello or greetings from the PLC. So basically, basically we just asked the PLC
to send us this message all the time. So again, so we are sending our custom
payload here and say hello loop. And basically the PLC just sending this loop
for us. So all of these things, again, are for bootloader 4.2.1. You have to readjust
certain things because Siemens saying they updated again their bootloader in the
recent 2019 December, which we bought new PLC, again, once again. And now here we
get a response. That's the PLC is sending basically to us this our raw data, which
is PLC is keep sending to us. That's showing that we are receiving this. But
maybe this was too basic. These are the raw data which we are getting from the
PLC. Let's actually do it a little more complex. Show something that is not from
us. So let's play a game called tic tac toe inside the PLC. And I guess if you
don't know, this is how tic tac toe is like this is I am playing and I just draw
with the google. So. Now we are again are going to send our custom payload. But this
time we are just use partial quotes from somebody else from the Internet and just
upload, compile it and then upload it to the PLC. Obviously, you have to readjust
lots of things. But so we are sending our payload, including a stager and these are
the raw data. Again, these are our client. And eventually you will see a tic tac toe
interface, which you have to enter. So Player 1 is actually playing with the X
and player 2 is playing with like 0. So you see of any positioning, which you
choose. You have X, X and hopefully a player one wins. Yes. So that was it. So
that was a demo. *applause*
Obviously, there are lots of other ideas which we can work on, on injecting other
custom code, using the special access functionality, we are still working on
this. Like lots of other things on Siemens, we are sorry Siemens we are just
working on this, but there are more to come. But in the meantime, there are some
ideas for other people in case they are looking into this and one to investigate
security of Siemens PLCs. So using this as special access entry, you can do somewhat
certain things. So, for example, you can use this prophylaxis functionality to
write to the firmware. As we mentioned, this functionality is available and it
doesn't require those cryptographic signature which normally during update
process of the firmware available. So you can just bypass it and it's just CRC
checksum. So what you can do is that, for example, adding entry to organize like
initialization routine, which is available. And then also you can do it
before organized initialization routine, which we call internal th_initial
Another one which we can do,
if you remember, Tobias talked about some undocumented and
lots of creativity on creating music. li li li lo lo lo
So what one person can do is
like basically adding specific handler or overwriting existing handler. And what it
makes actually is like something like triton. I don't know if anybody know her,
but triton is malware which were attacking petrochemical plant
in Saudi Arabia. So they were trying
to do it in the TCP. But attacker here can maybe do it in http
example and just listen and waiting for comments and also other alternatives like
patching one of the jump tables in the AWP handlers, which can be also used for
process a specific attack. So what else is out there? So what we looked is we looked
We looked at
at attack surface in the Siemens S7 PLCs. There are like for from prospective on
local privilege attacks. What we can... what we looked was bootloader. We are
still working on hardware attacks and some hardware software attacks on the edge. Is
this still ongoing work, which we don't obviously discuss now? Also interesting
thing, I think if somebody who is interested in security of PLCs and
especially internals, I'm not talking about like just general segregation of
network and stuff like that in ICS, I'm talking about more advanced low level
stuff. We think like MWSL is interesting target. There probably are some like bugs
in their implementations. Also, with respect to file system parsing and
firmware signing, there are probably some stuff and also MC7 parser basically,
which they have from privilege escalation perspective and also from remote code
execution perspective, both MiniWeb webserver and also any network
access of accessible services which they have might be interesting. You're actually
also looking at this part right now. So as a conclusion. PLCs are becoming more
complex. That's true, because they are actually providing more and more features
and because of this more complexity, there will be more bugs. We can see, for
example, in the MWSL, which we are looking at now, also bend or strike to basically
more make it more complex. They have basically some anti debugging which we
just discussed in Siemens PLCs, but also they have, for example, frame rate
integrity verification so that the sign frame where like upload to the PLC and
stuff like that. So they are making it more complex. But what you have to know is
that if in their like thread model which like lots of people make or this security
ecosystem which they built. If they have a feature which undermines the same security
ecosystem which they designed. I mean, I think it's obvious that they have to
remove like in the case of bootloader case in their special access features. One of
the good examples. So. And of course, customers also have to know, because if
they have such functionality and they need it, as long as customers know, it's fine.
But when they don't, they can't risk calculate this risk in their strategy or
in this threat model, which they have. So. And also they have to think or rethink
about security by obscurity. Maybe they allow us, for example, as researchers to
access the devices better and easier
to investigate it more. We are still doing
it, but it's just taking longer. And I believe that there are lots of seeing more
to be done on like PLCs and Siemens will not be the last one which we are working
on. So we have to thank some people Thorsten Holz our supervisor, he's not
here. Thomas, Alexandre, Marina, Lucian, Nikita and Robin. For their help and
their work. And now we are going to answer questions.
Herald: Thank you.
*applause*
Herald: So, yeah, feel free to line up for the microphones or write your questions in
the Elisa room. Ah, there you go. It's on right now I think.
Signal Angel: Hello. Yeah. So there is one question from the Internet. Did you check
the MC7 parser? If yes. Did you find any hidden unknown machine instruction
on it or something? Ail: Do you want to answer? So just is it
recorded or I have to repeat it again? So they ask that if we check the MC7
parser. OK. So it's fine. So we didn't like truly investigate the MC7 parser,
but we are working on it right now.
Mic: Hello? How were you able to find the
MFG security password? Ali: That's a very long story. First of
all, like we had we had it in front of us for a long, long time until Siemens
introduced this anti debugging feature. And after that, like we had to find other
ways, other means to find it, to find a similar function, like similar ways that
allow us because one thing which we didn't discuss here is that we didn't tell you
about how we, for example, executed that instruction before in the PLC. It was
involved some works which we received help from some researchers in Netherlands and
in France. So this is this was something informed by Siemens in 2013. I think they
knew about it. But until 2016, they patched it and then it became out like
basically they tried to protect their PLCs from these kind of attack. It was never
published before. So we were using it. And we don't want to talk about it, because
the original author didn't want to talk about it. But we replicated what they
were, what they were doing. And then once we really had to look for other ways, like
then it opened our eyes that there are some other functionalities as well. There
are so such as, for example, the bootloader. But before we before we need
it, like we never actually looked at these things. So it was like in front of us for
like two years. Tobias: Maybe one interesting piece of
background story on this is that we actually in the previous technique that we
used, we actually overrode the conditional jump that would lead to this special
access feature being executed with an unconditional jump. So we basically cut
out 60 percent of the whole code of the firmware image by accident. And then I
just because of the hunch that I was talking about before that there is just
too much functionality. I revisited it and actually realized that it was exactly the
spot that we overrode before and we had to basically replace it and use it for our
own sake.
Mic: Is there any boot time security other
than the CRC check? So you. Are you able to modify the contents of the SPI flash
and get arbitrary code execution that way as well?
Ali: So it depends in which year you are talking about 2017, 2016. So we are
talking about the same models of the PLC, but in 2017 and 2018. No. So you could
basically just take out SPI flash overwrite it. And that was fine. But if
you were overwriting and it caused a halt in the CPU core, it would again trigger
that anti debugging technology, which they have. This watchdog basically but from
like frameware integrity verification. Well basically once you write to.. the
firmware is written to the NAND flash, but it's just the CRC checksum. But during the
update process? No. There are some cryptographic checks, but once it's
written, no. There are some problems which there which again, it's a still ongoing
work and we don't want to discuss about it, but nice catch.
Mic: Thank you. Mic: Hi. Thanks for the talk. Could you
elaborate on your communication with the vendor and the timeline?
Ali: Yes. So, first of all, we know about this problem for like one year and half
before we reported to the vendor. And the primary reason was that we were using it
for some other project. This is actually this result is actually from a side
project rather than the main project, because the main project is still
something else and is still ongoing. But from a side of that projects, we had that
access. And because we were worried that reporting to the vendor, they can fix it
with software update and then do not allow all other CVEs which we find from this
other project, we didn't want to eventually at 2019. Thomas Weber wanted to
talk about his talk on like basically this JTAG interface with four CoreSight and
then we decided to actually talk about it as well. But other than that, we actually
talked in June I think with Siemens and they confirmed that there is this hardware
base, a special access feature. And they are.. they say that they are going to
remove it and that was it. We also send them a write up for them to read.
Herald: So there is one last question from the signal angel over there.
Signal Angel: So there's another question from the Internet. If tools like flashrom
doesn't have support for unknown SPI flashrom chip, then how do you usually
extract firmware if you don't want to decap a chip or use SOIC8 socket.
Ali: Can you repeat it again? I didn't get the question, did you?
Signal Angel: If tools like flashrom does not have support for unknown SPI flashrom
chip, then how do you usually extract firmware if you don't want to decap chip
and use SOIC8 socket. Ali: So first of all, we never actually
decap the SPI flash. So that's just did it for the CPU. And just because we want we
know that Siemens relabled their PLC, so it's not their own CPU, it's from
Renesas, but that's why we did the decapping. So story of decapoing setting
aside. But from other things all basically there are still this functionality, this
bootloader functionality, which actually lets you read the content of the memory.
So that's one thing you can read. Obviously you don't even need that thanks
to one of my students. We now know one that's actually you don't even need to
take out the bootloader, chip. We basically can just connect directly in the
board and dump the firmware. Marcello, that's his name. He's here, actually. But
anyway, so you can just directly read it. And yeah, I don't think the reading part,
especially some part of it, is protected, especially in the recent versions, which
you can't read everything. But besides that, I don't think there is any harder
now yet. I am sure that they are working on that and we are working also on
something to bypass that. So. Herald: Okay. That was our next talk is
gonna be about delivery robots. Sasha in 20 minutes. So let's give you a hand.
*applause*
*36c3 postrol music*
Subtitles created by c3subtitles.de in the year 2021. Join, and help us!