TP exploitation d’une CVE de type RCE sur Node.js

On fournit une application de départ en Node.js avec https://expressjs.com/. Le code de départ est disponible dans le fichier app.zip. Cette application se contente d’établir un cookie au contenu statique à la première visite sur la route GET / et le supprime sur la route GET /clear. Ici, l’analyse et l’exploitation se font en boîte blanche, c’est-à-dire avec l’accès au code source.

Une adresse de machine cible de la forme vm-pentest-${ID}.tiwfsa-pentest.os.univ-lyon1.fr est fournie dans https://tomuss.univ-lyon1.fr. L’application est censée être disponible à l’adresse http://vm-pentest-${ID}.tiwfsa-pentest.os.univ-lyon1.fr:8080/.

Prise en main de l’application en local

En local, installer l’application npm install puis la tester avec npm start. Lors de l’installation, noter le warning de sécurité.

  • Se connecter une première fois : noter ce qui s’affiche.
  • Se connecter une seconde fois : noter ce qui s’affiche.
  • Récupérer le cookie et le décoder :
    • soit via les developper tools du navigateur ;
    • soit via la console JS avec document.cookie.
  • Utiliser la route /clear pour vider le cookie.

À ce stade, une CVE de type RCE (Remote Code Execution) 2017 doit être identifiée, on va l’exploiter dans la suite.

Exploitation

Quand on peut exécuter du code à distance, une technique est d’ouvrir un shell pour ensuite avancer dans l’exploitation et par exemple augmenter ses privilèges. On peut opérer dans deux sens différents pour exécuter le code :

  • bind shell : on ouvre un port sur le serveur et on s’y connecte depuis l’hôte de l’attaquant ;
  • reverse shell : on ouvre un port sur l’hôte de l’attaquant (e.g. avec netcat nc -klnvp 4444) et le serveur s’y connecte.

On trouvera de tels scripts sur https://gtfobins.github.io/gtfobins/node/. On recommande de procéder selon les étapes suivantes pour arriver à exploiter la cible :

  1. Vérifier le fonctionnement des scripts de bind shell et reverse shell en local, hors de l’application ;
  2. Trouver une preuve de concept d’exploit sur la CVE ;
  3. Adapter la preuve de concept pour exploiter la RCE sur l’application en local pour ouvrir un shell avec les deux méthodes ;
  4. Avec https://nmap.org/ scanner les ports de votre cible et trouver un port supérieur à 1024 qui n’est pas utilisé et pas filtré par les firewall, voir la documentation ;
  5. Exploiter la RCE avec bind shell et se connecter avec netcat pour vérifier l’accès.

Remarques

  • Pour le reverse shell, penser à ouvrir son serveur et son firewall avant d’exécuter l’exploit.
  • Vérifier en local que le port est bien ouvert, par exemple avec la commande sudo lsof -i -P -n | grep LISTEN.
  • Il faudra peut-être nettoyer le payload pour remplacer les retours chariots ou les guillemets/apostrophes, par exemple avec la méthode String.prototype.replaceAll().
  • Si votre payload n’est pas parfait, on risque de faire planter le service sur votre serveur. Il y a assez peu de droit à l’erreur (mais on pourra relancer la VM si besoin).
  • Une fois que qu’on a accès à la machine, ajouter une clef ssh avec ssh-import-id pour simplifier la suite. Ce programme gère les clefs GitHub et GitLab, par exemple pour ma clef GitHub, utiliser ssh-import-id gh:romulusFR ou similairement pour ma clef GitLab.

Challenge

Sur la machine cible, un utilisateur a été créé avec un mot de passe faible.

  1. Trouver cet utilisateur depuis le shell et son mot de passe haché.
  2. Retrouver le mot de passe avec un outil comme https://www.openwall.com/john/ et un dictionnaire (en anglais). ⚠️ La recherche peut être assez longue selon le dictionnaire.
  3. Vérifier qu’on peut s’authentifier avec cet utilisateur depuis votre shell.
  4. Saisir le mot de passe obtenu dans https://tomuss.univ-lyon1.fr.

Protections

Il y a plusieurs problèmes majeurs dans cette application, les corriger :

  • Le module vulnérable est à remplacer.
  • Les cookies devraient être sécurisés :

De plus, la route GET /clear est vulnérable aux attaques de type CSRF. Montrer un exemple et proposer une correction, l’implémenter si vous avez le temps.

Enfin, il y a un problème majeur sur les droits de l’utilisateur qui exécute l’application, mais ici, c’est volontaire.