@@ -180,7 +180,7 @@ def use(mod, opts = { })
180
180
# Migrates the meterpreter instance to the process specified
181
181
# by pid. The connection to the server remains established.
182
182
#
183
- def migrate ( pid )
183
+ def migrate ( pid , socket_path = "/tmp/meterpreter.sock" )
184
184
keepalive = client . send_keepalives
185
185
client . send_keepalives = false
186
186
process = nil
@@ -204,8 +204,9 @@ def migrate( pid )
204
204
raise RuntimeError , "Cannot migrate into non existent process" , caller
205
205
end
206
206
207
- # We cant migrate into a process that we are unable to open
208
- if process [ 'arch' ] . nil? or process [ 'arch' ] . empty?
207
+ # We can't migrate into a process that we are unable to open
208
+ # On linux, arch is empty even if we can access the process
209
+ if client . platform =~ /win/ && ( process [ 'arch' ] == nil || process [ 'arch' ] . empty? )
209
210
raise RuntimeError , "Cannot migrate into this process (insufficient privileges)" , caller
210
211
end
211
212
@@ -214,7 +215,21 @@ def migrate( pid )
214
215
raise RuntimeError , "Cannot migrate into current process" , caller
215
216
end
216
217
217
- blob = generate_payload_stub ( client , process )
218
+ if client . platform =~ /linux/
219
+ if socket_path . blank?
220
+ socket_path = "/tmp/meterpreter.sock"
221
+ end
222
+
223
+ socket_dir = ::File . dirname ( socket_path )
224
+ stat_dir = client . fs . filestat . new ( socket_dir )
225
+
226
+ unless stat_dir . directory?
227
+ raise RuntimeError , "Directory #{ socket_dir } not found" , caller
228
+ end
229
+ # Rex::Post::FileStat#writable? isn't available
230
+ end
231
+
232
+ blob = generate_payload_stub ( client , process , socket_path )
218
233
219
234
# Build the migration request
220
235
request = Packet . create_request ( 'core_migrate' )
@@ -231,7 +246,7 @@ def migrate( pid )
231
246
ep = elf_ep ( blob )
232
247
request . add_tlv ( TLV_TYPE_MIGRATE_BASE_ADDR , 0x20040000 )
233
248
request . add_tlv ( TLV_TYPE_MIGRATE_ENTRY_POINT , ep )
234
- request . add_tlv ( TLV_TYPE_MIGRATE_SOCKET_PATH , "/tmp/meterpreter.secret" , false , client . capabilities [ :zlib ] )
249
+ request . add_tlv ( TLV_TYPE_MIGRATE_SOCKET_PATH , socket_path , false , client . capabilities [ :zlib ] )
235
250
end
236
251
237
252
# Send the migration request (bump up the timeout to 60 seconds)
@@ -329,12 +344,12 @@ def shutdown
329
344
330
345
private
331
346
332
- def generate_payload_stub ( client , process )
347
+ def generate_payload_stub ( client , process , socket_path )
333
348
case client . platform
334
349
when /win/i
335
350
blob = generate_windows_stub ( client , process )
336
351
when /linux/i
337
- blob = generate_linux_stub ( "/tmp/meterpreter.secret" )
352
+ blob = generate_linux_stub ( socket_path )
338
353
else
339
354
raise RuntimeError , "Unsupported platform '#{ client . platform } '"
340
355
end
@@ -391,12 +406,16 @@ def generate_windows_stub(client, process)
391
406
end
392
407
393
408
def generate_linux_stub ( socket_path )
409
+ pos = nil
394
410
file = ::File . join ( Msf ::Config . data_directory , "meterpreter" , "msflinker_linux_x86.bin" )
395
411
blob = ::File . open ( file , "rb" ) { |f |
396
412
f . read ( f . stat . size )
397
413
}
398
414
399
- pos = blob . index ( "/tmp/meterpreter.sock" )
415
+ unless socket_path . blank?
416
+ pos = blob . index ( "/tmp/meterpreter.sock" )
417
+ end
418
+
400
419
unless pos . nil?
401
420
blob [ pos , socket_path . length + 1 ] = socket_path + "\x00 "
402
421
end
0 commit comments