← voltar
CVE-2025-32433criticalsob ataqueCWE-306

Erlang/OTP SSH Vulnerable to Pre-Authentication RCE

100Vexday Risk Score

Corrija agora. Ela está sob exploração confirmada pelo CISA e tem exploit funcional público.

ssvc Actcvss 10epss 99%
da publicação à arma2 dias
Publicada no NVD16 de abr.
1ª PoC+2d
metasploit16 de abr.
CISA KEV+54d
probabilidade de exploração
99%top 1% das CVEs
exploração observada
simCISA + VulnCheck
76 exploit(s) público(s)
Ação exigida pela CISAprazo 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.

Resumo

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.

Detalhamento 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.

Como é explorada

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.

Versões

Afetadas
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.
Corrigidas em
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).

Como se proteger

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.

Como 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.

Pesquisado e redigido com IA a partir do advisory do fornecedor e de análises públicas, com as fontes acima. Confira sempre a versão corrigida no advisory oficial antes de agir.
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
Produtos afetados
erlang · otp
PoCs públicas encontradas76
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/m0usem0use/erl_mouse5githubgithub.com/ekomsSavior/POC_CVE-2025-324335githubgithub.com/darses/CVE-2025-324333githubgithub.com/dollarboysushil/CVE-2025-32433-Erlang-OTP-SSH-Unauthenticated-RCE3githubgithub.com/exa-offsec/ssh_erlangotp_rce3githubgithub.com/LemieOne/CVE-2025-324333githubgithub.com/0x7556/CVE-2025-324333githubgithub.com/yonathanpy/CVE-2025-32433.py2githubgithub.com/mirmeweu/cve-2025-324332githubgithub.com/AntonieSoga/Erlang-OTP-PoC_CVE-2025-324332githubgithub.com/joshuavanderpoll/cve-2025-324332githubgithub.com/becrevex/CVE-2025-324331githubgithub.com/Know56/CVE-2025-324331githubgithub.com/iteride/CVE-2025-324331githubgithub.com/bilalz5-github/Erlang-OTP-SSH-CVE-2025-324331githubgithub.com/teamtopkarl/CVE-2025-324331githubgithub.com/blackcat4347/CVE-2025-32433-available-for-windows0githubgithub.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/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-shell0githubgithub.com/ODST-Forge/CVE-2025-32433_PoC0cve_referencegithub.com/ProDefense/CVE-2025-32433/blob/main/CVE-2025-32433.pynão verificadovulncheckvulncheck.com/xdb/a61e0c6ed8a8não verificadovulncheckvulncheck.com/xdb/874f94accfdenão verificadovulncheckvulncheck.com/xdb/a2f1151c609anão verificadovulncheckvulncheck.com/xdb/ec3bcdccec72não verificadovulncheckvulncheck.com/xdb/42214d962233não verificadovulncheckvulncheck.com/xdb/822dbe209d89não verificadovulncheckvulncheck.com/xdb/22d7bf70f177não verificadovulncheckvulncheck.com/xdb/49e3a7890ab8não verificadovulncheckvulncheck.com/xdb/04468c21f876não verificadovulncheckvulncheck.com/xdb/734f3d7eff96não verificadovulncheckvulncheck.com/xdb/774a5554920fnão verificadovulncheckvulncheck.com/xdb/a78d51fa522enão verificadovulncheckvulncheck.com/xdb/839147304502não verificadovulncheckvulncheck.com/xdb/0b33fe6d7d52não verificadovulncheckvulncheck.com/xdb/38c75d4fe3dfnão verificadovulncheckvulncheck.com/xdb/6b216fd69575não verificadovulncheckvulncheck.com/xdb/d7301295748anão verificadovulncheckvulncheck.com/xdb/0e9bd89eb6d9não verificadovulncheckvulncheck.com/xdb/86ebf09be56anão verificadovulncheckvulncheck.com/xdb/f113515d8d4enão verificadovulncheckvulncheck.com/xdb/69cf5f0d4eabnão verificadovulncheckvulncheck.com/xdb/5d58dcd1c530não verificadovulncheckvulncheck.com/xdb/565faeb39625não verificadovulncheckvulncheck.com/xdb/e71bdbbefa5anão verificadovulncheckvulncheck.com/xdb/eb1588dc5012não verificadovulncheckvulncheck.com/xdb/a9222b177319não verificadovulncheckvulncheck.com/xdb/6902aa2406ccnão verificadovulncheckvulncheck.com/xdb/ee86353aa562não verificadovulncheckvulncheck.com/xdb/1dbe3f1ab0b2não verificadovulncheckvulncheck.com/xdb/c117b927dc2bnão verificadovulncheckvulncheck.com/xdb/4021c20bae31não verificadovulncheckvulncheck.com/xdb/6362122abe51não verificadovulncheckvulncheck.com/xdb/52fa692c3246não verificadovulncheckvulncheck.com/xdb/938bb25869efnão verificadovulncheckvulncheck.com/xdb/cf5a72dc6cf9não verificadovulncheckvulncheck.com/xdb/963c3b33eb36não verificadovulncheckvulncheck.com/xdb/aac0bdafa042não verificado
⚠ Recursos públicos, para você avaliar a exposição de sistemas que controla ou está autorizado a testar. Teste apenas com autorização.