cleanup
This commit is contained in:
@@ -16,15 +16,6 @@ module Filters
|
||||
true
|
||||
end
|
||||
|
||||
# Check if the command id valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string is a valid command id
|
||||
def self.is_valid_command_id?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false unless nums_only?(str)
|
||||
true
|
||||
end
|
||||
|
||||
# Check if the session id valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid hook session id characters
|
||||
|
||||
@@ -20,8 +20,8 @@ module BeEF
|
||||
# @param [String] configuration_file Configuration file to be loaded,
|
||||
# by default loads $root_dir/config.yaml
|
||||
def initialize(config)
|
||||
raise Exception::TypeError, "'config' needs to be a string" unless config.string?
|
||||
raise Exception::TypeError, "Configuration file '#{config}' cannot be found" unless File.exist? config
|
||||
raise TypeError, "'config' needs to be a string" unless config.string?
|
||||
raise TypeError, "Configuration file '#{config}' cannot be found" unless File.exist? config
|
||||
|
||||
begin
|
||||
#open base config
|
||||
|
||||
@@ -24,7 +24,7 @@ module Core
|
||||
token_length = len || config.get('beef.crypto_default_value_length').to_i
|
||||
|
||||
# type checking
|
||||
raise Exception::TypeError, "Token length is less than the minimum length enforced by the framework: #{TOKEN_MINIMUM_LENGTH}" if (token_length < TOKEN_MINIMUM_LENGTH)
|
||||
raise TypeError, "Token length is less than the minimum length enforced by the framework: #{TOKEN_MINIMUM_LENGTH}" if (token_length < TOKEN_MINIMUM_LENGTH)
|
||||
|
||||
# return random hex string
|
||||
OpenSSL::Random.random_bytes(token_length).unpack("H*")[0]
|
||||
|
||||
@@ -48,7 +48,7 @@ module Core
|
||||
# @return [Hash] IP address lookup results
|
||||
#
|
||||
def lookup(ip)
|
||||
raise Exception::TypeError, '"ip" needs to be a string' unless ip.string?
|
||||
raise TypeError, '"ip" needs to be a string' unless ip.string?
|
||||
|
||||
return unless @enabled
|
||||
|
||||
|
||||
@@ -4,81 +4,107 @@
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
module BeEF
|
||||
module Core
|
||||
module Handlers
|
||||
module Core
|
||||
module Handlers
|
||||
class Commands
|
||||
|
||||
class Commands
|
||||
include BeEF::Core::Handlers::Modules::BeEFJS
|
||||
include BeEF::Core::Handlers::Modules::Command
|
||||
|
||||
include BeEF::Core::Handlers::Modules::BeEFJS
|
||||
include BeEF::Core::Handlers::Modules::Command
|
||||
@data = {}
|
||||
|
||||
@data = {}
|
||||
#
|
||||
# Handles command data
|
||||
#
|
||||
# @param [Hash] data Data from command execution
|
||||
# @param [Class] kclass Class of command
|
||||
#
|
||||
# @todo Confirm argument data variable type [radoen]: type is Hash confirmed.
|
||||
#
|
||||
def initialize(data, kclass)
|
||||
@kclass = BeEF::Core::Command.const_get(kclass.capitalize)
|
||||
@data = data
|
||||
setup
|
||||
end
|
||||
|
||||
# Handles command data
|
||||
# @param [Hash] data Data from command execution
|
||||
# @param [Class] kclass Class of command
|
||||
# @todo Confirm argument data variable type [radoen]: type is Hash confirmed.
|
||||
def initialize(data, kclass)
|
||||
@kclass = BeEF::Core::Command.const_get(kclass.capitalize)
|
||||
@data = data
|
||||
setup()
|
||||
end
|
||||
|
||||
# Initial setup function, creates the command module and saves details to datastore
|
||||
def setup()
|
||||
|
||||
|
||||
@http_params = @data['request'].params
|
||||
@http_header = Hash.new
|
||||
http_header = @data['request'].env.select { |k, v| k.to_s.start_with? 'HTTP_' }.each { |key, value|
|
||||
@http_header[key.sub(/^HTTP_/, '')] = value.force_encoding('UTF-8')
|
||||
}
|
||||
|
||||
# @note get and check command id from the request
|
||||
command_id = get_param(@data, 'cid')
|
||||
# @todo ruby filter needs to be updated to detect fixnums not strings
|
||||
command_id = command_id.to_s()
|
||||
(print_error "command_id is invalid"; return) if not BeEF::Filters.is_valid_command_id?(command_id.to_s())
|
||||
|
||||
# @note get and check session id from the request
|
||||
beefhook = get_param(@data, 'beefhook')
|
||||
(print_error "BeEF hook is invalid"; return) if not BeEF::Filters.is_valid_hook_session_id?(beefhook)
|
||||
|
||||
result = get_param(@data, 'results')
|
||||
|
||||
# @note create the command module to handle the response
|
||||
command = @kclass.new(BeEF::Module.get_key_by_class(@kclass))
|
||||
command.build_callback_datastore(result, command_id, beefhook, @http_params, @http_header)
|
||||
command.session_id = beefhook
|
||||
if command.respond_to?(:post_execute)
|
||||
command.post_execute
|
||||
end
|
||||
#@todo this is the part that store result on db and the modify will be accessible from all the framework and so UI too
|
||||
# @note get/set details for datastore and log entry
|
||||
command_friendly_name = command.friendlyname
|
||||
(print_error "command friendly name is empty"; return) if command_friendly_name.empty?
|
||||
|
||||
command_status = @data['status']
|
||||
command_results = @data['results']
|
||||
(print_error "command results or status are empty"; return) if command_results.empty?
|
||||
|
||||
# @note save the command module results to the datastore and create a log entry
|
||||
command_results = {'data' => command_results}
|
||||
BeEF::Core::Models::Command.save_result(beefhook, command_id, command_friendly_name, command_results, command_status)
|
||||
|
||||
end
|
||||
|
||||
# Returns parameter from hash
|
||||
# @param [Hash] query Hash of data to return data from
|
||||
# @param [String] key Key to search for and return inside `query`
|
||||
# @return Value referenced in hash at the supplied key
|
||||
def get_param(query, key)
|
||||
return (query.class == Hash and query.has_key?(key)) ? query[key] : nil
|
||||
end
|
||||
#
|
||||
# @note Initial setup function, creates the command module and saves details to datastore
|
||||
#
|
||||
def setup
|
||||
@http_params = @data['request'].params
|
||||
@http_header = {}
|
||||
http_header = @data['request'].env.select { |k, v| k.to_s.start_with? 'HTTP_' }.each { |key, value|
|
||||
@http_header[key.sub(/^HTTP_/, '')] = value.force_encoding('UTF-8')
|
||||
}
|
||||
|
||||
# @note get and check command id from the request
|
||||
command_id = get_param(@data, 'cid')
|
||||
unless command_id.integer?
|
||||
print_error "command_id is invalid"
|
||||
return
|
||||
end
|
||||
|
||||
# @note get and check session id from the request
|
||||
beefhook = get_param(@data, 'beefhook')
|
||||
unless BeEF::Filters.is_valid_hook_session_id?(beefhook)
|
||||
print_error "BeEF hook is invalid"
|
||||
return
|
||||
end
|
||||
|
||||
result = get_param(@data, 'results')
|
||||
|
||||
# @note create the command module to handle the response
|
||||
command = @kclass.new(BeEF::Module.get_key_by_class(@kclass))
|
||||
command.build_callback_datastore(result, command_id, beefhook, @http_params, @http_header)
|
||||
command.session_id = beefhook
|
||||
command.post_execute if command.respond_to?(:post_execute)
|
||||
|
||||
# @todo this is the part that store result on db and the modify
|
||||
# will be accessible from all the framework and so UI too
|
||||
# @note get/set details for datastore and log entry
|
||||
command_friendly_name = command.friendlyname
|
||||
if command_friendly_name.empty?
|
||||
print_error 'command friendly name is empty'
|
||||
return
|
||||
end
|
||||
|
||||
command_status = @data['status']
|
||||
unless command_status.integer?
|
||||
print_error 'command status is invalid'
|
||||
return
|
||||
end
|
||||
|
||||
command_results = @data['results']
|
||||
if command_results.empty?
|
||||
print_error 'command results are empty'
|
||||
return
|
||||
end
|
||||
|
||||
# @note save the command module results to the datastore and create a log entry
|
||||
command_results = { 'data' => command_results }
|
||||
BeEF::Core::Models::Command.save_result(
|
||||
beefhook,
|
||||
command_id,
|
||||
command_friendly_name,
|
||||
command_results,
|
||||
command_status
|
||||
)
|
||||
end
|
||||
|
||||
#
|
||||
# @note Returns parameter from hash
|
||||
#
|
||||
# @param [Hash] query Hash of data to return data from
|
||||
# @param [String] key Key to search for and return inside `query`
|
||||
#
|
||||
# @return Value referenced in hash at the supplied key
|
||||
#
|
||||
def get_param(query, key)
|
||||
return unless query.class == Hash
|
||||
return unless query.key?(key)
|
||||
query[key]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -34,9 +34,9 @@ module Core
|
||||
time_now = Time.now
|
||||
|
||||
# arguments type checking
|
||||
raise Exception::TypeError, '"from" needs to be a string' unless from.string?
|
||||
raise Exception::TypeError, '"event" needs to be a string' unless event.string?
|
||||
raise Exception::TypeError, '"Hooked Browser ID" needs to be an integer' unless hb.integer?
|
||||
raise TypeError, '"from" needs to be a string' unless from.string?
|
||||
raise TypeError, '"event" needs to be a string' unless event.string?
|
||||
raise TypeError, '"Hooked Browser ID" needs to be an integer' unless hb.integer?
|
||||
|
||||
# logging the new event into the database
|
||||
@logs.new(:type => from.to_s, :event => event.to_s, :date => time_now, :hooked_browser_id => hb).save
|
||||
|
||||
@@ -23,58 +23,62 @@ module Models
|
||||
|
||||
has n, :results
|
||||
|
||||
|
||||
#
|
||||
# Save results and flag that the command has been run on the hooked browser
|
||||
#
|
||||
# @param [String] hook_session_id The session_id.
|
||||
# @param [String] command_id The command_id.
|
||||
# @param [String] command_friendly_name The command friendly name.
|
||||
# @param [String] result The result of the command module.
|
||||
#
|
||||
def self.save_result(hook_session_id, command_id, command_friendly_name, result, status)
|
||||
# @note enforcing arguments types
|
||||
command_id = command_id.to_i
|
||||
|
||||
# @note argument type checking
|
||||
raise Exception::TypeError, '"hook_session_id" needs to be a string' if not hook_session_id.string?
|
||||
raise Exception::TypeError, '"command_id" needs to be an integer' if not command_id.integer?
|
||||
raise Exception::TypeError, '"command_friendly_name" needs to be a string' if not command_friendly_name.string?
|
||||
raise Exception::TypeError, '"result" needs to be a hash' if not result.hash?
|
||||
raise Exception::TypeError, '"status" needs to be an integer' if not status.integer?
|
||||
raise TypeError, '"hook_session_id" needs to be a string' unless hook_session_id.string?
|
||||
raise TypeError, '"command_id" needs to be an integer' unless command_id.integer?
|
||||
raise TypeError, '"command_friendly_name" needs to be a string' unless command_friendly_name.string?
|
||||
raise TypeError, '"result" needs to be a hash' unless result.hash?
|
||||
raise TypeError, '"status" needs to be an integer' unless status.integer?
|
||||
|
||||
# @note get the hooked browser structure and id from the database
|
||||
hooked_browser = BeEF::Core::Models::HookedBrowser.first(:session => hook_session_id) || nil
|
||||
raise Exception::TypeError, "hooked_browser is nil" if hooked_browser.nil?
|
||||
raise Exception::TypeError, "hooked_browser.id is nil" if hooked_browser.id.nil?
|
||||
hooked_browser_id = hooked_browser.id
|
||||
raise Exception::TypeError, "hooked_browser.ip is nil" if hooked_browser.ip.nil?
|
||||
hooked_browser_ip = hooked_browser.ip
|
||||
raise TypeError, "hooked_browser is nil" if hooked_browser.nil?
|
||||
raise TypeError, "hooked_browser.id is nil" if hooked_browser.id.nil?
|
||||
|
||||
# @note get the command module data structure from the database
|
||||
command = first(:id => command_id.to_i, :hooked_browser_id => hooked_browser_id) || nil
|
||||
raise Exception::TypeError, "command is nil" if command.nil?
|
||||
command = first(:id => command_id, :hooked_browser_id => hooked_browser.id) || nil
|
||||
raise TypeError, "command is nil" if command.nil?
|
||||
|
||||
# @note create the entry for the results
|
||||
command.results.new(:hooked_browser_id => hooked_browser_id,
|
||||
:data => result.to_json,:status => status,:date => Time.now.to_i)
|
||||
command.results.new(
|
||||
:hooked_browser_id => hooked_browser.id,
|
||||
:data => result.to_json,
|
||||
:status => status,
|
||||
:date => Time.now.to_i
|
||||
)
|
||||
command.save
|
||||
|
||||
s = self.show_status(status)
|
||||
log = "Hooked browser [id:#{hooked_browser.id}, ip:#{hooked_browser.ip}] has executed instructions (status: #{s}) from command module [cid:#{command_id}, mod: #{command.command_module_id}, name:'#{command_friendly_name}']"
|
||||
BeEF::Core::Logger.instance.register('Command', log, hooked_browser_id)
|
||||
s = show_status(status)
|
||||
log = "Hooked browser [id:#{hooked_browser.id}, ip:#{hooked_browser.ip}]"
|
||||
log += " has executed instructions (status: #{s}) from command module [cid:#{command_id},"
|
||||
log += " mod: #{command.command_module_id}, name:'#{command_friendly_name}']"
|
||||
BeEF::Core::Logger.instance.register('Command', log, hooked_browser.id)
|
||||
print_info log
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
# @note show status
|
||||
def self.show_status(status)
|
||||
case status
|
||||
when -1
|
||||
result = 'ERROR'
|
||||
when 1
|
||||
result = 'SUCCESS'
|
||||
else
|
||||
result = 'UNKNOWN'
|
||||
when -1
|
||||
result = 'ERROR'
|
||||
when 1
|
||||
result = 'SUCCESS'
|
||||
else
|
||||
result = 'UNKNOWN'
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -12,9 +12,14 @@ module Models
|
||||
include DataMapper::Resource
|
||||
|
||||
storage_names[:default] = 'core_commandmodules'
|
||||
|
||||
|
||||
# @note command module ID
|
||||
property :id, Serial
|
||||
|
||||
# @note command module name
|
||||
property :name, Text, :lazy => false
|
||||
|
||||
# @note command module path
|
||||
property :path, Text, :lazy => false
|
||||
|
||||
has n, :commands
|
||||
|
||||
@@ -14,27 +14,42 @@ module Models
|
||||
include DataMapper::Resource
|
||||
|
||||
storage_names[:default] = 'core_hookedbrowsers'
|
||||
|
||||
|
||||
# @note zombie ID
|
||||
property :id, Serial
|
||||
|
||||
# @note hooked browser session ID
|
||||
property :session, Text, :lazy => false
|
||||
|
||||
# @note IP address of the hooked browser
|
||||
property :ip, Text, :lazy => false
|
||||
|
||||
# @note timestamp first time the browser communicated with BeEF
|
||||
property :firstseen, String, :length => 15
|
||||
|
||||
# @note timestamp last time the browser communicated with BeEF
|
||||
property :lastseen, String, :length => 15
|
||||
|
||||
# @note HTTP headers sent be the browser to the BeEF server upon first hook
|
||||
property :httpheaders, Text, :lazy => false
|
||||
|
||||
# @note the domain originating the hook request
|
||||
property :domain, Text, :lazy => false
|
||||
|
||||
# @note the port on the domain originating the hook request
|
||||
property :port, Integer, :default => 80
|
||||
|
||||
# @note number of times the zombie has polled
|
||||
property :count, Integer, :lazy => false
|
||||
property :has_init, Boolean, :default => false
|
||||
property :is_proxy, Boolean, :default => false
|
||||
|
||||
# @note if true the HB is used as a tunneling proxy
|
||||
property :is_proxy, Boolean, :default => false
|
||||
|
||||
has n, :commands
|
||||
has n, :results
|
||||
has n, :logs
|
||||
#has n, :https
|
||||
|
||||
# Increases the count of a zombie
|
||||
# @note Increases the count of a zombie
|
||||
def count!
|
||||
if not self.count.nil? then self.count += 1; else self.count = 1; end
|
||||
end
|
||||
|
||||
@@ -195,7 +195,7 @@ module BeEF
|
||||
command_status = data["status"]
|
||||
|
||||
(print_error "BeEFhook is invalid"; return) unless BeEF::Filters.is_valid_hook_session_id?(hooked_browser)
|
||||
(print_error "command_id is invalid"; return) unless BeEF::Filters.is_valid_command_id?(command_id)
|
||||
(print_error "command_id is invalid"; return) unless command_id.integer?
|
||||
(print_error "command name is empty"; return) if handler.empty?
|
||||
(print_error "command results are empty"; return) if command_results.empty?
|
||||
(print_error "command status is invalid"; return) unless command_status =~ /\A0|1|2|undefined\z/
|
||||
|
||||
@@ -55,7 +55,7 @@ module BeEF
|
||||
#
|
||||
def mount(url, http_handler_class, args = nil)
|
||||
# argument type checking
|
||||
raise Exception::TypeError, '"url" needs to be a string' unless url.string?
|
||||
raise TypeError, '"url" needs to be a string' unless url.string?
|
||||
|
||||
if args.nil?
|
||||
@mounts[url] = http_handler_class
|
||||
@@ -71,7 +71,7 @@ module BeEF
|
||||
# @param [String] url URL to unmount.
|
||||
#
|
||||
def unmount(url)
|
||||
raise Exception::TypeError, '"url" needs to be a string' unless url.string?
|
||||
raise TypeError, '"url" needs to be a string' unless url.string?
|
||||
@mounts.delete url
|
||||
end
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ module BeEF
|
||||
},
|
||||
|
||||
# the rules for the distributed engine
|
||||
'ditributed-engine-rules' => distributed_engine_rules
|
||||
'distributed-engine-rules' => distributed_engine_rules
|
||||
}
|
||||
|
||||
@body = ret.to_json
|
||||
|
||||
@@ -58,7 +58,7 @@ Ext.TaskMgr.start({
|
||||
var hr = document.getElementById("header-right");
|
||||
hr.innerHTML = "You appear to be logged out. <a href='<%= @base_path %>/panel/'>Login</a>";
|
||||
}
|
||||
var distributed_engine_rules = (updates['ditributed-engine-rules']) ? updates['ditributed-engine-rules'] : null;
|
||||
var distributed_engine_rules = (updates['distributed-engine-rules']) ? updates['distributed-engine-rules'] : null;
|
||||
beefwui.hooked_browsers = (updates['hooked-browsers']); //? updates['hooked-browsers'] : null;
|
||||
var hooked_browsers = (updates['hooked-browsers']) ? updates['hooked-browsers'] : null;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user