Skip to main content

Solution du CTF Fetch the Flag 2022 : Logster

Écrit par
feature ctf logster

10 novembre 2022

0 minutes de lecture

Merci d’avoir participé à Fetch avec nous ! Félicitations aux milliers de joueurs qui nous ont rejoints pour le CTF Fetch the Flag. Et un immense merci aux Snykers qui ont créé, testé et documenté les défis !

Si vous avez participé à Fetch the Flag 2022 de Snyk et cherchez la solution du défi Logster, vous êtes au bon endroit. Découvrons ensemble la solution !

Commençons par la phase de reconnaissance

Lors de cette phase, un attaquant repère une cible vulnérable et cherche comment l’exploiter. Dans notre cas, nous avons un lien vers un site web. Un seul point d’entrée suffit pour commencer.

Outil de recherche Logster pour un shell Jnioromous, avec un lien vers logster.cctf-snyk.io

Nous commençons par vérifier le lien et accéder à http://logster.c.ctf-snyk.io/. Ce site permet d’analyser un site web.

Interface du scanner de sites web avec un champ d’adresse, les boutons « Plus » et « Analyser », et un panneau « En-têtes bruts » sans données

Essayons avec https://www.cnn.com/. Les en-têtes s’affichent :

Scanner de site web affichant https://www.cnn.com/ dans le champ URL et un journal brut des en-têtes avec un statut HTTP 200

À partir de là, la description du défi (lookup) et le langage de programmation utilisé (Java) nous permettent de deviner qu’il s’agit de Log4Shell.

Passons au tunneling !

Créons maintenant un serveur web Express pour définir des en-têtes personnalisés, établissons un tunnel ngrok pour exécuter le serveur en local et l’exposer au monde extérieur. Nous allons ensuite l’analyser et voir ce qui se passe !

Si vous ne savez pas comment configurer un serveur Express, la documentation officielle vous aidera.

Éditeur de code en mode sombre affichant un serveur Express.js avec une route racine qui renvoie « Hello World! » et écoute sur le port 3000.

Nous créons notre serveur Express pour qu’il écoute sur le port 3000 et définissons un en-tête personnalisé avec ('PWN', 'pwn').

Exécutons-le avec la commande node express.js :

Terminal affichant une application exemple Node.js Express Fetch-The-Flag à l’écoute sur le port 3000

Créons également le tunnel ngrok avec la commande ngrok http 3000. Consultez la documentation officielle de ngrok pour le configurer sur votre machine.

Terminal affichant une session ngrok en ligne qui redirige une URL HTTPS publique vers localhost:3000, avec des statistiques de connexion et une URL d’inspection.

