
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.
| É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 |
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>