Skip to content

Commit a8e907d

Browse files
author
Tod Beardsley
committed
Land rapid7#4479, nil comparisons and missing DLLs
Also fixes rapid7#4474.
2 parents 48919ea + bdac5db commit a8e907d

File tree

4 files changed

+41
-23
lines changed

4 files changed

+41
-23
lines changed

lib/rex/post/meterpreter/client_core.rb

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -68,33 +68,33 @@ def load_library(opts)
6868
load_flags = LOAD_LIBRARY_FLAG_LOCAL
6969

7070
# No library path, no cookie.
71-
if (library_path == nil)
71+
if library_path.nil?
7272
raise ArgumentError, "No library file path was supplied", caller
7373
end
7474

7575
# Set up the proper loading flags
76-
if (opts['UploadLibrary'])
76+
if opts['UploadLibrary']
7777
load_flags &= ~LOAD_LIBRARY_FLAG_LOCAL
7878
end
79-
if (opts['SaveToDisk'])
79+
if opts['SaveToDisk']
8080
load_flags |= LOAD_LIBRARY_FLAG_ON_DISK
8181
end
82-
if (opts['Extension'])
82+
if opts['Extension']
8383
load_flags |= LOAD_LIBRARY_FLAG_EXTENSION
8484
end
8585

8686
# Create a request packet
8787
request = Packet.create_request('core_loadlib')
8888

8989
# If we must upload the library, do so now
90-
if ((load_flags & LOAD_LIBRARY_FLAG_LOCAL) != LOAD_LIBRARY_FLAG_LOCAL)
90+
if (load_flags & LOAD_LIBRARY_FLAG_LOCAL) != LOAD_LIBRARY_FLAG_LOCAL
9191
image = ''
9292

9393
::File.open(library_path, 'rb') { |f|
9494
image = f.read
9595
}
9696

97-
if (image != nil)
97+
if !image.nil?
9898
request.add_tlv(TLV_TYPE_DATA, image, false, client.capabilities[:zlib])
9999
else
100100
raise RuntimeError, "Failed to serialize library #{library_path}.", caller
@@ -103,7 +103,7 @@ def load_library(opts)
103103
# If it's an extension we're dealing with, rename the library
104104
# path of the local and target so that it gets loaded with a random
105105
# name
106-
if (opts['Extension'])
106+
if opts['Extension']
107107
library_path = "ext" + rand(1000000).to_s + ".#{client.binary_suffix}"
108108
target_path = library_path
109109
end
@@ -113,17 +113,17 @@ def load_library(opts)
113113
request.add_tlv(TLV_TYPE_LIBRARY_PATH, library_path)
114114
request.add_tlv(TLV_TYPE_FLAGS, load_flags)
115115

116-
if (target_path != nil)
116+
if !target_path.nil?
117117
request.add_tlv(TLV_TYPE_TARGET_PATH, target_path)
118118
end
119119

120120
# Transmit the request and wait the default timeout seconds for a response
121121
response = self.client.send_packet_wait_response(request, self.client.response_timeout)
122122

123123
# No response?
124-
if (response == nil)
124+
if response.nil?
125125
raise RuntimeError, "No response was received to the core_loadlib request.", caller
126-
elsif (response.result != 0)
126+
elsif response.result != 0
127127
raise RuntimeError, "The core_loadlib request failed with result: #{response.result}.", caller
128128
end
129129

@@ -147,18 +147,22 @@ def load_library(opts)
147147
# memory on the remote machine
148148
#
149149
def use(mod, opts = { })
150-
if (mod == nil)
150+
if mod.nil?
151151
raise RuntimeError, "No modules were specified", caller
152152
end
153153
# Get us to the installation root and then into data/meterpreter, where
154154
# the file is expected to be
155155
modname = "ext_server_#{mod.downcase}"
156156
path = MeterpreterBinaries.path(modname, client.binary_suffix)
157157

158-
if (opts['ExtensionPath'])
158+
if opts['ExtensionPath']
159159
path = opts['ExtensionPath']
160160
end
161161

162+
if path.nil?
163+
raise RuntimeError, "No module of the name #{modname}.#{client.binary_suffix} found", caller
164+
end
165+
162166
path = ::File.expand_path(path)
163167

164168
# Load the extension DLL
@@ -187,24 +191,24 @@ def migrate( pid )
187191

188192
# Determine the architecture for the pid we are going to migrate into...
189193
client.sys.process.processes.each { | p |
190-
if( p['pid'] == pid )
194+
if p['pid'] == pid
191195
process = p
192196
break
193197
end
194198
}
195199

196200
# We cant migrate into a process that does not exist.
197-
if( process == nil )
201+
if process.nil?
198202
raise RuntimeError, "Cannot migrate into non existent process", caller
199203
end
200204

201205
# We cant migrate into a process that we are unable to open
202-
if( process['arch'] == nil or process['arch'].empty? )
206+
if process['arch'].nil? or process['arch'].empty?
203207
raise RuntimeError, "Cannot migrate into this process (insufficient privileges)", caller
204208
end
205209

206210
# And we also cant migrate into our own current process...
207-
if( process['pid'] == client.sys.process.getpid )
211+
if process['pid'] == client.sys.process.getpid
208212
raise RuntimeError, "Cannot migrate into current process", caller
209213
end
210214

