1
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:
jvazquez-r7 2014-07-31 12:35:32 -05:00 committed by Brent Cook
parent 4df4e8b9d6
commit f17a7e8a61
2 changed files with 37 additions and 12 deletions

View File

@ -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

View File

@ -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.")