diff --git a/core/api/module.rb b/core/api/module.rb index 02c86939f..c47471ba0 100644 --- a/core/api/module.rb +++ b/core/api/module.rb @@ -28,6 +28,7 @@ module API 'pre_hard_load' => :pre_hard_load, 'post_hard_load' => :post_hard_load, 'get_options' => :get_options, + 'get_payload_options' => :get_payload_options, 'override_execute' => :override_execute } @@ -58,6 +59,11 @@ module API # @note Hooking this API method stops the default flow of the Module.execute() method. def override_execute(mod, opts); end + # Fired when retreiving dynamic payload + # @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_payload_options; end + end end diff --git a/core/module.rb b/core/module.rb index c19c6d06b..4a0b47b3d 100644 --- a/core/module.rb +++ b/core/module.rb @@ -72,6 +72,18 @@ module Module end return [] end + + # Gets all module payload options + # @param [String] mod module key + # @return [Hash] a hash of all the module options + # @note API Fire: get_options + def self.get_payload_options(mod,payload) + if BeEF::API::Registra.instance.matched?(BeEF::API::Module, 'get_payload_options', [mod,nil]) + options = BeEF::API::Registra.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) diff --git a/extensions/admin_ui/controllers/modules/modules.rb b/extensions/admin_ui/controllers/modules/modules.rb index 0acad450e..0847a4584 100644 --- a/extensions/admin_ui/controllers/modules/modules.rb +++ b/extensions/admin_ui/controllers/modules/modules.rb @@ -500,17 +500,13 @@ class Modules < BeEF::Extension::AdminUI::HttpController command_module_id = @params['command_module_id'] || nil raise WEBrick::HTTPStatus::BadRequest, "command_module_id is nil" if command_module_id.nil? command_module = BeEF::Core::Models::CommandModule.get(command_module_id) + key = BeEF::Module.get_key_by_database_id(command_module_id) - if(command_module != nil && command_module.path.match(/^Dynamic/)) - payload_name = @params['payload_name'] || nil - if not payload_name.nil? - @body = dynamic_payload2json(command_module_id, payload_name) - else - @body = dynamic_modules2json(command_module_id); - end - else - key = BeEF::Module.get_key_by_database_id(command_module_id) - @body = command_modules2json([key]); + payload_name = @params['payload_name'] || nil + if not payload_name.nil? + @body = dynamic_payload2json(command_module_id, payload_name) + else + @body = command_modules2json([key]) end end @@ -666,7 +662,7 @@ class Modules < BeEF::Extension::AdminUI::HttpController results = [] # get params - command_id = @params['command_id'] || nil + command_id = @params['command_id']|| nil raise WEBrick::HTTPStatus::BadRequest, "Command id is nil" if command_id.nil? command = BeEF::Core::Models::Command.first(:id => command_id.to_i) || nil raise WEBrick::HTTPStatus::BadRequest, "Command is nil" if command.nil? @@ -770,17 +766,16 @@ class Modules < BeEF::Extension::AdminUI::HttpController def dynamic_payload2json(id, payload_name) command_modules_json = {} - dynamic_command_module = BeEF::Core::Models::CommandModule.first(:id => id) - raise WEBrick::HTTPStatus::BadRequest, "Module does not exists" if dynamic_command_module.nil? - - # the path will equal Dynamic/ and this will get just the type - dynamic_type = dynamic_command_module.path.split("/").last + command_module = BeEF::Core::Models::CommandModule.get(id) + raise WEBrick::HTTPStatus::BadRequest, "Module does not exists" if command_module.nil? + payload_options = BeEF::Module.get_payload_options(command_module.name,payload_name) # get payload options in JSON - e = BeEF::Modules::Commands.const_get(dynamic_type.capitalize).new + #e = BeEF::Modules::Commands.const_get(dynamic_type.capitalize).new payload_options_json = [] - payload_options_json[1] = e.get_payload_options(payload_name) - raise WEBrick::HTTPStatus::BadRequest, "Payload JSON generation error" if payload_options_json.empty? + payload_options_json[1] = payload_options + #payload_options_json[1] = e.get_payload_options(payload_name) + #raise WEBrick::HTTPStatus::BadRequest, "Payload JSON generation error" if payload_options_json.empty? return {'success' => 'true', 'command_modules' => payload_options_json}.to_json diff --git a/extensions/admin_ui/media/javascript/ui/panel/common.js b/extensions/admin_ui/media/javascript/ui/panel/common.js index 599054da3..dcf7388fc 100644 --- a/extensions/admin_ui/media/javascript/ui/panel/common.js +++ b/extensions/admin_ui/media/javascript/ui/panel/common.js @@ -117,7 +117,6 @@ function generate_form_input_field(form, input, value, disabled, zombie) { }; function get_dynamic_payload_details(payload, zombie) { - modid = Ext.getCmp( 'form-zombie-'+zombie.session+'-field-mod_id').value Ext.Ajax.request({ loadMask: true, @@ -126,10 +125,9 @@ function get_dynamic_payload_details(payload, zombie) { params: 'command_module_id=' + modid + '&' + 'payload_name=' + payload, success: function(resp) { var module = Ext.decode(resp.responseText); - module = module.command_modules[1]; - + module = module.command_modules[1][0]; Ext.getCmp("payload-panel").removeAll(); // clear the panel contents - Ext.each(module.Data, function(input){ + Ext.each(module.data , function(input){ // generate each of the payload input options generate_form_input_field(Ext.getCmp("payload-panel"), input, null, false, zombie); }); diff --git a/extensions/metasploit/api.rb b/extensions/metasploit/api.rb index ab3315a41..0ff94a78d 100644 --- a/extensions/metasploit/api.rb +++ b/extensions/metasploit/api.rb @@ -39,6 +39,7 @@ module API count = 1 msf_module_config.each{|k,v| BeEF::API::Registra.instance.register(BeEF::Extension::Metasploit::API::MetasploitHooks, BeEF::API::Module, 'get_options', [k]) + BeEF::API::Registra.instance.register(BeEF::Extension::Metasploit::API::MetasploitHooks, BeEF::API::Module, 'get_payload_options', [k,nil]) BeEF::API::Registra.instance.register(BeEF::Extension::Metasploit::API::MetasploitHooks, BeEF::API::Module, 'override_execute', [k, nil]) print_over "Loaded #{count} Metasploit exploits." count += 1 @@ -69,6 +70,7 @@ module API 'class'=> 'Msf_module' } BeEF::API::Registra.instance.register(BeEF::Extension::Metasploit::API::MetasploitHooks, BeEF::API::Module, 'get_options', [key]) + BeEF::API::Registra.instance.register(BeEF::Extension::Metasploit::API::MetasploitHooks, BeEF::API::Module, 'get_payload_options', [key,nil]) BeEF::API::Registra.instance.register(BeEF::Extension::Metasploit::API::MetasploitHooks, BeEF::API::Module, 'override_execute', [key, nil]) print_over "Loaded #{count} Metasploit exploits." count += 1 @@ -90,8 +92,10 @@ module API msf = BeEF::Extension::Metasploit::RpcClient.instance if msf_key != nil and msf.login msf_module_options = msf.call('module.options', 'exploit', msf_key) + com = BeEF::Core::Models::CommandModule.first(:name => mod ) if msf_module_options options = BeEF::Extension::Metasploit.translate_options(msf_module_options) + options << { 'name' => 'mod_id', 'id' => 'mod_id' , 'type' => 'hidden', 'value' => com.id} msf_payload_options = msf.call('module.compatible_payloads', msf_key) if msf_payload_options options << BeEF::Extension::Metasploit.translate_payload(msf_payload_options) @@ -115,9 +119,6 @@ module API next if ['e','ie_session','and_module_id'].include? opt['name'] msf_opts[opt["name"]] = opt["value"] } - msf_opts["LPORT"] = rand(50000) + 1024 - msf_opts['LHOST'] = BeEF::Core::Configuration.instance.get('beef.extension.metasploit.callback_host') - if msf_key != nil and msf.login # Are the options correctly formatted for msf? @@ -129,10 +130,24 @@ module API return true end + # Get module options + payloads when the beef framework requests this information + def self.get_payload_options(mod,payload) + msf_key = BeEF::Core::Configuration.instance.get("beef.module.#{mod}.msf_key") + + msf = BeEF::Extension::Metasploit::RpcClient.instance + if msf_key != nil and msf.login + msf_module_options = msf.call('module.options', 'payload', payload) + + com = BeEF::Core::Models::CommandModule.first(:name => mod ) + if msf_module_options + options = BeEF::Extension::Metasploit.translate_options(msf_module_options) + return options + else + print_error "Unable to retrieve metasploit payload options for exploit: #{msf_key}" + end + end + end end - - - end end end diff --git a/extensions/metasploit/extension.rb b/extensions/metasploit/extension.rb index 359351a4d..9b6b4b695 100644 --- a/extensions/metasploit/extension.rb +++ b/extensions/metasploit/extension.rb @@ -13,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # -require 'pp' module BeEF module Extension module Metasploit @@ -31,6 +30,8 @@ module Metasploit v['type'] = 'text' v['value'] = rand(3**20).to_s(16) if k == 'URIPATH' v['value'] = v['default'] if k != "URIPATH" + v['value'] = BeEF::Core::Configuration.instance.get('beef.extension.metasploit.callback_host') if k == "LHOST" + when "bool" v['type'] = 'checkbox' @@ -71,7 +72,9 @@ module Metasploit 'valueField' => 'payload', 'displayField' => 'payload', 'mode' => 'local', - 'autoWidth' => true + 'autoWidth' => true, + 'defaultPayload' => defaultPayload, + 'reloadOnChange' => true } end end