Finished commenting BeEF core. From this point on each developer should be commenting their own core changes
git-svn-id: https://beef.googlecode.com/svn/trunk@1362 b87d56ec-f9c0-11de-8c8a-61c5e9addfc9
This commit is contained in:
@@ -13,42 +13,38 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
module BeEF
|
||||
module Core
|
||||
|
||||
|
||||
#
|
||||
# This module contains a list of utils functions to use
|
||||
# when writing commands.
|
||||
#
|
||||
# @note This module contains a list of utils functions to use when writing commands
|
||||
module CommandUtils
|
||||
|
||||
# Format a string to support multiline in javascript.
|
||||
# @param [String] text String to convert
|
||||
# @return [String] Formatted string
|
||||
def format_multiline(text); text.gsub(/\n/, '\n'); end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
#
|
||||
# The Command Module Context is being used when evaluating code in eruby.
|
||||
# In other words, we use that code to add funky functions to the
|
||||
# javascript templates of our commands.
|
||||
#
|
||||
# @note The Command Module Context is being used when evaluating code in eruby.
|
||||
# In other words, we use that code to add funky functions to the
|
||||
# javascript templates of our commands.
|
||||
class CommandContext < Erubis::Context
|
||||
include BeEF::Core::CommandUtils
|
||||
|
||||
# Constructor
|
||||
# @param [Hash] hash
|
||||
def initialize(hash=nil);
|
||||
super(hash);
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
#
|
||||
# This class is the base class for all command modules in the framework.
|
||||
#
|
||||
# Two instances of this object are created during the execution of command module.
|
||||
#
|
||||
# @note This class is the base class for all command modules in the framework.
|
||||
# Two instances of this object are created during the execution of command module.
|
||||
class Command
|
||||
|
||||
attr_reader :datastore, :path, :default_command_url, :beefjs_components, :friendlyname
|
||||
@@ -59,6 +55,7 @@ module Core
|
||||
include BeEF::Core::Constants::CommandModule
|
||||
|
||||
# Super class controller
|
||||
# @param [String] key command module key
|
||||
def initialize(key)
|
||||
get_extensions
|
||||
config = BeEF::Core::Configuration.instance
|
||||
@@ -75,42 +72,32 @@ module Core
|
||||
@beefjs_components = {}
|
||||
end
|
||||
|
||||
#
|
||||
# Uses the API to include all the code from extensions that need to add
|
||||
# methods, constants etc to that class.
|
||||
#
|
||||
# See BeEF::API::Command for examples.
|
||||
#
|
||||
# Uses the API to include all the code from extensions that need to add methods, constants etc to that class.
|
||||
# @todo Determine if this method is deprecated
|
||||
def get_extensions
|
||||
BeEF::API::Command.extended_in_modules.each do |mod|
|
||||
self.class.send(:include, mod)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# This function is called just before the intructions are sent to hooked browser.
|
||||
# The derived class can use this function to update params used in the command module.
|
||||
#
|
||||
# This function is called just before the instructions are sent to hooked browser.
|
||||
def pre_send; end
|
||||
|
||||
#
|
||||
# Callback method. This function is called when the hooked browser sends results back.
|
||||
#
|
||||
def callback; end
|
||||
|
||||
#
|
||||
# If the command requires some data to be sent back, this function will process them.
|
||||
#
|
||||
# @param [] head
|
||||
# @param [Hash] params Hash of parameters
|
||||
# @todo Determine argument "head" type
|
||||
def process_zombie_response(head, params); end
|
||||
|
||||
#
|
||||
# Returns true if the command needs configurations to work. False if not.
|
||||
#
|
||||
# @deprecated This command should not be used since the implementation of the new configuration system
|
||||
def needs_configuration?; !@datastore.nil?; end
|
||||
|
||||
#
|
||||
# Returns information about the command in a JSON format.
|
||||
#
|
||||
# @return [String] JSON formatted string
|
||||
def to_json
|
||||
{
|
||||
'Name' => @friendlyname,
|
||||
@@ -120,18 +107,16 @@ module Core
|
||||
}.to_json
|
||||
end
|
||||
|
||||
#
|
||||
# Builds the 'datastore' attribute of the command which is used to generate javascript code.
|
||||
#
|
||||
# @param [Hash] data Data to be inserted into the datastore
|
||||
# @todo Confirm argument "data" type
|
||||
def build_datastore(data);
|
||||
@datastore = JSON.parse(data)
|
||||
end
|
||||
|
||||
#
|
||||
# Sets the datastore for the callback function. This function is meant to be called by the CommandHandler
|
||||
#
|
||||
# build_callback_datastore(http_params, http_header)
|
||||
#
|
||||
# @param [Hash] http_params HTTP parameters
|
||||
# @param [Hash] http_header HTTP headers
|
||||
def build_callback_datastore(http_params, http_header)
|
||||
@datastore = {'http_headers' => {}} # init the datastore
|
||||
|
||||
@@ -152,9 +137,8 @@ module Core
|
||||
}
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the output of the command. These are the actual instructions sent to the browser.
|
||||
#
|
||||
# @return [String] The command output
|
||||
def output
|
||||
f = @path+'command.js'
|
||||
raise WEBrick::HTTPStatus::BadRequest, "#{f} file does not exist" if not File.exists? f
|
||||
@@ -178,28 +162,25 @@ module Core
|
||||
@output
|
||||
end
|
||||
|
||||
#
|
||||
# Saves the results received from the zombie.
|
||||
#
|
||||
# Saves the results received from the hooked browser
|
||||
# @param [Hash] results Results from hooked browser
|
||||
def save(results);
|
||||
@results = results;
|
||||
end
|
||||
|
||||
# If nothing else than the file is specified, the function will map the file to a random path
|
||||
# without any extension.
|
||||
# If nothing else than the file is specified, the function will map the file to a random path without any extension.
|
||||
# @param [String] file File to be mounted
|
||||
# @param [String] path URL path to mounted file
|
||||
# @param [String] extension URL extension
|
||||
# @param [Integer] count The amount of times this file can be accessed before being automatically unmounted
|
||||
# @deprecated This function is possibly deprecated in place of the API
|
||||
def map_file_to_url(file, path=nil, extension=nil, count=1)
|
||||
return BeEF::Core::NetworkStack::Handlers::AssetHandler.instance.bind(file, path, extension, count)
|
||||
end
|
||||
|
||||
#
|
||||
# Tells the framework to load a specific module of the BeEFJS library that
|
||||
# the command will be using.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# use 'beef.net.local'
|
||||
# use 'beef.encode.base64'
|
||||
#
|
||||
# Tells the framework to load a specific module of the BeEFJS library that the command will be using.
|
||||
# @param [String] component String of BeEFJS component to load
|
||||
# @note Example: use 'beef.net.local'
|
||||
def use(component)
|
||||
return if @beefjs_components.include? component
|
||||
|
||||
@@ -213,12 +194,14 @@ module Core
|
||||
@beefjs_components[component] = component_path
|
||||
end
|
||||
|
||||
# @todo Document
|
||||
def oc_value(name)
|
||||
option = BeEF::Core::Models::OptionCache.first(:name => name)
|
||||
return nil if not option
|
||||
return option.value
|
||||
end
|
||||
|
||||
# @todo Document
|
||||
def apply_defaults()
|
||||
@datastore.each { |opt|
|
||||
opt["value"] = oc_value(opt["name"]) || opt["value"]
|
||||
|
||||
@@ -13,23 +13,16 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
module BeEF
|
||||
module Core
|
||||
#
|
||||
# Parses the user configuration file for beef.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# configuration = BeEF::Core::Configuration.instance
|
||||
# p configuration.get('beef.http.host) # => "0.0.0.0"
|
||||
#
|
||||
|
||||
class Configuration
|
||||
|
||||
include Singleton
|
||||
|
||||
#
|
||||
# Constructor
|
||||
#
|
||||
# Loads the default configuration system
|
||||
# @param [String] configuration_file Configuration file to be loaded, by default loads $root_dir/config.yaml
|
||||
def initialize(configuration_file="#{$root_dir}/config.yaml")
|
||||
# argument type checking
|
||||
raise Exception::TypeError, '"configuration_file" needs to be a string' if not configuration_file.string?
|
||||
@@ -41,18 +34,18 @@ module Core
|
||||
@config.default = nil
|
||||
end
|
||||
|
||||
#
|
||||
# Loads yaml file
|
||||
#
|
||||
# @param [String] file YAML file to be loaded
|
||||
# @return [Hash] YAML formatted hash
|
||||
def load(file)
|
||||
return nil if not File.exists?(file)
|
||||
raw = File.read(file)
|
||||
return YAML.load(raw)
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the value of a selected key in the configuration file.
|
||||
#
|
||||
# @param [String] key Key of configuration item
|
||||
# @return [Hash|String] The resulting value stored against the 'key'
|
||||
def get(key)
|
||||
subkeys = key.split('.')
|
||||
lastkey = subkeys.pop
|
||||
@@ -62,9 +55,10 @@ module Core
|
||||
return (subhash != nil and subhash.has_key?(lastkey)) ? subhash[lastkey] : nil
|
||||
end
|
||||
|
||||
#
|
||||
# Sets the give key value pair to the config instance
|
||||
#
|
||||
# @param [String] key The configuration key
|
||||
# @param value The value to be stored against the 'key'
|
||||
# @return [Boolean] If the store procedure was successful
|
||||
def set(key, value)
|
||||
subkeys = key.split('.').reverse
|
||||
return false if subkeys.length == 0
|
||||
@@ -76,9 +70,9 @@ module Core
|
||||
return true
|
||||
end
|
||||
|
||||
#
|
||||
# Clears the given key hash
|
||||
#
|
||||
# @param [String] key Configuration key to be cleared
|
||||
# @return [Boolean] If the configuration key was cleared
|
||||
def clear(key)
|
||||
subkeys = key.split('.')
|
||||
return false if subkeys.length == 0
|
||||
@@ -90,9 +84,7 @@ module Core
|
||||
return (hash.delete(lastkey) == nil) ? false : true
|
||||
end
|
||||
|
||||
#
|
||||
# load extensions configurations
|
||||
#
|
||||
# Load extensions configurations
|
||||
def load_extensions_config
|
||||
self.set('beef.extension', {})
|
||||
Dir.glob("#{$root_dir}/extensions/*/config.yaml") do | cf |
|
||||
@@ -104,9 +96,7 @@ module Core
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Load module configurations
|
||||
#
|
||||
def load_modules_config
|
||||
self.set('beef.module', {})
|
||||
Dir.glob("#{$root_dir}/modules/**/*/config.yaml") do | cf |
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
module BeEF
|
||||
module Core
|
||||
module Constants
|
||||
@@ -38,6 +39,9 @@ module Constants
|
||||
FRIENDLY_O_NAME = 'Opera'
|
||||
FRIENDLY_UN_NAME = "UNKNOWN"
|
||||
|
||||
# Attempt to retrieve a browsers friendly name
|
||||
# @param [String] browser_name Short browser name
|
||||
# @return [String] Friendly browser name
|
||||
def self.friendly_name(browser_name)
|
||||
|
||||
case browser_name
|
||||
@@ -53,6 +57,10 @@ module Constants
|
||||
|
||||
end
|
||||
|
||||
# Attempt to match the browserstring to a browser constant
|
||||
# @param [String] browserstring Browser UA string
|
||||
# @return [Array] An array of matching browser constants
|
||||
# @todo Confirm this function returns an array if multiple constants are matched
|
||||
def self.match_browser(browserstring)
|
||||
matches = []
|
||||
browserstring.split(" ").each do |chunk|
|
||||
@@ -80,4 +88,4 @@ module Constants
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
module BeEF
|
||||
module Core
|
||||
module Constants
|
||||
@@ -20,6 +21,7 @@ module Constants
|
||||
module CommandModule
|
||||
|
||||
|
||||
# @note Constants to define the execution probability of a command module (this is browser dependant)
|
||||
VERIFIED_WORKING = 0
|
||||
VERIFIED_UNKNOWN = 1
|
||||
VERIFIED_USER_NOTIFY = 2
|
||||
@@ -30,4 +32,4 @@ module Constants
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -13,11 +13,12 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
module BeEF
|
||||
module Core
|
||||
module Constants
|
||||
|
||||
# The distributed engine codes
|
||||
# @note The distributed engine codes
|
||||
module DistributedEngine
|
||||
|
||||
REQUESTER = 1
|
||||
@@ -27,4 +28,4 @@ module Constants
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -13,11 +13,12 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
module BeEF
|
||||
module Core
|
||||
module Constants
|
||||
|
||||
# The OS'es strings for os detection.
|
||||
# @note The OS'es strings for os detection.
|
||||
module Os
|
||||
|
||||
OS_UNKNOWN_IMG = 'unknown.png'
|
||||
@@ -47,6 +48,9 @@ module Constants
|
||||
OS_ANDROID_IMG = 'android.png'
|
||||
OS_ALL_UA_STR = 'All'
|
||||
|
||||
# Attempt to match operating system string to constant
|
||||
# @param [String] name Name of operating system
|
||||
# @return [String] Constant name of matched operating system, returns 'ALL' if nothing are matched
|
||||
def self.match_os(name)
|
||||
case name.downcase
|
||||
when /win/
|
||||
|
||||
@@ -13,21 +13,18 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
module BeEF
|
||||
module Core
|
||||
#
|
||||
# This module provides crypto functionality
|
||||
#
|
||||
|
||||
module Crypto
|
||||
|
||||
# the minimum length of the security token
|
||||
# @note the minimum length of the security token
|
||||
TOKEN_MINIMUM_LENGTH = 15
|
||||
|
||||
#
|
||||
# Generate a secure random token
|
||||
#
|
||||
# @param: {Integer} the length of the secure token
|
||||
#
|
||||
# @param [Integer] len The length of the secure token
|
||||
# @return [String] Security token
|
||||
def self.secure_token(len = nil)
|
||||
# get default length from config
|
||||
config = BeEF::Core::Configuration.instance
|
||||
|
||||
@@ -13,13 +13,13 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
module BeEF
|
||||
module Core
|
||||
module DistributedEngine
|
||||
module Models
|
||||
#
|
||||
# Table stores the rules for the Distributed Engine.
|
||||
#
|
||||
|
||||
# @note Table stores the rules for the Distributed Engine.
|
||||
class Rules
|
||||
|
||||
include DataMapper::Resource
|
||||
@@ -35,4 +35,4 @@ module Models
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -25,6 +25,10 @@ module Handlers
|
||||
attr_reader :guard
|
||||
@data = {}
|
||||
|
||||
# Handles command data
|
||||
# @param [Hash] data Data from command execution
|
||||
# @param [Class] kclass Class of command
|
||||
# @todo Confirm argument data variable type.
|
||||
def initialize(data, kclass)
|
||||
@guard = Mutex.new
|
||||
@kclass = BeEF::Core::Command.const_get(kclass.capitalize)
|
||||
@@ -32,40 +36,45 @@ module Handlers
|
||||
setup()
|
||||
end
|
||||
|
||||
# Initial setup function, creates the command module and saves details to datastore
|
||||
def setup()
|
||||
@http_params = @data['request'].query # used to populate datastore
|
||||
@http_header = @data['request'].header # used to populate datastore
|
||||
@http_header['referer'] ||= '' # used to populate datastore
|
||||
@http_params = @data['request'].query
|
||||
@http_header = @data['request'].header
|
||||
@http_header['referer'] ||= ''
|
||||
|
||||
# get and check command id from the request
|
||||
# @note get and check command id from the request
|
||||
command_id = get_param(@data, 'cid')
|
||||
# ruby filter needs to be updated to detect fixnums not strings
|
||||
# @todo ruby filter needs to be updated to detect fixnums not strings
|
||||
command_id = command_id.to_s()
|
||||
raise WEBrick::HTTPStatus::BadRequest, "command_id is invalid" if not BeEF::Filters.is_valid_command_id?(command_id.to_s())
|
||||
|
||||
# get and check session id from the request
|
||||
# @note get and check session id from the request
|
||||
beefhook = get_param(@data, 'beefhook')
|
||||
raise WEBrick::HTTPStatus::BadRequest, "beefhook is invalid" if not BeEF::Filters.is_valid_hook_session_id?(beefhook)
|
||||
|
||||
# create the command module to handle the response
|
||||
command = @kclass.new(BeEF::Module.get_key_by_class(@kclass)) # create the commamd module
|
||||
command.build_callback_datastore(@http_params, @http_header) # build datastore from the response
|
||||
# @note create the command module to handle the response
|
||||
command = @kclass.new(BeEF::Module.get_key_by_class(@kclass))
|
||||
command.build_callback_datastore(@http_params, @http_header)
|
||||
command.session_id = beefhook
|
||||
if command.respond_to?(:post_execute)
|
||||
command.post_execute
|
||||
end
|
||||
|
||||
# get/set details for datastore and log entry
|
||||
# @note get/set details for datastore and log entry
|
||||
command_friendly_name = command.friendlyname
|
||||
raise WEBrick::HTTPStatus::BadRequest, "command friendly name empty" if command_friendly_name.empty?
|
||||
command_results = get_param(@data, 'results')
|
||||
raise WEBrick::HTTPStatus::BadRequest, "command results empty" if command_results.empty?
|
||||
# save the command module results to the datastore and create a log entry
|
||||
# @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)
|
||||
|
||||
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
|
||||
|
||||
@@ -17,9 +17,7 @@ module BeEF
|
||||
module Core
|
||||
module Handlers
|
||||
|
||||
#
|
||||
# This class handles connections from zombies to the framework.
|
||||
#
|
||||
# @note This class handles connections from hooked browsers to the framework.
|
||||
class HookedBrowsers < WEBrick::HTTPServlet::AbstractServlet
|
||||
|
||||
include BeEF::Core::Handlers::Modules::BeEFJS
|
||||
@@ -31,11 +29,10 @@ module Handlers
|
||||
@guard = Mutex.new
|
||||
end
|
||||
|
||||
#
|
||||
# This method processes the http requests sent by a zombie to the framework.
|
||||
# It will update the database to add or update the current zombie and deploy
|
||||
# some command modules or plugins.
|
||||
#
|
||||
# This method processes the http requests sent by a hooked browser to the framework. It will update the database to add or update the current zombie and deploy some command modules or plugins.
|
||||
# @param [Hash] request HTTP request object
|
||||
# @param [Hash] response HTTP response object
|
||||
# @todo Confirm return type of this function
|
||||
def do_GET(request, response)
|
||||
@body = ''
|
||||
@params = request.query
|
||||
@@ -43,7 +40,7 @@ module Handlers
|
||||
@response = response
|
||||
config = BeEF::Core::Configuration.instance
|
||||
|
||||
# check source ip address of browser
|
||||
# @note check source ip address of browser
|
||||
permitted_hooking_subnet = config.get('beef.restrictions.permitted_hooking_subnet')
|
||||
target_network = IPAddr.new(permitted_hooking_subnet)
|
||||
if not target_network.include?(request.peeraddr[3].to_s)
|
||||
@@ -52,23 +49,24 @@ module Handlers
|
||||
return
|
||||
end
|
||||
|
||||
# get zombie if already hooked the framework
|
||||
# @note get zombie if already hooked the framework
|
||||
hook_session_id = request.get_hook_session_id()
|
||||
hooked_browser = BeEF::Core::Models::HookedBrowser.first(:session => hook_session_id) if not hook_session_id.nil?
|
||||
|
||||
if not hooked_browser # is a new browser so return instructions to set up the hook
|
||||
|
||||
# @note is a new browser so return instructions to set up the hook
|
||||
if not hooked_browser
|
||||
|
||||
# generate the instructions to hook the browser
|
||||
host_name = @request.host # get the host from the HOST attribute in the HTTP header
|
||||
# @note generate the instructions to hook the browser
|
||||
host_name = @request.host
|
||||
raise WEBrick::HTTPStatus::BadRequest, "Invalid host name" if not BeEF::Filters.is_valid_hostname?(host_name)
|
||||
build_beefjs!(host_name)
|
||||
|
||||
else # is a known browseer so send instructions
|
||||
|
||||
# record the last poll from the browser
|
||||
|
||||
# @note is a known browser so send instructions
|
||||
else
|
||||
# @note record the last poll from the browser
|
||||
hooked_browser.lastseen = Time.new.to_i
|
||||
|
||||
# Check for a change in zombie IP and log an event
|
||||
# @note Check for a change in zombie IP and log an event
|
||||
if hooked_browser.ip != @request.peeraddr[3].to_s
|
||||
BeEF::Core::Logger.instance.register('Zombie',"IP address has changed from #{hooked_browser.ip} to #{@request.peeraddr[3].to_s}","#{hooked_browser.id}")
|
||||
hooked_browser.ip = @request.peeraddr[3].to_s
|
||||
@@ -77,17 +75,15 @@ module Handlers
|
||||
hooked_browser.count!
|
||||
hooked_browser.save
|
||||
|
||||
# add all availible command module instructions to the response
|
||||
# @note add all available command module instructions to the response
|
||||
zombie_commands = BeEF::Core::Models::Command.all(:hooked_browser_id => hooked_browser.id, :instructions_sent => false)
|
||||
zombie_commands.each{|command| add_command_instructions(command, hooked_browser)}
|
||||
|
||||
#
|
||||
# We dynamically get the list of all browser hook handler using the API and register them
|
||||
#
|
||||
# @note We dynamically get the list of all browser hook handler using the API and register them
|
||||
BeEF::API::Registrar.instance.fire(BeEF::API::Server::Hook, 'pre_hook_send', hooked_browser, @body, @params, @request, @response)
|
||||
end
|
||||
|
||||
# set response headers and body
|
||||
# @note set response headers and body
|
||||
response.set_no_cache
|
||||
response.header['Content-Type'] = 'text/javascript'
|
||||
response.header['Access-Control-Allow-Origin'] = '*'
|
||||
@@ -96,17 +92,19 @@ module Handlers
|
||||
|
||||
end
|
||||
|
||||
# @note alias do_POST function to do_GET
|
||||
alias do_POST do_GET
|
||||
|
||||
private
|
||||
|
||||
# Object representing the HTTP request
|
||||
# @note Object representing the HTTP request
|
||||
@request
|
||||
|
||||
# Object representing the HTTP response
|
||||
# @note Object representing the HTTP response
|
||||
@response
|
||||
|
||||
# A string containing the list of BeEF components active in the hooked browser
|
||||
# @note A string containing the list of BeEF components active in the hooked browser
|
||||
# @todo Confirm this variable is still used
|
||||
@beef_js_cmps
|
||||
|
||||
end
|
||||
|
||||
@@ -18,50 +18,45 @@ module Core
|
||||
module Handlers
|
||||
module Modules
|
||||
|
||||
#
|
||||
# Purpose: avoid rewriting several times the same code.
|
||||
#
|
||||
# @note Purpose: avoid rewriting several times the same code.
|
||||
module BeEFJS
|
||||
|
||||
#
|
||||
# Builds the default beefjs library (all default components of the library).
|
||||
#
|
||||
# @param: {Object} the hook session id
|
||||
# @param: {Boolean} if the framework is already loaded in the hooked browser
|
||||
#
|
||||
# @param [Object] req_host The request object
|
||||
def build_beefjs!(req_host)
|
||||
|
||||
# set up values required to construct beefjs
|
||||
beefjs = '' # init the beefjs string (to be sent as the beefjs file)
|
||||
beefjs_path = "#{$root_dir}/core/main/client/" # location of sub files
|
||||
# @note set up values required to construct beefjs
|
||||
beefjs = ''
|
||||
# @note location of sub files
|
||||
beefjs_path = "#{$root_dir}/core/main/client/"
|
||||
js_sub_files = %w(lib/jquery-1.5.2.min.js lib/evercookie.js lib/json2.js beef.js browser.js browser/cookie.js session.js os.js dom.js logger.js net.js updater.js encode/base64.js encode/json.js net/local.js init.js)
|
||||
|
||||
# construct the beefjs string from file(s)
|
||||
# @note construct the beefjs string from file(s)
|
||||
js_sub_files.each {|js_sub_file_name|
|
||||
js_sub_file_abs_path = beefjs_path + js_sub_file_name # construct absolute path
|
||||
beefjs << (File.read(js_sub_file_abs_path) + "\n\n") # concat each js sub file
|
||||
js_sub_file_abs_path = beefjs_path + js_sub_file_name
|
||||
beefjs << (File.read(js_sub_file_abs_path) + "\n\n")
|
||||
}
|
||||
|
||||
# create the config for the hooked browser session
|
||||
# @note create the config for the hooked browser session
|
||||
config = BeEF::Core::Configuration.instance
|
||||
hook_session_name = config.get('beef.http.hook_session_name')
|
||||
hook_session_config = BeEF::Core::Server.instance.to_h
|
||||
|
||||
# if http_host="0.0.0.0" in config ini, use the host requested by client
|
||||
# @note if http_host="0.0.0.0" in config ini, use the host requested by client
|
||||
if hook_session_config['beef_host'].eql? "0.0.0.0"
|
||||
hook_session_config['beef_host'] = req_host
|
||||
hook_session_config['beef_url'].sub!(/0\.0\.0\.0/, req_host)
|
||||
end
|
||||
|
||||
# populate place holders in the beefjs string and set the response body
|
||||
# @note populate place holders in the beefjs string and set the response body
|
||||
eruby = Erubis::FastEruby.new(beefjs)
|
||||
@body << eruby.evaluate(hook_session_config)
|
||||
|
||||
end
|
||||
|
||||
#
|
||||
# Finds the path to js components
|
||||
#
|
||||
# @param [String] component Name of component
|
||||
# @return [String|Boolean] Returns false if path was not found, otherwise returns component path
|
||||
def find_beefjs_component_path(component)
|
||||
component_path = component
|
||||
component_path.gsub!(/beef./, '')
|
||||
@@ -73,13 +68,10 @@ module Modules
|
||||
component_path
|
||||
end
|
||||
|
||||
#
|
||||
# Builds missing beefjs components.
|
||||
#
|
||||
# Ex: build_missing_beefjs_components(['beef.net.local', 'beef.net.requester'])
|
||||
#
|
||||
# @param [Array] beefjs_components An array of component names
|
||||
def build_missing_beefjs_components(beefjs_components)
|
||||
# verifies that @beef_js_cmps is not nil to avoid bugs
|
||||
# @note verifies that @beef_js_cmps is not nil to avoid bugs
|
||||
@beef_js_cmps = '' if @beef_js_cmps.nil?
|
||||
|
||||
if beefjs_components.is_a? String
|
||||
@@ -91,14 +83,13 @@ module Modules
|
||||
beefjs_components.keys.each {|k|
|
||||
next if @beef_js_cmps.include? beefjs_components[k]
|
||||
|
||||
# path to the component
|
||||
# @note path to the component
|
||||
component_path = beefjs_components[k]
|
||||
|
||||
# we output the component to the hooked browser
|
||||
# @note we output the component to the hooked browser
|
||||
@body << File.read(component_path)+"\n\n"
|
||||
|
||||
# finally we add the component to the list of components already generated so it does not
|
||||
# get generated numerous times.
|
||||
# @note finally we add the component to the list of components already generated so it does not get generated numerous times.
|
||||
if @beef_js_cmps.eql? ''
|
||||
@beef_js_cmps = component_path
|
||||
else
|
||||
|
||||
@@ -20,9 +20,9 @@ module Modules
|
||||
|
||||
module Command
|
||||
|
||||
#
|
||||
# Adds the command module instructions to a hooked browser's http response.
|
||||
#
|
||||
# @param [Object] command Command object
|
||||
# @param [Object] hooked_browser Hooked Browser object
|
||||
def add_command_instructions(command, hooked_browser)
|
||||
|
||||
raise WEBrick::HTTPStatus::BadRequest, "hooked_browser is nil" if hooked_browser.nil?
|
||||
@@ -30,7 +30,7 @@ module Modules
|
||||
raise WEBrick::HTTPStatus::BadRequest, "hooked_browser is nil" if command.nil?
|
||||
raise WEBrick::HTTPStatus::BadRequest, "hooked_browser.command_module_id is nil" if command.command_module_id.nil?
|
||||
|
||||
# get the command module
|
||||
# @note get the command module
|
||||
command_module = BeEF::Core::Models::CommandModule.first(:id => command.command_module_id)
|
||||
raise WEBrick::HTTPStatus::BadRequest, "command_module is nil" if command_module.nil?
|
||||
raise WEBrick::HTTPStatus::BadRequest, "command_module.path is nil" if command_module.path.nil?
|
||||
@@ -51,13 +51,13 @@ module Modules
|
||||
|
||||
@body << command_module.output + "\n\n"
|
||||
|
||||
# prints the event to the console
|
||||
# @note prints the event to the console
|
||||
if BeEF::Settings.console?
|
||||
name = command_module.friendlyname || kclass
|
||||
print_info "Hooked browser #{hooked_browser.ip} has been sent instructions from command module '#{name}'"
|
||||
end
|
||||
|
||||
# flag that the command has been sent to the hooked browser
|
||||
# @note flag that the command has been sent to the hooked browser
|
||||
command.instructions_sent = true
|
||||
command.save
|
||||
end
|
||||
|
||||
@@ -13,48 +13,35 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
module BeEF
|
||||
module Core
|
||||
#
|
||||
# This class takes care of logging events in the db.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# logger = BeEF::Core::Logger.instance
|
||||
# logger.register('Authentication', 'User with ip 127.0.0.1 has successfully authenticated into the application') # => true
|
||||
#
|
||||
# zombie_id = 1
|
||||
# logger.register('Zombie', '123.456.789.123 just joined the horde', zombie_id) # => true
|
||||
#
|
||||
|
||||
class Logger
|
||||
|
||||
include Singleton
|
||||
|
||||
#
|
||||
# Constructor
|
||||
#
|
||||
def initialize
|
||||
@logs = BeEF::Core::Models::Log
|
||||
end
|
||||
|
||||
#
|
||||
# Registers a new event in the logs
|
||||
#
|
||||
# @param: {String} the origine of the event (i.e. Authentication, Zombie)
|
||||
# @param: {String} the event description
|
||||
# @param: {Integer} the id of the hooked browser affected (default = 0 if no HB)
|
||||
#
|
||||
def register(from, event, zombie = 0)
|
||||
# @param [String] from The origin of the event (i.e. Authentication, Hooked Browser)
|
||||
# @param [String] event The event description
|
||||
# @param [Integer] hb The id of the hooked browser affected (default = 0 if no HB)
|
||||
# @return [Boolean] True if the register was successful
|
||||
def register(from, event, hb = 0)
|
||||
# type conversion to enforce standards
|
||||
zombie = zombie.to_i
|
||||
hb = hb.to_i
|
||||
|
||||
# arguments type checking
|
||||
raise Exception::TypeError, '"from" needs to be a string' if not from.string?
|
||||
raise Exception::TypeError, '"event" needs to be a string' if not event.string?
|
||||
raise Exception::TypeError, '"zombie" needs to be an integer' if not zombie.integer?
|
||||
raise Exception::TypeError, '"Hooked Browser ID" needs to be an integer' if not hb.integer?
|
||||
|
||||
# logging the new event into the database
|
||||
@logs.new(:type => "#{from}", :event => "#{event}", :date => Time.now, :hooked_browser_id => zombie).save
|
||||
@logs.new(:type => "#{from}", :event => "#{event}", :date => Time.now, :hooked_browser_id => hb).save
|
||||
|
||||
# return
|
||||
true
|
||||
|
||||
@@ -13,27 +13,23 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
module BeEF
|
||||
module Core
|
||||
#
|
||||
# This class migrates and updates values in the database each time you restart BeEF.
|
||||
# So for example, when you want to add a new command module, you stop BeEF, copy your command module into the framework
|
||||
# and then restart BeEF. That class will take care of installing automatically the new command module in the db.
|
||||
#
|
||||
|
||||
# @note This class migrates and updates values in the database each time you restart BeEF.
|
||||
# So for example, when you want to add a new command module, you stop BeEF, copy your command module into the framework
|
||||
# and then restart BeEF. That class will take care of installing automatically the new command module in the db.
|
||||
class Migration
|
||||
|
||||
include Singleton
|
||||
|
||||
#
|
||||
# Updates the database.
|
||||
#
|
||||
def update_db!
|
||||
update_commands!
|
||||
end
|
||||
|
||||
#
|
||||
# Checks for new command modules and updates the database.
|
||||
#
|
||||
def update_commands!
|
||||
config = BeEF::Core::Configuration.instance
|
||||
|
||||
|
||||
@@ -13,22 +13,12 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
module BeEF
|
||||
module Core
|
||||
module Models
|
||||
#
|
||||
# Table stores the commands that have been sent to the Hooked Browsers.
|
||||
#
|
||||
# Attributes:
|
||||
#
|
||||
# - id
|
||||
# - data
|
||||
# - creationdate
|
||||
# - label
|
||||
# - instructions_sent
|
||||
# - command_module_id
|
||||
# - hooked_browser_id
|
||||
#
|
||||
|
||||
# @note Table stores the commands that have been sent to the Hooked Browsers.
|
||||
class Command
|
||||
|
||||
include DataMapper::Resource
|
||||
@@ -43,25 +33,22 @@ module Models
|
||||
|
||||
has n, :results
|
||||
|
||||
#
|
||||
# Save results and flag that the command has been run on the hooked browser
|
||||
#
|
||||
# @param: {String} the session_id.
|
||||
# @param: {String} the command_id.
|
||||
# @param: {String} the command friendly name.
|
||||
# @param: {String} the result of the command module.
|
||||
#
|
||||
# @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)
|
||||
# enforcing arguments types
|
||||
# @note enforcing arguments types
|
||||
command_id = command_id.to_i
|
||||
|
||||
# argument type checking
|
||||
# @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?
|
||||
|
||||
# get the hooked browser structure and id from the database
|
||||
# @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?
|
||||
@@ -69,18 +56,18 @@ module Models
|
||||
raise Exception::TypeError, "hooked_browser.ip is nil" if hooked_browser.ip.nil?
|
||||
hooked_browser_ip = hooked_browser.ip
|
||||
|
||||
# get the command module data structure from the database
|
||||
# @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?
|
||||
|
||||
# create the entry for the results
|
||||
# @note create the entry for the results
|
||||
command.results.new(:hooked_browser_id => hooked_browser_id, :data => result.to_json, :date => Time.now.to_i)
|
||||
command.save
|
||||
|
||||
# log that the result was returned
|
||||
# @note log that the result was returned
|
||||
BeEF::Core::Logger.instance.register('Command', "Hooked browser #{hooked_browser.ip} has executed instructions from command module '#{command_friendly_name}'", hooked_browser_id)
|
||||
|
||||
# prints the event into the console
|
||||
# @note prints the event into the console
|
||||
if BeEF::Settings.console?
|
||||
print_info "Hooked browser #{hooked_browser.ip} has executed instructions from command module '#{command_friendly_name}'"
|
||||
end
|
||||
@@ -90,4 +77,4 @@ module Models
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -31,27 +31,25 @@ module Models
|
||||
property :firstseen, String, :length => 15
|
||||
property :lastseen, String, :length => 15
|
||||
property :httpheaders, Text, :lazy => false
|
||||
property :domain, Text, :lazy => false # the domain originating the hook request
|
||||
# @note the domain originating the hook request
|
||||
property :domain, Text, :lazy => false
|
||||
property :count, Integer, :lazy => false
|
||||
property :has_init, Boolean, :default => false
|
||||
property :is_proxy, Boolean, :default => false # if true the HB is used as a tunneling proxy
|
||||
|
||||
property :is_proxy, Boolean, :default => false
|
||||
# @note if true the HB is used as a tunneling proxy
|
||||
|
||||
has n, :commands
|
||||
has n, :results
|
||||
has n, :logs
|
||||
#has n, :https
|
||||
|
||||
#
|
||||
# Increases the count of a zombie
|
||||
#
|
||||
def count!
|
||||
if not self.count.nil? then self.count += 1; else self.count = 1; end
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the icon representing the browser type the
|
||||
# zombie is using (i.e. Firefox, Internet Explorer)
|
||||
#
|
||||
# Returns the icon representing the browser type the hooked browser is using (i.e. Firefox, Internet Explorer)
|
||||
# @return [String] String constant containing browser icon path
|
||||
def browser_icon
|
||||
agent = JSON.parse(self.httpheaders)['user-agent'].to_s || nil
|
||||
|
||||
@@ -67,10 +65,8 @@ module Models
|
||||
BeEF::Extension::AdminUI::Constants::Agents::AGENT_UNKNOWN_IMG
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the icon representing the os type the
|
||||
# hooked browser is running (i.e. Windows, Linux)
|
||||
#
|
||||
# Returns the icon representing the os type the hooked browser is running (i.e. Windows, Linux)
|
||||
# @return [String] String constant containing operating system icon path
|
||||
def os_icon
|
||||
agent = JSON.parse(self.httpheaders)['user-agent'].to_s || nil
|
||||
|
||||
@@ -86,4 +82,4 @@ module Models
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -16,11 +16,7 @@
|
||||
module BeEF
|
||||
module Core
|
||||
module Models
|
||||
#
|
||||
# This table stores the logs from the framework.
|
||||
#
|
||||
# See BeEF::Core::Logger for how to log events.
|
||||
#
|
||||
|
||||
class Log
|
||||
|
||||
include DataMapper::Resource
|
||||
@@ -36,4 +32,4 @@ module Models
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -16,9 +16,7 @@
|
||||
module BeEF
|
||||
module Core
|
||||
module Models
|
||||
#
|
||||
# Table stores the results from commands.
|
||||
#
|
||||
|
||||
class Result
|
||||
|
||||
include DataMapper::Resource
|
||||
@@ -33,4 +31,4 @@ module Models
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -16,11 +16,8 @@
|
||||
module BeEF
|
||||
module Core
|
||||
module Models
|
||||
#
|
||||
# Table stores the list of users that have authenticated into beef.
|
||||
#
|
||||
# TODO: move this table into the AdminUI extension folder.
|
||||
#
|
||||
|
||||
# @todo move this table into the AdminUI extension folder.
|
||||
class User
|
||||
|
||||
include DataMapper::Resource
|
||||
@@ -31,9 +28,8 @@ module Models
|
||||
property :session_id, String, :length => 255
|
||||
property :ip, Text
|
||||
|
||||
#
|
||||
# Checks if the user has been authenticated
|
||||
#
|
||||
# @return [Boolean] If the user is authenticated
|
||||
def authenticated?
|
||||
true || false if not @ip.nil?
|
||||
end
|
||||
@@ -42,4 +38,4 @@ module Models
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -18,17 +18,16 @@ module Core
|
||||
module NetworkStack
|
||||
|
||||
module RegisterHttpHandler
|
||||
#
|
||||
|
||||
# Register the http handler for the network stack
|
||||
#
|
||||
# @param [Object] server HTTP server instance
|
||||
def self.mount_handler(server)
|
||||
#dynamic handler
|
||||
# @note this mounts the dynamic handler
|
||||
server.mount('/dh', true, BeEF::Core::NetworkStack::Handlers::DynamicReconstruction)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Register core API calls
|
||||
BeEF::API::Registrar.instance.register(BeEF::Core::NetworkStack::RegisterHttpHandler, BeEF::API::Server, 'mount_handler')
|
||||
|
||||
end
|
||||
|
||||
@@ -18,25 +18,28 @@ module Core
|
||||
module NetworkStack
|
||||
module Handlers
|
||||
|
||||
#
|
||||
# Class defining BeEF assets
|
||||
#
|
||||
# @note Class defining BeEF assets
|
||||
class AssetHandler
|
||||
|
||||
# call BeEF::Core::NetworkStack::Handlers::AssetHandler.instance
|
||||
# @note call BeEF::Core::NetworkStack::Handlers::AssetHandler.instance
|
||||
include Singleton
|
||||
|
||||
attr_reader :allocations, :root_dir
|
||||
|
||||
# Starts the AssetHandler instance
|
||||
def initialize
|
||||
@allocations = {}
|
||||
@http_server = BeEF::Core::Server.instance
|
||||
@root_dir = File.expand_path('../../../../', __FILE__)
|
||||
end
|
||||
|
||||
#
|
||||
# Binds a file to a mount point
|
||||
#
|
||||
# @param [String] file File path to asset
|
||||
# @param [String] path URL path to mount the asset to (can be nil for random path)
|
||||
# @param [String] extension Extension to append to the URL path (can be nil for none)
|
||||
# @param [Integer] count The amount of times the asset can be accessed before being automatically unbinded (-1 = unlimited)
|
||||
# @return [String] URL Path of mounted asset
|
||||
# @todo This function should accept a hooked browser session to limit the mounted file to a certain session
|
||||
def bind(file, path=nil, extension=nil, count=-1)
|
||||
url = buildURL(path, extension)
|
||||
@allocations[url] = {'file' => "#{root_dir}"+file, 'path' => path, 'extension' => extension, 'count' => count}
|
||||
@@ -45,26 +48,27 @@ module Handlers
|
||||
return url
|
||||
end
|
||||
|
||||
#
|
||||
# Unbinds a file from a mount point
|
||||
#
|
||||
# @param [String] url URL path of asset to be unbinded
|
||||
def unbind(url)
|
||||
@allocations.delete(url)
|
||||
@http_server.unmount(url, true)
|
||||
end
|
||||
|
||||
#
|
||||
# Builds a URL based on the path and extention, if neither are passed a random URL will be generated
|
||||
#
|
||||
# Builds a URL based on the path and extension, if neither are passed a random URL will be generated
|
||||
# @param [String] path URL Path defined by bind()
|
||||
# @param [String] extension Extension defined by bind()
|
||||
# @param [Integer] length The amount of characters to be used when generating a random URL
|
||||
# @return [String] Generated URL
|
||||
def buildURL(path, extension, length=20)
|
||||
url = (path == nil) ? '/'+rand(36**length).to_s(36) : path;
|
||||
url += (extension == nil) ? '' : '.'+extension;
|
||||
return url
|
||||
end
|
||||
|
||||
#
|
||||
# Checks if the file is allocated, if the file isn't return true to pass onto FileHandler.
|
||||
#
|
||||
# @param [String] url URL Path of mounted file
|
||||
# @return [Boolean] Returns true if the file is mounted
|
||||
def check(url)
|
||||
if @allocations.has_key?(url)
|
||||
count = @allocations[url]['count']
|
||||
|
||||
@@ -18,19 +18,20 @@ module Core
|
||||
module NetworkStack
|
||||
module Handlers
|
||||
|
||||
#DynamicHanlder is used reconstruct segmented traffic from the zombies
|
||||
|
||||
# @note DynamicHanlder is used reconstruct segmented traffic from the hooked browser
|
||||
class DynamicReconstruction < WEBrick::HTTPServlet::AbstractServlet
|
||||
|
||||
attr_reader :guard
|
||||
|
||||
#holds packet queue
|
||||
# @note holds packet queue
|
||||
PQ = Array.new()
|
||||
|
||||
#obtain dynamic mount points from HttpHookServer
|
||||
# @note obtain dynamic mount points from HttpHookServer
|
||||
MOUNTS = BeEF::Core::Server.instance.mounts
|
||||
|
||||
#Combines packet information and pushes to PQ, then checks packets
|
||||
# Combines packet information and pushes to PQ, then checks packets
|
||||
# @param [Object] request Request object
|
||||
# @param [Object] response Response object
|
||||
def do_POST(request, response)
|
||||
@request = request
|
||||
response.set_no_cache
|
||||
@@ -48,9 +49,10 @@ module Handlers
|
||||
check_packets()
|
||||
end
|
||||
|
||||
# @note Alias do_GET function to do_POST
|
||||
alias do_GET do_POST
|
||||
|
||||
#check packets goes through the PQ array and attempts to reconstruct the stream from multiple packets
|
||||
# Check packets goes through the PQ array and attempts to reconstruct the stream from multiple packets
|
||||
def check_packets()
|
||||
checked = Array.new()
|
||||
PQ.each do |packet|
|
||||
@@ -88,14 +90,17 @@ module Handlers
|
||||
end
|
||||
end
|
||||
|
||||
#delete packets that have been reconstructed, return deleted packets
|
||||
# Delete packets that have been reconstructed, return deleted packets
|
||||
# @param [String] beefhook Beefhook of hooked browser
|
||||
# @param [Integer] stream_id The stream ID
|
||||
def expunge(beefhook, stream_id)
|
||||
packets = PQ.select{ |p| p[:beefhook] == beefhook and p[:stream_id] == stream_id }
|
||||
PQ.delete_if { |p| p[:beefhook] == beefhook and p[:stream_id] == stream_id }
|
||||
return packets.sort_by { |p| p[:packet_id] }
|
||||
end
|
||||
|
||||
#execute is called once a stream has been rebuilt. it searches the mounts and passes the data to the correct handler
|
||||
# Execute is called once a stream has been rebuilt. it searches the mounts and passes the data to the correct handler
|
||||
# @param [Hash] data Hash of data that has been rebuilt by the dynamic reconstruction
|
||||
def execute(data)
|
||||
handler = get_param(data, 'handler')
|
||||
if (MOUNTS.has_key?(handler))
|
||||
@@ -107,7 +112,10 @@ module Handlers
|
||||
end
|
||||
end
|
||||
|
||||
#assist function for getting parameter from hash
|
||||
# Assist function for getting parameter from hash
|
||||
# @param [Hash] query Hash to pull key from
|
||||
# @param [String] key The key association to return from `query`
|
||||
# @return Value associated with `key`
|
||||
def get_param(query, key)
|
||||
return nil if query[key].nil?
|
||||
query[key]
|
||||
|
||||
@@ -13,30 +13,20 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
module BeEF
|
||||
module Core
|
||||
#
|
||||
# Class defining the BeEF http server.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# server = BeEF::Core::Server.instance
|
||||
# server.prepare
|
||||
# server.start
|
||||
# ...
|
||||
# server.stop
|
||||
#
|
||||
|
||||
class Server
|
||||
|
||||
include Singleton
|
||||
|
||||
# Grabs the version of beef the framework is deployed on
|
||||
# @note Grabs the version of beef the framework is deployed on
|
||||
VERSION = BeEF::Core::Configuration.instance.get('beef.version')
|
||||
|
||||
attr_reader :root_dir, :url, :configuration, :command_urls, :mounts
|
||||
#
|
||||
# Constructor
|
||||
#
|
||||
|
||||
# Constructor starts the BeEF server including the configuration system
|
||||
def initialize
|
||||
@configuration = BeEF::Core::Configuration.instance
|
||||
beef_host = @configuration.get("beef.http.public") || @configuration.get("beef.http.host")
|
||||
@@ -46,10 +36,8 @@ module Core
|
||||
@mounts = {}
|
||||
end
|
||||
|
||||
#
|
||||
# Returns all server variables in a hash. Useful for Erubis when
|
||||
# generating the javascript for the command modules and hooking.
|
||||
#
|
||||
# Returns all server variables in a hash. Useful for Erubis when generating the javascript for the command modules and hooking.
|
||||
# @return [Hash] BeEF info hash
|
||||
def to_h
|
||||
{
|
||||
'beef_version' => VERSION,
|
||||
@@ -62,9 +50,11 @@ module Core
|
||||
}
|
||||
end
|
||||
|
||||
#
|
||||
#
|
||||
#
|
||||
# Returns command URL
|
||||
# @param [String] command_path Command path
|
||||
# @return [String] URL of command
|
||||
# @todo Unsure how @command_urls is populated, this command is possibly deprecated
|
||||
# @deprecated See note
|
||||
def get_command_url(command_path)
|
||||
# argument type checking
|
||||
raise Exception::TypeError, '"command_path" needs to be a string' if not command_path.string?
|
||||
@@ -76,9 +66,7 @@ module Core
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Starts the BeEF http server.
|
||||
#
|
||||
def prepare
|
||||
if not @http_server
|
||||
config = {}
|
||||
@@ -93,16 +81,12 @@ module Core
|
||||
# Create http handler for the javascript hook file
|
||||
mount("#{@configuration.get("beef.http.hook_file")}", true, BeEF::Core::Handlers::HookedBrowsers)
|
||||
|
||||
#
|
||||
# We dynamically get the list of all http handler using the API and register them
|
||||
#
|
||||
BeEF::API::Registrar.instance.fire(BeEF::API::Server, 'mount_handler', self)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Starts the BeEF http server
|
||||
#
|
||||
def start
|
||||
# we trap CTRL+C in the console and kill the server
|
||||
trap("INT") { BeEF::Core::Server.instance.stop }
|
||||
@@ -111,9 +95,7 @@ module Core
|
||||
@http_server.start
|
||||
end
|
||||
|
||||
#
|
||||
# Stops the BeEF http server.
|
||||
#
|
||||
def stop
|
||||
if @http_server
|
||||
# shuts down the server
|
||||
@@ -125,19 +107,14 @@ module Core
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Restarts the BeEF http server.
|
||||
#
|
||||
def restart; stop; start; end
|
||||
|
||||
#
|
||||
# Mounts a handler, can either be a hard or soft mount
|
||||
#
|
||||
# @param: {String} the url to mount
|
||||
# @param: {Boolean} set to true for a hard mount, false for a soft mount.
|
||||
# @param: {Class} class to call once mount is triggered
|
||||
# @param: {Various} arguments to pass to the http handler class
|
||||
#
|
||||
# @param [String] url The url to mount
|
||||
# @param [Boolean] hard Set to true for a hard mount, false for a soft mount.
|
||||
# @param [Class] http_handler_class Class to call once mount is triggered
|
||||
# @param args Arguments to pass to the http handler class
|
||||
def mount(url, hard, http_handler_class, args = nil)
|
||||
# argument type checking
|
||||
raise Exception::TypeError, '"url" needs to be a string' if not url.string?
|
||||
@@ -161,12 +138,9 @@ module Core
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Unmounts handler
|
||||
#
|
||||
# @param: {String} url to mount.
|
||||
# @param: {Boolean} set to true for a hard mount, false for a soft mount.
|
||||
#
|
||||
# @param [String] url URL to unmount.
|
||||
# @param [Boolean] hard Set to true for a hard mount, false for a soft mount.
|
||||
def unmount(url, hard)
|
||||
# argument type checking
|
||||
raise Exception::TypeError, '"url" needs to be a string' if not url.string?
|
||||
|
||||
Reference in New Issue
Block a user