← volver
CVE-2025-32433criticalbajo ataqueCWE-306

Erlang/OTP SSH Vulnerable to Pre-Authentication RCE

100Vexday Risk Score

Corrige ahora. Ella está bajo explotación confirmada por CISA y tiene exploit funcional público.

ssvc Actcvss 10epss 99%
de la publicación al arma2 días
Publicada en NVD16 abr
1ª PoC+2d
metasploit16 abr
CISA KEV+54d
probabilidad de explotación
99%top 1% de las CVE
explotación observada
CISA + VulnCheck
75 exploit(s) público(s)
Acción exigida por CISAplazo federal: 2025-06-30

Apply mitigations per vendor instructions, follow applicable BOD 22-01 guidance for cloud services, or discontinue use of the product if mitigations are unavailable.

Resumen

Falha de CWE-306 (ausência de verificação de autenticação) no servidor SSH da biblioteca `ssh` do Erlang/OTP: a máquina de estados aceitava mensagens do protocolo de conexão SSH (channel open, channel request) antes de a etapa de autenticação terminar. Um atacante sem credenciais podia abrir um canal e enviar um `channel_request` do tipo "exec" pré-autenticação, que o servidor processava como se a sessão já estivesse autenticada — resultando em execução de código arbitrário na VM Erlang. Afeta qualquer aplicação que rode `ssh:daemon` (papel de servidor) da própria biblioteca `ssh` do OTP, o que inclui produtos embarcados e appliances (Cisco, NetApp, etc.) que usam essa stack para gerenciamento remoto.

Detalle técnico

A implementação da RFC 4252 exige que mensagens SSH com número >= 80 (mensagens do protocolo de conexão, RFC 4254, como SSH_MSG_CHANNEL_OPEN e SSH_MSG_CHANNEL_REQUEST) só sejam aceitas depois que a autenticação (SSH_MSG_USERAUTH_SUCCESS) for concluída. No módulo `ssh_connection.erl`, a função `handle_msg/4` despachava essas mensagens para o tratamento normal de canal independentemente do estado `#ssh{authenticated}`. Não havia nenhuma cláusula que verificasse `authenticated == false` antes de processar o payload — a checagem simplesmente não existia no fluxo de mensagens do lado servidor.

O patch (visível nos três commits de backport para os ramos 25/26/27) adiciona uma cláusula de guarda: quando o processo está no papel `server` e `Ssh#ssh.authenticated =:= false`, qualquer mensagem que não seja `ssh_msg_disconnect` gera um log de depuração e força a desconexão com `SSH_DISCONNECT_PROTOCOL_ERROR`. Ou seja, a correção não é um novo parser ou sanitização de input — é a adição da verificação de estado que faltava.

O vetor de exploração demonstrado no próprio caso de teste (`early_rce`) manda um `channel_open` seguido de um `channel_request` do tipo "exec" cujo payload é uma string Erlang (`lists:seq(1,10).` no teste, mas qualquer expressão válida na prática, incluindo chamadas como `os:cmd/1`). O manipulador padrão de "exec" da biblioteca avalia essa string como código Erlang via `erl_eval`, então o atacante controla diretamente a expressão executada dentro do processo BEAM do servidor — com os privilégios do processo Erlang, não de um shell do sistema, mas suficiente para chamar funções que executam comandos do SO.

O atacante controla: o payload textual do `channel_request` (a expressão Erlang a ser avaliada) e o timing do ataque (enviar antes de qualquer troca de autenticação). Não precisa de usuário, senha, chave pública nem de nenhuma configuração incomum do servidor SSH — o bug está na máquina de estados do protocolo, não em uma feature opcional.

Cómo se explota

Pré-requisito real é único e simples: acesso de rede TCP até uma porta onde um processo Erlang/OTP esteja rodando `ssh:daemon` (papel servidor). Não é necessário conhecer usuário ou senha, nem burlar autenticação por chave — o atacante nunca chega a enviar `SSH_MSG_USERAUTH_REQUEST`. Basta completar o handshake de transporte (hello, kexinit, key exchange) e, assim que o canal de criptografia está ativo, enviar `SSH_MSG_CHANNEL_OPEN` seguido de `SSH_MSG_CHANNEL_REQUEST` tipo "exec" com a expressão desejada como payload.

A complexidade é baixa (AC:L no CVSS): não há necessidade de manipular parâmetros de kex, nem contornar proteções adicionais — a única condição é que o servidor use o manipulador padrão de "exec" da lib (a mesma que avalia expressões Erlang), que é o comportamento de fábrica quando a aplicação não substitui o callback de shell/exec. Isso está confirmado por PoC pública (script Python que monta manualmente os pacotes SSH necessários) e por módulo Metasploit já disponível, o que reduz a barreira de exploração a praticamente zero. A CISA já confirma exploração ativa em produção (entrada no catálogo KEV).

