
De la RCE de MCPJam Inspector à root — CVE-2026-23744, divulgation de jeton JupyterLab, exécution du noyau et élévation de privilèges OPSMCP
Ce dépôt est destiné uniquement à la recherche en sécurité autorisée, aux tests d'intrusion et à des fins éducatives. N'utilisez pas les techniques décrites ici contre des systèmes sans autorisation explicite.
De la RCE de MCPJam Inspector au root — CVE-2026-23744, divulgation de jeton JupyterLab, exécution du kernel et élévation de privilèges OPSMCP.
Ce dépôt documente une chaîne d'attaque Linux complète, d'une instance MCPJam Inspector exposée à un accès niveau root.
La chaîne enchaîne des faiblesses à travers l'outillage des développeurs, les services locaux, la gestion des identifiants et l'autorisation applicative :
MCPJam Inspector
│ CVE-2026-23744
▼
RCE
│
▼
JupyterLab Token
│
▼
Jupyter Kernel
│
▼
User
│
▼
OPSMCP API
│
▼
Hidden Admin Tool
│
▼
Root Credential
│
▼
root
[!WARNING] Ce dépôt est destiné uniquement à la recherche en sécurité autorisée, aux tests d'intrusion et à des fins éducatives. Les adresses cibles, identifiants, jetons et autres valeurs spécifiques à l'environnement tout au long de ce document sont expurgés ou remplacés par des espaces réservés de laboratoire.
La reconnaissance initiale se concentre sur l'identification des services exposés à l'extérieur.
nmap -sC -sV -oN nmap_initial.txt TARGET
Un scan TCP complet peut ensuite être effectué :
nmap -p- --min-rate 5000 -oN nmap_full.txt TARGET
Services externes pertinents :
| Port | Service | Rôle |
|---|---|---|
| 22 | SSH | Administration à distance |
| 6274 | MCPJam Inspector | Surface d'attaque initiale |
Services liés uniquement à localhost :
| Port | Service | Privilège |
|---|---|---|
| 8888 | JupyterLab | Utilisateur |
| 5000 | OPSMCP | root |
L'instance MCPJam Inspector accessible depuis l'extérieur sur le port 6274 devient le point d'entrée initial.
L'instance MCPJam Inspector exposée est affectée par CVE-2026-23744.
MCPJam Inspector est principalement conçu comme une interface de développement et de test pour les serveurs MCP. La vulnérabilité devient particulièrement dangereuse lorsque cette interface est exposée à un réseau non fiable — un flux de configuration vulnérable permet à des données contrôlées par l'attaquant d'atteindre un chemin d'exécution de commandes.
Remote Request
│
▼
MCP Server Configuration
│
▼
Command Execution
│
▼
Initial Shell
La vulnérabilité affecte les versions de MCPJam Inspector jusqu'à la 1.4.2 incluse. Pour des tests autorisés, une preuve de concept publique peut être utilisée pour valider la vulnérabilité contre l'environnement cible.
Après une exploitation réussie, confirmez le contexte d'exécution :
id
whoami
hostname
Une fois le premier point d'appui obtenu, les services locaux deviennent 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 différence de privilèges entre les deux applications internes est particulièrement intéressante.
Le processus JupyterLab a été démarré avec son jeton d'authentification directement sur la ligne de commande :
--ServerApp.token=<JUPYTER_TOKEN>
La ligne de commande peut être inspectée via :
ps aux | grep jupyter
# or
cat /proc/<PID>/cmdline
Ceci illustre un problème courant de gestion des secrets :
Secret → Command-line argument → Process metadata → Local credential disclosure
Le jeton récupéré fournit un accès à l'API Jupyter locale.
Jupyter expose une API REST pour gérer les kernels. Après s'être authentifié avec le jeton récupéré, un kernel peut être créé via :
POST /api/kernels
La réponse contient un UUID de kernel. Les kernels Jupyter communiquent via des WebSockets :
/api/kernels/<KERNEL_ID>/channels
Le protocole de messagerie Jupyter utilise un message execute_request pour exécuter du code Python :
{
"header": { "msg_type": "execute_request" },
"content": { "code": "<AUTHORIZED_LAB_CODE>" }
}
Cela établit une exécution Python sous l'identité du service Jupyter — dans cet environnement, le kernel s'exécute en tant qu'utilisateur.
MCPJam RCE → JupyterLab → User
Avec un shell utilisateur disponible, l'étape suivante consiste à examiner les applications installées localement. L'application OPSMCP se trouve sous :
/opt/opsmcp/
L'examen du code source révèle un identifiant API intégré :
VALID_API_KEY = "<REDACTED_OPSMCP_API_KEY>"
L'application gère également deux collections d'outils :
Outils visibles
ops.system_statusops.list_servicesops.check_diskops.view_logsOutils cachés
ops._admin_dumpops._debug_modeLes fonctions administratives sont particulièrement intéressantes car elles ne sont pas renvoyées par l'énumération normale des outils.
Non documenté ne signifie pas inaccessible.
Le backend enregistre toujours les outils cachés et accepte leurs noms via le mécanisme générique d'exécution d'outils.
L'application authentifie les requêtes à l'aide d'une clé API :
X-API-Key: <OPSMCP_API_KEY>
Une fois authentifié, le point de terminaison d'exécution d'outils vérifie uniquement si la fonction demandée existe — pas si l'appelant est autorisé à l'exécuter.
Ce qui se passe :
API Key → Authenticated → Tool exists? → Execute
Ce qui devrait se passer :
API Key → Authenticated → Permission check → Allowed → Execute
└ Denied → 403
La fonction administrative cachée peut accéder à des ressources sensibles appartenant à root.
L'outil administratif accepte une cible décrivant les informations demandées. Une ressource prise en charge est la clé SSH de root :
{
"name": "ops._admin_dump",
"arguments": {
"target": "ssh_keys",
"confirm": true
}
}
L'application lit ensuite la clé privée SSH appartenant à root, ce qui est possible car OPSMCP s'exécute en tant que root et peut lire /root/*. L'application devient donc une primitive de divulgation d'identifiants.
Après avoir récupéré l'identifiant SSH du laboratoire autorisé, stockez-le avec des permissions restrictives :
chmod 600 <ROOT_KEY>
Vérifiez le contexte d'authentification résultant :
whoami
id
Niveau de privilège 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
| Système |
|---|
01 — L'outillage des développeurs est une surface d'attaque Les outils conçus pour le développement local peuvent devenir des vulnérabilités critiques lorsqu'ils sont exposés à des réseaux non fiables.
02 — Les jetons Jupyter sont des identifiants puissants L'accès à un jeton Jupyter peut fournir bien plus qu'un accès à l'interface utilisateur — les API de kernels peuvent fournir une exécution de code arbitraire.
03 — Caché ne signifie pas sécurisé Un point de terminaison non documenté n'est pas un mécanisme d'autorisation.
04 — Le code source est précieux en post-exploitation Le code source d'une application peut révéler immédiatement des mécanismes d'authentification, des secrets, des fonctionnalités cachées et des limites de privilèges.
05 — Le moindre privilège peut casser les chaînes d'attaque Si OPSMCP s'était exécuté sous un compte de service non privilégié, l'impact final aurait été considérablement réduit.
Ce dépôt est destiné uniquement à la recherche en sécurité autorisée, aux tests d'intrusion et à des fins éducatives. N'utilisez pas les techniques décrites ici contre des systèmes sans autorisation explicite.
⚡ MCPJam → RCE → Jupyter → User → OPSMCP → root ⚡
| Étape | Phase |
|---|
| 1 | MCPJam Inspector exposé sur le réseau |
| 2 | CVE-2026-23744 exploitée |
| 3 | RCE initiale obtenue |
| 4 | Jeton JupyterLab divulgué |
| 5 | Exécution du kernel Jupyter |
| 6 | Shell au niveau utilisateur |
| 7 | Revue du code source d'OPSMCP |
| 8 | Identifiant API codé en dur découvert |
| 9 | Fonctionnalité administrative cachée abusée |
| 10 | Identifiant root divulgué |
| 11 | root |
| # | Faiblesse | Impact |
|---|
| 1 | MCPJam Inspector exposé | Surface d'attaque à distance |
| 2 | CVE-2026-23744 | RCE initiale |
| 3 | Jeton dans les arguments de processus | Divulgation d'identifiants |
| 4 | Accès au kernel Jupyter | Exécution de code au niveau utilisateur |
| 5 | Code source de l'application lisible | Découverte d'identifiants |
| 6 | Clé API OPSMCP codée en dur | Contournement de l'authentification API |
| 7 | Fonctionnalité admin cachée | Opération privilégiée |
| 8 | OPSMCP s'exécutant en tant que root | Compromission totale du système |
| À surveiller |
|---|
| MCPJam | Changements de configuration inattendus · processus enfants suspects · clients distants inhabituels |
| JupyterLab | Utilisation inattendue du jeton · création inattendue de kernels · connexions WebSocket anormales · processus shell lancés par les kernels |
| OPSMCP | Invocation d'outils non documentés · requêtes liées aux identifiants · clients API inattendus · opérations administratives |
| SSH | Connexions root inattendues · nouvelles clés SSH · sources d'authentification inhabituelles |