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!