
De RCE en MCPJam Inspector a root — CVE-2026-23744, divulgación de tokens de JupyterLab, ejecución del kernel y escalada de privilegios de OPSMCP
Este repositorio está destinado únicamente a investigación de seguridad autorizada, pruebas de penetración y fines educativos. No utilice las técnicas aquí descritas contra sistemas sin autorización explícita.
De MCPJam Inspector RCE a root — CVE-2026-23744, divulgación del token de JupyterLab, ejecución de kernel y escalada de privilegios de OPSMCP.
Este repositorio documenta una cadena de ataque completa en Linux, desde una instancia expuesta de MCPJam Inspector hasta el acceso de nivel root.
La cadena encadena debilidades en herramientas de desarrollo, servicios locales, gestión de credenciales y autorización de aplicaciones:
MCPJam Inspector
│ CVE-2026-23744
▼
RCE
│
▼
JupyterLab Token
│
▼
Jupyter Kernel
│
▼
User
│
▼
OPSMCP API
│
▼
Hidden Admin Tool
│
▼
Root Credential
│
▼
root
[!WARNING] Este repositorio está destinado únicamente a investigación de seguridad autorizada, pruebas de penetración y fines educativos. Las direcciones de destino, credenciales, tokens y otros valores específicos del entorno a lo largo de este documento están redactados o reemplazados con marcadores de laboratorio.
El reconocimiento inicial se centra en identificar servicios expuestos externamente.
nmap -sC -sV -oN nmap_initial.txt TARGET
A continuación se puede realizar un escaneo TCP completo:
nmap -p- --min-rate 5000 -oN nmap_full.txt TARGET
Servicios externos relevantes:
| Puerto | Servicio | Rol |
|---|---|---|
| 22 | SSH | Administración remota |
| 6274 | MCPJam Inspector | Superficie de ataque inicial |
Servicios vinculados solo a localhost:
| Puerto | Servicio | Privilegio |
|---|---|---|
| 8888 | JupyterLab | Usuario |
| 5000 | OPSMCP | root |
El MCPJam Inspector, accesible externamente en el puerto 6274, se convierte en el punto de entrada inicial.
La instancia expuesta de MCPJam Inspector está afectada por CVE-2026-23744.
MCPJam Inspector está pensado principalmente como una interfaz de desarrollo y prueba para servidores MCP. La vulnerabilidad se vuelve especialmente peligrosa cuando esta interfaz se expone a una red no confiable: un flujo de configuración vulnerable permite que datos controlados por el atacante lleguen a una ruta de ejecución de comandos.
Remote Request
│
▼
MCP Server Configuration
│
▼
Command Execution
│
▼
Initial Shell
La vulnerabilidad afecta a las versiones de MCPJam Inspector hasta la 1.4.2 inclusive. Para pruebas autorizadas, se puede utilizar una prueba de concepto pública para validar la vulnerabilidad contra el entorno objetivo.
Tras una explotación exitosa, confirme el contexto de ejecución:
id
whoami
hostname
Una vez obtenido el punto de apoyo inicial, los servicios locales se vuelven visibles.
ss -tlnp
ps aux | grep -E 'jupyter|python|node'
Network
│
▼
MCPJam Inspector
:6274
│
▼
Initial RCE
│
┌─────────┴─────────┐
▼ ▼
JupyterLab OPSMCP
:8888/local :5000/local
│ │
▼ ▼
User root
La diferencia de privilegios entre las dos aplicaciones internas resulta especialmente interesante.
El proceso de JupyterLab se inició con su token de autenticación directamente en la línea de comandos:
--ServerApp.token=<JUPYTER_TOKEN>
La línea de comandos se puede inspeccionar mediante:
ps aux | grep jupyter
# or
cat /proc/<PID>/cmdline
Esto demuestra un problema común en la gestión de secretos:
Secret → Command-line argument → Process metadata → Local credential disclosure
El token recuperado proporciona acceso a la API local de Jupyter.
Jupyter expone una API REST para gestionar kernels. Tras autenticarse con el token recuperado, se puede crear un kernel mediante:
POST /api/kernels
La respuesta contiene un UUID de kernel. Los kernels de Jupyter se comunican a través de WebSockets:
/api/kernels/<KERNEL_ID>/channels
El protocolo de mensajería de Jupyter utiliza un mensaje execute_request para ejecutar código Python:
{
"header": { "msg_type": "execute_request" },
"content": { "code": "<AUTHORIZED_LAB_CODE>" }
}
Esto establece la ejecución de Python bajo la identidad del servicio de Jupyter; en este entorno, el kernel se ejecuta como Usuario.
MCPJam RCE → JupyterLab → User
Con un shell de usuario disponible, el siguiente paso es examinar las aplicaciones instaladas localmente. La aplicación OPSMCP se encuentra en:
/opt/opsmcp/
La revisión del código fuente revela una credencial de API incrustada:
VALID_API_KEY = "<REDACTED_OPSMCP_API_KEY>"
La aplicación también mantiene dos colecciones de herramientas:
Herramientas visibles
ops.system_statusops.list_servicesops.check_diskops.view_logsHerramientas ocultas
ops._admin_dumpops._debug_modeLas funciones administrativas resultan especialmente interesantes porque no se devuelven a través de la enumeración normal de herramientas.
No documentado no significa inaccesible.
El backend sigue registrando las herramientas ocultas y acepta sus nombres a través del mecanismo genérico de ejecución de herramientas.
La aplicación autentica las solicitudes mediante una clave de API:
X-API-Key: <OPSMCP_API_KEY>
Una vez autenticada, el endpoint de ejecución de herramientas solo comprueba si la función solicitada existe, no si quien la invoca está autorizado para ejecutarla.
Lo que ocurre:
API Key → Authenticated → Tool exists? → Execute
Lo que debería ocurrir:
API Key → Authenticated → Permission check → Allowed → Execute
└ Denied → 403
La función administrativa oculta puede acceder a recursos sensibles propiedad de root.
La herramienta administrativa acepta un objetivo que describe la información solicitada. Uno de los recursos admitidos es la clave SSH de root:
{
"name": "ops._admin_dump",
"arguments": {
"target": "ssh_keys",
"confirm": true
}
}
La aplicación lee entonces la clave privada SSH propiedad de root, lo cual es posible porque OPSMCP se ejecuta como root y puede leer /root/*. Por tanto, la aplicación se convierte en una primitiva de divulgación de credenciales.
Tras recuperar la credencial SSH del laboratorio autorizado, guárdela con permisos restrictivos:
chmod 600 <ROOT_KEY>
Verifique el contexto de autenticación resultante:
whoami
id
Nivel de privilegio final: root 🎉
┌──────────────────────────────┐
│ MCPJam Inspector │
│ TCP/6274 │
└──────────────┬───────────────┘
│ CVE-2026-23744
▼
┌──────────────────────────────┐
│ Initial RCE │
└──────────────┬───────────────┘
▼
┌──────────────────────────────┐
│ JupyterLab │
│ 127.0.0.1:8888 │
└──────────────┬───────────────┘
│ Token disclosure
▼
┌──────────────────────────────┐
│ Jupyter Kernel │
│ WebSocket RCE │
└──────────────┬───────────────┘
▼
User
│ Source review
▼
┌──────────────────────────────┐
│ OPSMCP │
│ 127.0.0.1:5000 │
│ root │
└──────────────┬───────────────┘
│ API key + hidden tool
▼
┌──────────────────────────────┐
│ Root Credential Leak │
└──────────────┬───────────────┘
▼
root
| Sistema |
|---|
01 — Las herramientas de desarrollo son superficie de ataque Las herramientas diseñadas para el desarrollo local pueden convertirse en vulnerabilidades críticas cuando se exponen a redes no confiables.
02 — Los tokens de Jupyter son credenciales potentes El acceso a un token de Jupyter puede proporcionar mucho más que acceso a la interfaz: las API de kernel pueden permitir la ejecución arbitraria de código.
03 — Oculto no significa seguro Un endpoint no documentado no es un mecanismo de autorización.
04 — El código fuente es valioso tras la explotación El código fuente de la aplicación puede revelar mecanismos de autenticación, secretos, funcionalidad oculta y límites de privilegios de inmediato.
05 — El privilegio mínimo puede romper cadenas de ataque Si OPSMCP se hubiera ejecutado como una cuenta de servicio sin privilegios, el impacto final se habría reducido significativamente.
Este repositorio está destinado únicamente a investigación de seguridad autorizada, pruebas de penetración y fines educativos. No utilice las técnicas aquí descritas contra sistemas sin autorización explícita.
⚡ MCPJam → RCE → Jupyter → User → OPSMCP → root ⚡
| Paso | Etapa |
|---|
| 1 | MCPJam Inspector expuesto en la red |
| 2 | CVE-2026-23744 explotado |
| 3 | RCE inicial logrado |
| 4 | Token de JupyterLab divulgado |
| 5 | Ejecución de kernel de Jupyter |
| 6 | Shell de nivel de usuario |
| 7 | Revisión del código fuente de OPSMCP |
| 8 | Credencial de API codificada descubierta |
| 9 | Funcionalidad administrativa oculta abusada |
| 10 | Credencial de root divulgada |
| 11 | root |
| # | Debilidad | Impacto |
|---|
| 1 | MCPJam Inspector expuesto | Superficie de ataque remota |
| 2 | CVE-2026-23744 | RCE inicial |
| 3 | Token en los argumentos del proceso | Divulgación de credenciales |
| 4 | Acceso al kernel de Jupyter | Ejecución de código de nivel usuario |
| 5 | Código fuente legible de la aplicación | Descubrimiento de credenciales |
| 6 | Clave de API de OPSMCP codificada | Bypass de autenticación de la API |
| 7 | Funcionalidad administrativa oculta | Operación privilegiada |
| 8 | OPSMCP ejecutándose como root | Compromiso total del sistema |
| Vigile |
|---|
| MCPJam | Cambios de configuración inesperados · procesos hijos sospechosos · clientes remotos inusuales |
| JupyterLab | Uso inesperado de tokens · creación inesperada de kernels · conexiones WebSocket anómalas · procesos shell generados por kernels |
| OPSMCP | Invocación de herramientas no documentadas · solicitudes relacionadas con credenciales · clientes de API inesperados · operaciones administrativas |
| SSH | Inicios de sesión de root inesperados · nuevas claves SSH · fuentes de autenticación inusuales |