Minor formatting changes

This commit is contained in:
Wade Alcorn
2012-01-17 20:59:29 +10:00
parent c4f0b04389
commit 13f364c372
8 changed files with 514 additions and 514 deletions

View File

@@ -15,172 +15,172 @@
#
module BeEF
module API
module API
# Registrar class to handle all registered timed API calls
class Registrar
include Singleton
# Create registrar
def initialize
@registry = []
@count = 1
end
include Singleton
# 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)
id = @count
@registry << {
'id' => id,
'owner' => owner,
'class' => c,
'method' => method,
'params' => params
}
@count += 1
return id
else
print_debug "API Registrar: Attempting to re-register API call #{c.to_s} :#{method.to_s}"
end
else
print_error "API Registrar: Attempted to register non-existant API method #{c.to_s} :#{method.to_s}"
end
end
# 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']
return true
end
# Create registrar
def initialize
@registry = []
@count = 1
end
# 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)
id = @count
@registry << {
'id' => id,
'owner' => owner,
'class' => c,
'method' => method,
'params' => params
}
return false
@count += 1
return id
else
print_debug "API Registrar: Attempting to re-register API call #{c.to_s} :#{method.to_s}"
end
else
print_error "API Registrar: Attempted to register non-existant API method #{c.to_s} :#{method.to_s}"
end
end
# 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)
return true
end
}
return false
end
# 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
# 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|
if r['class'] == c and r['method'] == method
if self.is_matched_params?(r, params)
owners << { :owner => r['owner'], :id => r['id']}
end
end
}
return owners
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
# 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
# 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
matched = true
stored.each_index{|i|
next if stored[i] == nil
if not stored[i] == params[i]
matched = false
end
}
return false if not matched
end
# 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']
return true
end
end
}
return false
end
# 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
data = []
if self.verify_api_path(c, m) and c.ancestors[0].to_s > "BeEF::API"
method = self.get_api_path(c, m)
mods.each do |mod|
begin
#Only used for API Development (very verbose)
#print_info "API: #{mod} fired #{method}"
result = mod[:owner].method(method).call(*args)
if not result == nil
data << {:api_id => mod[:id], :data => result}
end
rescue Exception => e
print_error "API Fire Error: #{e.message} in #{mod.to_s}.#{method.to_s}()"
end
end
else
print_error "API Path not defined for Class: #{c.to_s} method:#{method.to_s}"
end
return data
# 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)
return true
end
}
return false
end
# 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
# 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|
if r['class'] == c and r['method'] == method
if self.is_matched_params?(r, params)
owners << { :owner => r['owner'], :id => r['id']}
end
return nil
end
}
return owners
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
# 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
# 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
matched = true
stored.each_index{|i|
next if stored[i] == nil
if not stored[i] == params[i]
matched = false
end
}
return false if not matched
end
return true
end
# 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
data = []
if self.verify_api_path(c, m) and c.ancestors[0].to_s > "BeEF::API"
method = self.get_api_path(c, m)
mods.each do |mod|
begin
#Only used for API Development (very verbose)
#print_info "API: #{mod} fired #{method}"
result = mod[:owner].method(method).call(*args)
if not result == nil
data << {:api_id => mod[:id], :data => result}
end
rescue Exception => e
print_error "API Fire Error: #{e.message} in #{mod.to_s}.#{method.to_s}()"
end
end
else
print_error "API Path not defined for Class: #{c.to_s} method:#{method.to_s}"
end
return data
end
return nil
end
end
end
end
end
require 'core/api/module'

View File