O resultado final é execução de código dentro do runtime Erlang do servidor, com potencial de leitura/gravação de arquivos, pivotamento na rede e comprometimento total do host dependendo dos privilégios do processo BEAM — o CVSS 10.0 reflete justamente essa combinação de vetor de rede, sem autenticação, sem interação do usuário e impacto total de confidencialidade/integridade/disponibilidade.

Versiones

Afectadas
Erlang/OTP com aplicação `ssh` >= 3.0.1, para OTP >= 17.0 (o advisory do fornecedor afirma que versões anteriores a OTP 17.0 também são provavelmente afetadas, mas não há comparação de versão bem definida para esse período pelo esquema de versionamento antigo). Afeta apenas o papel de servidor SSH (`ssh:daemon`); o papel de cliente não é impactado segundo o advisory.
Corregidas en
OTP-27.3.3 (aplicação ssh 5.2.10), OTP-26.2.5.11 (aplicação ssh 5.1.4.8), OTP-25.3.2.20 (aplicação ssh 4.15.3.12).

Cómo protegerse

A correção definitiva é atualizar para OTP-27.3.3, OTP-26.2.5.11 ou OTP-25.3.2.20 (aplicação `ssh` nas versões 5.2.10, 5.1.4.8 ou 4.15.3.12, respectivamente) — qualquer versão igual ou superior à correspondente ao seu ramo já contém a checagem de estado de autenticação que faltava. O advisory do fornecedor also afirma que versões anteriores a OTP 17.0 provavelmente também são afetadas, mas não há comparação de versão bem definida para esse período (esquema de versionamento anterior).

Se a atualização não é viável imediatamente, o único paliativo real recomendado pelo fornecedor é desligar o servidor SSH da aplicação Erlang/OTP (não usar `ssh:daemon`) ou bloquear acesso à porta via firewall/controle de rede, restringindo a origem a hosts confiáveis. Isso não é um WAF ou regra de assinatura — a falha está no processamento de protocolo antes da autenticação, então qualquer conexão TCP alcançando a porta é suficiente para o ataque; segmentação de rede é o controle compensatório efetivo.

O que não funciona: trocar chaves de host, desabilitar métodos de autenticação específicos (senha vs chave pública) ou reforçar políticas de autenticação não mitiga nada, porque o ataque nunca chega à fase de autenticação — ele explora justamente a ausência da checagem antes dela. Restringir os tipos de canal/exec permitidos na configuração do daemon também não é confirmado como mitigação eficaz, já que o bug está na aceitação da mensagem antes da fase de auth, não no conteúdo do payload em si.

Cómo detectar

O tráfego SSH é criptografado após a troca de chaves, então não é possível inspecionar o conteúdo do `channel_request` "exec" via captura de pacotes de rede sem decriptação — a assinatura de exploração não é visível em NIDS tradicional além de metadados de timing (canal aberto e requisição de exec logo após o key exchange, sem troca de `SSH_MSG_USERAUTH_*` completa). Em ambientes já corrigidos (pós-patch), o próprio código de defesa gera um log de depuração com a mensagem "Connection terminated. Unexpected message for unauthenticated user" via `?LOG_DEBUG`, seguido de desconexão com código de erro de protocolo — presença recorrente desse log é forte indício de tentativas de exploração contra uma instância já atualizada.

Em instâncias não corrigidas não há sinal de aplicação equivalente, porque o servidor simplesmente processa o comando como legítimo; o único rastro provável é comportamental — processos ou comandos inesperados originados do processo BEAM/erlang, conexões SSH cuja sessão nunca completou autenticação nos logs de auditoria do sistema, ou uso do PoC/módulo Metasploit público (que segue o padrão hello → kexinit → channel_open → channel_request exec) capturável em honeypots ou telemetria de fluxo caso a decriptação esteja disponível.

