From 5b4ff619097e92188de6e78c7131db8ff8b31b9c Mon Sep 17 00:00:00 2001 From: passbe Date: Thu, 28 Jul 2011 00:50:04 +0000 Subject: [PATCH] Final changes to convert from old super() method to new configuration system. Fixes Issue 329 git-svn-id: https://beef.googlecode.com/svn/trunk@1119 b87d56ec-f9c0-11de-8c8a-61c5e9addfc9 --- core/main/command.rb | 62 +++++------------ core/main/handlers/commands.rb | 2 +- core/main/handlers/modules/command.rb | 3 +- core/main/server.rb | 5 -- core/module.rb | 67 ++++++++++++++----- core/modules.rb | 2 +- .../admin_ui/controllers/modules/modules.rb | 13 ++-- extensions/console/banners.rb | 2 +- 8 files changed, 78 insertions(+), 78 deletions(-) diff --git a/core/main/command.rb b/core/main/command.rb index 7c87f43e6..b2ca0743a 100644 --- a/core/main/command.rb +++ b/core/main/command.rb @@ -51,26 +51,25 @@ module Core # class Command - attr_reader :info, :datastore, :path, :default_command_url, :beefjs_components, :friendlyname - attr_accessor :zombie, :command_id, :session_id, :target + attr_reader :datastore, :path, :default_command_url, :beefjs_components, :friendlyname + attr_accessor :zombie, :command_id, :session_id include BeEF::Core::CommandUtils include BeEF::Core::Constants::Browsers include BeEF::Core::Constants::CommandModule # Super class controller - def initialize(info) + def initialize(key) get_extensions + config = BeEF::Core::Configuration.instance - @info = info - @datastore = @info['Data'] || {} - @friendlyname = @info['Name'] || nil - @target = @info['Target'] || nil + @key = key + @datastore = {} + @friendlyname = config.get("beef.module.#{key}.name") @output = '' - @path = @info['File'].sub(BeEF::Core::Server.instance.root_dir, '') - @default_command_url = '/command/'+@path.split(File::SEPARATOR).reverse[1]+'.js' - @id = BeEF::Core::Models::CommandModule.first(:path => @info['File']).object_id - @use_template = false + @path = config.get("beef.module.#{key}.path") + @default_command_url = config.get("beef.module.#{key}.mount") + @id = config.get("beef.module.#{key}.id") @auto_update_zombie = false @results = {} @beefjs_components = {} @@ -114,10 +113,10 @@ module Core # def to_json { - 'Name' => info['Name'], - 'Description' => info['Description'], - 'Category' => info['Category'], - 'Data' => info['Data'] + 'Name' => @friendlyname, + 'Description' => BeEF::Core::Configuration.instance.get("beef.module.#{@key}.description"), + 'Category' => BeEF::Core::Configuration.instance.get("beef.module.#{@key}.category"), + 'Data' => BeEF::Module.get_options(@key) }.to_json end @@ -153,40 +152,14 @@ module Core } end - # - # set the target details - # this function is used when determining the code of the node icon - # - def set_target(definition) - @target = [] if not @target - @target.push(definition) - end - - # - # Tells the framework that the command module will be using a template file. - # - def use_template!; - tpl = @info['File'].sub(/module.rb$/, 'command.js') - @template = tpl if File.exists? tpl - - @use_template = true; - end - - # - # Returns true if the command uses a template. False if not. - # - def use_template?; @use_template; end - # # Returns the output of the command. These are the actual instructions sent to the browser. # def output - if use_template? - #TODO: name exceptions correctly - raise Exception::TypeError, "@template is nil" if @template.nil? - raise WEBrick::HTTPStatus::BadRequest, "@template file does not exist" if not File.exists? @template + f = @path+'command.js' + raise WEBrick::HTTPStatus::BadRequest, "#{f} file does not exist" if not File.exists? f - @eruby = Erubis::FastEruby.new(File.read(@template)) + @eruby = Erubis::FastEruby.new(File.read(f)) if @datastore @datastore['command_url'] = BeEF::Core::Server.instance.get_command_url(@default_command_url) @@ -201,7 +174,6 @@ module Core else @ouput = @eruby.result() end - end @output end diff --git a/core/main/handlers/commands.rb b/core/main/handlers/commands.rb index 47905d2e0..d3832c73d 100644 --- a/core/main/handlers/commands.rb +++ b/core/main/handlers/commands.rb @@ -48,7 +48,7 @@ module Handlers 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 # create the commamd module + 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 command.session_id = beefhook command.callback # call the command module's callback function - it will parse and save the results diff --git a/core/main/handlers/modules/command.rb b/core/main/handlers/modules/command.rb index a75276bd5..11979e071 100644 --- a/core/main/handlers/modules/command.rb +++ b/core/main/handlers/modules/command.rb @@ -38,7 +38,8 @@ module Modules if(command_module.path.match(/^Dynamic/)) command_module = BeEF::Modules::Commands.const_get(command_module.path.split('/').last.capitalize).new else - command_module = BeEF::Core::Command.const_get(command_module.name.capitalize).new + key = BeEF::Module.get_key_by_database_id(command.command_module_id) + command_module = BeEF::Core::Command.const_get(BeEF::Core::Configuration.instance.get("beef.module.#{key}.class")).new(key) end command_module.command_id = command.id diff --git a/core/main/server.rb b/core/main/server.rb index facd040c2..4f708a8f8 100644 --- a/core/main/server.rb +++ b/core/main/server.rb @@ -93,11 +93,6 @@ module Core # Create http handler for the javascript hook file mount("#{@configuration.get("beef.http.hook_file")}", true, BeEF::Core::Handlers::HookedBrowsers) - # Create http handlers for all commands in the framework - BeEF::Modules.get_loaded.each { |k,v| - mount("/command/#{k}.js", false, BeEF::Core::Handlers::Commands, k) - } - # # We dynamically get the list of all http handler using the API and register them # diff --git a/core/module.rb b/core/module.rb index aa00bcdad..a42f85702 100644 --- a/core/module.rb +++ b/core/module.rb @@ -33,38 +33,69 @@ module Module # Gets all module options def self.get_options(mod) - begin + 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 + if class_symbol and class_symbol.respond_to?(:options) return class_symbol.options + else + print_debug "Module '#{mod}', no options method defined" end - rescue - print_debug "Unable to find module class: BeEF::Core::Commands::#{mod.capitalize}" end + return [] end - # Loads module - def self.load(mod) + # Soft Load, loads the module without requiring the module.rb file + def self.soft_load(mod) config = BeEF::Core::Configuration.instance - if File.exists?(config.get('beef.module.'+mod+'.path')+'/module.rb') - require config.get('beef.module.'+mod+'.path')+'/module.rb' - BeEF::Core::Configuration.instance.set('beef.module.'+mod+'.class', mod.capitalize) - if self.exists?(mod) - BeEF::Core::Configuration.instance.set('beef.module.'+mod+'.loaded', true) + if not config.get("beef.module.#{mod}.loaded") + if File.exists?(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 "Loaded module: '#{mod}'" + print_debug "Soft Load module: '#{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}'" + end + return false + end + + # Hard Load, loads a pre-soft-loaded module by requiring the module.rb + def self.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?(mod) + # start server mount point + BeEF::Core::Server.instance.mount("/command/#{mod}.js", false, 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}'" + 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_debug "Unable to locate module class: BeEF::Core::Commands::#{mod.capitalize}" + 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_debug "Unable to locate module file: #{config.get('beef.module.'+mod+'.path')}module.rb" + print_error "Hard load attempted on module '#{mod.to_s}' that is not enabled." end - print_error "Unable to load module '#{mod}'" return false end + + # Utility function to check if hard load has occured, if not attempt hard load + def self.check_hard_load(mod) + if not self.is_loaded(mod) + return self.hard_load(mod) + end + return true + end # Return module key by database id def self.get_key_by_database_id(id) @@ -72,6 +103,12 @@ module Module return (ret.kind_of?(Array)) ? ret.first.first : ret.keys.first end + # Return module key by database id + 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 def self.exists?(mod) begin diff --git a/core/modules.rb b/core/modules.rb index 52137aa78..839d371a0 100644 --- a/core/modules.rb +++ b/core/modules.rb @@ -44,7 +44,7 @@ module Modules # Loads modules def self.load self.get_enabled.each { |k,v| - BeEF::Module.load(k) + BeEF::Module.soft_load(k) } end end diff --git a/extensions/admin_ui/controllers/modules/modules.rb b/extensions/admin_ui/controllers/modules/modules.rb index 837c44f4e..053ba104d 100644 --- a/extensions/admin_ui/controllers/modules/modules.rb +++ b/extensions/admin_ui/controllers/modules/modules.rb @@ -303,7 +303,7 @@ class Modules < BeEF::Extension::AdminUI::HttpController # Returns the list of all command_modules in a JSON format def select_all_command_modules - @body = command_modules2json(BeEF::Modules.get_loaded.keys) + @body = command_modules2json(BeEF::Modules.get_enabled.keys) end # Set the correct icon for the command module @@ -365,14 +365,11 @@ class Modules < BeEF::Extension::AdminUI::HttpController }) } - BeEF::Modules.get_loaded.each{|k, mod| + BeEF::Modules.get_enabled.each{|k, mod| # get the hooked browser session id and set it in the command module hook_session_id = @params['zombie_session'] || nil raise WEBrick::HTTPStatus::BadRequest, "hook_session_id is nil" if hook_session_id.nil? - command_mod = BeEF::Core::Command.const_get(k.capitalize).new - command_mod.session_id = hook_session_id - # create url path and file for the command module icon command_module_status = set_command_module_status(k) command_module_icon_path = set_command_module_icon(command_module_status) @@ -650,14 +647,14 @@ class Modules < BeEF::Extension::AdminUI::HttpController e = BeEF::Modules::Commands.const_get(dyn_mod_name.capitalize).new else command_module_name = command_module.name - e = BeEF::Core::Command.const_get(command_module_name.capitalize).new + e = BeEF::Core::Command.const_get(command_module_name.capitalize).new(command_module_name) end @body = { 'success' => 'true', 'command_module_name' => command_module_name, 'command_module_id' => command_module.id, - 'data' => JSON.parse(command.data), + 'data' => BeEF::Module.get_options(command_module_name), 'definition' => JSON.parse(e.to_json) }.to_json @@ -671,7 +668,6 @@ class Modules < BeEF::Extension::AdminUI::HttpController i = 1 config = BeEF::Core::Configuration.instance command_modules.each do |command_module| - if BeEF::Module.is_enabled(command_module) h = { 'Name'=> config.get("beef.module.#{command_module}.name"), 'Description'=> config.get("beef.module.#{command_module}.description"), @@ -680,7 +676,6 @@ class Modules < BeEF::Extension::AdminUI::HttpController } command_modules_json[i] = h i += 1 - end end if not command_modules_json.empty? diff --git a/extensions/console/banners.rb b/extensions/console/banners.rb index 95bb18715..13858f973 100644 --- a/extensions/console/banners.rb +++ b/extensions/console/banners.rb @@ -115,7 +115,7 @@ module Banners # # Print loaded modules def print_loaded_modules - print_info "#{BeEF::Modules::get_loaded.count} modules loaded." + print_info "#{BeEF::Modules::get_enabled.count} modules loaded." end end end