@@ -14,27 +14,27 @@
# limitations under the License.
#
module BeEF
module Extension
module Extension
# 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)
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)
return (self.is_present(ext) and BeEF::Core::Configuration.instance.get('beef.extension.'+ext.to_s+'.enable') == true)
end
# 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)
return (self.is_enabled(ext) and BeEF::Core::Configuration.instance.get('beef.extension.'+ext.to_s+'.loaded') == true)
end
# Loads an extension
@@ -42,14 +42,14 @@ module Extension
# @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'
print_debug "Loaded extension: '#{ext}'"
BeEF::Core::Configuration.instance.set('beef.extension.'+ext+'.loaded', true)
return true
end
print_error "Unable to load extension '#{ext}'"
return false
if File.exists?('extensions/'+ext+'/extension.rb')
require 'extensions/'+ext+'/extension.rb'
print_debug "Loaded extension: '#{ext}'"
BeEF::Core::Configuration.instance.set('beef.extension.'+ext+'.loaded', true)
return true
end
print_error "Unable to load extension '#{ext}'"
return false
end
end
end
end

View File

@@ -14,31 +14,31 @@
# limitations under the License.
#
module BeEF
module Extensions
module Extensions
# 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 }
return BeEF::Core::Configuration.instance.get('beef.extension').select { |k,v| v['enable'] == true }
end
# 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 }
return BeEF::Core::Configuration.instance.get('beef.extension').select {|k,v| v['loaded'] == true }
end
# 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|
BeEF::Extension.load(k)
}
# API post extension load
BeEF::API::Registrar.instance.fire(BeEF::API::Extensions, 'post_load')
BeEF::Core::Configuration.instance.load_extensions_config
self.get_enabled.each { |k,v|
BeEF::Extension.load(k)
}
# API post extension load
BeEF::API::Registrar.instance.fire(BeEF::API::Extensions, 'post_load')
end
end
end
end

View File

@@ -14,9 +14,9 @@
# limitations under the License.
#
module BeEF
module Filters
module Filters
end
end
end
# @note Include the filters

View File

@@ -14,21 +14,21 @@
# limitations under the License.
#
module BeEF
module HBManager
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)
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)
BeEF::Core::Models::HookedBrowser.first(:id => id)
end
end
end
end

View File

