
Riproduzione di cve-2025-32433-erlang_ssh_rce_reproduction
Punteggio CVSS: 10.0 (CRITICO)
Stato: sfruttata attivamente in natura
Divulgazione: giugno 2025
CVE-2025-32433 è una vulnerabilità critica di esecuzione remota di codice senza autenticazione nell'implementazione del server SSH (applicazione ssh) distribuita con Erlang/OTP. Il difetto risiede nella logica di gestione della connessione SSH prima del completamento dell'autenticazione, il che significa che non sono richieste credenziali valide per attivare lo sfruttamento. Un attaccante che riesce a raggiungere una porta SSH Erlang vulnerabile (tipicamente la 22, o porte personalizzate utilizzate da RabbitMQ, Riak, CouchDB, ecc.) può eseguire comandi shell arbitrari sul sistema target.
La vulnerabilità è stata scoperta dal ricercatore di sicurezza Felix "xcz" Lange e segnalata tramite il processo di divulgazione della sicurezza di OTP. Un codice PoC pubblico è emerso entro 72 ore dall'avviso, e molteplici attori di minaccia sono stati osservati mentre scansionavano la rete alla ricerca di banner SSH vulnerabili (SSH-2.0-Erlang/OTP-*) subito dopo la divulgazione.
La vulnerabilità è presente nell'implementazione SSH di Erlang, situata nell'applicazione ssh di OTP. Nello specifico, il bug riguarda il modo in cui il demone SSH gestisce i messaggi di avvio dello scambio di chiavi prima della fase di autenticazione.
I moduli ssh_bind.erl e ssh_connection_handler.erl non riescono a convalidare correttamente la transizione della macchina a stati durante l'elaborazione di alcuni messaggi del protocollo SSH fuori sequenza o malformati. Inviando un pacchetto SSH_MSG_KEXINIT manipolato ad arte o un messaggio di richiesta di servizio appositamente costruito durante la fase di scambio di chiavi, un attaccante può indurre la VM Erlang a:
Si tratta fondamentalmente di una vulnerabilità di deserializzazione non sicura di termini Erlang combinata con un bypass della macchina a stati. La funzione binary_to_term/1 di Erlang viene applicata a input controllati dall'attaccante senza la modalità safe abilitata, consentendo l'istanziazione di atomi arbitrari e la chiamata di qualsiasi processo registrato.
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 ────│
Il punto chiave è che il gestore della connessione SSH entra in uno stato imprevisto in cui invoca binary_to_term sui dati in arrivo prima che l'handshake di sicurezza venga completato. Incorporando un termine Erlang malevolo che codifica un payload di esecuzione di comandi (ad esempio, utilizzando erlang:open_port/2 con spawn), l'attaccante ottiene l'esecuzione di codice con i privilegi del processo della VM Erlang.
Un payload tipico utilizza il formato dei termini esterni di Erlang per codificare:
{run, "cmd.exe /c <command>"}
-- or --
{spawn, "<command>"}
Questi termini, una volta decodificati da binary_to_term/1, interagiscono con la macchina a stati della connessione SSH per eseguire comandi di sistema.
| Prodotto | Versioni interessate | Versioni corrette |
|---|---|---|
| Erlang/OTP | < 27.3.2, < 26.2.6, < 25.3.3 | 27.3.2+, 26.2.6+, 25.3.3+ |
| Elixir (tramite Erlang) | Tutte le versioni che eseguono OTP vulnerabile | Ricompilato con OTP corretto |
| RabbitMQ | < 3.12.14, < 3.13.7 (su OTP vulnerabile) | 3.12.14+, 3.13.7+ con OTP corretto |
| Riak KV/TS | < KV 2.9.6, < TS 1.5.5 (su OTP vulnerabile) | Pacchetti aggiornati con OTP corretto |
| CouchDB | < 3.3.3 (quando si utilizza l'SSH di Erlang) | 3.3.3+ oppure disabilitare SSH |
| Ejabberd | < 24.06 (su OTP vulnerabile) | 24.06+ con OTP corretto |
Una cattura del banner è generalmente sufficiente:
# 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
Qualsiasi versione di Erlang/OTP inferiore ai numeri delle versioni corrette sopra indicati è vulnerabile.
paramiko o socket grezzi (il PoC utilizza socket grezzi)# 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)"]
In alternativa, utilizza un servizio vulnerabile già presente sulla tua rete.
Identifica un target vulnerabile tramite cattura del banner:
nc -w 3 <target> 22
# Look for: SSH-2.0-Erlang/OTP-
Esegui l'exploit PoC:
python exploit.py --target 192.168.1.100 --port 22 --command "whoami"
Verifica l'esecuzione:
[+] 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
Il file exploit.py fornito implementa un PoC funzionante che:
L'exploit sfrutta tre componenti chiave:
ssh_bind.erl e ssh_transport.erl