mirror of
https://github.com/rapid7/metasploit-framework
synced 2024-10-29 18:07:27 +01:00
Better handling of the unix domain socket argument
This commit is contained in:
parent
4df4e8b9d6
commit
f17a7e8a61
@ -180,7 +180,7 @@ class ClientCore < Extension
|
||||
# Migrates the meterpreter instance to the process specified
|
||||
# by pid. The connection to the server remains established.
|
||||
#
|
||||
def migrate( pid )
|
||||
def migrate(pid, socket_path="/tmp/meterpreter.sock")
|
||||
keepalive = client.send_keepalives
|
||||
client.send_keepalives = false
|
||||
process = nil
|
||||
@ -204,8 +204,9 @@ class ClientCore < Extension
|
||||
raise RuntimeError, "Cannot migrate into non existent process", caller
|
||||
end
|
||||
|
||||
# We cant migrate into a process that we are unable to open
|
||||
if process['arch'].nil? or process['arch'].empty?
|
||||
# We can't migrate into a process that we are unable to open
|
||||
# On linux, arch is empty even if we can access the process
|
||||
if client.platform =~ /win/ && (process['arch'] == nil || process['arch'].empty?)
|
||||
raise RuntimeError, "Cannot migrate into this process (insufficient privileges)", caller
|
||||
end
|
||||
|
||||
@ -214,7 +215,21 @@ class ClientCore < Extension
|
||||
raise RuntimeError, "Cannot migrate into current process", caller
|
||||
end
|
||||
|
||||
blob = generate_payload_stub(client, process)
|
||||
if client.platform =~ /linux/
|
||||
if socket_path.blank?
|
||||
socket_path = "/tmp/meterpreter.sock"
|
||||
end
|
||||
|
||||
socket_dir = ::File.dirname(socket_path)
|
||||
stat_dir = client.fs.filestat.new(socket_dir)
|
||||
|
||||
unless stat_dir.directory?
|
||||
raise RuntimeError, "Directory #{socket_dir} not found", caller
|
||||
end
|
||||
# Rex::Post::FileStat#writable? isn't available
|
||||
end
|
||||
|
||||
blob = generate_payload_stub(client, process, socket_path)
|
||||
|
||||
# Build the migration request
|
||||
request = Packet.create_request( 'core_migrate' )
|
||||
@ -231,7 +246,7 @@ class ClientCore < Extension
|
||||
ep = elf_ep(blob)
|
||||
request.add_tlv(TLV_TYPE_MIGRATE_BASE_ADDR, 0x20040000)
|
||||
request.add_tlv(TLV_TYPE_MIGRATE_ENTRY_POINT, ep)
|
||||
request.add_tlv(TLV_TYPE_MIGRATE_SOCKET_PATH, "/tmp/meterpreter.secret", false, client.capabilities[:zlib])
|
||||
request.add_tlv(TLV_TYPE_MIGRATE_SOCKET_PATH, socket_path, false, client.capabilities[:zlib])
|
||||
end
|
||||
|
||||
# Send the migration request (bump up the timeout to 60 seconds)
|
||||
@ -329,12 +344,12 @@ class ClientCore < Extension
|
||||
|
||||
private
|
||||
|
||||
def generate_payload_stub(client, process)
|
||||
def generate_payload_stub(client, process, socket_path)
|
||||
case client.platform
|
||||
when /win/i
|
||||
blob = generate_windows_stub(client, process)
|
||||
when /linux/i
|
||||
blob = generate_linux_stub("/tmp/meterpreter.secret")
|
||||
blob = generate_linux_stub(socket_path)
|
||||
else
|
||||
raise RuntimeError, "Unsupported platform '#{client.platform}'"
|
||||
end
|
||||
@ -391,12 +406,16 @@ class ClientCore < Extension
|
||||
end
|
||||
|
||||
def generate_linux_stub(socket_path)
|
||||
pos = nil
|
||||
file = ::File.join(Msf::Config.data_directory, "meterpreter", "msflinker_linux_x86.bin")
|
||||
blob = ::File.open(file, "rb") {|f|
|
||||
f.read(f.stat.size)
|
||||
}
|
||||
|
||||
pos = blob.index("/tmp/meterpreter.sock")
|
||||
unless socket_path.blank?
|
||||
pos = blob.index("/tmp/meterpreter.sock")
|
||||
end
|
||||
|
||||
unless pos.nil?
|
||||
blob[pos, socket_path.length + 1] = socket_path + "\x00"
|
||||
end
|
||||
|
@ -69,7 +69,7 @@ class Console::CommandDispatcher::Core
|
||||
# whatever reason it is not adding core_migrate to its list of commands.
|
||||
# Use a dumb platform til it gets sorted.
|
||||
#if client.commands.include? "core_migrate"
|
||||
if client.platform =~ /win/
|
||||
if client.platform =~ /win/ || client.platform =~ /linux/
|
||||
c["migrate"] = "Migrate the server to another process"
|
||||
end
|
||||
|
||||
@ -321,7 +321,11 @@ class Console::CommandDispatcher::Core
|
||||
end
|
||||
|
||||
def cmd_migrate_help
|
||||
print_line "Usage: migrate <pid>"
|
||||
if client.platform =~ /linux/
|
||||
print_line "Usage: migrate <pid> [af_unix_socket_path]"
|
||||
else
|
||||
print_line "Usage: migrate <pid>"
|
||||
end
|
||||
print_line
|
||||
print_line "Migrates the server instance to another process."
|
||||
print_line "NOTE: Any open channels or other dynamic state will be lost."
|
||||
@ -331,7 +335,8 @@ class Console::CommandDispatcher::Core
|
||||
#
|
||||
# Migrates the server to the supplied process identifier.
|
||||
#
|
||||
# @param args [Array<String>] Commandline arguments, only -h or a pid
|
||||
# @param args [Array<String>] Commandline arguments, -h or a pid. On linux
|
||||
# platforms a path for the unix domain socket used for IPC.
|
||||
# @return [void]
|
||||
def cmd_migrate(*args)
|
||||
if ( args.length == 0 or args.include?("-h") )
|
||||
@ -344,6 +349,7 @@ class Console::CommandDispatcher::Core
|
||||
print_error("A process ID must be specified, not a process name")
|
||||
return
|
||||
end
|
||||
socket_path = (args.length >= 2) ? args[1] : "/tmp/meterpreter.sock"
|
||||
|
||||
begin
|
||||
server = client.sys.process.open
|
||||
@ -385,7 +391,7 @@ class Console::CommandDispatcher::Core
|
||||
server ? print_status("Migrating from #{server.pid} to #{pid}...") : print_status("Migrating to #{pid}")
|
||||
|
||||
# Do this thang.
|
||||
client.core.migrate(pid)
|
||||
client.core.migrate(pid, socket_path)
|
||||
|
||||
print_status("Migration completed successfully.")
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user