From e772e683fd0fdceeb4af57ec448b83154a89378c Mon Sep 17 00:00:00 2001 From: antisnatchor Date: Thu, 31 Mar 2016 09:56:40 +0200 Subject: [PATCH] Issue #1214. Now command module post_execute is honoured also with WebSockets channel. --- core/main/command.rb | 33 +++++++------- core/main/handlers/commands.rb | 2 +- .../main/network_stack/websocket/websocket.rb | 45 +++++++++++-------- 3 files changed, 45 insertions(+), 35 deletions(-) diff --git a/core/main/command.rb b/core/main/command.rb index 462855911..17799ee69 100644 --- a/core/main/command.rb +++ b/core/main/command.rb @@ -98,24 +98,27 @@ module BeEF # Sets the datastore for the callback function. This function is meant to be called by the CommandHandler # @param [Hash] http_params HTTP parameters # @param [Hash] http_headers HTTP headers - def build_callback_datastore(http_params, http_headers, result, command_id, beefhook) + def build_callback_datastore(result, command_id, beefhook, http_params, http_headers) @datastore = {'http_headers' => {}} # init the datastore - # get, check and add the http_params to the datastore - http_params.keys.each { |http_params_key| - (print_error 'http_params_key is invalid';return) if not BeEF::Filters.is_valid_command_module_datastore_key?(http_params_key) - http_params_value = Erubis::XmlHelper.escape_xml(http_params[http_params_key]) - (print_error 'http_params_value is invalid';return) if not BeEF::Filters.is_valid_command_module_datastore_param?(http_params_value) - @datastore[http_params_key] = http_params_value # add the checked key and value to the datastore - } + if http_params != nil && http_headers != nil + # get, check and add the http_params to the datastore + http_params.keys.each { |http_params_key| + (print_error 'http_params_key is invalid';return) if not BeEF::Filters.is_valid_command_module_datastore_key?(http_params_key) + http_params_value = Erubis::XmlHelper.escape_xml(http_params[http_params_key]) + (print_error 'http_params_value is invalid';return) if not BeEF::Filters.is_valid_command_module_datastore_param?(http_params_value) + @datastore[http_params_key] = http_params_value # add the checked key and value to the datastore + } + + # get, check and add the http_headers to the datastore + http_headers.keys.each { |http_header_key| + (print_error 'http_header_key is invalid';return) if not BeEF::Filters.is_valid_command_module_datastore_key?(http_header_key) + http_header_value = Erubis::XmlHelper.escape_xml(http_headers[http_header_key][0]) + (print_error 'http_header_value is invalid';return) if not BeEF::Filters.is_valid_command_module_datastore_param?(http_header_value) + @datastore['http_headers'][http_header_key] = http_header_value # add the checked key and value to the datastore + } + end - # get, check and add the http_headers to the datastore - http_headers.keys.each { |http_header_key| - (print_error 'http_header_key is invalid';return) if not BeEF::Filters.is_valid_command_module_datastore_key?(http_header_key) - http_header_value = Erubis::XmlHelper.escape_xml(http_headers[http_header_key][0]) - (print_error 'http_header_value is invalid';return) if not BeEF::Filters.is_valid_command_module_datastore_param?(http_header_value) - @datastore['http_headers'][http_header_key] = http_header_value # add the checked key and value to the datastore - } @datastore['results'] = result @datastore['cid'] = command_id @datastore['beefhook'] = beefhook diff --git a/core/main/handlers/commands.rb b/core/main/handlers/commands.rb index 2e4f0a089..99182434a 100644 --- a/core/main/handlers/commands.rb +++ b/core/main/handlers/commands.rb @@ -48,7 +48,7 @@ module BeEF # @note create the command module to handle the response command = @kclass.new(BeEF::Module.get_key_by_class(@kclass)) - command.build_callback_datastore(@http_params, @http_header, result, command_id, beefhook) + command.build_callback_datastore(result, command_id, beefhook, @http_params, @http_header) command.session_id = beefhook if command.respond_to?(:post_execute) command.post_execute diff --git a/core/main/network_stack/websocket/websocket.rb b/core/main/network_stack/websocket/websocket.rb index 194aad629..ae6261fa6 100644 --- a/core/main/network_stack/websocket/websocket.rb +++ b/core/main/network_stack/websocket/websocket.rb @@ -138,41 +138,47 @@ module BeEF } end - BeEF::Core::Handlers::Commands #call the handler for websocket cmd response #@param [Hash] data contains the answer of a command def execute (data) command_results=Hash.new - print_debug Base64.decode64(data['result']) - # the last gsub is to remove leading/trailing double quotes from the result value. command_results["data"] = unescape_stringify(Base64.decode64(data['result'])).gsub!(/\A"|"\Z/, '') - command_results["data"].force_encoding('UTF-8') + command_results["data"].force_encoding('UTF-8') if command_results["data"] != nil hooked_browser = data["bh"] - (print_error "BeEFhook is invalid"; return) if not BeEF::Filters.is_valid_hook_session_id?(hooked_browser) - (print_error "command_id is invalid"; return) if not BeEF::Filters.is_valid_command_id?(data["cid"]) - (print_error "command name is empty"; return) if data["handler"].empty? - (print_error "command results are empty"; return) if command_results.empty? - (print_error "command status is invalid"; return) unless data["status"] =~ /\A0|1|2|undefined\z/ - if data["status"] == "undefined" - status = 0 - else - status = data["status"].to_i - end handler = data["handler"] + command_id = data["cid"] + command_status = data["status"] + + (print_error "BeEFhook is invalid"; return) unless BeEF::Filters.is_valid_hook_session_id?(hooked_browser) + (print_error "command_id is invalid"; return) unless BeEF::Filters.is_valid_command_id?(command_id) + (print_error "command name is empty"; return) if handler.empty? + (print_error "command results are empty"; return) if command_results.empty? + (print_error "command status is invalid"; return) unless command_status =~ /\A0|1|2|undefined\z/ + + command_mod = "beef.module.#{handler.gsub('/command/','').gsub('.js','')}" + command_name = @@config.get("#{command_mod}.class") + + data["status"] == "undefined" ? status = 0 : status = data["status"].to_i + if handler.match(/command/) + + command = BeEF::Core::Command.const_get(command_name.capitalize) + command_obj = command.new(BeEF::Module.get_key_by_class(command_name)) + command_obj.build_callback_datastore(command_results["data"], command_id, hooked_browser, nil, nil) + command_obj.session_id = hooked_browser + if command_obj.respond_to?(:post_execute) + command_obj.post_execute + end + BeEF::Core::Models::Command.save_result(hooked_browser, data["cid"], - @@config.get("beef.module.#{handler.gsub("/command/", "").gsub(".js", "")}.name"), + @@config.get("#{command_mod}.name"), command_results, status) else #processing results from extensions, call the right handler data["beefhook"] = hooked_browser - - - print_debug Base64.decode64(data["result"]).inspect - data["results"] = JSON.parse(Base64.decode64(data["result"])) if MOUNTS.has_key?(handler) if MOUNTS[handler].class == Array and MOUNTS[handler].length == 2 @@ -182,6 +188,7 @@ module BeEF end end end + end end end