@@ -14,34 +14,34 @@
# limitations under the License.
#
module BeEF
module Module
module Module
# 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)
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)
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)
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"))
return BeEF::Core::Command.const_get(BeEF::Core::Configuration.instance.get("beef.module.#{mod.to_s}.class"))
end
# Gets all module options
@@ -49,31 +49,31 @@ module Module
# @return [Hash] a hash of all the module options
# @note API Fire: get_options
def self.get_options(mod)
if BeEF::API::Registrar.instance.matched?(BeEF::API::Module, 'get_options', [mod])
options = BeEF::API::Registrar.instance.fire(BeEF::API::Module, 'get_options', mod)
mo = []
options.each{|o|
if o[:data].kind_of?(Array)
mo += o[:data]
else
print_debug "API Warning: return result for BeEF::Module.get_options() was not an array."
end
}
return mo
if BeEF::API::Registrar.instance.matched?(BeEF::API::Module, 'get_options', [mod])
options = BeEF::API::Registrar.instance.fire(BeEF::API::Module, 'get_options', mod)
mo = []
options.each{|o|
if o[:data].kind_of?(Array)
mo += o[:data]
else
print_debug "API Warning: return result for BeEF::Module.get_options() was not an array."
end
}
return mo
end
if self.check_hard_load(mod)
class_name = BeEF::Core::Configuration.instance.get("beef.module.#{mod}.class")
class_symbol = BeEF::Core::Command.const_get(class_name)
if class_symbol and class_symbol.respond_to?(:options)
return class_symbol.options
end
if self.check_hard_load(mod)
class_name = BeEF::Core::Configuration.instance.get("beef.module.#{mod}.class")
class_symbol = BeEF::Core::Command.const_get(class_name)
if class_symbol and class_symbol.respond_to?(:options)
return class_symbol.options
end
#TODO: do we really need to print this info? At then modules with no options are common,
# so I guess we shouldn't print this info even in debug mode
# else
# print_debug "Module '#{mod}', no options method defined"
# end
end
return []
#TODO: do we really need to print this info? At then modules with no options are common,
# so I guess we shouldn't print this info even in debug mode
# else
# print_debug "Module '#{mod}', no options method defined"
# end
end
return []
end
# Gets all module payload options
@@ -81,13 +81,13 @@ module Module
# @return [Hash] a hash of all the module options
# @note API Fire: get_options
def self.get_payload_options(mod,payload)
if BeEF::API::Registrar.instance.matched?(BeEF::API::Module, 'get_payload_options', [mod,nil])
options = BeEF::API::Registrar.instance.fire(BeEF::API::Module, 'get_payload_options', mod,payload)
return options
end
return []
if BeEF::API::Registrar.instance.matched?(BeEF::API::Module, 'get_payload_options', [mod,nil])
options = BeEF::API::Registrar.instance.fire(BeEF::API::Module, 'get_payload_options', mod,payload)
return options
end
return []
end
# 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
@@ -95,23 +95,23 @@ module Module
# @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::Registrar.instance.fire(BeEF::API::Module, 'pre_soft_load', mod)
config = BeEF::Core::Configuration.instance
if not config.get("beef.module.#{mod}.loaded")
if File.exists?($root_dir+"/"+config.get('beef.module.'+mod+'.path')+'/module.rb')
BeEF::Core::Configuration.instance.set('beef.module.'+mod+'.class', mod.capitalize)
self.parse_targets(mod)
print_debug "Soft Load module: '#{mod}'"
# API call for post-soft-load module
BeEF::API::Registrar.instance.fire(BeEF::API::Module, 'post_soft_load', mod)
return true
else
print_debug "Unable to locate module file: #{config.get('beef.module.'+mod+'.path')}module.rb"
end
print_error "Unable to load module '#{mod}'"
# API call for pre-soft-load module
BeEF::API::Registrar.instance.fire(BeEF::API::Module, 'pre_soft_load', mod)
config = BeEF::Core::Configuration.instance
if not config.get("beef.module.#{mod}.loaded")
if File.exists?($root_dir+"/"+config.get('beef.module.'+mod+'.path')+'/module.rb')
BeEF::Core::Configuration.instance.set('beef.module.'+mod+'.class', mod.capitalize)
self.parse_targets(mod)
print_debug "Soft Load module: '#{mod}'"
# API call for post-soft-load module
BeEF::API::Registrar.instance.fire(BeEF::API::Module, 'post_soft_load', mod)
return true
else
print_debug "Unable to locate module file: #{config.get('beef.module.'+mod+'.path')}module.rb"
end
return false
print_error "Unable to load module '#{mod}'"
end
return false
end
# Hard loads a module
@@ -121,71 +121,71 @@ module Module
# @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::Registrar.instance.fire(BeEF::API::Module, 'pre_hard_load', mod)
config = BeEF::Core::Configuration.instance
if self.is_enabled(mod)
begin
require config.get("beef.module.#{mod}.path")+'module.rb'
if self.exists?(config.get("beef.module.#{mod}.class"))
# start server mount point
BeEF::Core::Server.instance.mount("/command/#{mod}.js", BeEF::Core::Handlers::Commands, mod)
BeEF::Core::Configuration.instance.set("beef.module.#{mod}.mount", "/command/#{mod}.js")
BeEF::Core::Configuration.instance.set('beef.module.'+mod+'.loaded', true)
print_debug "Hard Load module: '#{mod.to_s}'"
# API call for post-hard-load module
BeEF::API::Registrar.instance.fire(BeEF::API::Module, 'post_hard_load', mod)
return true
else
print_error "Hard loaded module '#{mod.to_s}' but the class BeEF::Core::Commands::#{mod.capitalize} does not exist"
end
rescue => e
BeEF::Core::Configuration.instance.set('beef.module.'+mod+'.loaded', false)
print_error "There was a problem loading the module '#{mod.to_s}'"
print_debug "Hard load module syntax error: #{e.to_s}"
end
else
print_error "Hard load attempted on module '#{mod.to_s}' that is not enabled."
# API call for pre-hard-load module
BeEF::API::Registrar.instance.fire(BeEF::API::Module, 'pre_hard_load', mod)
config = BeEF::Core::Configuration.instance
if self.is_enabled(mod)
begin
require config.get("beef.module.#{mod}.path")+'module.rb'
if self.exists?(config.get("beef.module.#{mod}.class"))
# start server mount point
BeEF::Core::Server.instance.mount("/command/#{mod}.js", BeEF::Core::Handlers::Commands, mod)
BeEF::Core::Configuration.instance.set("beef.module.#{mod}.mount", "/command/#{mod}.js")
BeEF::Core::Configuration.instance.set('beef.module.'+mod+'.loaded', true)
print_debug "Hard Load module: '#{mod.to_s}'"
# API call for post-hard-load module
BeEF::API::Registrar.instance.fire(BeEF::API::Module, 'post_hard_load', mod)
return true
else
print_error "Hard loaded module '#{mod.to_s}' but the class BeEF::Core::Commands::#{mod.capitalize} does not exist"
end
rescue => e
BeEF::Core::Configuration.instance.set('beef.module.'+mod+'.loaded', false)
print_error "There was a problem loading the module '#{mod.to_s}'"
print_debug "Hard load module syntax error: #{e.to_s}"
end
return false
else
print_error "Hard load attempted on module '#{mod.to_s}' that is not enabled."
end
return false
end
# 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)
end
return true
if not self.is_loaded(mod)
return self.hard_load(mod)
end
return true
end
# 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
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
# 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
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
# @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)
return kclass.is_a?(Class)
rescue NameError
return false
end
begin
kclass = BeEF::Core::Command.const_get(mod.capitalize)
return kclass.is_a?(Class)
rescue NameError
return false
end
end
# Checks target configuration to see if browser / version / operating system is supported
@@ -199,138 +199,138 @@ module Module
# 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
if opts.key?('browser')
results = []
target_config.each{|k,m|
m.each{|v|
case v
when String
if opts['browser'] == v
results << {'rating' => 2, 'const' => k}
end
when Hash
if opts['browser'] == v.keys.first
subv = v[v.keys.first]
rating = 1
#version check
if opts.key?('ver')
if subv.key?('min_ver')
if subv['min_ver'].kind_of? Fixnum and opts['ver'].to_i >= subv['min_ver']
rating += 1
else
break
end
end
if subv.key?('max_ver')
if (subv['max_ver'].kind_of? Fixnum and opts['ver'].to_i <= subv['max_ver']) or subv['max_ver'] == "latest"
rating += 1
else
break
end
end
end
# os check
if opts.key?('os') and subv.key?('os')
match = false
opts['os'].each{|o|
case subv['os']
when String
if o == subv['os']
rating += 1
match = true
elsif subv['os'] == BeEF::Core::Constants::Os::OS_ALL_UA_STR
rating += 1
match = true
end
when Array
subv['os'].each{|p|
if o == p or p == BeEF::Core::Constants::Os::OS_ALL_UA_STR
rating += 1
match = true
end
}
end
}
if not match
break
end
end
if rating != 1
results << {'rating' => rating, 'const' => k}
end
end
target_config = BeEF::Core::Configuration.instance.get('beef.module.'+mod+'.target')
if target_config and opts.kind_of? Hash
if opts.key?('browser')
results = []
target_config.each{|k,m|
m.each{|v|
case v
when String
if opts['browser'] == v
results << {'rating' => 2, 'const' => k}
end
when Hash
if opts['browser'] == v.keys.first
subv = v[v.keys.first]
rating = 1
#version check
if opts.key?('ver')
if subv.key?('min_ver')
if subv['min_ver'].kind_of? Fixnum and opts['ver'].to_i >= subv['min_ver']
rating += 1
else
break
end
if v == BeEF::Core::Constants::Browsers::ALL
results << {'rating' => 1, 'const' => k}
end
if subv.key?('max_ver')
if (subv['max_ver'].kind_of? Fixnum and opts['ver'].to_i <= subv['max_ver']) or subv['max_ver'] == "latest"
rating += 1
else
break
end
}
}
if results.count > 0
return results.sort_by {|v| v['rating']}.last['const']
else
return BeEF::Core::Constants::CommandModule::VERIFIED_UNKNOWN
end
else
print_error "BeEF::Module.support() was passed a hash without a valid browser constant"
end
end
end
# os check
if opts.key?('os') and subv.key?('os')
match = false
opts['os'].each{|o|
case subv['os']
when String
if o == subv['os']
rating += 1
match = true
elsif subv['os'] == BeEF::Core::Constants::Os::OS_ALL_UA_STR
rating += 1
match = true
end
when Array
subv['os'].each{|p|
if o == p or p == BeEF::Core::Constants::Os::OS_ALL_UA_STR
rating += 1
match = true
end
}
end
}
if not match
break
end
end
if rating != 1
results << {'rating' => rating, 'const' => k}
end
end
end
if v == BeEF::Core::Constants::Browsers::ALL
results << {'rating' => 1, 'const' => k}
end
}
}
if results.count > 0
return results.sort_by {|v| v['rating']}.last['const']
else
return BeEF::Core::Constants::CommandModule::VERIFIED_UNKNOWN
end
else
print_error "BeEF::Module.support() was passed a hash without a valid browser constant"
end
return nil
end
return nil
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
targets = {}
target_config.each{|k,v|
begin
if BeEF::Core::Constants::CommandModule.const_defined?('VERIFIED_'+k.upcase)
key = BeEF::Core::Constants::CommandModule.const_get('VERIFIED_'+k.upcase)
if not targets.key?(key)
targets[key] = []
end
browser = nil
case v
when String
browser = self.match_target_browser(v)
if browser
targets[key] << browser
end
when Array
v.each{|c|
browser = self.match_target_browser(c)
if browser
targets[key] << browser
end
}
when Hash
v.each{|k,c|
browser = self.match_target_browser(k)
if browser
case c
when TrueClass
targets[key] << browser
when Hash
details = self.match_target_browser_spec(c)
if details
targets[key] << {browser => details}
end
end
end
}
end
target_config = BeEF::Core::Configuration.instance.get('beef.module.'+mod+'.target')
if target_config
targets = {}
target_config.each{|k,v|
begin
if BeEF::Core::Constants::CommandModule.const_defined?('VERIFIED_'+k.upcase)
key = BeEF::Core::Constants::CommandModule.const_get('VERIFIED_'+k.upcase)
if not targets.key?(key)
targets[key] = []
end
browser = nil
case v
when String
browser = self.match_target_browser(v)
if browser
targets[key] << browser
end
when Array
v.each{|c|
browser = self.match_target_browser(c)
if browser
targets[key] << browser
end
rescue NameError
print_error "Module \"#{mod}\" configuration has invalid target status defined \"#{k}\""
end
}
BeEF::Core::Configuration.instance.clear("beef.module.#{mod}.target")
BeEF::Core::Configuration.instance.set("beef.module.#{mod}.target", targets)
end
}
when Hash
v.each{|k,c|
browser = self.match_target_browser(k)
if browser
case c
when TrueClass
targets[key] << browser
when Hash
details = self.match_target_browser_spec(c)
if details
targets[key] << {browser => details}
end
end
end
}
end
end
rescue NameError
print_error "Module \"#{mod}\" configuration has invalid target status defined \"#{k}\""
end
}
BeEF::Core::Configuration.instance.clear("beef.module.#{mod}.target")
BeEF::Core::Configuration.instance.set("beef.module.#{mod}.target", targets)
end
end
# Translates simple browser target configuration
@@ -338,19 +338,19 @@ module Module
# @param [String] v user defined browser
# @return [Constant] a BeEF browser constant
def self.match_target_browser(v)
browser = false
if v.class == String
begin
if BeEF::Core::Constants::Browsers.const_defined?(v.upcase)
browser = BeEF::Core::Constants::Browsers.const_get(v.upcase)
end
rescue NameError
print_error "Could not identify browser target specified as \"#{v}\""
end
else
print_error "Invalid datatype passed to BeEF::Module.match_target_browser()"
browser = false
if v.class == String
begin
if BeEF::Core::Constants::Browsers.const_defined?(v.upcase)
browser = BeEF::Core::Constants::Browsers.const_get(v.upcase)
end
rescue NameError
print_error "Could not identify browser target specified as \"#{v}\""
end
return browser
else
print_error "Invalid datatype passed to BeEF::Module.match_target_browser()"
end
return browser
end
# Translates complex browser target configuration
@@ -358,35 +358,35 @@ module Module
# @param [Hash] v user defined browser hash
# @return [Hash] BeEF constants hash
def self.match_target_browser_spec(v)
browser = {}
if v.class == Hash
if v.key?('max_ver') and (v['max_ver'].is_a?(Fixnum) or v['max_ver'].is_a?(Float) or v['max_ver'] == "latest")
browser['max_ver'] = v['max_ver']
end
if v.key?('min_ver') and (v['min_ver'].is_a?(Fixnum) or v['min_ver'].is_a?(Float))
browser['min_ver'] = v['min_ver']
end
if v.key?('os')
case v['os']
when String
os = self.match_target_os(v['os'])
if os
browser['os'] = os
end
when Array
browser['os'] = []
v['os'].each{|c|
os = self.match_target_os(c)
if os
browser['os'] << os
end
}
end
end
else
print_error "Invalid datatype passed to BeEF::Module.match_target_browser_spec()"
browser = {}
if v.class == Hash
if v.key?('max_ver') and (v['max_ver'].is_a?(Fixnum) or v['max_ver'].is_a?(Float) or v['max_ver'] == "latest")
browser['max_ver'] = v['max_ver']
end
return browser
if v.key?('min_ver') and (v['min_ver'].is_a?(Fixnum) or v['min_ver'].is_a?(Float))
browser['min_ver'] = v['min_ver']
end
if v.key?('os')
case v['os']
when String
os = self.match_target_os(v['os'])
if os
browser['os'] = os
end
when Array
browser['os'] = []
v['os'].each{|c|
os = self.match_target_os(c)
if os
browser['os'] << os
end
}
end
end
else
print_error "Invalid datatype passed to BeEF::Module.match_target_browser_spec()"
end
return browser
end
# Translates simple OS target configuration
@@ -394,19 +394,19 @@ module Module
# @param [String] v user defined OS string
# @return [Constant] BeEF OS Constant
def self.match_target_os(v)
os = false
if v.class == String
begin
if BeEF::Core::Constants::Os.const_defined?("OS_#{v.upcase}_UA_STR")
os = BeEF::Core::Constants::Os.const_get("OS_#{v.upcase}_UA_STR")
end
rescue NameError
print_error "Could not identify OS target specified as \"#{v}\""
end
else
print_error "Invalid datatype passed to BeEF::Module.match_target_os()"
os = false
if v.class == String
begin
if BeEF::Core::Constants::Os.const_defined?("OS_#{v.upcase}_UA_STR")
os = BeEF::Core::Constants::Os.const_get("OS_#{v.upcase}_UA_STR")
end
rescue NameError
print_error "Could not identify OS target specified as \"#{v}\""
end
return os
else
print_error "Invalid datatype passed to BeEF::Module.match_target_os()"
end
return os
end
# Executes a module
@@ -416,32 +416,32 @@ module Module
# @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."
return false
end
if BeEF::API::Registrar.instance.matched?(BeEF::API::Module, 'override_execute', [mod, nil,nil])
BeEF::API::Registrar.instance.fire(BeEF::API::Module, 'override_execute', mod, hbsession,opts)
# @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)
if not hb
print_error "Could not find hooked browser when attempting to execute module '#{mod}'"
return false
end
self.check_hard_load(mod)
command_module = self.get_definition(mod).new(mod)
if command_module.respond_to?(:pre_execute)
command_module.pre_execute
end
h = self.merge_options(mod, [])
c = BeEF::Core::Models::Command.new(:data => self.merge_options(mod, opts).to_json,
:hooked_browser_id => hb.id,
:command_module_id => BeEF::Core::Configuration.instance.get("beef.module.#{mod}.db.id"),
:creationdate => Time.new.to_i
).save
if not (self.is_present(mod) and self.is_enabled(mod))
print_error "Module not found '#{mod}'. Failed to execute module."
return false
end
if BeEF::API::Registrar.instance.matched?(BeEF::API::Module, 'override_execute', [mod, nil,nil])
BeEF::API::Registrar.instance.fire(BeEF::API::Module, 'override_execute', mod, hbsession,opts)
# @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)
if not hb
print_error "Could not find hooked browser when attempting to execute module '#{mod}'"
return false
end
self.check_hard_load(mod)
command_module = self.get_definition(mod).new(mod)
if command_module.respond_to?(:pre_execute)
command_module.pre_execute
end
h = self.merge_options(mod, [])
c = BeEF::Core::Models::Command.new(:data => self.merge_options(mod, opts).to_json,
:hooked_browser_id => hb.id,
:command_module_id => BeEF::Core::Configuration.instance.get("beef.module.#{mod}.db.id"),
:creationdate => Time.new.to_i
).save
return true
end
# Merges default module options with array of custom options
@@ -449,29 +449,29 @@ module Module
# @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)
merged = []
defaults = self.get_options(mod)
defaults.each{|v|
mer = nil
h.each{|o|
if v.has_key?('name') and o.has_key?('name') and v['name'] == o['name']
mer = v.deep_merge(o)
end
}
if mer != nil
merged.push(mer)
else
merged.push(v)
end
}
return merged
end
return nil
if self.is_present(mod)
self.check_hard_load(mod)
merged = []
defaults = self.get_options(mod)
defaults.each{|v|
mer = nil
h.each{|o|
if v.has_key?('name') and o.has_key?('name') and v['name'] == o['name']
mer = v.deep_merge(o)
end
}
if mer != nil
merged.push(mer)
else
merged.push(v)
end
}
return merged
end
return nil
end
end
end
end