Investigado y redactado con IA a partir del advisory del fabricante y análisis públicos, con las fuentes citadas. Verifica siempre la versión corregida en el advisory oficial antes de actuar.
Erlang/OTP is a set of libraries for the Erlang programming language. Prior to versions OTP-27.3.3, OTP-26.2.5.11, and OTP-25.3.2.20, a SSH server may allow an attacker to perform unauthenticated remote code execution (RCE). By exploiting a flaw in SSH protocol message handling, a malicious actor could gain unauthorized access to affected systems and execute arbitrary commands without valid credentials. This issue is patched in versions OTP-27.3.3, OTP-26.2.5.11, and OTP-25.3.2.20. A temporary workaround involves disabling the SSH server or to prevent access via firewall rules.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
Productos afectados
erlang · otp
PoCs públicas encontradas75
githubgithub.com/ProDefense/CVE-2025-32433142githubgithub.com/omer-efe-curkus/CVE-2025-32433-Erlang-OTP-SSH-RCE-PoC16githubgithub.com/NiteeshPujari/CVE-2025-32433-PoC7githubgithub.com/0xPThree/cve-2025-324336githubgithub.com/ekomsSavior/POC_CVE-2025-324335githubgithub.com/m0usem0use/erl_mouse5githubgithub.com/0x7556/CVE-2025-324333githubgithub.com/exa-offsec/ssh_erlangotp_rce3githubgithub.com/dollarboysushil/CVE-2025-32433-Erlang-OTP-SSH-Unauthenticated-RCE3githubgithub.com/darses/CVE-2025-324333githubgithub.com/LemieOne/CVE-2025-324333githubgithub.com/yonathanpy/CVE-2025-32433.py2githubgithub.com/joshuavanderpoll/cve-2025-324332githubgithub.com/AntonieSoga/Erlang-OTP-PoC_CVE-2025-324332githubgithub.com/mirmeweu/cve-2025-324332githubgithub.com/Know56/CVE-2025-324331githubgithub.com/teamtopkarl/CVE-2025-324331githubgithub.com/iteride/CVE-2025-324331githubgithub.com/becrevex/CVE-2025-324331githubgithub.com/bilalz5-github/Erlang-OTP-SSH-CVE-2025-324331githubgithub.com/ODST-Forge/CVE-2025-32433_PoC0githubgithub.com/Epivalent/CVE-2025-32433-detection0githubgithub.com/meloppeitreet/CVE-2025-32433-Remote-Shell0githubgithub.com/ps-interactive/lab_CVE-2025-324330githubgithub.com/MrDreamReal/CVE-2025-324330githubgithub.com/abrewer251/CVE-2025-32433_Erlang-OTP_PoC0githubgithub.com/vigilante-1337/CVE-2025-324330githubgithub.com/te0rwx/CVE-2025-32433-Detection0githubgithub.com/Mdusmandasthaheer/CVE-2025-324330githubgithub.com/l1nuxkid/CVE-2025-32433-exploit0githubgithub.com/soltanali0/CVE-2025-32433-Eploit0githubgithub.com/giriaryan694-a11y/cve-2025-32433_rce_exploit0githubgithub.com/blackcat4347/CVE-2025-32433-available-for-windows0githubgithub.com/carlosalbertotuma/CVE-2025-324330githubgithub.com/0xBlackash/CVE-2025-324330githubgithub.com/leehunkoo/hk_CVE-2025-324330githubgithub.com/chuzouX/CVE-2025-32433-Exploit-edited0githubgithub.com/dampedcoast/Exploiting-a-vulnerability-using-reverse-shell0cve_referencegithub.com/ProDefense/CVE-2025-32433/blob/main/CVE-2025-32433.pyno verificadovulncheckvulncheck.com/xdb/a61e0c6ed8a8no verificadovulncheckvulncheck.com/xdb/874f94accfdeno verificadovulncheckvulncheck.com/xdb/a2f1151c609ano verificadovulncheckvulncheck.com/xdb/ec3bcdccec72no verificadovulncheckvulncheck.com/xdb/42214d962233no verificadovulncheckvulncheck.com/xdb/822dbe209d89no verificadovulncheckvulncheck.com/xdb/22d7bf70f177no verificadovulncheckvulncheck.com/xdb/49e3a7890ab8no verificadovulncheckvulncheck.com/xdb/04468c21f876no verificadovulncheckvulncheck.com/xdb/734f3d7eff96no verificadovulncheckvulncheck.com/xdb/774a5554920fno verificadovulncheckvulncheck.com/xdb/a78d51fa522eno verificadovulncheckvulncheck.com/xdb/839147304502no verificadovulncheckvulncheck.com/xdb/0b33fe6d7d52no verificadovulncheckvulncheck.com/xdb/38c75d4fe3dfno verificadovulncheckvulncheck.com/xdb/6b216fd69575no verificadovulncheckvulncheck.com/xdb/d7301295748ano verificadovulncheckvulncheck.com/xdb/0e9bd89eb6d9no verificadovulncheckvulncheck.com/xdb/86ebf09be56ano verificadovulncheckvulncheck.com/xdb/f113515d8d4eno verificadovulncheckvulncheck.com/xdb/69cf5f0d4eabno verificadovulncheckvulncheck.com/xdb/5d58dcd1c530no verificadovulncheckvulncheck.com/xdb/565faeb39625no verificadovulncheckvulncheck.com/xdb/e71bdbbefa5ano verificadovulncheckvulncheck.com/xdb/eb1588dc5012no verificadovulncheckvulncheck.com/xdb/a9222b177319no verificadovulncheckvulncheck.com/xdb/6902aa2406ccno verificadovulncheckvulncheck.com/xdb/ee86353aa562no verificadovulncheckvulncheck.com/xdb/1dbe3f1ab0b2no verificadovulncheckvulncheck.com/xdb/c117b927dc2bno verificadovulncheckvulncheck.com/xdb/4021c20bae31no verificadovulncheckvulncheck.com/xdb/6362122abe51no verificadovulncheckvulncheck.com/xdb/52fa692c3246no verificadovulncheckvulncheck.com/xdb/938bb25869efno verificadovulncheckvulncheck.com/xdb/cf5a72dc6cf9no verificadovulncheckvulncheck.com/xdb/963c3b33eb36no verificado
⚠ Recursos públicos, para evaluar la exposición de sistemas que controlas o estás autorizado a probar. Prueba solo con autorización.