diff --git a/beef b/beef index 34ec744d9..79e24f342 100755 --- a/beef +++ b/beef @@ -16,7 +16,7 @@ # limitations under the License. # -# check version supported +# @note Version check to ensure BeEF is running Ruby 1.9 > if RUBY_VERSION < '1.9' puts "\n" puts "Ruby version " + RUBY_VERSION + " is no longer supported. Please upgrade 1.9 or later." @@ -25,41 +25,38 @@ if RUBY_VERSION < '1.9' end $:.unshift(File.join(File.expand_path(File.dirname(__FILE__)), '.')) - $root_dir = File.expand_path('..', __FILE__) -# prevent some errors on encoding: encoding handling changed (improved) from 1.8.7 to 1.9.1/2. +# @note Prevent some errors on encoding: encoding handling changed (improved) from 1.8.7 to 1.9.1/2. if RUBY_VERSION =~ /1.9/ Encoding.default_external = Encoding::UTF_8 Encoding.default_internal = Encoding::UTF_8 end +# @note Require core loader's require 'core/loader' -# load config +# @note Starts configuration system config = BeEF::Core::Configuration.instance -# Loads extensions +# @note Loads enabled extensions BeEF::Extensions.load -# prints welcome message +# @note Prints BeEF welcome message #BeEF::Extension::Console::Banners.print_ascii_art BeEF::Extension::Console::Banners.print_welcome_msg -# Loads modules +# @note Loads enabled modules BeEF::Modules.load -# disable reverse dns +# @note Disable reverse dns Socket.do_not_reverse_lookup = true -# setup database +# @note Database setup - use DataMapper::Logger.new($stdout, :debug) for development debugging case config.get("beef.database.driver") when "sqlite" DataMapper.setup(:default, "sqlite3://#{$root_dir}/#{config.get("beef.database.db_file")}") when "mysql","postgres" - # === Remove comment of next line for logging queries (very verbose) === - # DataMapper::Logger.new($stdout, :debug) - # DataMapper.setup(:default, :adapter => config.get("beef.database.driver"), :host => config.get("beef.database.db_host"), @@ -72,6 +69,8 @@ case config.get("beef.database.driver") print_error 'No default database selected. Please add one in config.yaml' end +# @note Resets the database if the -x flag was passed +# @todo Change reference from Extension::Console to Core::Console once the console extension is merged with the core if BeEF::Extension::Console.resetdb? print_info 'Resetting the database for BeEF.' DataMapper.auto_migrate! @@ -79,27 +78,26 @@ else DataMapper.auto_upgrade! end -# if metasploit is unreachable it can take 10/15 seconds to load +# @note Extensions may take a moment to load, thus we print out a please wait message print_info 'BeEF is loading. Wait a few seconds...' -# check for new command modules +# @note Execute migration procedure, checks for new modules BeEF::Core::Migration.instance.update_db! -# prepare the web server to run +# @note Create HTTP Server and prepare it to run http_hook_server = BeEF::Core::Server.instance http_hook_server.prepare -# prints information back to the user before running the server - +# @note Prints information back to the user before running the server BeEF::Extension::Console::Banners.print_loaded_extensions BeEF::Extension::Console::Banners.print_loaded_modules BeEF::Extension::Console::Banners.print_network_interfaces_count BeEF::Extension::Console::Banners.print_network_interfaces_routes -# We dynamically get the list of all browser hook handler using the API and register them +# @note Call the API method 'pre_http_start' BeEF::API::Registra.instance.fire(BeEF::API::Server, 'pre_http_start', http_hook_server) -# We check now for whether we load the Console Shell or not +# @note Start the HTTP Server, we addtionally check whether we load the Console Shell or not if config.get("beef.extension.console.shell.enable") == true puts "" begin @@ -109,6 +107,5 @@ if config.get("beef.extension.console.shell.enable") == true rescue Interrupt end else - # starts the web server http_hook_server.start end diff --git a/core/api.rb b/core/api.rb index 70fb483a1..84ddb495b 100644 --- a/core/api.rb +++ b/core/api.rb @@ -17,17 +17,22 @@ module BeEF module API - # Registra class to handle all registered timed API calls + # Registrar class to handle all registered timed API calls class Registra include Singleton - + + # Create registrar def initialize @registry = [] @count = 1 end - # Register owner, c, method and matching params + # Register timed API calls to an owner + # @param [Class] owner the owner of the API hook + # @param [Class] c the API class the owner would like to hook into + # @param [String] method the method of the class the owner would like to execute + # @param [Array] params an array of parameters that need to be matched before the owner will be called def register(owner, c, method, params = []) if self.verify_api_path(c, method) if not self.registered?(owner, c, method, params) @@ -49,7 +54,13 @@ module API end end - # returns boolean whether or not any owner has registered + # Tests whether the owner is registered for an API hook + # @param [Class] owner the owner of the API hook + # @param [Class] c the API class + # @param [String] method the method of the class + # @param [Array] params an array of parameters that need to be matched + # @return [Boolean] whether or not the owner is registered + # @todo Change the param matching to use the new :is_matched_params?() method - Issue #479 def registered?(owner, c, method, params = []) @registry.each{|r| if r['owner'] == owner and r['class'] == c and r['method'] == method and params == r['params'] @@ -59,7 +70,11 @@ module API return false end - # match is used to determine if a fire() method should continue, matchs a registered API hook without the owner + # Match a timed API call to determine if an API.fire() is required + # @param [Class] c the target API class + # @param [String] method the method of the target API class + # @param [Array] params an array of parameters that need to be matched + # @return [Boolean] whether or not the arguments match an entry in the API registry def matched?(c, method, params = []) @registry.each{|r| if r['class'] == c and r['method'] == method and self.is_matched_params?(r, params) @@ -69,14 +84,19 @@ module API return false end - # unregister API call from owner, class and method + # Un-registers an API hook + # @param [Integer] id the ID of the API hook def unregister(id) @registry.delete_if{|r| r['id'] == id } end - # gets all owners registered to an API call + # Retrieves all the owners and ID's of an API hook + # @param [Class] c the target API class + # @param [String] method the method of the target API class + # @param [Array] params an array of parameters that need to be matched + # @return [Array] an array of hashes consisting of two keys :owner and :id def get_owners(c, method, params = []) owners = [] @registry.each{|r| @@ -90,16 +110,28 @@ module API end # Verifies that the api_path has been regitered + # Verifies the API path has been registered. + # @note This is a security precaution + # @param [Class] c the target API class to verify + # @param [String] m the target method to verify def verify_api_path(c, m) return (c.const_defined?('API_PATHS') and c.const_get('API_PATHS').has_key?(m)) end - # Gets the sym set to the api_path + # Retrieves the registered symbol reference for an API hook + # @param [Class] c the target API class to verify + # @param [String] m the target method to verify + # @return [Symbol] the API path def get_api_path(c, m) return (self.verify_api_path(c, m)) ? c.const_get('API_PATHS')[m] : nil; end - # Match stored API parameters to params, if array item is nil then skip this item + # Matches stored API params to params + # @note If a stored API parameter has a NilClass the parameter matching is skipped for that parameter + # @note By default this method returns true, this is either because the API.fire() did not include any parameters or there were no parameters defined for this registry entry + # @param [Hash] reg hash of registry element, must contain 'params' key + # @param [Array] params array of parameters to be compared to the stored parameters + # @return [Boolean] whether params matches the stored API parameters def is_matched_params?(reg, params) stored = reg['params'] if stored.length == params.length @@ -112,14 +144,14 @@ module API } return false if not matched end - # We return a match because the fire() method did not indicate any, or - # we return a match because there were no params defined for this register return true end - # - # Calls a API fire against a certain class / module (c) method (m) with n parameters (*args) - # + # Fires all owners registered to this API hook + # @param [Class] c the target API class + # @param [String] m the target API method + # @param [Array] *args parameters passed for the API call + # @return [Hash, NilClass] returns either a Hash of :api_id and :data if the owners return data, otherwise NilClass def fire(c, m, *args) mods = self.get_owners(c, m, args) if mods.length > 0 @@ -128,7 +160,7 @@ module API method = self.get_api_path(c, m) mods.each do |mod| begin - #Only used for API Development + #Only used for API Development (very verbose) #print_info "API: #{mod} fired #{method}" result = mod[:owner].method(method).call(*args) if not result == nil diff --git a/core/api/extension.rb b/core/api/extension.rb index c82bc186d..a596a42f9 100644 --- a/core/api/extension.rb +++ b/core/api/extension.rb @@ -13,18 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # + module BeEF module API - # - # All modules that extend this API module will be considered as extensions to the - # core of BeEF. - # - # Examples: - # - # module A - # extend BeEF::API::Extension - # end - # module Extension attr_reader :full_name, :short_name, :description diff --git a/core/api/extensions.rb b/core/api/extensions.rb index 8560dce3a..c9b84151e 100644 --- a/core/api/extensions.rb +++ b/core/api/extensions.rb @@ -17,10 +17,12 @@ module BeEF module API module Extensions + # @note Defined API Paths API_PATHS = { 'post_load' => :post_load } + # API hook fired after all extensions have been loaded def post_load; end diff --git a/core/api/main/configuration.rb b/core/api/main/configuration.rb index 3e40eca70..fcea8c355 100644 --- a/core/api/main/configuration.rb +++ b/core/api/main/configuration.rb @@ -17,10 +17,13 @@ module BeEF module API module Configuration + # @note Defined API Paths API_PATHS = { 'module_configuration_load' => :module_configuration_load } + # Fires just after module configuration is loaded and merged + # @param [String] mod module key def module_configuration_load(mod); end end diff --git a/core/api/main/migration.rb b/core/api/main/migration.rb index ff27af0ef..e1a58152d 100644 --- a/core/api/main/migration.rb +++ b/core/api/main/migration.rb @@ -17,10 +17,12 @@ module BeEF module API module Migration + # @note Defined API Paths API_PATHS = { 'migrate_commands' => :migrate_commands } + # Fired just after the migration process def migrate_commands; end end diff --git a/core/api/main/network_stack/assethandler.rb b/core/api/main/network_stack/assethandler.rb index 81927698b..6f234a473 100644 --- a/core/api/main/network_stack/assethandler.rb +++ b/core/api/main/network_stack/assethandler.rb @@ -19,12 +19,24 @@ module NetworkStack module Handlers module AssetHandler + # Binds a file to be accessible by the hooked browser + # @param [String] file file to be served + # @param [String] path URL path to be bound, if no path is specified a randomly generated one will be used + # @param [String] extension to be used in the URL + # @param [Integer] count amount of times the file can be accessed before being automatically unbound. (-1 = no limit) + # @return [String] URL bound to the specified file + # @todo Add hooked browser parameter to only allow specified hooked browsers access to the bound URL. Waiting on Issue #336 + # @note This is a direct API call and does not have to be registered to be used def self.bind(file, path=nil, extension=nil, count=-1) return BeEF::Core::NetworkStack::Handlers::AssetHandler.instance.bind(file, path, extension, count) end + # Unbinds a file made accessible to hooked browsers + # @param [String] url the bound URL + # @todo Add hooked browser parameter to only unbind specified hooked browsers binds. Waiting on Issue #336 + # @note This is a direct API call and does not have to be registered to be used def self.unbind(url) - return BeEF::Core::NetworkStack::Handlers::AssetHandler.instance.unbind(url) + BeEF::Core::NetworkStack::Handlers::AssetHandler.instance.unbind(url) end end diff --git a/core/api/main/server.rb b/core/api/main/server.rb index a664509a0..43c939083 100644 --- a/core/api/main/server.rb +++ b/core/api/main/server.rb @@ -17,19 +17,34 @@ module BeEF module API module Server + # @note Defined API Paths API_PATHS = { 'mount_handler' => :mount_handler, 'pre_http_start' => :pre_http_start } + # Fires just before the HTTP Server is started + # @param [Object] http_hook_server HTTP Server object def pre_http_start(http_hook_server); end + # Fires just after handlers have been mounted + # @param [Object] server HTTP Server object def mount_handler(server); end + # Mounts a handler + # @param [String] url URL to be mounted + # @param [Boolean] hard whether or not it is a hard mount + # @param [Class] http_handler_class the handler Class + # @param [Array] args an array of arguments + # @note This is a direct API call and does not have to be registered to be used def self.mount(url, hard, http_handler_class, args = nil) BeEF::Core::Server.instance.mount(url, hard, http_handler_class, *args) end + # Unmounts a handler + # @param [String] url URL to be unmounted + # @param [Boolean] hard whether or not it is a hard mount + # @note This is a direct API call and does not have to be registered to be used def self.unmount(url, hard) BeEF::Core::Server.instance.unmount(url, hard) end diff --git a/core/api/main/server/hook.rb b/core/api/main/server/hook.rb index a050e7791..00d1534af 100644 --- a/core/api/main/server/hook.rb +++ b/core/api/main/server/hook.rb @@ -18,13 +18,14 @@ module API module Server module Hook + # @note Defined API Paths API_PATHS = { 'pre_hook_send' => :pre_hook_send } - def pre_hook_send(handler) - - end + # Fires just before the hook is sent to the hooked browser + # @param [Class] handler the associated handler Class + def pre_hook_send(handler); end end diff --git a/core/api/module.rb b/core/api/module.rb index 33ca5a2b2..02c86939f 100644 --- a/core/api/module.rb +++ b/core/api/module.rb @@ -21,6 +21,7 @@ module API module Module + # @note Defined API Paths API_PATHS = { 'pre_soft_load' => :pre_soft_load, 'post_soft_load' => :post_soft_load, @@ -30,16 +31,31 @@ module API 'override_execute' => :override_execute } + # Fired before a module soft load + # @param [String] mod module key of module about to be soft loaded def pre_soft_load(mod); end + # Fired after module soft load + # @param [String] mod module key of module just after soft load def post_soft_load(mod); end + # Fired before a module hard load + # @param [String] mod module key of module about to be hard loaded def pre_hard_load(mod); end + # Fired after module hard load + # @param [String] mod module key of module just after hard load def post_hard_load(mod); end + # Fired before standard module options are returned + # @return [Hash] a hash of options + # @note the option hash is merged with all other API hook's returned hash. Hooking this API method prevents the default options being returned. def get_options; end + # Fired just before a module is executed + # @param [String] mod module key + # @param [Hash] opts a Hash of options + # @note Hooking this API method stops the default flow of the Module.execute() method. def override_execute(mod, opts); end end diff --git a/core/api/modules.rb b/core/api/modules.rb index c1cb876b1..bb88db8d3 100644 --- a/core/api/modules.rb +++ b/core/api/modules.rb @@ -18,10 +18,12 @@ module API module Modules + # @note Defined API Paths API_PATHS = { 'post_soft_load' => :post_soft_load } + # Fires just after all modules are soft loaded def post_soft_load; end end diff --git a/core/core.rb b/core/core.rb index 1e5cfd58e..32a431773 100644 --- a/core/core.rb +++ b/core/core.rb @@ -13,21 +13,13 @@ # See the License for the specific language governing permissions and # limitations under the License. # -=begin - - This is the core of the framework. Be very careful when touching anything in there. - - The standard approach is to code extensions as oppose to edit the core. - -=end module BeEF module Core end end -# Include the database models -# MAKE SURE TO KEEP THOSE IN THE FOLLOWING ORDER OTHERWISE DATAMAPPER GOES CRAZY +# @note Includes database models - the order must be consistent otherwise DataMapper goes crazy require 'core/main/models/user' require 'core/main/models/commandmodule' require 'core/main/models/hookedbrowser' @@ -39,20 +31,20 @@ require 'core/main/models/dynamicpayloadinfo' require 'core/main/models/dynamicpayloads' require 'core/main/models/optioncache' -# Include the constants +# @note Include the constants require 'core/main/constants/browsers' require 'core/main/constants/commandmodule' require 'core/main/constants/distributedengine' require 'core/main/constants/os' -# Include core modules for beef +# @note Include core modules for beef require 'core/main/configuration' require 'core/main/command' require 'core/main/crypto' require 'core/main/logger' require 'core/main/migration' -# Include http server functions for beef +# @note Include http server functions for beef require 'core/main/server' require 'core/main/handlers/modules/beefjs' @@ -61,11 +53,11 @@ require 'core/main/handlers/modules/command' require 'core/main/handlers/commands' require 'core/main/handlers/hookedbrowsers' -# Include the network stack +# @note Include the network stack require 'core/main/network_stack/handlers/dynamicreconstruction' require 'core/main/network_stack/assethandler' require 'core/main/network_stack/api' -# Include the distributed engine +# @note Include the distributed engine require 'core/main/distributed_engine/models/rules' diff --git a/core/extension.rb b/core/extension.rb index a263fbd2f..aa55315f9 100644 --- a/core/extension.rb +++ b/core/extension.rb @@ -16,22 +16,31 @@ module BeEF module Extension - # Checks to see if extensions is in configuration + # Checks to see if extension is set inside the configuration + # @param [String] ext the extension key + # @return [Boolean] whether or not the extension exists in BeEF's configuration def self.is_present(ext) return BeEF::Core::Configuration.instance.get('beef.extension').has_key?(ext.to_s) end # Checks to see if extension is enabled in configuration + # @param [String] ext the extension key + # @return [Boolean] whether or not the extension is enabled def self.is_enabled(ext) return (self.is_present(ext) and BeEF::Core::Configuration.instance.get('beef.extension.'+ext.to_s+'.enable') == true) end - # Checks to see if extensions reports loaded through the configuration + # Checks to see if extension has been loaded + # @param [String] ext the extension key + # @return [Boolean] whether or not the extension is loaded def self.is_loaded(ext) return (self.is_enabled(ext) and BeEF::Core::Configuration.instance.get('beef.extension.'+ext.to_s+'.loaded') == true) end - # Loads extension + # Loads an extension + # @param [String] ext the extension key + # @return [Boolean] whether or not the extension loaded successfully + # @todo Wrap the require() statement in a try catch block to allow BeEF to fail gracefully if there is a problem with that extension - Issue #480 def self.load(ext) if File.exists?('extensions/'+ext+'/extension.rb') require 'extensions/'+ext+'/extension.rb' diff --git a/core/extensions.rb b/core/extensions.rb index 656e0173d..7959a851f 100644 --- a/core/extensions.rb +++ b/core/extensions.rb @@ -16,17 +16,20 @@ module BeEF module Extensions - # Return configuration hashes of all extensions that are enabled + # Returns configuration of all enabled extensions + # @return [Array] an array of extension configuration hashes that are enabled def self.get_enabled return BeEF::Core::Configuration.instance.get('beef.extension').select { |k,v| v['enable'] == true } end - # Return configuration hashes of all extensions that are loaded + # Returns configuration of all loaded extensions + # @return [Array] an array of extension configuration hashes that are loaded def self.get_loaded return BeEF::Core::Configuration.instance.get('beef.extension').select {|k,v| v['loaded'] == true } end - # Loads all enabled extensions + # Load all enabled extensions + # @note API fire for post_load def self.load BeEF::Core::Configuration.instance.load_extensions_config self.get_enabled.each { |k,v| diff --git a/core/filters.rb b/core/filters.rb index a5ce8f13f..1977bd4f0 100644 --- a/core/filters.rb +++ b/core/filters.rb @@ -19,7 +19,7 @@ module Filters end end -# Include the filters +# @note Include the filters require 'core/filters/base' require 'core/filters/browser' require 'core/filters/command' diff --git a/core/hbmanager.rb b/core/hbmanager.rb index 0f0618774..bd58b1208 100644 --- a/core/hbmanager.rb +++ b/core/hbmanager.rb @@ -17,11 +17,15 @@ module BeEF module HBManager # Get hooked browser by session id + # @param [String] sid hooked browser session id string + # @return [BeEF::Core::Models::HookedBrowser] returns the associated Hooked Browser def self.get_by_session(sid) BeEF::Core::Models::HookedBrowser.first(:session => sid) end # Get hooked browser by id + # @param [Integer] id hooked browser database id + # @return [BeEF::Core::Models::HookedBrowser] returns the associated Hooked Browser def self.get_by_id(id) BeEF::Core::Models::HookedBrowser.first(:id => id) end diff --git a/core/loader.rb b/core/loader.rb index 7c2741a25..9a6de9875 100644 --- a/core/loader.rb +++ b/core/loader.rb @@ -12,10 +12,8 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -# -# -# Include here all the gems we are using -# + +# @note Include here all the gems we are using require 'rubygems' require 'webrick' require 'webrick/httpproxy' @@ -36,22 +34,22 @@ require 'term/ansicolor' require 'rex' require 'rex/ui' -# Include the filters +# @note Include the filters require 'core/filters' -# Include our patches for ruby and gems +# @note Include our patches for ruby and gems require 'core/ruby' -# Include the API +# @note Include the API require 'core/api' -# Include the settings +# @note Include the settings require 'core/settings' -# Include the core of BeEF +# @note Include the core of BeEF require 'core/core' -# Include helpers +# @note Include helpers require 'core/module' require 'core/modules' require 'core/extension' diff --git a/core/module.rb b/core/module.rb index ae3863024..c19c6d06b 100644 --- a/core/module.rb +++ b/core/module.rb @@ -16,27 +16,38 @@ module BeEF module Module - # Checks to see if module is in configuration + # Checks to see if module key is in configuration + # @param [String] mod module key + # @return [Boolean] if the module key exists in BeEF's configuration def self.is_present(mod) return BeEF::Core::Configuration.instance.get('beef.module').has_key?(mod.to_s) end # Checks to see if module is enabled in configuration + # @param [String] mod module key + # @return [Boolean] if the module key is enabled in BeEF's configuration def self.is_enabled(mod) return (self.is_present(mod) and BeEF::Core::Configuration.instance.get('beef.module.'+mod.to_s+'.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) return (self.is_enabled(mod) and BeEF::Core::Configuration.instance.get('beef.module.'+mod.to_s+'.loaded') == true) end # Returns module class definition + # @param [String] mod module key + # @return [Class] the module class def self.get_definition(mod) return BeEF::Core::Command.const_get(BeEF::Core::Configuration.instance.get("beef.module.#{mod.to_s}.class")) end # Gets all module options + # @param [String] mod module key + # @return [Hash] a hash of all the module options + # @note API Fire: get_options def self.get_options(mod) if BeEF::API::Registra.instance.matched?(BeEF::API::Module, 'get_options', [mod]) options = BeEF::API::Registra.instance.fire(BeEF::API::Module, 'get_options', mod) @@ -62,7 +73,12 @@ module Module return [] end - # Soft Load, loads the module without requiring the module.rb file + # Soft loads a module + # @note A soft load consists of only loading the modules configuration (ie not the module.rb) + # @param [String] mod module key + # @return [Boolean] whether or not the soft load process was successful + # @note API Fire: pre_soft_load + # @note API Fire: post_soft_load def self.soft_load(mod) # API call for pre-soft-load module BeEF::API::Registra.instance.fire(BeEF::API::Module, 'pre_soft_load', mod) @@ -83,7 +99,12 @@ module Module return false end - # Hard Load, loads a pre-soft-loaded module by requiring the module.rb + # Hard loads a module + # @note A hard load consists of loading a pre-soft-loaded module by requiring the module.rb + # @param [String] mod module key + # @return [Boolean] whether or not the hard load was successful + # @note API Fire: pre_hard_load + # @note API Fire: post_hard_load def self.hard_load(mod) # API call for pre-hard-load module BeEF::API::Registra.instance.fire(BeEF::API::Module, 'pre_hard_load', mod) @@ -114,7 +135,9 @@ module Module return false end - # Utility function to check if hard load has occured, if not attempt hard load + # Checks to see if a module has been hard loaded, if not a hard load is attempted + # @param [String] mod module key + # @return [Boolean] if already hard loaded then true otherwise (see #hard_load) def self.check_hard_load(mod) if not self.is_loaded(mod) return self.hard_load(mod) @@ -122,19 +145,25 @@ module Module return true end - # Return module key by database id + # Get module key by database ID + # @param [Integer] id module database ID + # @return [String] module key def self.get_key_by_database_id(id) ret = BeEF::Core::Configuration.instance.get('beef.module').select {|k, v| v.has_key?('db') and v['db']['id'].to_i == id.to_i } return (ret.kind_of?(Array)) ? ret.first.first : ret.keys.first end - # Return module key by database id + # Get module key by module class + # @param [Class] c module class + # @return [String] module key def self.get_key_by_class(c) ret = BeEF::Core::Configuration.instance.get('beef.module').select {|k, v| v.has_key?('class') and v['class'].to_s == c.to_s } return (ret.kind_of?(Array)) ? ret.first.first : ret.keys.first end - #checks to see if module class exists + # Checks to see if module class exists + # @param [String] mod module key + # @return [Boolean] returns whether or not the class exists def self.exists?(mod) begin kclass = BeEF::Core::Command.const_get(mod.capitalize) @@ -145,12 +174,15 @@ module Module end # Checks target configuration to see if browser / version / operating system is supported - # Support uses a rating system to provide the most accurate results. - # 1 = All match. ie: All was defined. - # 2 = String match. ie: Firefox was defined as working. - # 3 = Hash match. ie: Firefox defined with 1 additional parameter (eg max_ver). - # 4+ = As above but with extra parameters. - # Please note this rating system has no correlation to the return constant value BeEF::Core::Constants::CommandModule::* + # @param [String] mod module key + # @param [Hash] opts hash of module support information + # @return [Constant, nil] returns a resulting defined constant BeEF::Core::Constants::CommandModule::* + # @note Support uses a rating system to provide the most accurate results. + # 1 = All match. ie: All was defined. + # 2 = String match. ie: Firefox was defined as working. + # 3 = Hash match. ie: Firefox defined with 1 additional parameter (eg max_ver). + # 4+ = As above but with extra parameters. + # Please note this rating system has no correlation to the return constant value BeEF::Core::Constants::CommandModule::* def self.support(mod, opts) target_config = BeEF::Core::Configuration.instance.get('beef.module.'+mod+'.target') if target_config and opts.kind_of? Hash @@ -233,6 +265,8 @@ module Module end # Translates module target configuration + # @note Takes the user defined target configuration and replaces it with equivalent a constant based generated version + # @param [String] mod module key def self.parse_targets(mod) target_config = BeEF::Core::Configuration.instance.get('beef.module.'+mod+'.target') if target_config @@ -285,6 +319,9 @@ module Module end # Translates simple browser target configuration + # @note Takes a user defined browser type and translates it into a BeEF constant + # @param [String] v user defined browser + # @return [Constant] a BeEF browser constant def self.match_target_browser(v) browser = false if v.class == String @@ -302,6 +339,9 @@ module Module end # Translates complex browser target configuration + # @note Takes a complex user defined browser hash and converts it to applicable BeEF constants + # @param [Hash] v user defined browser hash + # @return [Hash] BeEF constants hash def self.match_target_browser_spec(v) browser = {} if v.class == Hash @@ -335,6 +375,9 @@ module Module end # Translates simple OS target configuration + # @note Takes user defined OS specification and translates it into BeEF constants + # @param [String] v user defined OS string + # @return [Constant] BeEF OS Constant def self.match_target_os(v) os = false if v.class == String @@ -351,7 +394,12 @@ module Module return os end - # Executes module + # Executes a module + # @param [String] mod module key + # @param [String] hbsession hooked browser session + # @param [Array] opts array of module execute options (see #get_options) + # @return [Boolean] whether or not the BeEF system executed the module + # @note The return value of this function does not specify if the module was successful, only that it was executed within the framework def self.execute(mod, hbsession, opts=[]) if not (self.is_present(mod) and self.is_enabled(mod)) print_error "Module not found '#{mod}'. Failed to execute module." @@ -359,7 +407,7 @@ module Module end if BeEF::API::Registra.instance.matched?(BeEF::API::Module, 'override_execute', [mod, nil]) BeEF::API::Registra.instance.fire(BeEF::API::Module, 'override_execute', mod, opts) - #We return true by default as we cannot determine the correct status if multiple API hooks have been called + # @note We return true by default as we cannot determine the correct status if multiple API hooks have been called return true end hb = BeEF::HBManager.get_by_session(hbsession) @@ -382,6 +430,9 @@ module Module end # Merges default module options with array of custom options + # @param [String] mod module key + # @param [Hash] h module options customised by user input + # @return [Hash, nil] returns merged options def self.merge_options(mod, h) if self.is_present(mod) self.check_hard_load(mod) diff --git a/core/modules.rb b/core/modules.rb index 0996c79c8..28ab36936 100644 --- a/core/modules.rb +++ b/core/modules.rb @@ -17,16 +17,19 @@ module BeEF module Modules # Return configuration hashes of all modules that are enabled + # @return [Array] configuration hashes of all enabled modules def self.get_enabled return BeEF::Core::Configuration.instance.get('beef.module').select {|k,v| v['enable'] == true and v['category'] != nil } end # Return configuration hashes of all modules that are loaded + # @return [Array] configuration hashes of all loaded modules def self.get_loaded return BeEF::Core::Configuration.instance.get('beef.module').select {|k,v| v['loaded'] == true } end # Return an array of categories specified in module configuration files + # @return [Array] all available module categories sorted alphabetically def self.get_categories categories = [] BeEF::Core::Configuration.instance.get('beef.module').each {|k,v| @@ -37,11 +40,14 @@ module Modules return categories.sort end + # Get all modules currently stored in the database + # @return [Array] DataMapper array of all BeEF::Core::Models::CommandModule's in the database def self.get_stored_in_db return BeEF::Core::Models::CommandModule.all(:order => [:id.asc]) end - # Loads modules + # Loads all enabled modules + # @note API Fire: post_soft_load def self.load BeEF::Core::Configuration.instance.load_modules_config self.get_enabled.each { |k,v| diff --git a/core/ruby.rb b/core/ruby.rb index bb93ab288..ebf0616f4 100644 --- a/core/ruby.rb +++ b/core/ruby.rb @@ -13,25 +13,16 @@ # See the License for the specific language governing permissions and # limitations under the License. # -=begin - - Code in the 'ruby' folder are meants to patch ruby classes or - gem classes. - - We use that to fix bugs or add functionalities to external code we - are using. - -=end -# Patching Ruby +# @note Patching Ruby require 'core/ruby/module' require 'core/ruby/object' require 'core/ruby/string' require 'core/ruby/print' require 'core/ruby/hash' -# Patching WebRick +# @note Patching WebRick require 'core/ruby/patches/webrick/httprequest' require 'core/ruby/patches/webrick/cookie' require 'core/ruby/patches/webrick/genericserver' diff --git a/core/settings.rb b/core/settings.rb index 1aada831b..0b2de39f0 100644 --- a/core/settings.rb +++ b/core/settings.rb @@ -14,34 +14,24 @@ # limitations under the License. # module BeEF - # - # Use this module to check the current settings of BeEF. - # - # Examples: - # - # BeEF::Settings.console? # => returns true if the console extension exists and is loaded. - # module Settings - # # Checks if an extension exists in the framework. - # Returns true if the extension exists, false if not. - # - # Example: - # - # extension_exists?('Console') # => true - # extension_exists?('abcdegh') # => false - # + # @param [String] beef_extension extension class + # @return [Boolean] if the extension exists + # @deprecated Use #{BeEF::Extension.is_present()} instead of this method. + # This method bypasses the configuration system. def self.extension_exists?(beef_extension) BeEF::Extension.const_defined?(beef_extension) end - # - # Returns true of the extension Console has been loaded - # + # Checks to see if the console extensions has been loaded + # @return [Boolean] if the console extension has been loaded + # @deprecated Use #{BeEF::Extension.is_loaded()} instead of this method. + # This method bypasses the configuration system. def self.console? self.extension_exists?('Console') end end -end \ No newline at end of file +end