
Reproduction de cve-2025-43564-tomcat_put_rce_reproduction
| Champ | Valeur |
|---|---|
| Identifiant CVE | CVE-2025-43564 |
| Score CVSS | 9.8 (CRITIQUE) |
| Vecteur | AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| CWE | CWE-494 — Téléchargement de code sans vérification d'intégrité |
| Exploitation | Confirmée dans la nature moins d'une semaine après la divulgation |
| Divulgation | Juillet 2025 |
| Correctif | Tomcat 11.0.6, 10.1.40, 9.0.102 |
CVE-2025-43564 est une vulnérabilité critique d'exécution de code à distance non authentifiée dans la gestion des requêtes PUT partielles HTTP d'Apache Tomcat. Le défaut réside dans la manière dont Tomcat traite les requêtes PUT avec un contenu partiel (HTTP/1.1 Content-Range ou Transfer-Encoding: chunked avec une sémantique partielle). Un attaquant peut concevoir une requête PUT partielle qui contourne les contrôles d'accès et les contraintes d'écriture, permettant le téléchargement de fichiers arbitraires — y compris des webshells JSP accessibles via le web — vers la racine web du serveur ou tout répertoire inscriptible accessible via le contexte de servlet.
Une fois qu'un fichier JSP est installé, l'attaquant n'a plus qu'à le requêter et à transmettre des commandes du système d'exploitation via les paramètres de requête, obtenant ainsi une exécution de code à distance entièrement non authentifiée avec les droits de l'utilisateur du processus Tomcat.
CVSS 9.8 — Critique car :
Le DefaultServlet d'Apache Tomcat et le connecteur HTTP/1.1 (NIO/NIO2/Apr) gèrent les requêtes PUT pour le téléchargement de ressources statiques. La vulnérabilité se situe dans la logique de gestion des requêtes PUT partielles : lorsqu'un client envoie un PUT avec un en-tête Content-Range (RFC 7233 §4.2) ou utilise un encodage par blocs avec une sémantique partielle spécifique, le serveur ne valide pas correctement :
Le code d'analyse dans org.apache.catalina.servlets.DefaultServlet et les composants sous-jacents HttpInput / SocketProcessorBase gèrent mal la frontière entre les écritures de contenu partiel et les écritures complètes de ressources, permettant à un attaquant d'ajouter ou d'écraser un contenu arbitraire sur tout chemin auquel le processus Tomcat a accès en écriture.
Attacker ──PUT /exec.jsp HTTP/1.1──► Tomcat (DefaultServlet)
Content-Range: bytes 0-99/100
[JSP payload bytes]
└──► Server writes partial content to exec.jsp
without full validation of the target path
Attacker ──GET /exec.jsp?cmd=whoami──► Tomcat
└──► JSP executes → RCE
L'attaquant envoie un PUT partiel avec un en-tête Content-Range qui amène Tomcat à croire que la requête est la continuation d'un téléchargement existant. Le serveur crée ou ouvre le fichier cible et écrit les octets fournis sans vérifier que le fichier existe déjà, sans vérifier les permissions d'écriture au moment de l'écriture, et sans assainir le chemin cible par rapport à la racine web.
readonly=false sur le DefaultServlet pour qu'un PUT standard fonctionne. Le chemin PUT partiel ignore cette vérification dans certaines conditions.Content-Range échappe souvent à ces signatures.| Produit | Versions concernées | Corrigé dans |
|---|---|---|
| Apache Tomcat 11 | 11.0.0-M1 à 11.0.5 | 11.0.6 |
| Apache Tomcat 10.1 | 10.1.0-M1 à 10.1.39 | 10.1.40 |
| Apache Tomcat 10.0 | toutes les versions (fin de vie) | passer à 10.1.x |
| Apache Tomcat 9 | 9.0.0-M1 à 9.0.101 | 9.0.102 |
| Apache Tomcat 8.5 | toutes les versions (fin de vie) | passer à 9.0.x |
| Apache Tomcat 8 | toutes les versions (fin de vie) | passer à 9.0.x |
| Apache Tomcat 7 | toutes les versions (fin de vie) | passer à 9.0.x |
Remarque : Les branches plus anciennes (7.x, 8.x, 8.5.x, 10.0.x) sont en fin de vie et ne recevront pas de backport. Les utilisateurs doivent passer à une branche prise en charge.
Téléchargez un Apache Tomcat vulnérable (par exemple, Tomcat 9.0.50) :
wget https://archive.apache.org/dist/tomcat/tomcat-9/v9.0.50/bin/apache-tomcat-9.0.50.zip
Extrayez et démarrez Tomcat avec la configuration par défaut :
unzip apache-tomcat-9.0.50.zip
cd apache-tomcat-9.0.50/bin
./startup.sh # or startup.bat on Windows
Vérifiez que le serveur est en cours d'exécution :
curl -v http://localhost:8080
Téléversez le webshell JSP à l'aide du script PoC :
python exploit.py --target http://localhost:8080 --cmd id
Vérifiez que le webshell a bien été installé :
curl http://localhost:8080/exec.jsp?cmd=whoami
Exécutez des commandes arbitraires :
python exploit.py --target http://localhost:8080 --cmd "cat /etc/passwd"
Session interactive (si souhaité) :
python exploit.py --target http://localhost:8080 --shell
L'exploit.py inclus est un PoC Python fonctionnel qui :
Content-Type et la structure de la charge utile déclenchent le chemin de code vulnérablewebapps/ROOT/)exec.jsp?cmd=<command> pour exécuter des commandes du système d'exploitation--cmd) et shell interactif (--shell)