Compare commits
136 Commits
beef-0.4.7
...
v0.5.0.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0b67f4c2e8 | ||
|
|
5a05bd965e | ||
|
|
bc6d7dc934 | ||
|
|
7043212a58 | ||
|
|
3273513e9d | ||
|
|
ae70388da3 | ||
|
|
4db3853535 | ||
|
|
3c809a785d | ||
|
|
9a6b410aaa | ||
|
|
b4013bb74b | ||
|
|
a4139d6e60 | ||
|
|
a397b67148 | ||
|
|
42b5a4fe58 | ||
|
|
b5e5689eca | ||
|
|
dff44bc865 | ||
|
|
6594aa0b03 | ||
|
|
750c41cca8 | ||
|
|
c56ca60241 | ||
|
|
cc08bb56f2 | ||
|
|
f5a4671550 | ||
|
|
52f091fd21 | ||
|
|
6a208245ed | ||
|
|
8ca7e2135c | ||
|
|
173d55714a | ||
|
|
502a52452c | ||
|
|
b89fbd9268 | ||
|
|
7c2a56945c | ||
|
|
97ab3625f5 | ||
|
|
8b244c6f58 | ||
|
|
3950e934a6 | ||
|
|
0f74b6faf2 | ||
|
|
ea9c281804 | ||
|
|
36336e4c5f | ||
|
|
7462dea1e0 | ||
|
|
f83add866e | ||
|
|
3959d2c8bb | ||
|
|
9b5c8e39df | ||
|
|
87b8093504 | ||
|
|
eff7b99393 | ||
|
|
b88774cdbf | ||
|
|
58447e4007 | ||
|
|
fce763e9f3 | ||
|
|
3068fbead5 | ||
|
|
96e4063e2a | ||
|
|
8cbae6a830 | ||
|
|
66bec03158 | ||
|
|
557452b95d | ||
|
|
91332844c8 | ||
|
|
88c488969e | ||
|
|
80bfc21516 | ||
|
|
aac1b0bc10 | ||
|
|
d1d5d1d648 | ||
|
|
c85e3c01b5 | ||
|
|
7841f55166 | ||
|
|
12e5f51721 | ||
|
|
b6d338d334 | ||
|
|
151976176a | ||
|
|
2f71b35f7b | ||
|
|
5bfd1e54df | ||
|
|
0574bdf002 | ||
|
|
91265cad77 | ||
|
|
21d0906c12 | ||
|
|
d588c56391 | ||
|
|
4cecca4075 | ||
|
|
9babcba7c3 | ||
|
|
405241c5d0 | ||
|
|
0cd8878a3f | ||
|
|
06d1ba7754 | ||
|
|
704e675edf | ||
|
|
d6972adfcb | ||
|
|
ba3183ef38 | ||
|
|
0b0e7840fc | ||
|
|
3de78156c2 | ||
|
|
0531cdf745 | ||
|
|
d8f838980f | ||
|
|
731527e259 | ||
|
|
ad3927485c | ||
|
|
a35d0eae5e | ||
|
|
dd336fa8a2 | ||
|
|
ce6d261c05 | ||
|
|
6b34f1ea3a | ||
|
|
c2f9922920 | ||
|
|
fb168f7480 | ||
|
|
a777be1254 | ||
|
|
31aae8fdaf | ||
|
|
060ed96c7f | ||
|
|
43dd97fe72 | ||
|
|
625e4ce386 | ||
|
|
042713f257 | ||
|
|
3df5afc930 | ||
|
|
61f0363859 | ||
|
|
de8eb60370 | ||
|
|
b238595a2c | ||
|
|
a2151e77ad | ||
|
|
dc8d59f000 | ||
|
|
494650923e | ||
|
|
d1cb59a728 | ||
|
|
10cd685007 | ||
|
|
d8885ef51e | ||
|
|
5e18495b33 | ||
|
|
86f4697765 | ||
|
|
c2d82ace7d | ||
|
|
6ca6054c68 | ||
|
|
b0732f21e6 | ||
|
|
1867a69311 | ||
|
|
07cc6f9542 | ||
|
|
7df8888505 | ||
|
|
3ea946ed19 | ||
|
|
a62e502fce | ||
|
|
dab4288501 | ||
|
|
367e91b095 | ||
|
|
a6cce27518 | ||
|
|
b8fe5f1b80 | ||
|
|
64d5638a81 | ||
|
|
5eb3b686f1 | ||
|
|
639d14c682 | ||
|
|
7c5a5b4df4 | ||
|
|
4396547cdd | ||
|
|
c385b1a352 | ||
|
|
a103ca3f30 | ||
|
|
0ed6c3866e | ||
|
|
355cb38593 | ||
|
|
35b3505bf8 | ||
|
|
654cf5427f | ||
|
|
1cc3136421 | ||
|
|
20e61d9e81 | ||
|
|
99b54583cc | ||
|
|
46d82dc8b8 | ||
|
|
d698b6a0ba | ||
|
|
8e7522b1b1 | ||
|
|
6052ec99da | ||
|
|
13c539effe | ||
|
|
39aa3fdeea | ||
|
|
00dca685c1 | ||
|
|
f24a25f6b1 | ||
|
|
2fa56c419f |
2
.github/ISSUE_TEMPLATE.md
vendored
2
.github/ISSUE_TEMPLATE.md
vendored
@@ -3,7 +3,7 @@ Verify first that your issue/request has not been posted previously:
|
||||
* https://github.com/beefproject/beef/issues
|
||||
* https://github.com/beefproject/beef/wiki/FAQ
|
||||
|
||||
Ensure you're using the [latest version of BeEF](https://github.com/beefproject/beef/releases/tag/beef-0.4.7.1).
|
||||
Ensure you're using the [latest version of BeEF](https://github.com/beefproject/beef/releases/tag/beef-0.4.7.2).
|
||||
|
||||
|
||||
#### Environment
|
||||
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -1,16 +1,22 @@
|
||||
### BeEF ###
|
||||
beef.db
|
||||
beef.log
|
||||
test/msf-test
|
||||
extensions/admin_ui/media/javascript-min/
|
||||
custom-config.yaml
|
||||
.DS_Store
|
||||
.gitignore
|
||||
.rvmrc
|
||||
beef.log
|
||||
|
||||
*.lock
|
||||
|
||||
extensions/metasploit/msf-exploits.cache
|
||||
|
||||
# ruby debugging
|
||||
.byebug_history
|
||||
|
||||
|
||||
# The following lines were created by https://www.gitignore.io
|
||||
|
||||
### Linux ###
|
||||
|
||||
4
.rspec
Normal file
4
.rspec
Normal file
@@ -0,0 +1,4 @@
|
||||
--format documentation
|
||||
--color
|
||||
--require spec_helper
|
||||
-I .
|
||||
@@ -1,10 +1,8 @@
|
||||
language: ruby
|
||||
rvm:
|
||||
- 2.4.0
|
||||
- 2.5.0
|
||||
- 2.5.3
|
||||
- 2.6.0
|
||||
env:
|
||||
- "BEEF_TEST=true"
|
||||
notifications:
|
||||
email:
|
||||
recipients:
|
||||
@@ -21,3 +19,4 @@ addons:
|
||||
- zlib1g-dev
|
||||
- liblzma-dev
|
||||
- libcurl4-openssl-dev
|
||||
|
||||
|
||||
37
Gemfile
37
Gemfile
@@ -8,37 +8,23 @@
|
||||
|
||||
gem 'eventmachine'
|
||||
gem 'thin'
|
||||
gem 'sinatra', '~> 2.0'
|
||||
gem 'rack', '~> 2.0'
|
||||
gem 'rack-protection', '~> 2.0'
|
||||
gem 'sinatra'
|
||||
gem 'rack'
|
||||
gem 'rack-protection'
|
||||
gem 'em-websocket' # WebSocket support
|
||||
gem 'uglifier'
|
||||
gem 'mime-types'
|
||||
gem 'execjs'
|
||||
gem 'ansi'
|
||||
gem 'term-ansicolor', :require => 'term/ansicolor'
|
||||
gem 'dm-core'
|
||||
gem 'json'
|
||||
gem 'data_objects'
|
||||
gem 'rubyzip', '>= 1.2.2'
|
||||
gem 'espeak-ruby', '>= 1.0.4' # Text-to-Voice
|
||||
gem 'nokogiri', '>= 1.7'
|
||||
gem 'nokogiri', '>= 1.10.4'
|
||||
gem 'rake'
|
||||
|
||||
# SQLite support
|
||||
group :sqlite do
|
||||
gem 'dm-sqlite-adapter'
|
||||
end
|
||||
|
||||
# PostgreSQL support
|
||||
group :postgres do
|
||||
#gem dm-postgres-adapter
|
||||
end
|
||||
|
||||
# MySQL support
|
||||
group :mysql do
|
||||
#gem dm-mysql-adapter
|
||||
end
|
||||
gem 'otr-activerecord'
|
||||
gem 'sqlite3'
|
||||
|
||||
# Geolocation support
|
||||
group :geoip do
|
||||
@@ -47,7 +33,6 @@ end
|
||||
|
||||
gem 'parseconfig'
|
||||
gem 'erubis'
|
||||
gem 'dm-migrations'
|
||||
|
||||
# Metasploit Integration extension
|
||||
group :ext_msf do
|
||||
@@ -77,7 +62,6 @@ end
|
||||
|
||||
# For running unit tests
|
||||
group :test do
|
||||
if ENV['BEEF_TEST']
|
||||
gem 'test-unit'
|
||||
gem 'test-unit-full'
|
||||
gem 'rspec'
|
||||
@@ -86,16 +70,17 @@ group :test do
|
||||
# sudo apt-get install libcurl4-openssl-dev
|
||||
gem 'curb'
|
||||
# selenium-webdriver 3.x is incompatible with Firefox version 48 and prior
|
||||
gem 'selenium'
|
||||
gem 'selenium-webdriver', '~> 2.53.4'
|
||||
# gem 'selenium' # Requires old version of selenium which is no longer available
|
||||
gem 'geckodriver-helper'
|
||||
gem 'selenium-webdriver'
|
||||
# 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'
|
||||
# RESTful API tests/generic command module tests
|
||||
gem 'rest-client', '>= 2.0.1'
|
||||
gem 'byebug'
|
||||
end
|
||||
gem 'irb'
|
||||
gem 'pry-byebug'
|
||||
end
|
||||
|
||||
source 'https://rubygems.org'
|
||||
|
||||
59
Rakefile
59
Rakefile
@@ -4,62 +4,24 @@
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
require 'yaml'
|
||||
require 'bundler/setup'
|
||||
load 'tasks/otr-activerecord.rake'
|
||||
#require 'pry-byebug'
|
||||
|
||||
task :default => ["quick"]
|
||||
|
||||
desc "Run quick tests"
|
||||
task :quick do
|
||||
Rake::Task['unit'].invoke # run unit tests
|
||||
end
|
||||
|
||||
desc "Run all tests"
|
||||
task :all do
|
||||
Rake::Task['integration'].invoke # run integration tests
|
||||
Rake::Task['unit'].invoke # run unit tests
|
||||
Rake::Task['msf'].invoke # run msf tests
|
||||
end
|
||||
|
||||
desc "Run automated tests (for Jenkins)"
|
||||
task :automated do
|
||||
Rake::Task['xserver_start'].invoke
|
||||
Rake::Task['all'].invoke
|
||||
Rake::Task['xserver_stop'].invoke
|
||||
end
|
||||
|
||||
desc "Run integration unit tests"
|
||||
task :integration => ["install"] do
|
||||
Rake::Task['beef_start'].invoke
|
||||
sh "export DISPLAY=:0; cd test/integration;ruby -W0 ts_integration.rb"
|
||||
Rake::Task['beef_stop'].invoke
|
||||
end
|
||||
|
||||
desc "Run integration unit tests"
|
||||
task :unit => ["install"] do
|
||||
sh "cd test/unit;ruby -W0 ts_unit.rb"
|
||||
end
|
||||
|
||||
desc "Run MSF unit tests"
|
||||
task :msf => ["install", "msf_install"] do
|
||||
Rake::Task['msf_update'].invoke
|
||||
Rake::Task['msf_start'].invoke
|
||||
sh "cd test/thirdparty/msf/unit/;ruby -W0 ts_metasploit.rb"
|
||||
Rake::Task['msf_stop'].invoke
|
||||
end
|
||||
task :default => ["spec"]
|
||||
|
||||
desc 'Generate API documentation to doc/rdocs/index.html'
|
||||
task :rdoc do
|
||||
Rake::Task['rdoc:rerdoc'].invoke
|
||||
end
|
||||
|
||||
desc 'rest test examples'
|
||||
task :rest_test do
|
||||
Rake::Task['beef_start'].invoke
|
||||
## RSPEC
|
||||
require 'rspec/core/rake_task'
|
||||
RSpec::Core::RakeTask.new(:spec)
|
||||
|
||||
|
||||
sh 'cd test/api/; ruby -W2 1333_auth_rate.rb'
|
||||
|
||||
Rake::Task['beef_stop'].invoke
|
||||
end
|
||||
|
||||
################################
|
||||
# SSL/TLS certificate
|
||||
@@ -276,5 +238,10 @@ task :cde_beef_start => 'beef' do
|
||||
puts '.'
|
||||
end
|
||||
|
||||
|
||||
################################
|
||||
# ActiveRecord
|
||||
namespace :db do
|
||||
task :environment do
|
||||
require_relative "beef"
|
||||
end
|
||||
end
|
||||
|
||||
2
VERSION
2
VERSION
@@ -4,4 +4,4 @@
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
0.4.7.1-alpha
|
||||
0.4.7.4-alpha-pre
|
||||
|
||||
171
beef
171
beef
@@ -7,7 +7,7 @@
|
||||
#
|
||||
|
||||
#
|
||||
# @note stop deprecation warning from being displayed
|
||||
# @note stop Fixnum deprecation warning from being displayed
|
||||
#
|
||||
$VERBOSE = nil
|
||||
|
||||
@@ -26,7 +26,7 @@ end
|
||||
#
|
||||
if RUBY_PLATFORM.downcase.include?('mswin') || RUBY_PLATFORM.downcase.include?('mingw')
|
||||
puts
|
||||
puts "Ruby platform #{RUBY_PLATFORM} is no longer supported."
|
||||
puts "Ruby platform #{RUBY_PLATFORM} is not supported."
|
||||
puts
|
||||
exit 1
|
||||
end
|
||||
@@ -39,20 +39,18 @@ $:.unshift($root_dir)
|
||||
$home_dir = File.expand_path("#{Dir.home}/.beef/", __FILE__).freeze
|
||||
|
||||
#
|
||||
# @note Require core loader's
|
||||
# @note Require core loader
|
||||
#
|
||||
require 'core/loader'
|
||||
|
||||
#
|
||||
# @note Check the system language settings for UTF-8 compatibility
|
||||
# @note Create ~/.beef/
|
||||
#
|
||||
env_lang = ENV['LANG']
|
||||
if env_lang !~ /(utf8|utf-8)/i
|
||||
print_warning "Warning: System language $LANG does not appear to be UTF-8 compatible."
|
||||
if env_lang =~ /\A([a-z]+_[a-z]+)\./i
|
||||
country = $1
|
||||
print_more "Try: export LANG=#{country}.utf8"
|
||||
end
|
||||
begin
|
||||
FileUtils.mkdir_p($home_dir) unless File.directory?($home_dir)
|
||||
rescue => e
|
||||
print_error "Could not create '#{$home_dir}': #{e.message}"
|
||||
exit 1
|
||||
end
|
||||
|
||||
#
|
||||
@@ -65,20 +63,20 @@ else
|
||||
end
|
||||
|
||||
#
|
||||
# @note After the BeEF core is loaded, bootstrap the rest of the framework internals
|
||||
# @note set log level
|
||||
#
|
||||
require 'core/bootstrap'
|
||||
BeEF.logger.level = config.get('beef.debug') ? Logger::DEBUG : Logger::WARN
|
||||
|
||||
#
|
||||
# @note Loads enabled extensions
|
||||
# @note Check the system language settings for UTF-8 compatibility
|
||||
#
|
||||
BeEF::Extensions.load
|
||||
|
||||
#
|
||||
# @note Prints the BeEF ascii art if the -a flag was passed
|
||||
#
|
||||
if BeEF::Core::Console::CommandLine.parse[:ascii_art] == true
|
||||
BeEF::Core::Console::Banners.print_ascii_art
|
||||
env_lang = ENV['LANG']
|
||||
if env_lang !~ /(utf8|utf-8)/i
|
||||
print_warning "Warning: System language $LANG '#{env_lang}' does not appear to be UTF-8 compatible."
|
||||
if env_lang =~ /\A([a-z]+_[a-z]+)\./i
|
||||
country = $1
|
||||
print_more "Try: export LANG=#{country}.utf8"
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
@@ -92,11 +90,57 @@ unless BeEF::Core::Console::CommandLine.parse[:ws_port].empty?
|
||||
config.set('beef.http.websocket.port', BeEF::Core::Console::CommandLine.parse[:ws_port])
|
||||
end
|
||||
|
||||
#
|
||||
# @note Validate configuration file
|
||||
#
|
||||
unless BeEF::Core::Configuration.instance.validate
|
||||
exit 1
|
||||
end
|
||||
|
||||
#
|
||||
# @note Exit on default credentials
|
||||
#
|
||||
if config.get("beef.credentials.user").eql?('beef') && config.get("beef.credentials.passwd").eql?('beef')
|
||||
print_error "ERROR: Default username and password in use!"
|
||||
print_more "Change the beef.credentials.passwd in config.yaml"
|
||||
exit 1
|
||||
end
|
||||
|
||||
#
|
||||
# @note Validate beef.http.public and beef.http.public_port
|
||||
#
|
||||
unless config.get('beef.http.public').to_s.eql?('') || BeEF::Filters.is_valid_hostname?(config.get('beef.http.public'))
|
||||
print_error "ERROR: Invalid public hostname: #{config.get('beef.http.public')}"
|
||||
exit 1
|
||||
end
|
||||
|
||||
unless config.get('beef.http.public_port').to_s.eql?('') || BeEF::Filters.is_valid_port?(config.get('beef.http.public_port'))
|
||||
print_error "ERROR: Invalid public port: #{config.get('beef.http.public_port')}"
|
||||
exit 1
|
||||
end
|
||||
|
||||
#
|
||||
# @note After the BeEF core is loaded, bootstrap the rest of the framework internals
|
||||
#
|
||||
require 'core/bootstrap'
|
||||
|
||||
#
|
||||
# @note Prints the BeEF ascii art if the -a flag was passed
|
||||
#
|
||||
if BeEF::Core::Console::CommandLine.parse[:ascii_art] == true
|
||||
BeEF::Core::Console::Banners.print_ascii_art
|
||||
end
|
||||
|
||||
#
|
||||
# @note Prints BeEF welcome message
|
||||
#
|
||||
BeEF::Core::Console::Banners.print_welcome_msg
|
||||
|
||||
#
|
||||
# @note Loads enabled extensions
|
||||
#
|
||||
BeEF::Extensions.load
|
||||
|
||||
#
|
||||
# @note Loads enabled modules
|
||||
#
|
||||
@@ -108,43 +152,25 @@ BeEF::Modules.load
|
||||
Socket.do_not_reverse_lookup = true
|
||||
|
||||
#
|
||||
# @note Database setup - use DataMapper::Logger.new($stdout, :debug) for development debugging
|
||||
# @note Database setup
|
||||
#
|
||||
case config.get("beef.database.driver")
|
||||
when "sqlite"
|
||||
DataMapper.setup(:default, "sqlite3://#{$root_dir}/#{config.get("beef.database.db_file")}")
|
||||
when "mysql", "postgres"
|
||||
DataMapper.setup(:default,
|
||||
:adapter => config.get("beef.database.driver"),
|
||||
:host => config.get("beef.database.db_host"),
|
||||
:port => config.get("beef.database.db_port"),
|
||||
:username => config.get("beef.database.db_user"),
|
||||
:password => config.get("beef.database.db_passwd"),
|
||||
:database => config.get("beef.database.db_name"),
|
||||
:encoding => config.get("beef.database.db_encoding")
|
||||
)
|
||||
else
|
||||
print_error 'No default database selected. Please add one in config.yaml'
|
||||
exit 1
|
||||
end
|
||||
|
||||
#
|
||||
# @note Load the database
|
||||
#
|
||||
begin
|
||||
# @note Resets the database if the -x flag was passed
|
||||
if BeEF::Core::Console::CommandLine.parse[:resetdb]
|
||||
db_file = config.get('beef.database.file')
|
||||
# @note Resets the database if the -x flag was passed
|
||||
if BeEF::Core::Console::CommandLine.parse[:resetdb]
|
||||
print_info 'Resetting the database for BeEF.'
|
||||
DataMapper.auto_migrate!
|
||||
else
|
||||
DataMapper.auto_upgrade!
|
||||
end
|
||||
rescue => e
|
||||
print_error "Could not connect to database: #{e.message}"
|
||||
if config.get("beef.database.driver") == 'sqlite'
|
||||
print_more "Ensure the #{config.get("beef.database.db_file")} database file is writable"
|
||||
end
|
||||
exit 1
|
||||
File.delete(db_file) if File.exists?(db_file)
|
||||
end
|
||||
# Connect to DB
|
||||
ActiveRecord::Base.logger = nil
|
||||
OTR::ActiveRecord.migrations_paths = [File.join('core', 'main', 'ar-migrations')]
|
||||
OTR::ActiveRecord.configure_from_hash!(adapter:'sqlite3', database:db_file)
|
||||
# Migrate (if required)
|
||||
context = ActiveRecord::Migration.new.migration_context
|
||||
if context.needs_migration?
|
||||
ActiveRecord::Migrator.new(:up, context.migrations, context.schema_migration).migrate
|
||||
end
|
||||
|
||||
#
|
||||
@@ -171,45 +197,6 @@ BeEF::Core::Console::Banners.print_loaded_modules
|
||||
BeEF::Core::Console::Banners.print_network_interfaces_count
|
||||
BeEF::Core::Console::Banners.print_network_interfaces_routes
|
||||
|
||||
#
|
||||
# @note Create ~/.beef/
|
||||
#
|
||||
begin
|
||||
FileUtils.mkdir_p($home_dir) unless File.directory?($home_dir)
|
||||
rescue => e
|
||||
print_error "Could not create '#{$home_dir}': #{e.message}"
|
||||
end
|
||||
|
||||
#
|
||||
# @note Check whether we load the Console Shell or not
|
||||
#
|
||||
if config.get("beef.extension.console.shell.enable") == true
|
||||
print_error "The console extension is currently unsupported."
|
||||
print_more "See issue #1090 - https://github.com/beefproject/beef/issues/1090"
|
||||
end
|
||||
|
||||
#
|
||||
# @note Exit on default credentials
|
||||
#
|
||||
if config.get("beef.credentials.user").eql?('beef') && config.get("beef.credentials.passwd").eql?('beef')
|
||||
print_error "ERROR: Default username and password in use!"
|
||||
print_more "Change the beef.credentials.passwd in config.yaml"
|
||||
exit 1
|
||||
end
|
||||
|
||||
#
|
||||
# @note Validate beef.http.public and beef.http.public_port
|
||||
#
|
||||
unless config.get('beef.http.public').to_s.eql?('') || BeEF::Filters.is_valid_hostname?(config.get('beef.http.public'))
|
||||
print_error "ERROR: Invalid public hostname: #{config.get('beef.http.public')}"
|
||||
exit 1
|
||||
end
|
||||
|
||||
unless config.get('beef.http.public_port').to_s.eql?('') || BeEF::Filters.is_valid_port?(config.get('beef.http.public_port'))
|
||||
print_error "ERROR: Invalid public port: #{config.get('beef.http.public_port')}"
|
||||
exit 1
|
||||
end
|
||||
|
||||
#
|
||||
# @note Prints the API key needed to use the RESTful API
|
||||
#
|
||||
|
||||
31
config.yaml
31
config.yaml
@@ -6,7 +6,7 @@
|
||||
# BeEF Configuration file
|
||||
|
||||
beef:
|
||||
version: '0.4.7.1-alpha'
|
||||
version: '0.4.7.4-alpha-pre'
|
||||
# More verbose messages (server-side)
|
||||
debug: false
|
||||
# More verbose messages (client-side)
|
||||
@@ -23,10 +23,10 @@ beef:
|
||||
# Interface / IP restrictions
|
||||
restrictions:
|
||||
# subnet of IP addresses that can hook to the framework
|
||||
permitted_hooking_subnet: "0.0.0.0/0"
|
||||
permitted_hooking_subnet: ["0.0.0.0/0", "::/0"]
|
||||
# subnet of IP addresses that can connect to the admin UI
|
||||
#permitted_ui_subnet: "127.0.0.1/32"
|
||||
permitted_ui_subnet: "0.0.0.0/0"
|
||||
#permitted_ui_subnet: ["127.0.0.1/32", "::1/128"]
|
||||
permitted_ui_subnet: ["0.0.0.0/0", "::/0"]
|
||||
# slow API calls to 1 every api_attempt_delay seconds
|
||||
api_attempt_delay: "0.05"
|
||||
|
||||
@@ -90,28 +90,7 @@ beef:
|
||||
cert: "beef_cert.pem"
|
||||
|
||||
database:
|
||||
# For information on using other databases please read the
|
||||
# README.databases file
|
||||
|
||||
# supported DBs: sqlite, mysql, postgres
|
||||
# NOTE: you must change the Gemfile adding a gem require line like:
|
||||
# gem "dm-postgres-adapter"
|
||||
# or
|
||||
# gem "dm-mysql-adapter"
|
||||
# if you want to switch drivers from sqlite to postgres (or mysql).
|
||||
# Finally, run a 'bundle install' command and start BeEF.
|
||||
driver: "sqlite"
|
||||
|
||||
# db_file is only used for sqlite
|
||||
db_file: "beef.db"
|
||||
|
||||
# db connection information is only used for mysql/postgres
|
||||
db_host: "localhost"
|
||||
db_port: 3306
|
||||
db_name: "beef"
|
||||
db_user: "beef"
|
||||
db_passwd: "beef"
|
||||
db_encoding: "UTF-8"
|
||||
file: "beef.db"
|
||||
|
||||
# Autorun Rule Engine
|
||||
autorun:
|
||||
|
||||
@@ -30,8 +30,6 @@ require 'core/main/network_stack/assethandler'
|
||||
require 'core/main/network_stack/api'
|
||||
|
||||
# @note Include the autorun engine
|
||||
require 'core/main/autorun_engine/models/rule'
|
||||
require 'core/main/autorun_engine/models/execution'
|
||||
require 'core/main/autorun_engine/parser'
|
||||
require 'core/main/autorun_engine/engine'
|
||||
require 'core/main/autorun_engine/rule_loader'
|
||||
|
||||
@@ -10,6 +10,7 @@ end
|
||||
end
|
||||
|
||||
# @note Includes database models - the order must be consistent otherwise DataMapper goes crazy
|
||||
require 'core/main/model'
|
||||
require 'core/main/models/commandmodule'
|
||||
require 'core/main/models/hookedbrowser'
|
||||
require 'core/main/models/log'
|
||||
@@ -17,6 +18,8 @@ require 'core/main/models/command'
|
||||
require 'core/main/models/result'
|
||||
require 'core/main/models/optioncache'
|
||||
require 'core/main/models/browserdetails'
|
||||
require 'core/main/models/rule'
|
||||
require 'core/main/models/execution'
|
||||
|
||||
# @note Include the constants
|
||||
require 'core/main/constants/browsers'
|
||||
|
||||
@@ -10,14 +10,14 @@ module BeEF
|
||||
# @param [String] sid hooked browser session id string
|
||||
# @return [BeEF::Core::Models::HookedBrowser] returns the associated Hooked Browser
|
||||
def self.get_by_session(sid)
|
||||
BeEF::Core::Models::HookedBrowser.first(:session => sid)
|
||||
BeEF::Core::Models::HookedBrowser.where(:session => sid).first
|
||||
end
|
||||
|
||||
# Get hooked browser by id
|
||||
# @param [Integer] id hooked browser database id
|
||||
# @return [BeEF::Core::Models::HookedBrowser] returns the associated Hooked Browser
|
||||
def self.get_by_id(id)
|
||||
BeEF::Core::Models::HookedBrowser.first(:id => id)
|
||||
BeEF::Core::Models::HookedBrowser.find(id)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -31,7 +31,7 @@ require 'execjs'
|
||||
require 'ansi'
|
||||
require 'term/ansicolor'
|
||||
require 'json'
|
||||
require 'data_objects'
|
||||
require 'otr-activerecord'
|
||||
require 'parseconfig'
|
||||
require 'erubis'
|
||||
require 'mime/types'
|
||||
@@ -39,6 +39,9 @@ require 'optparse'
|
||||
require 'resolv'
|
||||
require 'digest'
|
||||
require 'zip'
|
||||
require 'logger'
|
||||
# @note Logger
|
||||
require 'core/logger'
|
||||
|
||||
# @note Include the filters
|
||||
require 'core/filters'
|
||||
|
||||
21
core/logger.rb
Normal file
21
core/logger.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
#
|
||||
# @note log to file
|
||||
#
|
||||
module BeEF
|
||||
class << self
|
||||
attr_writer :logger
|
||||
|
||||
def logger
|
||||
@logger ||= Logger.new("#{$home_dir}/beef.log").tap do |log|
|
||||
log.progname = self.name
|
||||
log.level = Logger::WARN
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
12
core/main/ar-migrations/001_create_command_modules.rb
Normal file
12
core/main/ar-migrations/001_create_command_modules.rb
Normal file
@@ -0,0 +1,12 @@
|
||||
class CreateCommandModules < ActiveRecord::Migration[6.0]
|
||||
|
||||
def change
|
||||
|
||||
create_table :command_modules do |t|
|
||||
t.text :name
|
||||
t.text :path
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
19
core/main/ar-migrations/002_create_hooked_browsers.rb
Normal file
19
core/main/ar-migrations/002_create_hooked_browsers.rb
Normal file
@@ -0,0 +1,19 @@
|
||||
class CreateHookedBrowsers < ActiveRecord::Migration[6.0]
|
||||
|
||||
def change
|
||||
|
||||
create_table :hooked_browsers do |t|
|
||||
t.text :session
|
||||
t.text :ip
|
||||
t.text :firstseen
|
||||
t.text :lastseen
|
||||
t.text :httpheaders
|
||||
t.text :domain
|
||||
t.integer :port
|
||||
t.integer :count
|
||||
t.boolean :is_proxy
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
14
core/main/ar-migrations/003_create_logs.rb
Normal file
14
core/main/ar-migrations/003_create_logs.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
class CreateLogs < ActiveRecord::Migration[6.0]
|
||||
|
||||
def change
|
||||
|
||||
create_table :logs do |t|
|
||||
t.text :logtype
|
||||
t.text :event
|
||||
t.datetime :date
|
||||
t.references :hooked_browser
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
16
core/main/ar-migrations/004_create_commands.rb
Normal file
16
core/main/ar-migrations/004_create_commands.rb
Normal file
@@ -0,0 +1,16 @@
|
||||
class CreateCommands < ActiveRecord::Migration[6.0]
|
||||
|
||||
def change
|
||||
|
||||
create_table :commands do |t|
|
||||
t.references :command_module
|
||||
t.references :hooked_browser
|
||||
t.text :data
|
||||
t.datetime :creationdate
|
||||
t.text :label
|
||||
t.boolean :instructions_sent, default: false
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
15
core/main/ar-migrations/005_create_results.rb
Normal file
15
core/main/ar-migrations/005_create_results.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
class CreateResults < ActiveRecord::Migration[6.0]
|
||||
|
||||
def change
|
||||
|
||||
create_table :results do |t|
|
||||
t.references :command
|
||||
t.references :hooked_browser
|
||||
t.datetime :date
|
||||
t.integer :status
|
||||
t.text :data
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
12
core/main/ar-migrations/006_create_option_caches.rb
Normal file
12
core/main/ar-migrations/006_create_option_caches.rb
Normal file
@@ -0,0 +1,12 @@
|
||||
class CreateOptionCaches < ActiveRecord::Migration[6.0]
|
||||
|
||||
def change
|
||||
|
||||
create_table :option_caches do |t|
|
||||
t.text :name
|
||||
t.text :value
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
13
core/main/ar-migrations/007_create_browser_details.rb
Normal file
13
core/main/ar-migrations/007_create_browser_details.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
class CreateBrowserDetails < ActiveRecord::Migration[6.0]
|
||||
|
||||
def change
|
||||
|
||||
create_table :browser_details do |t|
|
||||
t.text :session_id
|
||||
t.text :detail_key
|
||||
t.text :detail_value
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
17
core/main/ar-migrations/008_create_executions.rb
Normal file
17
core/main/ar-migrations/008_create_executions.rb
Normal file
@@ -0,0 +1,17 @@
|
||||
class CreateExecutions < ActiveRecord::Migration[6.0]
|
||||
|
||||
def change
|
||||
|
||||
create_table :executions do |t|
|
||||
t.text :session_id
|
||||
t.integer :mod_count
|
||||
t.integer :mod_successful
|
||||
t.text :mod_body
|
||||
t.text :exec_time
|
||||
t.text :rule_token
|
||||
t.boolean :is_sent
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
20
core/main/ar-migrations/009_create_rules.rb
Normal file
20
core/main/ar-migrations/009_create_rules.rb
Normal file
@@ -0,0 +1,20 @@
|
||||
class CreateRules < ActiveRecord::Migration[6.0]
|
||||
|
||||
def change
|
||||
|
||||
create_table :rules do |t|
|
||||
t.text :name
|
||||
t.text :author
|
||||
t.text :browser
|
||||
t.text :browser_version
|
||||
t.text :os
|
||||
t.text :os_version
|
||||
t.text :modules
|
||||
t.text :execution_order
|
||||
t.text :execution_delay
|
||||
t.text :chain_mode
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
12
core/main/ar-migrations/010_create_interceptor.rb
Normal file
12
core/main/ar-migrations/010_create_interceptor.rb
Normal file
@@ -0,0 +1,12 @@
|
||||
class CreateInterceptor < ActiveRecord::Migration[6.0]
|
||||
|
||||
def change
|
||||
|
||||
create_table :interceptors do |t|
|
||||
t.text :ip
|
||||
t.text :post_data
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
12
core/main/ar-migrations/011_create_web_cloner.rb
Normal file
12
core/main/ar-migrations/011_create_web_cloner.rb
Normal file
@@ -0,0 +1,12 @@
|
||||
class CreateWebCloner < ActiveRecord::Migration[6.0]
|
||||
|
||||
def change
|
||||
|
||||
create_table :web_cloner do |t|
|
||||
t.text :uri
|
||||
t.text :mount
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
11
core/main/ar-migrations/012_create_mass_mailer.rb
Normal file
11
core/main/ar-migrations/012_create_mass_mailer.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
class CreateMassMailer < ActiveRecord::Migration[6.0]
|
||||
|
||||
def change
|
||||
|
||||
create_table :mass_mailer do |t|
|
||||
#todo fields
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
17
core/main/ar-migrations/013_create_network_host.rb
Normal file
17
core/main/ar-migrations/013_create_network_host.rb
Normal file
@@ -0,0 +1,17 @@
|
||||
class CreateNetworkHost < ActiveRecord::Migration[6.0]
|
||||
|
||||
def change
|
||||
|
||||
create_table :network_hosts do |t|
|
||||
t.references :hooked_browser
|
||||
t.text :ip
|
||||
t.text :hostname
|
||||
t.text :ntype
|
||||
t.text :os
|
||||
t.text :mac
|
||||
t.text :lastseen
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
15
core/main/ar-migrations/014_create_network_service.rb
Normal file
15
core/main/ar-migrations/014_create_network_service.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
class CreateNetworkService < ActiveRecord::Migration[6.0]
|
||||
|
||||
def change
|
||||
|
||||
create_table :network_services do |t|
|
||||
t.references :hooked_browser
|
||||
t.text :proto
|
||||
t.text :ip
|
||||
t.text :port
|
||||
t.text :ntype
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
44
core/main/ar-migrations/015_create_http.rb
Normal file
44
core/main/ar-migrations/015_create_http.rb
Normal file
@@ -0,0 +1,44 @@
|
||||
class CreateHttp < ActiveRecord::Migration[6.0]
|
||||
|
||||
def change
|
||||
|
||||
create_table :http do |t|
|
||||
t.references :hooked_browser
|
||||
# The http request to perform. In clear text.
|
||||
t.text :request
|
||||
# Boolean value as string to say whether cross-domain requests are allowed
|
||||
t.boolean :allow_cross_domain, :default => true
|
||||
# The http response body received. In clear text.
|
||||
t.text :response_data
|
||||
# The http response code. Useful to handle cases like 404, 500, 302, ...
|
||||
t.integer :response_status_code
|
||||
# The http response code. Human-readable code: success, error, ecc..
|
||||
t.text :response_status_text
|
||||
# The port status. closed, open or not http
|
||||
t.text :response_port_status
|
||||
# The XHR Http response raw headers
|
||||
t.text :response_headers
|
||||
# The http response method. GET or POST.
|
||||
t.text :method
|
||||
# The content length for the request.
|
||||
t.text :content_length, :default => 0
|
||||
# The request protocol/scheme (http/https)
|
||||
t.text :proto
|
||||
# The domain on which perform the request.
|
||||
t.text :domain
|
||||
# The port on which perform the request.
|
||||
t.text :port
|
||||
# Boolean value to say if the request was cross-domain
|
||||
t.text :has_ran, :default => "waiting"
|
||||
# The path of the request.
|
||||
# Example: /secret.html
|
||||
t.text :path
|
||||
# The date at which the http response has been saved.
|
||||
t.datetime :response_date
|
||||
# The date at which the http request has been saved.
|
||||
t.datetime :request_date
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
13
core/main/ar-migrations/016_create_rtc_status.rb
Normal file
13
core/main/ar-migrations/016_create_rtc_status.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
class CreateRtcStatus < ActiveRecord::Migration[6.0]
|
||||
|
||||
def change
|
||||
|
||||
create_table :rtc_status do |t|
|
||||
t.references :hooked_browser
|
||||
t.integer :target_hooked_browser_id
|
||||
t.text :status
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
13
core/main/ar-migrations/017_create_rtc_manage.rb
Normal file
13
core/main/ar-migrations/017_create_rtc_manage.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
class CreateRtcManage < ActiveRecord::Migration[6.0]
|
||||
|
||||
def change
|
||||
|
||||
create_table :rtc_manage do |t|
|
||||
t.references :hooked_browser
|
||||
t.text :message
|
||||
t.text :has_sent, default: "waiting"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
14
core/main/ar-migrations/018_create_rtc_signal.rb
Normal file
14
core/main/ar-migrations/018_create_rtc_signal.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
class CreateRtcSignal < ActiveRecord::Migration[6.0]
|
||||
|
||||
def change
|
||||
|
||||
create_table :rtc_signal do |t|
|
||||
t.references :hooked_browser
|
||||
t.integer :target_hooked_browser_id
|
||||
t.text :signal
|
||||
t.text :has_sent, default: "waiting"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
14
core/main/ar-migrations/019_create_rtc_module_status.rb
Normal file
14
core/main/ar-migrations/019_create_rtc_module_status.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
class CreateRtcModuleStatus < ActiveRecord::Migration[6.0]
|
||||
|
||||
def change
|
||||
|
||||
create_table :rtc_module_status do |t|
|
||||
t.references :hooked_browser
|
||||
t.references :command_module
|
||||
t.integer :target_hooked_browser_id
|
||||
t.text :status
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
14
core/main/ar-migrations/020_create_xssrays_detail.rb
Normal file
14
core/main/ar-migrations/020_create_xssrays_detail.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
class CreateXssraysDetail < ActiveRecord::Migration[6.0]
|
||||
|
||||
def change
|
||||
|
||||
create_table :xssrays_detail do |t|
|
||||
t.references :hooked_browser
|
||||
t.text :vector_name
|
||||
t.text :vector_method
|
||||
t.text :vector_poc
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
14
core/main/ar-migrations/021_create_dns_rule.rb
Normal file
14
core/main/ar-migrations/021_create_dns_rule.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
class CreateDnsRule < ActiveRecord::Migration[6.0]
|
||||
|
||||
def change
|
||||
|
||||
create_table :dns_rule do |t|
|
||||
t.text :pattern
|
||||
t.text :resource
|
||||
t.text :response
|
||||
t.text :callback
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
13
core/main/ar-migrations/022_create_ipec_exploit.rb
Normal file
13
core/main/ar-migrations/022_create_ipec_exploit.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
class CreateIpecExploit < ActiveRecord::Migration[6.0]
|
||||
|
||||
def change
|
||||
|
||||
create_table :ipec_exploit do |t|
|
||||
t.text :name
|
||||
t.text :protocol
|
||||
t.text :os
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
13
core/main/ar-migrations/023_create_ipec_exploit_run.rb
Normal file
13
core/main/ar-migrations/023_create_ipec_exploit_run.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
class CreateIpecExploitRun < ActiveRecord::Migration[6.0]
|
||||
|
||||
def change
|
||||
|
||||
create_table :ipec_exploit_run do |t|
|
||||
t.boolean :launched
|
||||
t.text :http_headers
|
||||
t.text :junk_size
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
12
core/main/ar-migrations/024_create_autoloader.rb
Normal file
12
core/main/ar-migrations/024_create_autoloader.rb
Normal file
@@ -0,0 +1,12 @@
|
||||
class CreateAutoloader < ActiveRecord::Migration[6.0]
|
||||
|
||||
def change
|
||||
|
||||
create_table :autoloader do |t|
|
||||
t.references :command
|
||||
t.boolean :in_use
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
18
core/main/ar-migrations/025_create_xssrays_scan.rb
Normal file
18
core/main/ar-migrations/025_create_xssrays_scan.rb
Normal file
@@ -0,0 +1,18 @@
|
||||
class CreateXssraysScan < ActiveRecord::Migration[6.0]
|
||||
|
||||
def change
|
||||
|
||||
create_table :xssrays_scan do |t|
|
||||
t.references :hooked_browser
|
||||
t.datetime :scan_start
|
||||
t.datetime :scan_finish
|
||||
t.text :domain
|
||||
t.text :cross_domain
|
||||
t.integer :clean_timeout
|
||||
t.boolean :is_started
|
||||
t.boolean :is_finished
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
@@ -41,7 +41,7 @@ module BeEF
|
||||
hb_session = hb.session
|
||||
|
||||
rule_ids.each do |rule_id|
|
||||
rule = BeEF::Core::AutorunEngine::Models::Rule.get(rule_id)
|
||||
rule = BeEF::Core::Models::Rule.find(rule_id)
|
||||
modules = JSON.parse(rule.modules)
|
||||
|
||||
execution_order = JSON.parse(rule.execution_order)
|
||||
@@ -57,7 +57,7 @@ module BeEF
|
||||
rule_token = SecureRandom.hex(5)
|
||||
|
||||
modules.each do |cmd_mod|
|
||||
mod = BeEF::Core::Models::CommandModule.first(:name => cmd_mod['name'])
|
||||
mod = BeEF::Core::Models::CommandModule.where(:name => cmd_mod['name']).first
|
||||
options = []
|
||||
replace_input = false
|
||||
cmd_mod['options'].each do|k,v|
|
||||
@@ -85,7 +85,7 @@ module BeEF
|
||||
# TODO catch error, which should never happen as values are checked way before ;-)
|
||||
end
|
||||
|
||||
are_exec = BeEF::Core::AutorunEngine::Models::Execution.new(
|
||||
are_exec = BeEF::Core::Models::Execution.new(
|
||||
:session => hb_session,
|
||||
:mod_count => modules.length,
|
||||
:mod_successful => 0,
|
||||
@@ -94,7 +94,7 @@ module BeEF
|
||||
:is_sent => false,
|
||||
:rule_id => rule_id
|
||||
)
|
||||
are_exec.save
|
||||
are_exec.save!
|
||||
# Once Engine.check() verified that the hooked browser match a Rule, trigger the Rule ;-)
|
||||
print_more "Triggering ruleset #{rule_ids.to_s} on HB #{hb_id}"
|
||||
end
|
||||
@@ -272,9 +272,9 @@ module BeEF
|
||||
:creationdate => Time.new.to_i,
|
||||
:instructions_sent => true
|
||||
)
|
||||
command.save
|
||||
command.save!
|
||||
|
||||
command_module = BeEF::Core::Models::CommandModule.first(:id => mod.id)
|
||||
command_module = BeEF::Core::Models::CommandModule.find(mod.id)
|
||||
if (command_module.path.match(/^Dynamic/))
|
||||
# metasploit and similar integrations
|
||||
command_module = BeEF::Modules::Commands.const_get(command_module.path.split('/').last.capitalize).new
|
||||
@@ -385,9 +385,9 @@ module BeEF
|
||||
def match(browser, browser_version, os, os_version, rule_id=nil)
|
||||
match_rules = []
|
||||
if rule_id != nil
|
||||
rules = [BeEF::Core::AutorunEngine::Models::Rule.get(rule_id)]
|
||||
rules = [BeEF::Core::Models::Rule.find(rule_id)]
|
||||
else
|
||||
rules = BeEF::Core::AutorunEngine::Models::Rule.all()
|
||||
rules = BeEF::Core::Models::Rule.all
|
||||
end
|
||||
return nil if rules == nil
|
||||
return nil unless rules.length > 0
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 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 AutorunEngine
|
||||
module Models
|
||||
# @note Stored info about the execution of the ARE on hooked browsers.
|
||||
class Execution
|
||||
|
||||
include DataMapper::Resource
|
||||
|
||||
storage_names[:default] = 'core_areexecution'
|
||||
|
||||
property :id, Serial
|
||||
property :session, Text # hooked browser session where a ruleset triggered
|
||||
property :mod_count, Integer # number of command modules of the ruleset
|
||||
property :mod_successful, Integer # number of command modules that returned with success
|
||||
# By default Text is only 65K, so field length increased to 1 MB
|
||||
property :mod_body, Text, :length => 1024000 # entire command module(s) body to be sent
|
||||
property :exec_time, String, :length => 15 # timestamp of ruleset triggering
|
||||
property :rule_token, String, :length => 10 # unique token to be appended to wrapper function names
|
||||
property :is_sent, Boolean
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,34 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 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 AutorunEngine
|
||||
module Models
|
||||
# @note Table stores the rules for the Distributed Engine.
|
||||
class Rule
|
||||
include DataMapper::Resource
|
||||
|
||||
storage_names[:default] = 'core_arerules'
|
||||
|
||||
property :id, Serial
|
||||
property :name, Text # rule name
|
||||
property :author, String # rule author
|
||||
property :browser, String, :length => 10 # browser name
|
||||
property :browser_version, String, :length => 15 # browser version
|
||||
property :os, String, :length => 10 # OS name
|
||||
property :os_version, String, :length => 15 # OS version
|
||||
property :modules, Text # JSON stringyfied representation of the JSON rule for further parsing
|
||||
property :execution_order, Text # command module execution order
|
||||
property :execution_delay, Text # command module time delays
|
||||
property :chain_mode, String, :length => 40 # rule chaining mode
|
||||
|
||||
has n, :executions
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -53,7 +53,7 @@ module BeEF
|
||||
|
||||
# check if module names, conditions and options are ok
|
||||
modules.each do |cmd_mod|
|
||||
mod = BeEF::Core::Models::CommandModule.first(:name => cmd_mod['name'])
|
||||
mod = BeEF::Core::Models::CommandModule.where(:name => cmd_mod['name']).first
|
||||
if mod != nil
|
||||
modk = BeEF::Module.get_key_by_database_id(mod.id)
|
||||
mod_options = BeEF::Module.get_options(modk)
|
||||
|
||||
@@ -52,7 +52,7 @@ module BeEF
|
||||
print_more "Exec order: #{exec_order}"
|
||||
print_more "Exec delay: #{exec_delay}"
|
||||
end
|
||||
are_rule = BeEF::Core::AutorunEngine::Models::Rule.new(
|
||||
are_rule = BeEF::Core::Models::Rule.new(
|
||||
:name => name,
|
||||
:author => author,
|
||||
:browser => browser,
|
||||
|
||||
@@ -40,16 +40,17 @@ beef.geolocation = {
|
||||
},
|
||||
success: function(data, status, xhr){
|
||||
beef.debug("[geolocation.js] openstreetmap success");
|
||||
var jsonResp = $j.parseJSON(data);
|
||||
//var jsonResp = $j.parseJSON(data);
|
||||
|
||||
beef.net.send(command_url, command_id, "latitude=" + latitude
|
||||
+ "&longitude=" + longitude
|
||||
// + "&osm=" + encodeURI(jsonResp.display_name)
|
||||
+ "&osm=tofix"
|
||||
+ "&osm=" + data.display_name
|
||||
+ "&geoLocEnabled=True");
|
||||
},
|
||||
type: "get",
|
||||
url: "http://nominatim.openstreetmap.org/reverse?format=json&lat=" +
|
||||
dataType: "json",
|
||||
url: "https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=" +
|
||||
latitude + "&lon=" + longitude + "&zoom=18&addressdetails=1"
|
||||
});
|
||||
|
||||
|
||||
@@ -179,7 +179,7 @@ module BeEF
|
||||
return
|
||||
end
|
||||
|
||||
command = BeEF::Core::Models::Command.first(:id => @command_id)
|
||||
command = BeEF::Core::Models::Command.find(@command_id)
|
||||
|
||||
@eruby = Erubis::FastEruby.new(File.read(f))
|
||||
|
||||
@@ -237,7 +237,7 @@ module BeEF
|
||||
|
||||
# @todo TODO Document
|
||||
def oc_value(name)
|
||||
option = BeEF::Core::Models::OptionCache.first(:name => name)
|
||||
option = BeEF::Core::Models::OptionCache.where(:name => name).first
|
||||
return nil unless option
|
||||
option.value
|
||||
end
|
||||
|
||||
@@ -30,8 +30,8 @@ module BeEF
|
||||
@config.default = nil
|
||||
@@config = config
|
||||
rescue => e
|
||||
print_error "Fatal Error: cannot load configuration file"
|
||||
print_debug e
|
||||
print_error "Fatal Error: cannot load configuration file '#{config}' : #{e.message}"
|
||||
print_error e.backtrace
|
||||
end
|
||||
|
||||
@@instance = self
|
||||
@@ -45,8 +45,35 @@ module BeEF
|
||||
raw = File.read file
|
||||
YAML.safe_load raw
|
||||
rescue => e
|
||||
print_debug "Unable to load '#{file}' #{e}"
|
||||
nil
|
||||
print_debug "Unable to load configuration file '#{file}' : #{e.message}"
|
||||
print_error e.backtrace
|
||||
end
|
||||
|
||||
#
|
||||
# @note balidate the configuration file
|
||||
#
|
||||
def validate
|
||||
if @config.empty?
|
||||
print_error 'Configuration file is empty'
|
||||
return
|
||||
end
|
||||
|
||||
if @config['beef'].nil?
|
||||
print_error "Configuration file is malformed: 'beef' is nil"
|
||||
return
|
||||
end
|
||||
|
||||
if @config['beef']['credentials'].nil?
|
||||
print_error "Configuration file is malformed: 'beef.credentials' is nil"
|
||||
return
|
||||
end
|
||||
|
||||
if @config['beef']['http'].nil?
|
||||
print_error "Configuration file is malformed: 'beef.http' is nil"
|
||||
return
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
@@ -82,7 +82,7 @@ module Core
|
||||
|
||||
begin
|
||||
id = random_hex_string(8)
|
||||
BeEF::Core::Models::Dns::Rule.each { |rule| throw StandardError if id == rule.id }
|
||||
BeEF::Core::Models::Dns::Rule.all.each { |rule| throw StandardError if id == rule.id }
|
||||
rescue StandardError
|
||||
retry
|
||||
end
|
||||
|
||||
@@ -30,7 +30,7 @@ module BeEF
|
||||
# validate hook session value
|
||||
session_id = get_param(@data, 'beefhook')
|
||||
(self.err_msg "session id is invalid"; return) if not BeEF::Filters.is_valid_hook_session_id?(session_id)
|
||||
hooked_browser = HB.first(:session => session_id)
|
||||
hooked_browser = HB.where(:session => session_id).first
|
||||
return if not hooked_browser.nil? # browser is already registered with framework
|
||||
|
||||
# create the structure representing the hooked browser
|
||||
@@ -73,7 +73,7 @@ module BeEF
|
||||
@http_headers[key.sub(/^HTTP_/, '')] = value.force_encoding('UTF-8')
|
||||
}
|
||||
zombie.httpheaders = @http_headers.to_json
|
||||
zombie.save
|
||||
zombie.save!
|
||||
#print_debug "[INIT] HTTP Headers: #{zombie.httpheaders}"
|
||||
|
||||
# add a log entry for the newly hooked browser
|
||||
@@ -211,7 +211,7 @@ module BeEF
|
||||
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')
|
||||
BeEF::Core::Models::NetworkHost.create(:hooked_browser_id => session_id, :ip => $1, :type => 'Proxy')
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -504,7 +504,7 @@ module BeEF
|
||||
# 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, 'host.os.name'))
|
||||
BeEF::Core::Models::NetworkHost.create(:hooked_browser_id => session_id, :ip => '127.0.0.1', :hostname => 'localhost', :os => BeEF::Core::Models::BrowserDetails.get(session_id, 'host.os.name'))
|
||||
end
|
||||
|
||||
# check if any ARE rules shall be triggered only if the channel is != WebSockets (XHR). If the channel
|
||||
|
||||
@@ -24,22 +24,36 @@ module Handlers
|
||||
# and deploy some command modules or extensions to the hooked browser.
|
||||
get '/' do
|
||||
@body = ''
|
||||
@params = request.query_string
|
||||
params = request.query_string
|
||||
#@response = Rack::Response.new(body=[], 200, header={})
|
||||
config = BeEF::Core::Configuration.instance
|
||||
|
||||
# @note check source ip address of browser
|
||||
permitted_hooking_subnet = config.get('beef.restrictions.permitted_hooking_subnet')
|
||||
target_network = IPAddr.new(permitted_hooking_subnet)
|
||||
if not target_network.include?(request.ip)
|
||||
BeEF::Core::Logger.instance.register('Target Range', "Attempted hook from out of target range browser (#{request.ip}) rejected.")
|
||||
error 500
|
||||
if permitted_hooking_subnet.nil? || permitted_hooking_subnet.empty?
|
||||
BeEF::Core::Logger.instance.register('Target Range', "Attempted hook from outside of permitted hooking subnet (#{request.ip}) rejected.")
|
||||
error 404
|
||||
end
|
||||
|
||||
found = false
|
||||
permitted_hooking_subnet.each do |subnet|
|
||||
found = true if IPAddr.new(subnet).include?(request.ip)
|
||||
end
|
||||
|
||||
unless found
|
||||
BeEF::Core::Logger.instance.register('Target Range', "Attempted hook from outside of permitted hooking subnet (#{request.ip}) rejected.")
|
||||
error 404
|
||||
end
|
||||
|
||||
# @note get zombie if already hooked the framework
|
||||
hook_session_name = config.get('beef.http.hook_session_name')
|
||||
hook_session_id = request[hook_session_name]
|
||||
hooked_browser = BeEF::Core::Models::HookedBrowser.first(:session => hook_session_id) if not hook_session_id.nil?
|
||||
begin
|
||||
raise ActiveRecord::RecordNotFound if hook_session_id.nil?
|
||||
hooked_browser = BeEF::Core::Models::HookedBrowser.where(:session => hook_session_id).first
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
hooked_browser = false
|
||||
end
|
||||
|
||||
# @note is a new browser so return instructions to set up the hook
|
||||
if not hooked_browser
|
||||
@@ -73,21 +87,21 @@ module Handlers
|
||||
end
|
||||
|
||||
hooked_browser.count!
|
||||
hooked_browser.save
|
||||
hooked_browser.save!
|
||||
|
||||
# @note add all available command module instructions to the response
|
||||
zombie_commands = BeEF::Core::Models::Command.all(:hooked_browser_id => hooked_browser.id, :instructions_sent => false)
|
||||
zombie_commands = BeEF::Core::Models::Command.where(:hooked_browser_id => hooked_browser.id, :instructions_sent => false)
|
||||
zombie_commands.each{|command| add_command_instructions(command, hooked_browser)}
|
||||
|
||||
# @note Check if there are any ARE rules to be triggered. If is_sent=false rules are triggered
|
||||
are_executions = BeEF::Core::AutorunEngine::Models::Execution.all(:is_sent => false, :session => hook_session_id)
|
||||
are_executions = BeEF::Core::Models::Execution.where(:is_sent => false, :session_id => hook_session_id)
|
||||
are_executions.each do |are_exec|
|
||||
@body += are_exec.mod_body
|
||||
are_exec.update(:is_sent => true, :exec_time => Time.new.to_i)
|
||||
end
|
||||
|
||||
# @note We dynamically get the list of all browser hook handler using the API and register them
|
||||
BeEF::API::Registrar.instance.fire(BeEF::API::Server::Hook, 'pre_hook_send', hooked_browser, @body, @params, request, response)
|
||||
BeEF::API::Registrar.instance.fire(BeEF::API::Server::Hook, 'pre_hook_send', hooked_browser, @body, params, request, response)
|
||||
end
|
||||
|
||||
# @note set response headers and body
|
||||
|
||||
@@ -21,7 +21,7 @@ module BeEF
|
||||
|
||||
config = BeEF::Core::Configuration.instance
|
||||
# @note get the command module
|
||||
command_module = BeEF::Core::Models::CommandModule.first(:id => command.command_module_id)
|
||||
command_module = BeEF::Core::Models::CommandModule.where(:id => command.command_module_id).first
|
||||
(print_error "command_module is nil"; return) if command_module.nil?
|
||||
(print_error "command_module.path is nil"; return) if command_module.path.nil?
|
||||
|
||||
@@ -70,7 +70,7 @@ module BeEF
|
||||
|
||||
# @note flag that the command has been sent to the hooked browser
|
||||
command.instructions_sent = true
|
||||
command.save
|
||||
command.save!
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -15,7 +15,8 @@ module Core
|
||||
@config = BeEF::Core::Configuration.instance
|
||||
|
||||
# if notifications are enabled create a new instance
|
||||
@notifications = BeEF::Extension::Notifications::Notifications unless @config.get('beef.extension.notifications.enable') == false
|
||||
notifications_enabled = @config.get('beef.extension.notifications.enable')
|
||||
@notifications = BeEF::Extension::Notifications::Notifications unless (notifications_enabled == false or notifications_enabled.nil?)
|
||||
end
|
||||
|
||||
#
|
||||
@@ -39,7 +40,7 @@ module Core
|
||||
raise TypeError, '"Hooked Browser ID" needs to be an integer' unless hb.integer?
|
||||
|
||||
# logging the new event into the database
|
||||
@logs.new(:type => from.to_s, :event => event.to_s, :date => time_now, :hooked_browser_id => hb).save
|
||||
@logs.create(:logtype => from.to_s, :event => event.to_s, :date => time_now, :hooked_browser_id => hb).save!
|
||||
print_debug "Event: #{event}"
|
||||
# if notifications are enabled send the info there too
|
||||
if @notifications
|
||||
|
||||
@@ -27,14 +27,10 @@ module Core
|
||||
def update_commands!
|
||||
config = BeEF::Core::Configuration.instance
|
||||
|
||||
db_modules = []
|
||||
BeEF::Core::Models::CommandModule.all.each do |mod|
|
||||
db_modules << mod.name
|
||||
end
|
||||
db_modules = BeEF::Core::Models::CommandModule.all.pluck(:name)
|
||||
|
||||
config.get('beef.module').each do |k, v|
|
||||
h = { :name => k, :path => "#{v['path']}module.rb" }
|
||||
BeEF::Core::Models::CommandModule.new(h).save unless db_modules.include? k
|
||||
BeEF::Core::Models::CommandModule.new(name: k, path: "#{v['path']}module.rb").save! unless db_modules.include? k
|
||||
end
|
||||
|
||||
BeEF::Core::Models::CommandModule.all.each do |mod|
|
||||
|
||||
14
core/main/model.rb
Normal file
14
core/main/model.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
module BeEF
|
||||
module Core
|
||||
class Model < ActiveRecord::Base
|
||||
# Tell ActiveRecord that this is not a model
|
||||
self.abstract_class = true
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -11,20 +11,13 @@ module Models
|
||||
#
|
||||
# For example, the type and version of browser the hooked browsers are using.
|
||||
#
|
||||
class BrowserDetails
|
||||
|
||||
include DataMapper::Resource
|
||||
|
||||
storage_names[:default] = 'core_browserdetails'
|
||||
property :session_id, String, :length => 255, :key => true
|
||||
property :detail_key, String, :length => 255, :lazy => false, :key => true
|
||||
property :detail_value, Text, :lazy => false
|
||||
class BrowserDetails < BeEF::Core::Model
|
||||
|
||||
#
|
||||
# Returns the requested value from the data store
|
||||
#
|
||||
def self.get(session_id, key)
|
||||
browserdetail = first(:session_id => session_id, :detail_key => key)
|
||||
browserdetail = self.where(:session_id => session_id, :detail_key => key).first
|
||||
|
||||
return nil if browserdetail.nil?
|
||||
return nil if browserdetail.detail_value.nil?
|
||||
@@ -35,19 +28,20 @@ module Models
|
||||
# Stores or updates an existing key->value pair in the data store
|
||||
#
|
||||
def self.set(session_id, detail_key, detail_value)
|
||||
browserdetails = BeEF::Core::Models::BrowserDetails.all(
|
||||
browserdetails = BeEF::Core::Models::BrowserDetails.where(
|
||||
:session_id => session_id,
|
||||
:detail_key => detail_key )
|
||||
if browserdetails.nil? || browserdetails.empty?
|
||||
:detail_key => detail_key ).first
|
||||
if browserdetails.nil?
|
||||
# store the new browser details key/value
|
||||
browserdetails = BeEF::Core::Models::BrowserDetails.new(
|
||||
:session_id => session_id,
|
||||
:detail_key => detail_key,
|
||||
:detail_value => detail_value || '')
|
||||
result = browserdetails.save
|
||||
result = browserdetails.save!
|
||||
else
|
||||
# update the browser details key/value
|
||||
result = browserdetails.update(:detail_value => detail_value || '')
|
||||
browserdetails.detail_value = detail_value || ''
|
||||
result = browserdetails.save!
|
||||
print_debug "Browser has updated '#{detail_key}' to '#{detail_value}'"
|
||||
end
|
||||
|
||||
|
||||
@@ -9,19 +9,11 @@ module Core
|
||||
module Models
|
||||
|
||||
# @note Table stores the commands that have been sent to the Hooked Browsers.
|
||||
class Command
|
||||
class Command < BeEF::Core::Model
|
||||
|
||||
include DataMapper::Resource
|
||||
|
||||
storage_names[:default] = 'commands'
|
||||
|
||||
property :id, Serial
|
||||
property :data, Text
|
||||
property :creationdate, String, :length => 15, :lazy => false
|
||||
property :label, Text, :lazy => false
|
||||
property :instructions_sent, Boolean, :default => false
|
||||
|
||||
has n, :results
|
||||
has_many :results
|
||||
has_one :command_module
|
||||
has_one :hooked_browser
|
||||
|
||||
#
|
||||
# Save results and flag that the command has been run on the hooked browser
|
||||
@@ -40,22 +32,22 @@ module Models
|
||||
raise TypeError, '"status" needs to be an integer' unless status.integer?
|
||||
|
||||
# @note get the hooked browser structure and id from the database
|
||||
hooked_browser = BeEF::Core::Models::HookedBrowser.first(:session => hook_session_id) || nil
|
||||
hooked_browser = BeEF::Core::Models::HookedBrowser.where(:session => hook_session_id).first || nil
|
||||
raise TypeError, "hooked_browser is nil" if hooked_browser.nil?
|
||||
raise TypeError, "hooked_browser.id is nil" if hooked_browser.id.nil?
|
||||
|
||||
# @note get the command module data structure from the database
|
||||
command = first(:id => command_id, :hooked_browser_id => hooked_browser.id) || nil
|
||||
command = self.where(:id => command_id, :hooked_browser_id => hooked_browser.id).first || nil
|
||||
raise TypeError, "command is nil" if command.nil?
|
||||
|
||||
# @note create the entry for the results
|
||||
command.results.new(
|
||||
BeEF::Core::Models::Result.create(
|
||||
:hooked_browser_id => hooked_browser.id,
|
||||
:command_id => command.id,
|
||||
:data => result.to_json,
|
||||
:status => status,
|
||||
:date => Time.now.to_i
|
||||
)
|
||||
command.save
|
||||
|
||||
s = show_status(status)
|
||||
log = "Hooked browser [id:#{hooked_browser.id}, ip:#{hooked_browser.ip}]"
|
||||
|
||||
@@ -7,22 +7,10 @@ module BeEF
|
||||
module Core
|
||||
module Models
|
||||
|
||||
class CommandModule
|
||||
class CommandModule < BeEF::Core::Model
|
||||
|
||||
include DataMapper::Resource
|
||||
has_many :commands
|
||||
|
||||
storage_names[:default] = 'core_commandmodules'
|
||||
|
||||
# @note command module ID
|
||||
property :id, Serial
|
||||
|
||||
# @note command module name
|
||||
property :name, Text, :lazy => false
|
||||
|
||||
# @note command module path
|
||||
property :path, Text, :lazy => false
|
||||
|
||||
has n, :commands
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
14
core/main/models/execution.rb
Normal file
14
core/main/models/execution.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 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 # @note Stored info about the execution of the ARE on hooked browsers.
|
||||
class Execution < BeEF::Core::Model
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -9,45 +9,11 @@ module Models
|
||||
#
|
||||
#
|
||||
#
|
||||
class HookedBrowser
|
||||
class HookedBrowser < BeEF::Core::Model
|
||||
|
||||
include DataMapper::Resource
|
||||
|
||||
storage_names[:default] = 'core_hookedbrowsers'
|
||||
|
||||
# @note zombie ID
|
||||
property :id, Serial
|
||||
|
||||
# @note hooked browser session ID
|
||||
property :session, Text, :lazy => false
|
||||
|
||||
# @note IP address of the hooked browser
|
||||
property :ip, Text, :lazy => false
|
||||
|
||||
# @note timestamp first time the browser communicated with BeEF
|
||||
property :firstseen, String, :length => 15
|
||||
|
||||
# @note timestamp last time the browser communicated with BeEF
|
||||
property :lastseen, String, :length => 15
|
||||
|
||||
# @note HTTP headers sent be the browser to the BeEF server upon first hook
|
||||
property :httpheaders, Text, :lazy => false
|
||||
|
||||
# @note the domain originating the hook request
|
||||
property :domain, Text, :lazy => false
|
||||
|
||||
# @note the port on the domain originating the hook request
|
||||
property :port, Integer, :default => 80
|
||||
|
||||
# @note number of times the zombie has polled
|
||||
property :count, Integer, :lazy => false
|
||||
|
||||
# @note if true the HB is used as a tunneling proxy
|
||||
property :is_proxy, Boolean, :default => false
|
||||
|
||||
has n, :commands
|
||||
has n, :results
|
||||
has n, :logs
|
||||
has_many :commands
|
||||
has_many :results
|
||||
has_many :logs
|
||||
|
||||
# @note Increases the count of a zombie
|
||||
def count!
|
||||
|
||||
@@ -7,17 +7,10 @@ module BeEF
|
||||
module Core
|
||||
module Models
|
||||
|
||||
class Log
|
||||
class Log < BeEF::Core::Model
|
||||
|
||||
include DataMapper::Resource
|
||||
has_one :hooked_browser
|
||||
|
||||
storage_names[:default] = 'core_logs'
|
||||
|
||||
property :id, Serial
|
||||
property :type, Text, :lazy => false
|
||||
property :event, Text, :lazy => false
|
||||
property :date, DateTime, :lazy => false
|
||||
property :hooked_browser_id, Text, :lazy => false
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -7,15 +7,7 @@ module BeEF
|
||||
module Core
|
||||
module Models
|
||||
|
||||
class OptionCache
|
||||
|
||||
include DataMapper::Resource
|
||||
|
||||
storage_names[:default] = 'core_optioncache'
|
||||
|
||||
property :id, Serial
|
||||
property :name, Text
|
||||
property :value, Text
|
||||
class OptionCache < BeEF::Core::Model
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -7,16 +7,10 @@ module BeEF
|
||||
module Core
|
||||
module Models
|
||||
|
||||
class Result
|
||||
class Result < BeEF::Core::Model
|
||||
|
||||
include DataMapper::Resource
|
||||
|
||||
storage_names[:default] = 'core_results'
|
||||
|
||||
property :id, Serial
|
||||
property :date, String, :length => 15, :lazy => false
|
||||
property :status, Integer
|
||||
property :data, Text
|
||||
has_one :command
|
||||
has_one :hooked_browser
|
||||
|
||||
end
|
||||
|
||||
|
||||
16
core/main/models/rule.rb
Normal file
16
core/main/models/rule.rb
Normal file
@@ -0,0 +1,16 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 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
|
||||
# @note Table stores the rules for the Distributed Engine.
|
||||
class Rule < BeEF::Core::Model
|
||||
has_many :executions
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -96,7 +96,7 @@ module BeEF
|
||||
print_debug "[WebSocket] New message: #{msg_hash}" if @@debug
|
||||
rescue => e
|
||||
print_error "[WebSocket] Failed parsing WebSocket message: #{e.message}"
|
||||
puts e.backtrace
|
||||
print_error e.backtrace
|
||||
next
|
||||
end
|
||||
|
||||
@@ -108,7 +108,7 @@ module BeEF
|
||||
print_debug("[WebSocket] activeSocket content [#{@@activeSocket}]")
|
||||
|
||||
hb_session = msg_hash["cookie"]
|
||||
hooked_browser = BeEF::Core::Models::HookedBrowser.first(:session => hb_session)
|
||||
hooked_browser = BeEF::Core::Models::HookedBrowser.where(:session => hb_session).first
|
||||
if hooked_browser.nil?
|
||||
print_error '[WebSocket] Fingerprinting not finished yet.'
|
||||
print_more 'ARE rules were not triggered. You may want to trigger them manually via REST API.'
|
||||
@@ -126,7 +126,7 @@ module BeEF
|
||||
|
||||
# polling zombie
|
||||
unless msg_hash['alive'].nil?
|
||||
hooked_browser = BeEF::Core::Models::HookedBrowser.first(:session => msg_hash["alive"])
|
||||
hooked_browser = BeEF::Core::Models::HookedBrowser.where(:session => msg_hash["alive"]).first
|
||||
|
||||
# This will happen if you reset BeEF database (./beef -x),
|
||||
# and existing zombies try to connect. These zombies will be ignored,
|
||||
@@ -141,15 +141,15 @@ module BeEF
|
||||
|
||||
hooked_browser.lastseen = Time.new.to_i
|
||||
hooked_browser.count!
|
||||
hooked_browser.save
|
||||
hooked_browser.save!
|
||||
|
||||
# Check if new modules need to be sent
|
||||
zombie_commands = BeEF::Core::Models::Command.all(:hooked_browser_id => hooked_browser.id, :instructions_sent => false)
|
||||
zombie_commands = BeEF::Core::Models::Command.where(:hooked_browser_id => hooked_browser.id, :instructions_sent => false)
|
||||
zombie_commands.each { |command| add_command_instructions(command, hooked_browser) }
|
||||
|
||||
# Check if there are any ARE rules to be triggered. If is_sent=false rules are triggered
|
||||
are_body = ''
|
||||
are_executions = BeEF::Core::AutorunEngine::Models::Execution.all(:is_sent => false, :session => hooked_browser.session)
|
||||
are_executions = BeEF::Core::Models::Execution.where(:is_sent => false, :session => hooked_browser.session)
|
||||
are_executions.each do |are_exec|
|
||||
are_body += are_exec.mod_body
|
||||
are_exec.update(:is_sent => true, :exec_time => Time.new.to_i)
|
||||
|
||||
@@ -70,15 +70,20 @@ module BeEF
|
||||
# This is from extensions/admin_ui/controllers/authentication/authentication.rb
|
||||
#
|
||||
def self.permitted_source?(ip)
|
||||
# get permitted subnet
|
||||
# test if supplied IP address is valid
|
||||
return false unless BeEF::Filters::is_valid_ip?(ip)
|
||||
|
||||
# get permitted subnets
|
||||
permitted_ui_subnet = BeEF::Core::Configuration.instance.get("beef.restrictions.permitted_ui_subnet")
|
||||
target_network = IPAddr.new(permitted_ui_subnet)
|
||||
return false if permitted_ui_subnet.nil?
|
||||
return false if permitted_ui_subnet.empty?
|
||||
|
||||
# test if supplied IP address is valid dot-decimal format
|
||||
return false unless ip =~ /\A[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\z/
|
||||
# test if ip within subnets
|
||||
permitted_ui_subnet.each do |subnet|
|
||||
return true if IPAddr.new(subnet).include?(ip)
|
||||
end
|
||||
|
||||
# test if ip within subnet
|
||||
return target_network.include?(ip)
|
||||
false
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
@@ -38,7 +38,7 @@ module BeEF
|
||||
get '/rule/delete/:rule_id' do
|
||||
begin
|
||||
rule_id = params[:rule_id]
|
||||
rule = BeEF::Core::AutorunEngine::Models::Rule.get(rule_id)
|
||||
rule = BeEF::Core::AutorunEngine::Models::Rule.find(rule_id)
|
||||
rule.destroy
|
||||
{ 'success' => true}.to_json
|
||||
rescue => e
|
||||
@@ -53,7 +53,7 @@ module BeEF
|
||||
begin
|
||||
rule_id = params[:rule_id]
|
||||
|
||||
online_hooks = BeEF::Core::Models::HookedBrowser.all(:lastseen.gte => (Time.new.to_i - 15))
|
||||
online_hooks = BeEF::Core::Models::HookedBrowser.where('lastseen >= ?', (Time.new.to_i - 15))
|
||||
are = BeEF::Core::AutorunEngine::Engine.instance
|
||||
|
||||
if online_hooks != nil
|
||||
|
||||
@@ -24,10 +24,10 @@ module BeEF
|
||||
# @note Get all browser details for the specified session
|
||||
#
|
||||
get '/:session' do
|
||||
hb = BeEF::Core::Models::HookedBrowser.first(:session => params[:session])
|
||||
hb = BeEF::Core::Models::HookedBrowser.where(:session => params[:session]).first
|
||||
error 404 if hb.nil?
|
||||
|
||||
details = BeEF::Core::Models::BrowserDetails.all(:session_id => hb.session)
|
||||
details = BeEF::Core::Models::BrowserDetails.where(:session_id => hb.session)
|
||||
error 404 if details.nil?
|
||||
|
||||
result = []
|
||||
|
||||
@@ -24,8 +24,8 @@ module BeEF
|
||||
# @note Get online and offline hooked browsers details (like name, version, os, ip, port, ...)
|
||||
#
|
||||
get '/' do
|
||||
online_hooks = hb_to_json(BeEF::Core::Models::HookedBrowser.all(:lastseen.gte => (Time.new.to_i - 15)))
|
||||
offline_hooks = hb_to_json(BeEF::Core::Models::HookedBrowser.all(:lastseen.lt => (Time.new.to_i - 15)))
|
||||
online_hooks = hb_to_json(BeEF::Core::Models::HookedBrowser.where('lastseen >= ?', (Time.new.to_i - 15)))
|
||||
offline_hooks = hb_to_json(BeEF::Core::Models::HookedBrowser.where('lastseen <= ?', (Time.new.to_i - 15)))
|
||||
|
||||
output = {
|
||||
'hooked-browsers' => {
|
||||
@@ -37,33 +37,33 @@ module BeEF
|
||||
end
|
||||
|
||||
get '/:session/delete' do
|
||||
hb = BeEF::Core::Models::HookedBrowser.first(:session => params[:session])
|
||||
hb = BeEF::Core::Models::HookedBrowser.where(:session => params[:session]).first
|
||||
error 401 unless hb != nil
|
||||
|
||||
details = BeEF::Core::Models::BrowserDetails.all(:session_id => hb.session)
|
||||
details = BeEF::Core::Models::BrowserDetails.where(:session_id => hb.session)
|
||||
details.destroy
|
||||
|
||||
logs = BeEF::Core::Models::Log.all(:hooked_browser_id => hb.id)
|
||||
logs = BeEF::Core::Models::Log.where(:hooked_browser_id => hb.id)
|
||||
logs.destroy
|
||||
|
||||
commands = BeEF::Core::Models::Command.all(:hooked_browser_id => hb.id)
|
||||
commands = BeEF::Core::Models::Command.where(:hooked_browser_id => hb.id)
|
||||
commands.destroy
|
||||
|
||||
results = BeEF::Core::Models::Result.all(:hooked_browser_id => hb.id)
|
||||
results = BeEF::Core::Models::Result.where(:hooked_browser_id => hb.id)
|
||||
results.destroy
|
||||
|
||||
begin
|
||||
requester = BeEF::Core::Models::Http.all(:hooked_browser_id => hb.id)
|
||||
requester = BeEF::Core::Models::Http.where(:hooked_browser_id => hb.id)
|
||||
requester.destroy
|
||||
rescue => e
|
||||
#the requester module may not be enabled
|
||||
end
|
||||
|
||||
begin
|
||||
xssraysscans = BeEF::Core::Models::Xssraysscan.all(:hooked_browser_id => hb.id)
|
||||
xssraysscans = BeEF::Core::Models::Xssraysscan.where(:hooked_browser_id => hb.id)
|
||||
xssraysscans.destroy
|
||||
|
||||
xssraysdetails = BeEF::Core::Models::Xssraysdetail.all(:hooked_browser_id => hb.id)
|
||||
xssraysdetails = BeEF::Core::Models::Xssraysdetail.where(:hooked_browser_id => hb.id)
|
||||
xssraysdetails.destroy
|
||||
rescue => e
|
||||
#the xssraysscan module may not be enabled
|
||||
@@ -96,7 +96,7 @@ module BeEF
|
||||
# Useful if you need to query the API via jQuery.dataTable < 1.10 which is currently used in PhishingFrenzy
|
||||
#
|
||||
get '/pf/online' do
|
||||
online_hooks = hbs_to_array(BeEF::Core::Models::HookedBrowser.all(:lastseen.gte => (Time.new.to_i - 15)))
|
||||
online_hooks = hbs_to_array(BeEF::Core::Models::HookedBrowser.where('lastseen >= ?', (Time.new.to_i - 15)))
|
||||
|
||||
output = {
|
||||
'aaData' => online_hooks
|
||||
@@ -109,7 +109,7 @@ module BeEF
|
||||
# Useful if you need to query the API via jQuery.dataTable < 1.10 which is currently used in PhishingFrenzy
|
||||
#
|
||||
get '/pf/offline' do
|
||||
offline_hooks = hbs_to_array(BeEF::Core::Models::HookedBrowser.all(:lastseen.lt => (Time.new.to_i - 15)))
|
||||
offline_hooks = hbs_to_array(BeEF::Core::Models::HookedBrowser.where('lastseen <= ?', (Time.new.to_i - 15)))
|
||||
|
||||
output = {
|
||||
'aaData' => offline_hooks
|
||||
@@ -121,10 +121,10 @@ module BeEF
|
||||
# @note Get all the hooked browser details (plugins enabled, technologies enabled, cookies)
|
||||
#
|
||||
get '/:session' do
|
||||
hb = BeEF::Core::Models::HookedBrowser.first(:session => params[:session])
|
||||
hb = BeEF::Core::Models::HookedBrowser.where(:session => params[:session]).first
|
||||
error 401 unless hb != nil
|
||||
|
||||
details = BeEF::Core::Models::BrowserDetails.all(:session_id => hb.session)
|
||||
details = BeEF::Core::Models::BrowserDetails.where(:session_id => hb.session)
|
||||
result = {}
|
||||
details.each do |property|
|
||||
result[property.detail_key] = property.detail_value
|
||||
@@ -140,16 +140,16 @@ module BeEF
|
||||
os_version = body['os_version']
|
||||
arch = body['arch']
|
||||
|
||||
hb = BeEF::Core::Models::HookedBrowser.first(:session => params[:session])
|
||||
hb = BeEF::Core::Models::HookedBrowser.where(:session => params[:session]).first
|
||||
error 401 unless hb != nil
|
||||
|
||||
BeEF::Core::Models::BrowserDetails.first(:session_id => hb.session, :detail_key => 'host.os.name').destroy
|
||||
BeEF::Core::Models::BrowserDetails.first(:session_id => hb.session, :detail_key => 'host.os.version').destroy
|
||||
BeEF::Core::Models::BrowserDetails.where(:session_id => hb.session, :detail_key => 'host.os.name').destroy
|
||||
BeEF::Core::Models::BrowserDetails.where(:session_id => hb.session, :detail_key => 'host.os.version').destroy
|
||||
#BeEF::Core::Models::BrowserDetails.first(:session_id => hb.session, :detail_key => 'Arch').destroy
|
||||
|
||||
BeEF::Core::Models::BrowserDetails.new(:session_id => hb.session, :detail_key => 'host.os.name', :detail_value => os).save
|
||||
BeEF::Core::Models::BrowserDetails.new(:session_id => hb.session, :detail_key => 'host.os.version', :detail_value => os_version).save
|
||||
BeEF::Core::Models::BrowserDetails.new(:session_id => hb.session, :detail_key => 'Arch', :detail_value => arch).save
|
||||
BeEF::Core::Models::BrowserDetails.create(:session_id => hb.session, :detail_key => 'host.os.name', :detail_value => os)
|
||||
BeEF::Core::Models::BrowserDetails.create(:session_id => hb.session, :detail_key => 'host.os.version', :detail_value => os_version)
|
||||
BeEF::Core::Models::BrowserDetails.create(:session_id => hb.session, :detail_key => 'Arch', :detail_value => arch)
|
||||
|
||||
# TODO if there where any ARE rules defined for this hooked browser,
|
||||
# after updating OS/arch, force a retrigger of the rule.
|
||||
|
||||
@@ -24,7 +24,7 @@ module BeEF
|
||||
# @note Get all global logs
|
||||
#
|
||||
get '/' do
|
||||
logs = BeEF::Core::Models::Log.all()
|
||||
logs = BeEF::Core::Models::Log.all
|
||||
logs_to_json(logs)
|
||||
end
|
||||
|
||||
@@ -44,10 +44,10 @@ module BeEF
|
||||
# @note Get hooked browser logs
|
||||
#
|
||||
get '/:session' do
|
||||
hb = BeEF::Core::Models::HookedBrowser.first(:session => params[:session])
|
||||
hb = BeEF::Core::Models::HookedBrowser.where(:session => params[:session]).first
|
||||
error 401 unless hb != nil
|
||||
|
||||
logs = BeEF::Core::Models::Log.all(:hooked_browser_id => hb.id)
|
||||
logs = BeEF::Core::Models::Log.where(:hooked_browser_id => hb.id)
|
||||
logs_to_json(logs)
|
||||
end
|
||||
|
||||
@@ -62,7 +62,7 @@ module BeEF
|
||||
'id' => log.id.to_i,
|
||||
'date' => log.date.to_s,
|
||||
'event' => log.event.to_s,
|
||||
'type' => log.type.to_s,
|
||||
'logtype' => log.logtype.to_s,
|
||||
'hooked_browser_id' => log.hooked_browser_id.to_s
|
||||
}
|
||||
end
|
||||
@@ -84,7 +84,7 @@ module BeEF
|
||||
logs.reverse.each do |log|
|
||||
maker.items.new_item do |item|
|
||||
item.id = log.id.to_s
|
||||
item.title = "[#{log.type}] #{log.event}"
|
||||
item.title = "[#{log.logtype}] #{log.event}"
|
||||
item.updated = log.date.to_s
|
||||
end
|
||||
end
|
||||
|
||||
@@ -43,7 +43,7 @@ module BeEF
|
||||
end
|
||||
|
||||
get '/search/:mod_name' do
|
||||
mod = BeEF::Core::Models::CommandModule.first(:name => params[:mod_name])
|
||||
mod = BeEF::Core::Models::CommandModule.where(:name => params[:mod_name]).first
|
||||
result = {}
|
||||
if mod != nil
|
||||
result = {'id' => mod.id}
|
||||
@@ -55,7 +55,7 @@ module BeEF
|
||||
# @note Get the module definition (info, options)
|
||||
#
|
||||
get '/:mod_id' do
|
||||
cmd = BeEF::Core::Models::CommandModule.get(params[:mod_id])
|
||||
cmd = BeEF::Core::Models::CommandModule.find(params[:mod_id])
|
||||
error 404 unless cmd != nil
|
||||
modk = BeEF::Module.get_key_by_database_id(params[:mod_id])
|
||||
error 404 unless modk != nil
|
||||
@@ -81,12 +81,12 @@ module BeEF
|
||||
#{"date":"1331637093","data":"{\"data\":\"text=michele\"}"}
|
||||
#
|
||||
get '/:session/:mod_id/:cmd_id' do
|
||||
hb = BeEF::Core::Models::HookedBrowser.first(:session => params[:session])
|
||||
hb = BeEF::Core::Models::HookedBrowser.where(:session => params[:session]).first
|
||||
error 401 unless hb != nil
|
||||
cmd = BeEF::Core::Models::Command.first(:hooked_browser_id => hb.id,
|
||||
:command_module_id => params[:mod_id], :id => params[:cmd_id])
|
||||
cmd = BeEF::Core::Models::Command.where(:hooked_browser_id => hb.id,
|
||||
:command_module_id => params[:mod_id], :id => params[:cmd_id]).first
|
||||
error 404 unless cmd != nil
|
||||
results = BeEF::Core::Models::Result.all(:hooked_browser_id => hb.id, :command_id => cmd.id)
|
||||
results = BeEF::Core::Models::Result.where(:hooked_browser_id => hb.id, :command_id => cmd.id)
|
||||
error 404 unless results != nil
|
||||
|
||||
results_hash = {}
|
||||
@@ -137,7 +137,7 @@ module BeEF
|
||||
#{"success":"true","command_id":"not_available"}
|
||||
#
|
||||
post '/:session/:mod_id' do
|
||||
hb = BeEF::Core::Models::HookedBrowser.first(:session => params[:session])
|
||||
hb = BeEF::Core::Models::HookedBrowser.where(:session => params[:session]).first
|
||||
error 401 unless hb != nil
|
||||
modk = BeEF::Module.get_key_by_database_id(params[:mod_id])
|
||||
error 404 unless modk != nil
|
||||
@@ -198,7 +198,7 @@ module BeEF
|
||||
# run on all hooked browsers currently online?
|
||||
if hb_ids.first =~ /\Aall_online\z/i
|
||||
hb_ids = []
|
||||
BeEF::Core::Models::HookedBrowser.all(
|
||||
BeEF::Core::Models::HookedBrowser.where(
|
||||
:lastseen.gte => (Time.new.to_i - 15)).each {|hb| hb_ids << hb.id }
|
||||
# run on all hooked browsers?
|
||||
elsif hb_ids.first =~ /\Aall\z/i
|
||||
@@ -208,7 +208,7 @@ module BeEF
|
||||
|
||||
# run modules
|
||||
hb_ids.each do |hb_id|
|
||||
hb = BeEF::Core::Models::HookedBrowser.first(:id => hb_id)
|
||||
hb = BeEF::Core::Models::HookedBrowser.find(hb_id)
|
||||
if hb == nil
|
||||
results[hb_id] = 0
|
||||
next
|
||||
@@ -256,7 +256,7 @@ module BeEF
|
||||
request.body.rewind
|
||||
begin
|
||||
body = JSON.parse request.body.read
|
||||
hb = BeEF::Core::Models::HookedBrowser.first(:session => body["hb"])
|
||||
hb = BeEF::Core::Models::HookedBrowser.where(:session => body["hb"]).first
|
||||
error 401 unless hb != nil
|
||||
|
||||
results = Hash.new
|
||||
|
||||
@@ -154,7 +154,7 @@ module BeEF
|
||||
end
|
||||
rescue => e
|
||||
print_error "Failed to prepare HTTP server: #{e.message}"
|
||||
puts e.backtrace
|
||||
print_error e.backtrace
|
||||
exit 1
|
||||
end
|
||||
|
||||
@@ -162,7 +162,9 @@ module BeEF
|
||||
# Starts the BeEF http server
|
||||
#
|
||||
def start
|
||||
@http_server.start
|
||||
@http_server.start do
|
||||
use OTR::ActiveRecord::ConnectionManagement
|
||||
end
|
||||
rescue RuntimeError => e
|
||||
# port is in use
|
||||
raise unless e.message.include? 'no acceptor'
|
||||
|
||||
@@ -48,7 +48,7 @@ module BeEF
|
||||
# Get all modules currently stored in the database
|
||||
# @return [Array] DataMapper array of all BeEF::Core::Models::CommandModule's in the database
|
||||
def self.get_stored_in_db
|
||||
BeEF::Core::Models::CommandModule.all(:order => [:id.asc])
|
||||
BeEF::Core::Models::CommandModule.all.order(:id)
|
||||
end
|
||||
|
||||
# Loads all enabled modules
|
||||
|
||||
@@ -14,6 +14,3 @@ require 'core/ruby/string'
|
||||
require 'core/ruby/print'
|
||||
require 'core/ruby/hash'
|
||||
|
||||
# @note Patching DataMapper Data Objects Adapter (dm-do-adapter)
|
||||
require 'core/ruby/patches/dm-do-adapter/adapter.rb'
|
||||
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
|
||||
# @note The following file contains patches for DataMapper Data Objects Adapter (dm-do-adapter)
|
||||
# This patch fixes the following error:
|
||||
# DataObjects::URI.new with arguments is deprecated, use a Hash of URI components (/home/username/.rvm/gems/ruby-1.9.2-p290/gems/dm-do-adapter-1.1.0/lib/dm-do-adapter/adapter.rb:231:in `new')
|
||||
# The error is patched in dm-do-adapter 1.1.1 however it has yet to be released.
|
||||
# Patch: https://github.com/datamapper/dm-do-adapter/commit/7f0b53d1ada8735910e04ff37d60c6ff037ce288
|
||||
|
||||
=begin
|
||||
Deleted:
|
||||
< DataObjects::URI.new(
|
||||
< @options[:adapter],
|
||||
< @options[:user] || @options[:username],
|
||||
< @options[:password],
|
||||
< @options[:host],
|
||||
< port,
|
||||
< @options[:path] || @options[:database],
|
||||
< query,
|
||||
< @options[:fragment]
|
||||
< ).freeze
|
||||
|
||||
Added:
|
||||
> DataObjects::URI.new({
|
||||
> :scheme => @options[:adapter],
|
||||
> :user => @options[:user] || @options[:username],
|
||||
> :password => @options[:password],
|
||||
> :host => @options[:host],
|
||||
> :port => port,
|
||||
> :path => @options[:path] || @options[:database],
|
||||
> :query => query,
|
||||
> :fragment => @options[:fragment]
|
||||
> }).freeze
|
||||
=end
|
||||
|
||||
require 'dm-do-adapter'
|
||||
|
||||
module DataMapper
|
||||
module Adapters
|
||||
class DataObjectsAdapter < AbstractAdapter
|
||||
|
||||
def normalized_uri
|
||||
@normalized_uri ||=
|
||||
begin
|
||||
keys = [
|
||||
:adapter, :user, :password, :host, :port, :path, :fragment,
|
||||
:scheme, :query, :username, :database ]
|
||||
query = DataMapper::Ext::Hash.except(@options, keys)
|
||||
query = nil if query.empty?
|
||||
|
||||
# Better error message in case port is no Numeric value
|
||||
port = @options[:port].nil? ? nil : @options[:port].to_int
|
||||
|
||||
DataObjects::URI.new({
|
||||
:scheme => @options[:adapter],
|
||||
:user => @options[:user] || @options[:username],
|
||||
:password => @options[:password],
|
||||
:host => @options[:host],
|
||||
:port => port,
|
||||
:path => @options[:path] || @options[:database],
|
||||
:query => query,
|
||||
:fragment => @options[:fragment]
|
||||
}).freeze
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -7,13 +7,15 @@
|
||||
# Function used to print errors to the console
|
||||
# @param [String] s String to be printed
|
||||
def print_error(s)
|
||||
puts Time.now.localtime.strftime("[%k:%M:%S]")+'[!]'.red+' '+s
|
||||
puts Time.now.localtime.strftime("[%k:%M:%S]")+'[!]'+' '+s.to_s
|
||||
BeEF.logger.error s.to_s
|
||||
end
|
||||
|
||||
# Function used to print information to the console
|
||||
# @param [String] s String to be printed
|
||||
def print_info(s)
|
||||
puts Time.now.localtime.strftime("[%k:%M:%S]")+'[*]'.blue+' '+s
|
||||
puts Time.now.localtime.strftime("[%k:%M:%S]")+'[*]'+' '+s.to_s
|
||||
BeEF.logger.info s.to_s
|
||||
end
|
||||
|
||||
# Function used to print information to the console (wraps print_info)
|
||||
@@ -25,7 +27,8 @@ end
|
||||
# Function used to print warning information
|
||||
# @param [String] s String to be printed
|
||||
def print_warning(s)
|
||||
puts Time.now.localtime.strftime("[%k:%M:%S]")+'[!]'.yellow+' '+s.to_s
|
||||
puts Time.now.localtime.strftime("[%k:%M:%S]")+'[!]'+' '+s.to_s
|
||||
BeEF.logger.warn s.to_s
|
||||
end
|
||||
|
||||
# Function used to print debug information
|
||||
@@ -34,14 +37,16 @@ end
|
||||
def print_debug(s)
|
||||
config = BeEF::Core::Configuration.instance
|
||||
if config.get('beef.debug') || BeEF::Core::Console::CommandLine.parse[:verbose]
|
||||
puts Time.now.localtime.strftime("[%k:%M:%S]")+'[>]'.yellow+' '+s.to_s
|
||||
puts Time.now.localtime.strftime("[%k:%M:%S]")+'[>]'+' '+s.to_s
|
||||
BeEF.logger.debug s.to_s
|
||||
end
|
||||
end
|
||||
|
||||
# Function used to print successes to the console
|
||||
# @param [String] s String to be printed
|
||||
def print_success(s)
|
||||
puts Time.now.localtime.strftime("[%k:%M:%S]")+'[+]'.green+' '+s
|
||||
puts Time.now.localtime.strftime("[%k:%M:%S]")+'[+]'+' '+s.to_s
|
||||
BeEF.logger.info s.to_s
|
||||
end
|
||||
|
||||
# Function used to print successes to the console (wraps print_success)
|
||||
@@ -65,8 +70,10 @@ def print_more(s)
|
||||
lines.each_with_index do |line, index|
|
||||
if ((index+1) == lines.size)
|
||||
puts "#{time} |_ #{line}"
|
||||
BeEF.logger.info "#{time} |_ #{line}"
|
||||
else
|
||||
puts "#{time} | #{line}"
|
||||
BeEF.logger.info "#{time} | #{line}"
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -77,4 +84,5 @@ end
|
||||
def print_over(s)
|
||||
time = Time.now.localtime.strftime("[%k:%M:%S]")
|
||||
print "\r#{time}"+"[*]".blue+" #{s}"
|
||||
BeEF.logger.info s.to_s
|
||||
end
|
||||
|
||||
@@ -43,7 +43,7 @@ module API
|
||||
File.path write_to
|
||||
rescue => e
|
||||
print_error "[AdminUI] Error: #{e.message}"
|
||||
puts e.backtrace
|
||||
print_error e.backtrace
|
||||
end
|
||||
|
||||
def self.build_javascript_ui(beef_server)
|
||||
|
||||
@@ -81,7 +81,7 @@ module AdminUI
|
||||
end
|
||||
rescue => e
|
||||
print_error "Error handling HTTP request: #{e.message}"
|
||||
puts e.backtrace
|
||||
print_error e.backtrace
|
||||
end
|
||||
|
||||
# Constructs a html script tag (from media/javascript directory)
|
||||
|
||||
@@ -47,8 +47,8 @@ class Authentication < BeEF::Extension::AdminUI::HttpController
|
||||
ua_ip = @request.ip # get client ip address
|
||||
@body = '{ success : false }' # attempt to fail closed
|
||||
|
||||
# check if source IP address is permited to authenticate
|
||||
if not permited_source?(ua_ip)
|
||||
# check if source IP address is permitted to authenticate
|
||||
if not permitted_source?(ua_ip)
|
||||
BeEF::Core::Logger.instance.register('Authentication', "IP source address (#{@request.ip}) attempted to authenticate but is not within permitted subnet.")
|
||||
return
|
||||
end
|
||||
@@ -105,19 +105,22 @@ class Authentication < BeEF::Extension::AdminUI::HttpController
|
||||
#
|
||||
# Check the UI browser source IP is within the permitted subnet
|
||||
#
|
||||
def permited_source?(ip)
|
||||
# get permitted subnet
|
||||
config = BeEF::Core::Configuration.instance
|
||||
permitted_ui_subnet = config.get('beef.restrictions.permitted_ui_subnet')
|
||||
target_network = IPAddr.new(permitted_ui_subnet)
|
||||
# test if supplied IP address is valid dot-decimal format
|
||||
return false unless ip =~ /\A[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\z/
|
||||
# test if ip within subnet
|
||||
return target_network.include?(ip)
|
||||
def permitted_source?(ip)
|
||||
# test if supplied IP address is valid
|
||||
return false unless BeEF::Filters::is_valid_ip?(ip)
|
||||
|
||||
# get permitted subnets
|
||||
permitted_ui_subnet = BeEF::Core::Configuration.instance.get("beef.restrictions.permitted_ui_subnet")
|
||||
return false if permitted_ui_subnet.nil?
|
||||
return false if permitted_ui_subnet.empty?
|
||||
|
||||
# test if ip within subnets
|
||||
permitted_ui_subnet.each do |subnet|
|
||||
return true if IPAddr.new(subnet).include?(ip)
|
||||
end
|
||||
|
||||
|
||||
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -225,10 +225,10 @@ class Modules < BeEF::Extension::AdminUI::HttpController
|
||||
|
||||
# if dynamic modules are found in the DB, then we don't have yaml config for them
|
||||
# and loading must proceed in a different way.
|
||||
dynamic_modules = BeEF::Core::Models::CommandModule.all(:path.like => "Dynamic/")
|
||||
dynamic_modules = BeEF::Core::Models::CommandModule.where('path LIKE ?', 'Dynamic/')
|
||||
|
||||
if(dynamic_modules != nil)
|
||||
all_modules = BeEF::Core::Models::CommandModule.all(:order => [:id.asc])
|
||||
all_modules = BeEF::Core::Models::CommandModule.all.order(:id)
|
||||
all_modules.each{|dyn_mod|
|
||||
next if !dyn_mod.path.split('/')[1].match(/^metasploit/)
|
||||
command_mod_name = dyn_mod["name"]
|
||||
@@ -257,7 +257,7 @@ class Modules < BeEF::Extension::AdminUI::HttpController
|
||||
def select_command_module
|
||||
command_module_id = @params['command_module_id'] || nil
|
||||
(print_error "command_module_id is nil";return) if command_module_id.nil?
|
||||
command_module = BeEF::Core::Models::CommandModule.get(command_module_id)
|
||||
command_module = BeEF::Core::Models::CommandModule.find(command_module_id)
|
||||
key = BeEF::Module.get_key_by_database_id(command_module_id)
|
||||
|
||||
payload_name = @params['payload_name'] || nil
|
||||
@@ -284,12 +284,12 @@ class Modules < BeEF::Extension::AdminUI::HttpController
|
||||
(print_error "nonce incorrect";return) if @session.get_nonce != nonce
|
||||
|
||||
# get the browser id
|
||||
zombie = Z.first(:session => zombie_session)
|
||||
zombie = Z.where(:session => zombie_session).first
|
||||
(print_error "Zombie is nil";return) if zombie.nil?
|
||||
zombie_id = zombie.id
|
||||
(print_error "Zombie id is nil";return) if zombie_id.nil?
|
||||
|
||||
C.all(:command_module_id => command_module_id, :hooked_browser_id => zombie_id).each do |command|
|
||||
C.where(:command_module_id => command_module_id, :hooked_browser_id => zombie_id).each do |command|
|
||||
commands.push({
|
||||
'id' => i,
|
||||
'object_id' => command.id,
|
||||
@@ -346,7 +346,7 @@ class Modules < BeEF::Extension::AdminUI::HttpController
|
||||
# get params
|
||||
command_id = @params['command_id'] || nil
|
||||
(print_error "Command id is nil";return) if command_id.nil?
|
||||
command = BeEF::Core::Models::Command.first(:id => command_id.to_i) || nil
|
||||
command = BeEF::Core::Models::Command.find(command_id.to_i) || nil
|
||||
(print_error "Command is nil";return) if command.nil?
|
||||
# validate nonce
|
||||
nonce = @params['nonce'] || nil
|
||||
@@ -382,11 +382,11 @@ class Modules < BeEF::Extension::AdminUI::HttpController
|
||||
oc.save
|
||||
}
|
||||
|
||||
zombie = Z.first(:session => zombie_session)
|
||||
zombie = Z.where(:session => zombie_session).first
|
||||
(print_error "Zombie is nil";return) if zombie.nil?
|
||||
zombie_id = zombie.id
|
||||
(print_error "Zombie id is nil";return) if zombie_id.nil?
|
||||
command_module = BeEF::Core::Models::CommandModule.get(command_module_id)
|
||||
command_module = BeEF::Core::Models::CommandModule.find(command_module_id)
|
||||
|
||||
if(command_module != nil && command_module.path.match(/^Dynamic/))
|
||||
dyn_mod_name = command_module.path.split('/').last
|
||||
@@ -423,14 +423,14 @@ class Modules < BeEF::Extension::AdminUI::HttpController
|
||||
# get params
|
||||
command_id = @params['command_id']|| nil
|
||||
(print_error "Command id is nil";return) if command_id.nil?
|
||||
command = BeEF::Core::Models::Command.first(:id => command_id.to_i) || nil
|
||||
command = BeEF::Core::Models::Command.find(command_id.to_i) || nil
|
||||
(print_error "Command is nil";return) if command.nil?
|
||||
|
||||
# get command_module
|
||||
command_module = BeEF::Core::Models::CommandModule.first(:id => command.command_module_id)
|
||||
command_module = BeEF::Core::Models::CommandModule.find(command.command_module_id)
|
||||
(print_error "command_module is nil";return) if command_module.nil?
|
||||
|
||||
resultsdb = BeEF::Core::Models::Result.all(:command_id => command_id)
|
||||
resultsdb = BeEF::Core::Models::Result.where(:command_id => command_id)
|
||||
(print_error "Command id result is nil";return) if resultsdb.nil?
|
||||
|
||||
resultsdb.each{ |result| results.push({'date' => result.date, 'data' => JSON.parse(result.data)}) }
|
||||
@@ -450,10 +450,10 @@ class Modules < BeEF::Extension::AdminUI::HttpController
|
||||
# get params
|
||||
command_id = @params['command_id'] || nil
|
||||
(print_error "Command id is nil";return) if command_id.nil?
|
||||
command = BeEF::Core::Models::Command.first(:id => command_id.to_i) || nil
|
||||
command = BeEF::Core::Models::Command.find(command_id.to_i) || nil
|
||||
(print_error "Command is nil";return) if command.nil?
|
||||
|
||||
command_module = BeEF::Core::Models::CommandModule.get(command.command_module_id)
|
||||
command_module = BeEF::Core::Models::CommandModule.find(command.command_module_id)
|
||||
(print_error "command_module is nil";return) if command_module.nil?
|
||||
|
||||
if(command_module.path.split('/').first.match(/^Dynamic/))
|
||||
@@ -503,7 +503,7 @@ class Modules < BeEF::Extension::AdminUI::HttpController
|
||||
def dynamic_modules2json(id)
|
||||
command_modules_json = {}
|
||||
|
||||
mod = BeEF::Core::Models::CommandModule.first(:id => id)
|
||||
mod = BeEF::Core::Models::CommandModule.find(id)
|
||||
|
||||
# if the module id is not in the database return false
|
||||
return {'success' => 'false'}.to_json if(not mod)
|
||||
@@ -525,7 +525,7 @@ class Modules < BeEF::Extension::AdminUI::HttpController
|
||||
def dynamic_payload2json(id, payload_name)
|
||||
command_modules_json = {}
|
||||
|
||||
command_module = BeEF::Core::Models::CommandModule.get(id)
|
||||
command_module = BeEF::Core::Models::CommandModule.find(id)
|
||||
(print_error "Module does not exists";return 'success' => 'false') if command_module.nil?
|
||||
|
||||
payload_options = BeEF::Module.get_payload_options(command_module.name,payload_name)
|
||||
|
||||
@@ -7,14 +7,7 @@ module BeEF
|
||||
module Core
|
||||
module Models
|
||||
|
||||
class Autoloading
|
||||
|
||||
include DataMapper::Resource
|
||||
|
||||
storage_names[:default] = 'autoloading'
|
||||
|
||||
property :id, Serial
|
||||
property :in_use, Boolean
|
||||
class Autoloading < BeEF::Core::Model
|
||||
|
||||
belongs_to :command
|
||||
|
||||
|
||||
@@ -15,6 +15,18 @@ module Console
|
||||
@short_name = @full_name = 'console'
|
||||
@description = 'console environment to manage beef'
|
||||
|
||||
module PostLoad
|
||||
BeEF::API::Registrar.instance.register(BeEF::Extension::Console::PostLoad, BeEF::API::Extensions, 'post_load')
|
||||
|
||||
def self.post_load
|
||||
if BeEF::Core::Configuration.instance.get("beef.extension.console.enable")
|
||||
print_error "The console extension is currently unsupported."
|
||||
print_more "See issue #1090 - https://github.com/beefproject/beef/issues/1090"
|
||||
BeEF::Core::Configuration.instance.set('beef.extension.console.enable', false)
|
||||
BeEF::Core::Configuration.instance.set('beef.extension.console.loaded', false)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -150,7 +150,7 @@ class Core
|
||||
'Hardware'
|
||||
])
|
||||
|
||||
BeEF::Core::Models::HookedBrowser.all(:lastseen.gte => (Time.new.to_i - 30)).each do |zombie|
|
||||
BeEF::Core::Models::HookedBrowser.where('lastseen >= ?', (Time.new.to_i - 30)).each do |zombie|
|
||||
tbl << [zombie.id,zombie.ip,BeEF::Core::Models::BrowserDetails.get(zombie.session,"HostName").to_s,BeEF::Core::Models::BrowserDetails.get(zombie.session, 'BrowserName').to_s+"-"+BeEF::Core::Models::BrowserDetails.get(zombie.session, 'BrowserVersion').to_s,BeEF::Core::Models::BrowserDetails.get(zombie.session, 'OsName'),BeEF::Core::Models::BrowserDetails.get(zombie.session, 'Hardware')]
|
||||
end
|
||||
|
||||
@@ -184,7 +184,7 @@ class Core
|
||||
'Hardware'
|
||||
])
|
||||
|
||||
BeEF::Core::Models::HookedBrowser.all(:lastseen.lt => (Time.new.to_i - 30)).each do |zombie|
|
||||
BeEF::Core::Models::HookedBrowser.where('lastseen < ?', (Time.new.to_i - 30)).each do |zombie|
|
||||
tbl << [zombie.id,zombie.ip,BeEF::Core::Models::BrowserDetails.get(zombie.session,"HostName").to_s,BeEF::Core::Models::BrowserDetails.get(zombie.session, 'BrowserName').to_s+"-"+BeEF::Core::Models::BrowserDetails.get(zombie.session, 'BrowserVersion').to_s,BeEF::Core::Models::BrowserDetails.get(zombie.session, 'OsName'),BeEF::Core::Models::BrowserDetails.get(zombie.session, 'Hardware')]
|
||||
end
|
||||
|
||||
@@ -213,7 +213,7 @@ class Core
|
||||
end
|
||||
|
||||
onlinezombies = []
|
||||
BeEF::Core::Models::HookedBrowser.all(:lastseen.gt => (Time.new.to_i - 30)).each do |zombie|
|
||||
BeEF::Core::Models::HookedBrowser.where('lastseen > ?', (Time.new.to_i - 30)).each do |zombie|
|
||||
onlinezombies << zombie.id
|
||||
end
|
||||
|
||||
@@ -268,7 +268,7 @@ class Core
|
||||
end
|
||||
|
||||
onlinezombies = []
|
||||
BeEF::Core::Models::HookedBrowser.all(:lastseen.gt => (Time.new.to_i - 30)).each do |z|
|
||||
BeEF::Core::Models::HookedBrowser.where('lastseen > ?' (Time.new.to_i - 30)).each do |z|
|
||||
onlinezombies << z.id
|
||||
end
|
||||
|
||||
@@ -400,7 +400,7 @@ class Core
|
||||
end
|
||||
|
||||
offlinezombies = []
|
||||
BeEF::Core::Models::HookedBrowser.all(:lastseen.lt => (Time.new.to_i - 30)).each do |zombie|
|
||||
BeEF::Core::Models::HookedBrowser.where('lastseen < ?', (Time.new.to_i - 30)).each do |zombie|
|
||||
offlinezombies << zombie.id
|
||||
end
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@ class ShellInterface
|
||||
|
||||
def settarget(id)
|
||||
begin
|
||||
self.targetsession = BeEF::Core::Models::HookedBrowser.first(:id => id).session
|
||||
self.targetip = BeEF::Core::Models::HookedBrowser.first(:id => id).ip
|
||||
self.targetsession = BeEF::Core::Models::HookedBrowser.find(id).session
|
||||
self.targetip = BeEF::Core::Models::HookedBrowser.find(id).ip
|
||||
self.targetid = id
|
||||
rescue
|
||||
return nil
|
||||
@@ -28,8 +28,8 @@ class ShellInterface
|
||||
|
||||
def setofflinetarget(id)
|
||||
begin
|
||||
self.targetsession = BeEF::Core::Models::HookedBrowser.first(:id => id).session
|
||||
self.targetip = "(OFFLINE) " + BeEF::Core::Models::HookedBrowser.first(:id => id).ip
|
||||
self.targetsession = BeEF::Core::Models::HookedBrowser.find(id).session
|
||||
self.targetip = "(OFFLINE) " + BeEF::Core::Models::HookedBrowser.find(id).ip
|
||||
self.targetid = id
|
||||
rescue
|
||||
return nil
|
||||
@@ -80,10 +80,10 @@ class ShellInterface
|
||||
|
||||
# if dynamic modules are found in the DB, then we don't have yaml config for them
|
||||
# and loading must proceed in a different way.
|
||||
dynamic_modules = BeEF::Core::Models::CommandModule.all(:path.like => "Dynamic/")
|
||||
dynamic_modules = BeEF::Core::Models::CommandModule.where('path LIKE ?', 'Dynamic/')
|
||||
|
||||
if(dynamic_modules != nil)
|
||||
all_modules = BeEF::Core::Models::CommandModule.all(:order => [:id.asc])
|
||||
all_modules = BeEF::Core::Models::CommandModule.all.order(:id)
|
||||
all_modules.each{|dyn_mod|
|
||||
next if !dyn_mod.path.split('/').first.match(/^Dynamic/)
|
||||
|
||||
@@ -151,7 +151,7 @@ class ShellInterface
|
||||
commands = []
|
||||
i = 0
|
||||
|
||||
BeEF::Core::Models::Command.all(:command_module_id => cmdid, :hooked_browser_id => self.targetid).each do |command|
|
||||
BeEF::Core::Models::Command.where(:command_module_id => cmdid, :hooked_browser_id => self.targetid).each do |command|
|
||||
commands.push({
|
||||
'id' => i,
|
||||
'object_id' => command.id,
|
||||
@@ -167,7 +167,7 @@ class ShellInterface
|
||||
def getindividualresponse(cmdid)
|
||||
results = []
|
||||
begin
|
||||
BeEF::Core::Models::Result.all(:command_id => cmdid).each { |result|
|
||||
BeEF::Core::Models::Result.where(:command_id => cmdid).each { |result|
|
||||
results.push({'date' => result.date, 'data' => JSON.parse(result.data)})
|
||||
}
|
||||
rescue
|
||||
@@ -380,7 +380,7 @@ class ShellInterface
|
||||
'results' => []
|
||||
}
|
||||
@nh = BeEF::Core::Models::NetworkHost
|
||||
hosts = @nh.all(:hooked_browser_id => self.targetsession)
|
||||
hosts = @nh.where(:hooked_browser_id => self.targetsession)
|
||||
|
||||
# add property to summary hash
|
||||
if not hosts.empty?
|
||||
@@ -418,7 +418,7 @@ class ShellInterface
|
||||
'results' => []
|
||||
}
|
||||
@ns = BeEF::Core::Models::NetworkService
|
||||
services = @ns.all(:hooked_browser_id => self.targetsession)
|
||||
services = @ns.where(:hooked_browser_id => self.targetsession)
|
||||
|
||||
# add property to summary hash
|
||||
if not services.empty?
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
-->
|
||||
<head>
|
||||
<title>BeEF Basic Demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<script>
|
||||
var commandModuleStr = '<script src="<%= @hook_uri %>" type="text/javascript"><\/script>';
|
||||
document.write(commandModuleStr);
|
||||
|
||||
@@ -48,9 +48,10 @@ module BeEF
|
||||
pattern = Regexp.new(rule[:pattern], Regexp::IGNORECASE)
|
||||
$VERBOSE = verbose
|
||||
|
||||
@database.first_or_create(
|
||||
{ :resource => rule[:resource], :pattern => pattern.source },
|
||||
{ :response => rule[:response] }
|
||||
@database.find_or_create_by(
|
||||
:resource => rule[:resource].to_s,
|
||||
:pattern => pattern.source,
|
||||
:response => rule[:response]
|
||||
).id
|
||||
end
|
||||
end
|
||||
@@ -62,9 +63,11 @@ module BeEF
|
||||
# @return [Hash] hash representation of rule (empty hash if rule wasn't found)
|
||||
def get_rule(id)
|
||||
@lock.synchronize do
|
||||
if is_valid_id?(id)
|
||||
rule = @database.get(id)
|
||||
rule.nil? ? {} : to_hash(rule)
|
||||
begin
|
||||
rule = @database.find(id)
|
||||
return to_hash(rule)
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
return nil
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -76,10 +79,15 @@ module BeEF
|
||||
# @return [Boolean] true if rule was removed, otherwise false
|
||||
def remove_rule!(id)
|
||||
@lock.synchronize do
|
||||
if is_valid_id?(id)
|
||||
rule = @database.get(id)
|
||||
rule.nil? ? false : rule.destroy
|
||||
begin
|
||||
rule = @database.find(id)
|
||||
if not rule.nil? and rule.destroy
|
||||
return true
|
||||
end
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
return nil
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
@@ -94,14 +102,18 @@ module BeEF
|
||||
#
|
||||
# @return [Array<Hash>] DNS ruleset (empty array if no rules are currently defined)
|
||||
def get_ruleset
|
||||
@lock.synchronize { @database.collect { |rule| to_hash(rule) } }
|
||||
@lock.synchronize { @database.all { |rule| to_hash(rule) } }
|
||||
end
|
||||
|
||||
# Removes the entire DNS ruleset.
|
||||
#
|
||||
# @return [Boolean] true if ruleset was destroyed, otherwise false
|
||||
def remove_ruleset!
|
||||
@lock.synchronize { @database.destroy }
|
||||
@lock.synchronize do
|
||||
if @database.destroy_all
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Starts the DNS server.
|
||||
@@ -161,7 +173,7 @@ module BeEF
|
||||
|
||||
catch (:done) do
|
||||
# Find rules matching the requested resource class
|
||||
resources = @database.all(:resource => resource)
|
||||
resources = @database.where(:resource => resource)
|
||||
throw :done if resources.length == 0
|
||||
|
||||
# Narrow down search by finding a matching pattern
|
||||
@@ -257,7 +269,7 @@ module BeEF
|
||||
#
|
||||
# @return [String] resource name stripped of any module/class names
|
||||
def format_resource(resource)
|
||||
/::(\w+)$/.match(resource.name)[1]
|
||||
/::(\w+)$/.match(resource)[1]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -9,31 +9,28 @@ module BeEF
|
||||
module Dns
|
||||
|
||||
# Represents an individual DNS rule.
|
||||
class Rule
|
||||
include DataMapper::Resource
|
||||
|
||||
storage_names[:default] = 'extension_dns_rules'
|
||||
|
||||
property :id, String, :key => true
|
||||
property :pattern, Object, :required => true
|
||||
property :resource, Object, :required => true
|
||||
property :response, Object, :required => true
|
||||
property :callback, Object, :required => true
|
||||
class Rule < BeEF::Core::Model
|
||||
|
||||
# Hooks the model's "save" event. Validates pattern/response and generates a rule identifier.
|
||||
before :save do |rule|
|
||||
before_save :check_rule
|
||||
self.table_name = 'dns_rule'
|
||||
serialize :response, Array
|
||||
|
||||
private
|
||||
|
||||
def check_rule
|
||||
begin
|
||||
validate_pattern(rule.pattern)
|
||||
rule.callback = format_callback(rule.resource, rule.response)
|
||||
validate_pattern(self.pattern)
|
||||
self.callback = format_callback(self.resource.constantize, self.response)
|
||||
rescue InvalidDnsPatternError, UnknownDnsResourceError, InvalidDnsResponseError => e
|
||||
print_error e.message
|
||||
throw :halt
|
||||
end
|
||||
|
||||
rule.id = BeEF::Core::Crypto.dns_rule_id
|
||||
#self.id = BeEF::Core::Crypto.dns_rule_id
|
||||
|
||||
end
|
||||
|
||||
private
|
||||
# Verifies that the given pattern is valid (i.e. non-empty, no null's or printable characters).
|
||||
def validate_pattern(pattern)
|
||||
raise InvalidDnsPatternError unless BeEF::Filters.is_non_empty_string?(pattern) &&
|
||||
|
||||
@@ -66,7 +66,7 @@ module BeEF
|
||||
bootstrap
|
||||
rescue => e
|
||||
print_error "[Evasion] Failed to bootstrap obfuscation technique: #{e.message}"
|
||||
puts e.backtrace
|
||||
print_error e.backtrace
|
||||
end
|
||||
|
||||
def apply_chain(input)
|
||||
@@ -83,7 +83,7 @@ module BeEF
|
||||
output
|
||||
rescue => e
|
||||
print_error "[Evasion] Failed to apply obfuscation technique: #{e.message}"
|
||||
puts e.backtrace
|
||||
print_error e.backtrace
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -32,7 +32,7 @@ module Events
|
||||
end
|
||||
|
||||
# validates that a hooked browser with the beef_hook token exists in the db
|
||||
zombie = Z.first(:session => beef_hook) || nil
|
||||
zombie = Z.where(:session => beef_hook).first || nil
|
||||
if zombie.nil?
|
||||
print_error "[EVENTS] Invalid beef hook id: the hooked browser cannot be found in the database"
|
||||
return
|
||||
|
||||
@@ -6,19 +6,9 @@
|
||||
module BeEF
|
||||
module Core
|
||||
module Models
|
||||
class IpecExploits
|
||||
class IpecExploits < BeEF::Core::Model
|
||||
|
||||
include DataMapper::Resource
|
||||
#todo: use this table when we'll have a bigger IPEC exploits choice
|
||||
storage_names[:default] = 'extension_ipec_exploits'
|
||||
|
||||
property :id, Serial
|
||||
|
||||
property :name, Text, :lazy => false
|
||||
property :protocol, String, :lazy => false
|
||||
property :os, String, :lazy => false
|
||||
|
||||
has n, :extension_ipec_exploits_run, 'IpecExploitsRun'
|
||||
has_many :ipec_exploits_run
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -6,18 +6,9 @@
|
||||
module BeEF
|
||||
module Core
|
||||
module Models
|
||||
class IpecExploitsRun
|
||||
class IpecExploitsRun < BeEF::Core::Model
|
||||
|
||||
include DataMapper::Resource
|
||||
#todo: use this table when we'll have a bigger IPEC exploits choice
|
||||
storage_names[:default] = 'extension_ipec_exploits_run'
|
||||
|
||||
property :id, Serial
|
||||
property :launched, Boolean, :lazy => false
|
||||
property :http_headers, Text, :lazy => false
|
||||
property :junk_size, String, :length => 3, :lazy => false
|
||||
|
||||
belongs_to :ipec_exploits
|
||||
belongs_to :ipec_exploit
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -30,14 +30,15 @@ module BeEF
|
||||
|
||||
if connected
|
||||
msf_module_config = {}
|
||||
path = "#{$root_dir}/#{BeEF::Core::Configuration.instance.get('beef.extension.metasploit.path')}"
|
||||
if !BeEF::Core::Console::CommandLine.parse[:resetdb] && File.exists?("#{path}msf-exploits.cache")
|
||||
print_debug "Attempting to use Metasploit exploits cache file"
|
||||
raw = File.read("#{path}msf-exploits.cache")
|
||||
path = "#{$root_dir}/#{BeEF::Core::Configuration.instance.get('beef.extension.metasploit.path')}/msf-exploits.cache"
|
||||
if !BeEF::Core::Console::CommandLine.parse[:resetdb] && File.exist?(path)
|
||||
print_debug 'Attempting to use Metasploit exploits cache file'
|
||||
raw = File.read(path)
|
||||
begin
|
||||
msf_module_config = YAML.load(raw)
|
||||
rescue => e
|
||||
puts e
|
||||
print_error "[Metasploit] #{e.message}"
|
||||
print_error e.backtrace
|
||||
end
|
||||
count = 1
|
||||
msf_module_config.each { |k, v|
|
||||
@@ -102,9 +103,9 @@ module BeEF
|
||||
end
|
||||
}
|
||||
print "\r\n"
|
||||
File.open("#{path}msf-exploits.cache", "w") do |f|
|
||||
File.open(path, "w") do |f|
|
||||
f.write(msf_module_config.to_yaml)
|
||||
print_debug "Wrote Metasploit exploits to cache file"
|
||||
print_debug "Wrote Metasploit exploits to cache file: #{path}"
|
||||
end
|
||||
end
|
||||
BeEF::Core::Configuration.instance.set('beef.module', msf_module_config)
|
||||
@@ -117,7 +118,7 @@ module BeEF
|
||||
msf = BeEF::Extension::Metasploit::RpcClient.instance
|
||||
if msf_key != nil && msf.login
|
||||
msf_module_options = msf.call('module.options', 'exploit', msf_key)
|
||||
com = BeEF::Core::Models::CommandModule.first(:name => mod)
|
||||
com = BeEF::Core::Models::CommandModule.where(:name => mod).first
|
||||
if msf_module_options
|
||||
options = BeEF::Extension::Metasploit.translate_options(msf_module_options)
|
||||
options << {
|
||||
@@ -192,7 +193,7 @@ module BeEF
|
||||
if msf_key != nil && msf.login
|
||||
msf_module_options = msf.call('module.options', 'payload', payload)
|
||||
|
||||
com = BeEF::Core::Models::CommandModule.first(:name => mod)
|
||||
com = BeEF::Core::Models::CommandModule.where(:name => mod).first
|
||||
if msf_module_options
|
||||
options = BeEF::Extension::Metasploit.translate_options(msf_module_options)
|
||||
return options
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
class Msf_module < BeEF::Core::Command
|
||||
def output
|
||||
|
||||
command = BeEF::Core::Models::Command.first(:id => @command_id)
|
||||
command = BeEF::Core::Models::Command.find(@command_id)
|
||||
data = JSON.parse(command['data'])
|
||||
sploit_url = data[0]['sploit_url']
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@ module Metasploit
|
||||
super(meth, *args)
|
||||
rescue => e
|
||||
print_error "[Metasploit] RPC call to '#{meth}' failed: #{e}"
|
||||
puts e.backtrace
|
||||
print_error e.backtrace
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
@@ -9,19 +9,8 @@ module BeEF
|
||||
#
|
||||
# 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 :lastseen, String, length: 15
|
||||
class NetworkHost < BeEF::Core::Model
|
||||
belongs_to :hooked_browser
|
||||
|
||||
#
|
||||
# Stores a network host in the data store
|
||||
@@ -50,23 +39,24 @@ module BeEF
|
||||
new_host[:hooked_browser_id] = host[:hooked_browser_id]
|
||||
new_host[:ip] = host[:ip]
|
||||
new_host[:hostname] = host[:hostname] unless host[:hostname].nil?
|
||||
new_host[:type] = host[:type] unless host[:type].nil?
|
||||
new_host[:ntype] = host[:ntype] unless host[:ntype].nil?
|
||||
new_host[:os] = host[:os] unless host[:os].nil?
|
||||
new_host[:mac] = host[:mac] unless host[:mac].nil?
|
||||
|
||||
# if host already exists in data store with the same details
|
||||
# then update lastseen and return
|
||||
existing_host = BeEF::Core::Models::NetworkHost.all(new_host)
|
||||
existing_host = BeEF::Core::Models::NetworkHost.where(hooked_browser_id: new_host[:hooked_browser_id], ip: new_host[:ip]).limit(1)
|
||||
unless existing_host.empty?
|
||||
existing_host.update(lastseen: Time.new.to_i)
|
||||
existing_host = existing_host.first
|
||||
existing_host.lastseen = Time.new.to_i
|
||||
existing_host.save!
|
||||
return
|
||||
end
|
||||
|
||||
# store the new network host details
|
||||
new_host[:lastseen] = Time.new.to_i
|
||||
network_host = BeEF::Core::Models::NetworkHost.new(new_host)
|
||||
result = network_host.save
|
||||
if result.nil?
|
||||
if network_host.save
|
||||
print_error 'Failed to save network host'
|
||||
return
|
||||
end
|
||||
@@ -83,7 +73,7 @@ module BeEF
|
||||
return
|
||||
end
|
||||
|
||||
host = BeEF::Core::Models::NetworkHost.get(id.to_i)
|
||||
host = BeEF::Core::Models::NetworkHost.find(id.to_i)
|
||||
if host.nil?
|
||||
print_error "Failed to remove network host [id: #{id}]. Host does not exist."
|
||||
return
|
||||
@@ -100,7 +90,7 @@ module BeEF
|
||||
hooked_browser_id: hooked_browser_id,
|
||||
ip: ip,
|
||||
hostname: hostname,
|
||||
type: type,
|
||||
ntype: ntype,
|
||||
os: os,
|
||||
mac: mac,
|
||||
lastseen: lastseen
|
||||
|
||||
@@ -9,17 +9,9 @@ module BeEF
|
||||
#
|
||||
# Table stores each open port identified on the zombie browser's network(s)
|
||||
#
|
||||
class NetworkService
|
||||
include DataMapper::Resource
|
||||
storage_names[:default] = 'network_service'
|
||||
class NetworkService < BeEF::Core::Model
|
||||
belongs_to :hooked_browser
|
||||
|
||||
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
|
||||
|
||||
#
|
||||
# Stores a network service in the data store
|
||||
@@ -48,19 +40,20 @@ module BeEF
|
||||
end
|
||||
|
||||
# store the returned network host details
|
||||
BeEF::Core::Models::NetworkHost.add(
|
||||
BeEF::Core::Models::NetworkHost.create(
|
||||
hooked_browser_id: service[:hooked_browser_id],
|
||||
ip: service[:ip]
|
||||
)
|
||||
|
||||
# prevent duplicates
|
||||
return unless BeEF::Core::Models::NetworkService.all(
|
||||
total = BeEF::Core::Models::NetworkService.where(
|
||||
hooked_browser_id: service[:hooked_browser_id],
|
||||
proto: service[:proto],
|
||||
ip: service[:ip],
|
||||
port: service[:port],
|
||||
type: service[:type]
|
||||
).empty?
|
||||
ntype: service[:ntype]
|
||||
).length
|
||||
return if total > 0
|
||||
|
||||
# store the returned network service details
|
||||
network_service = BeEF::Core::Models::NetworkService.new(
|
||||
@@ -68,10 +61,9 @@ module BeEF
|
||||
proto: service[:proto],
|
||||
ip: service[:ip],
|
||||
port: service[:port],
|
||||
type: service[:type]
|
||||
ntype: service[:ntype]
|
||||
)
|
||||
result = network_service.save
|
||||
if result.nil?
|
||||
if network_service.save
|
||||
print_error 'Failed to save network service'
|
||||
return
|
||||
end
|
||||
@@ -87,7 +79,7 @@ module BeEF
|
||||
proto: proto,
|
||||
ip: ip,
|
||||
port: port,
|
||||
type: type
|
||||
ntype: ntype
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -27,7 +27,7 @@ module BeEF
|
||||
# Returns the entire list of network hosts for all zombies
|
||||
get '/hosts' do
|
||||
begin
|
||||
hosts = @nh.all(unique: true, order: [:id.asc])
|
||||
hosts = @nh.all.distinct.order(:id)
|
||||
count = hosts.length
|
||||
|
||||
result = {}
|
||||
@@ -47,7 +47,7 @@ module BeEF
|
||||
# Returns the entire list of network services for all zombies
|
||||
get '/services' do
|
||||
begin
|
||||
services = @ns.all(unique: true, order: [:id.asc])
|
||||
services = @ns.all.distinct.order(:id)
|
||||
count = services.length
|
||||
|
||||
result = {}
|
||||
@@ -69,7 +69,7 @@ module BeEF
|
||||
begin
|
||||
id = params[:id]
|
||||
|
||||
hosts = @nh.all(hooked_browser_id: id, unique: true, order: [:id.asc])
|
||||
hosts = @nh.where(hooked_browser_id: id).distinct.order(:id)
|
||||
count = hosts.length
|
||||
|
||||
result = {}
|
||||
@@ -94,7 +94,7 @@ module BeEF
|
||||
begin
|
||||
id = params[:id]
|
||||
|
||||
services = @ns.all(hooked_browser_id: id, unique: true, order: [:id.asc])
|
||||
services = @ns.where(hooked_browser_id: id).distinct.order(:id)
|
||||
count = services.length
|
||||
|
||||
result = {}
|
||||
@@ -119,7 +119,7 @@ module BeEF
|
||||
begin
|
||||
id = params[:id]
|
||||
|
||||
host = @nh.all(id: id)
|
||||
host = @nh.find(id)
|
||||
raise InvalidParamError, 'id' if host.nil?
|
||||
halt 404 if host.empty?
|
||||
|
||||
@@ -139,7 +139,7 @@ module BeEF
|
||||
id = params[:id]
|
||||
raise InvalidParamError, 'id' unless BeEF::Filters.nums_only?(id)
|
||||
|
||||
host = @nh.all(id: id)
|
||||
host = @nh.find(id)
|
||||
halt 404 if host.nil?
|
||||
|
||||
result = {}
|
||||
@@ -159,7 +159,7 @@ module BeEF
|
||||
begin
|
||||
id = params[:id]
|
||||
|
||||
service = @ns.all(id: id)
|
||||
service = @ns.find(id)
|
||||
raise InvalidParamError, 'id' if service.nil?
|
||||
halt 404 if service.empty?
|
||||
|
||||
|
||||
@@ -137,10 +137,10 @@ module BeEF
|
||||
|
||||
# Wait for the HTTP response to be stored in the db.
|
||||
# TODO: re-implement this with EventMachine or with the Observer pattern.
|
||||
while H.first(:id => http.id).has_ran != "complete"
|
||||
while H.find(http.id).has_ran != "complete"
|
||||
sleep 0.5
|
||||
end
|
||||
@response = H.first(:id => http.id)
|
||||
@response = H.find(http.id)
|
||||
print_debug "[PROXY] <-- Response for request ##{@response.id} to [#{@response.path}] on domain [#{@response.domain}:#{@response.port}] correctly processed"
|
||||
|
||||
response_body = @response['response_data']
|
||||
@@ -171,7 +171,7 @@ module BeEF
|
||||
header_key = line.split(': ')[0]
|
||||
header_value = line.split(': ')[1]
|
||||
next if header_key.nil?
|
||||
next if ignore_headers.include?(header_key)
|
||||
next if ignore_headers.any?{ |h| h.casecmp(header_key) == 0 }
|
||||
if header_value.nil?
|
||||
#headers_hash[header_key] = ""
|
||||
else
|
||||
@@ -191,7 +191,7 @@ module BeEF
|
||||
end
|
||||
|
||||
def get_tunneling_proxy
|
||||
proxy_browser = HB.first(:is_proxy => true)
|
||||
proxy_browser = HB.where(:is_proxy => true).first
|
||||
unless proxy_browser.nil?
|
||||
return proxy_browser.session.to_s
|
||||
end
|
||||
|
||||
@@ -35,8 +35,8 @@ module BeEF
|
||||
result['success'] = false
|
||||
return result.to_json if hb_id.nil?
|
||||
|
||||
hooked_browser = @hb.first(:session => hb_id)
|
||||
previous_proxy_hb = @hb.first(:is_proxy => true)
|
||||
hooked_browser = @hb.where(:session => hb_id).first
|
||||
previous_proxy_hb = @hb.where(:is_proxy => true).first
|
||||
|
||||
# if another HB is currently set as tunneling proxy, unset it
|
||||
unless previous_proxy_hb.nil?
|
||||
|
||||
@@ -20,7 +20,7 @@ module BeEF
|
||||
@body = body
|
||||
# Generate all the requests and output them to the hooked browser
|
||||
output = []
|
||||
BeEF::Core::Models::Http.all(:hooked_browser_id => hb.session, :has_ran => "waiting").each { |h|
|
||||
BeEF::Core::Models::Http.where(:hooked_browser_id => hb.session, :has_ran => "waiting").each { |h|
|
||||
output << self.requester_parse_db_request(h)
|
||||
}
|
||||
|
||||
|
||||
@@ -41,11 +41,11 @@ module BeEF
|
||||
end
|
||||
|
||||
# validates that a hooked browser with the beef_hook token exists in the db
|
||||
zombie_db = Z.first(:session => beef_hook) || nil
|
||||
zombie_db = Z.where(:session => beef_hook).first || nil
|
||||
(print_error "Invalid beefhook id: the hooked browser cannot be found in the database";return) if zombie_db.nil?
|
||||
|
||||
# validates that we have such a http request saved in the db
|
||||
http_db = H.first(:id => request_id.to_i, :hooked_browser_id => zombie_db.session) || nil
|
||||
http_db = H.where(:id => request_id.to_i, :hooked_browser_id => zombie_db.session).first || nil
|
||||
if http_db.nil?
|
||||
print_error "Invalid http_db: no such request found in the database"
|
||||
return
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user