@@ -213,10 +217,10 @@ def migrate( pid )
213217
c.include( ::Msf::Payload::Stager )
214218

215219
# Include the appropriate reflective dll injection module for the target process architecture...
216-
if( process['arch'] == ARCH_X86 )
220+
if process['arch'] == ARCH_X86
217221
c.include( ::Msf::Payload::Windows::ReflectiveDllInject )
218222
binary_suffix = "x86.dll"
219-
elsif( process['arch'] == ARCH_X86_64 )
223+
elsif process['arch'] == ARCH_X86_64
220224
c.include( ::Msf::Payload::Windows::ReflectiveDllInject_x64 )
221225
binary_suffix = "x64.dll"
222226
else
@@ -225,7 +229,12 @@ def migrate( pid )
225229

226230
# Create the migrate stager
227231
migrate_stager = c.new()
228-
migrate_stager.datastore['DLL'] = MeterpreterBinaries.path('metsrv',binary_suffix)
232+
233+
dll = MeterpreterBinaries.path('metsrv',binary_suffix)
234+
if dll.nil?
235+
raise RuntimeError, "metsrv.#{binary_suffix} not found", caller
236+
end
237+
migrate_stager.datastore['DLL'] = dll
229238

230239
blob = migrate_stager.stage_payload
231240

@@ -253,7 +262,7 @@ def migrate( pid )
253262
request.add_tlv( TLV_TYPE_MIGRATE_PID, pid )
254263
request.add_tlv( TLV_TYPE_MIGRATE_LEN, blob.length )
255264
request.add_tlv( TLV_TYPE_MIGRATE_PAYLOAD, blob, false, client.capabilities[:zlib])
256-
if( process['arch'] == ARCH_X86_64 )
265+
if process['arch'] == ARCH_X86_64
257266
request.add_tlv( TLV_TYPE_MIGRATE_ARCH, 2 ) # PROCESS_ARCH_X64
258267
else
259268
request.add_tlv( TLV_TYPE_MIGRATE_ARCH, 1 ) # PROCESS_ARCH_X86
@@ -301,7 +310,7 @@ def migrate( pid )
301310
# Update the meterpreter platform/suffix for loading extensions as we may have changed target architecture
302311
# sf: this is kinda hacky but it works. As ruby doesnt let you un-include a module this is the simplest solution I could think of.
303312
# If the platform specific modules Meterpreter_x64_Win/Meterpreter_x86_Win change significantly we will need a better way to do this.
304-
if( process['arch'] == ARCH_X86_64 )
313+
if process['arch'] == ARCH_X86_64
305314
client.platform = 'x64/win64'
306315
client.binary_suffix = 'x64.dll'
307316
else

lib/rex/post/meterpreter/extensions/priv/priv.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ def getsystem( technique=0 )
4646
elevator_name = Rex::Text.rand_text_alpha_lower( 6 )
4747

4848
elevator_path = MeterpreterBinaries.path('elevator', client.binary_suffix)
49+
if elevator_path.nil?
50+
raise RuntimeError, "elevator.#{binary_suffix} not found", caller
51+
end
4952

5053
elevator_path = ::File.expand_path( elevator_path )
5154

lib/rex/post/meterpreter/extensions/stdapi/ui.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,9 @@ def screenshot( quality=50 )
157157
# include the x64 screenshot dll if the host OS is x64
158158
if( client.sys.config.sysinfo['Architecture'] =~ /^\S*x64\S*/ )
159159
screenshot_path = MeterpreterBinaries.path('screenshot','x64.dll')
160+
if screenshot_path.nil?
161+
raise RuntimeError, "screenshot.x64.dll not found", caller
162+
end
160163
screenshot_path = ::File.expand_path( screenshot_path )
161164
screenshot_dll = ''
162165
::File.open( screenshot_path, 'rb' ) do |f|
@@ -165,8 +168,11 @@ def screenshot( quality=50 )
165168
request.add_tlv( TLV_TYPE_DESKTOP_SCREENSHOT_PE64DLL_BUFFER, screenshot_dll, false, true )
166169
request.add_tlv( TLV_TYPE_DESKTOP_SCREENSHOT_PE64DLL_LENGTH, screenshot_dll.length )
167170
end
168-
# but allways include the x86 screenshot dll as we can use it for wow64 processes if we are on x64
171+
# but always include the x86 screenshot dll as we can use it for wow64 processes if we are on x64
169172
screenshot_path = MeterpreterBinaries.path('screenshot','x86.dll')
173+
if screenshot_path.nil?
174+
raise RuntimeError, "screenshot.x86.dll not found", caller
175+
end
170176
screenshot_path = ::File.expand_path( screenshot_path )
171177
screenshot_dll = ''
172178
::File.open( screenshot_path, 'rb' ) do |f|

spec/lib/rex/post/meterpreter/client_core_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
context 'with a missing a module' do
4444
let(:mod) {"eaten_by_av"}
4545
it 'should be available' do
46-
expect { client_core.use(mod) }.to raise_error(TypeError)
46+
expect { client_core.use(mod) }.to raise_error(RuntimeError)
4747
end
4848
end
4949

0 commit comments

Comments
 (0)