Copiez le lien de redirection, collez-le sur le site web et lancez l’analyse. Dans la console ngrok (http://localhost:4040/), nous pouvons voir que l’en-tête reprend la valeur définie dans le fichier express.js

Console d’inspection ngrok affichant une liste de requêtes GET avec des réponses 200 OK et des en-têtes HTTP détaillés

Essayons de définir un en-tête contenant un payload de type Log4Shell. Dans notre fichier express.js, remplaçons l’en-tête par ('${java:version}', 'pwn') :

Éditeur de code sombre affichant une application Express.js avec une route racine qui renvoie « Hello World! » et écoute sur le port 3000

Redémarrez le serveur et relancez l’analyse du site web. Nous obtenons une erreur interne du serveur 500 et, si nous consultons les journaux, nous voyons que le nom de l’en-tête doit être un jeton HTTP valide.

Moniteur de requêtes serveur affichant une requête GET sélectionnée, avec une erreur 500 « Erreur interne du serveur » et un message indiquant un jeton HTTP invalide

Express n’autorise pas les en-têtes non valides : $ et {} ne sont pas des caractères autorisés. Nous devons donc contourner cette restriction. Pour cela, nous pouvons créer un serveur socket qui renvoie une réponse personnalisée à chaque connexion.

Voici à quoi ressemble le serveur socket. Il écoute sur le socket et, à chaque connexion, renvoie la réponse, qui inclut ici la version de Java. Nous allons essayer d’injecter cet en-tête personnalisé et voir s’il est évalué.

Code JavaScript dans index.js créant un serveur réseau qui renvoie une réponse HTTP 200 et écoute sur le port 3000

Démarrons le serveur avec la commande node index.js et remplaçons le tunnel ngrok par un tunnel TCP avec la commande ngrok tcp 3000. Vous devez créer un compte ngrok pour utiliser la fonctionnalité de tunnel TCP.

Terminal affichant une session ngrok en ligne qui redirige le trafic TCP de 0.tcp.eu.ngrok.io:14584 vers localhost:3000.

Copions le lien Forwarding sans la partie TCP et collons-le sur le site web. Ajoutez https:// au début et lancez l’analyse du lien. Nous voyons que l’en-tête personnalisé a été évalué. Une recherche a été effectuée et nous avons obtenu la version de Java. Nous savons que lookup fonctionne.

Interface d’analyse de site web affichant un champ URL, les boutons « Plus » et « Analyser », ainsi que les résultats bruts des en-têtes, dont le statut 200.

Nous devons maintenant configurer un exploit Log4Shell.

Qu’est-ce que Log4Shell ?

CVE-2021-44228, également appelée Log4Shell, est une vulnérabilité d’exécution de code à distance (RCE) sans authentification qui affecte presque toutes les versions 2 d’Apache Log4j. Le 9 décembre 2021, la nouvelle de cette vulnérabilité zero-day s’est propagée dans les communautés de la sécurité informatique, accompagnée d’une preuve de concept (POC) accessible au public.

Pour en savoir plus sur la vulnérabilité Log4Shell, consultez notre leçon gratuite sur Snyk Learn .

La POC

Nous utiliserons cette POC accessible au public pour les prochaines étapes. Ce dépôt contient tout ce dont nous avons besoin pour mener l’attaque.

Clonez le projet avec Git et accédez à la classe Evil.java. Nous devons la modifier pour créer le payload destiné à ce défi. Nous voulons afficher la liste de tous les fichiers du répertoire racine. Nous allons créer un objet File, récupérer la liste des fichiers et afficher tous leurs noms.

Éditeur de code sombre affichant Evil.java, une ObjectFactory Java qui répertorie les fichiers du répertoire racine et renvoie « You have been pwned! »

Créons notre image Docker avec la commande suivante :

docker build -t log4shell-vulnerable-server-exploit .

Démarrons le serveur TCP ngrok avec la commande :

ngrok tcp 9999
Terminal ngrok affichant une session en ligne transférant tcp://7.tcp.eu.ngrok.io:18771 vers localhost:9999

Et le serveur HTTP ngrok avec la commande : ngrok http 8888

Terminal ngrok affichant une session en ligne qui redirige une URL HTTPS publique vers http://localhost:8888

Nous devons exécuter le conteneur Docker à distance avec la commande suivante :

Commande de terminal exécutant un conteneur Docker avec des mappages de ports, l’hôte d’un serveur HTTP et le nom d’un test de vulnérabilité Log4Shell

Mais d’abord, le serveur LDAP doit pointer vers le bon lien Forwarding. Copiez et collez le lien du serveur HTTP qui écoute sur le port 8888.

Nous devons également inclure l’adresse du serveur TCP qui écoute sur le port 9999 dans le fichier socket index.js. Nous envoyons ici un en-tête contenant un véritable payload Log4Shell. Nous servons la classe Evil que nous avons modifiée précédemment.

Code JavaScript affichant une réponse du serveur qui intègre une adresse TCP ngrok et le texte « Evil », suivi de « hello ».

Redémarrons le serveur socket avec la commande : node index.js

Exécutons à nouveau cette commande :

Capture d’écran du terminal montrant une commande Docker qui exécute un serveur vulnérable à Log4Shell, avec les ports 8888 et 9999 exposés.

Vous devriez voir le même résultat dans votre terminal :

Terminal affichant une commande Docker qui lance l’exploitation d’un serveur vulnérable, avec des serveurs LDAP et HTTP à l’écoute sur les ports 9999 et 8888.

En retournant sur le site web, vous devriez voir la liste des fichiers du répertoire racine. Et voilà, le flag est là !

Capture d’écran intitulée « En-têtes bruts » montrant une sortie de débogage listant les répertoires et les fichiers du serveur, notamment package.json et node_modules.

Nous devons modifier le payload une dernière fois pour révéler le flag. Retournons à la classe Evil. Cet extrait de code nous permettra de lire le flag et d’afficher le contenu du fichier.

Éditeur de code sombre affichant Evil.java, une ObjectFactory Java qui lit /flag et renvoie « you have been pwned! »

Nous devons relancer le conteneur Docker pour que les modifications soient prises en compte. En relançant l’analyse, nous voyons le contenu du fichier contenant le flag !

Capture d’écran des en-têtes bruts affichant des journaux de débogage et une chaîne de jeton SNYK mise en évidence.

Récapitulatif de Logster

La simplicité de cet exploit et l’omniprésence de cette bibliothèque ont poussé les professionnels de la sécurité à réagir dans l’urgence depuis la divulgation de la faille. Le premier conseil pour atténuer les risques liés à Log4Shell était de passer à la version 2.16. Malheureusement, un exploit de déni de service a ensuite été découvert dans cette version. Il est désormais recommandé de passer à la version 2.17.

Pour découvrir en détail les recommandations de correction, consultez notre fiche pratique sur la correction de Log4Shell. Elle est mise à jour en continu, au fur et à mesure que de nouvelles informations sont disponibles.

J’espère que Logster et les autres défis du CTF vous ont plu :) Vous voulez savoir comment nous avons trouvé tous les autres flags ? Consultez notre page Solutions de Fetch the Flag pour découvrir comment nous avons procédé.

Lire la suite

Blog

Les modèles de pointe ont trouvé les vulnérabilités. Seul l’attaquant a trouvé les chaînes d’exploitation.

L’analyse statique a détecté les failles, mais seuls des tests d’attaque en conditions réelles ont prouvé comment elles pouvaient être enchaînées pour provoquer des compromissions. Comparaison d’Evo COS, de Claude Security et de Claude Code Security.

feature insights context
Blog

Les attaques autonomes sont déjà là. La défense doit suivre leur rythme.

Les attaquants autonomes réduisent la fenêtre de défense. Découvrez comment la découverte, la correction, la validation et la prévention continues peuvent aider les équipes de sécurité à suivre le rythme.

Blog

Pourquoi les agents de codage IA créent-ils sans cesse des failles de contrôle d’accès ?

Les agents de codage IA peuvent générer une logique d’autorisation qui compile et passe la revue, tout en exposant les données d’un tenant à un autre. Découvrez pourquoi les failles de contrôle d’accès sont difficiles à détecter et comment les prévenir.