View File

@@ -14,30 +14,30 @@
# limitations under the License.
#
module BeEF
module Modules
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 }
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 }
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|
if not categories.include?(v['category'])
categories << v['category']
end
}
return categories.sort
categories = []
BeEF::Core::Configuration.instance.get('beef.module').each {|k,v|
if not categories.include?(v['category'])
categories << v['category']
end
}
return categories.sort
end
# Get all modules currently stored in the database
@@ -45,15 +45,15 @@ module Modules
def self.get_stored_in_db
return BeEF::Core::Models::CommandModule.all(:order => [:id.asc])
end
# 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|
BeEF::Module.soft_load(k)
}
BeEF::API::Registrar.instance.fire(BeEF::API::Modules, 'post_soft_load')
BeEF::Core::Configuration.instance.load_modules_config
self.get_enabled.each { |k,v|
BeEF::Module.soft_load(k)
}
BeEF::API::Registrar.instance.fire(BeEF::API::Modules, 'post_soft_load')
end
end
end
end

View File

@@ -15,7 +15,7 @@
#
module BeEF
module Settings
# Checks if an extension exists in the framework.
# @param [String] beef_extension extension class
# @return [Boolean] if the extension exists
@@ -24,7 +24,7 @@ module BeEF
def self.extension_exists?(beef_extension)
BeEF::Extension.const_defined?(beef_extension)
end
# 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.
@@ -32,6 +32,6 @@ module BeEF
def self.console?
self.extension_exists?('Console')
end
end
end