From 45248dcdecbabffe0d1c5feb773a158153a53e17 Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Sat, 8 Feb 2014 21:07:03 -0600 Subject: [PATCH] Add YARD documentation for methods --- lib/msf/core/exploit/cmdstager.rb | 179 +++++++++++------- .../http/hp_sitescope_runomagentcommand.rb | 2 +- .../windows/winrm/winrm_script_exec.rb | 2 +- 3 files changed, 111 insertions(+), 72 deletions(-) diff --git a/lib/msf/core/exploit/cmdstager.rb b/lib/msf/core/exploit/cmdstager.rb index 7f2bcc8ad4..61f7d0851e 100644 --- a/lib/msf/core/exploit/cmdstager.rb +++ b/lib/msf/core/exploit/cmdstager.rb @@ -49,7 +49,7 @@ module Exploit::CmdStager } } - STUBS = { + DECODERS = { :debug_asm => File.join(Msf::Config.install_root, "data", "exploits", "cmdstager", "debug_asm"), :debug_write => File.join(Msf::Config.install_root, "data", "exploits", "cmdstager", "debug_write"), :vbs => File.join(Msf::Config.install_root, "data", "exploits", "cmdstager", "vbs_b64"), @@ -59,7 +59,7 @@ module Exploit::CmdStager attr_accessor :stager_instance attr_accessor :cmd_list attr_accessor :flavor - attr_accessor :decoder_stub + attr_accessor :decoder attr_accessor :exe # Creates an instance of an exploit that uses an CMD Stager and register the @@ -73,7 +73,7 @@ module Exploit::CmdStager register_advanced_options( [ OptString.new('CMDSTAGER::FLAVOR', [ false, 'The CMD Stager to use.']), - OptString.new('CMDSTAGER::DECODERSTUB', [ false, 'The decoder stub to use.']) + OptString.new('CMDSTAGER::DECODER', [ false, 'The decoder stub to use.']) ], self.class) end @@ -86,7 +86,6 @@ module Exploit::CmdStager # @option opts :flavor [Symbol] The CMD Stager to use. # @option opts :decoder [Symbol] The decoder stub to use. # @option opts :delay [Float] Delay between command executions. - # @option opts :code [String] Payload to embed into the resultant executable. # @return [void] def execute_cmdstager(opts = {}) self.cmd_list = generate_cmdstager(opts) @@ -124,6 +123,13 @@ module Exploit::CmdStager # Generates a cmd stub based on the current target's architecture # and platform. # + # @param opts [Hash] Hash containing configuration options. Also allow to + # send opts to the Rex::Exploitation::CmdStagerBase constructor. + # @option opts :flavor [Symbol] The CMD Stager to use. + # @option opts :decoder [Symbol] The decoder stub to use. + # @param pl [String] String containing the payload to execute + # @return [Array] The list of commands to execute + # @raise [ArgumentError] raised if the cmd stub can not be generated def generate_cmdstager(opts = {}, pl = nil) select_cmdstager(opts) @@ -140,94 +146,107 @@ module Exploit::CmdStager cmd_list end - def select_cmdstager(opts = {}) - select_flavor(opts) - raise ArgumentError, "Unable to select CMD Stager" if flavor.nil? - raise ArgumentError, "The CMD Stager selected isn't compatible with the target" unless compatible_flavor? - select_decoder_stub(opts) - raise ArgumentError, "Unable to select decoder stub" if decoder_stub.nil? and stub_required? - end - - def opts_with_decoder(opts = {}) - return opts if opts.include?(:decoder) - return opts.merge(:decoder => decoder_stub) if decoder_stub - - opts - end - - - # - # Show the progress of the upload + # Show the progress of the upload while cmd staging # + # @param total [Float] The total number of bytes to send + # @param sent [Float] The number of bytes sent + # @return [void] def progress(total, sent) done = (sent.to_f / total.to_f) * 100 percent = "%3.2f%%" % done.to_f print_status("Command Stager progress - %7s done (%d/%d bytes)" % [percent, sent, total]) end + # Selects the correct cmd stager and decoder stub to use # - # Create an instance of the flavored stager + # @param opts [Hash] Hash containing the options to select te correct cmd + # stager and decoder. + # @option opts :flavor [Symbol] The cmd stager to use. + # @option opts :decoder [Symbol] The decoder stub to use. + # @return [void] + # @raise [ArgumentError] raised if a cmd stager can not be selected, it isn't + # compatible with the target platform or a required decoder stub can not be + # selected. + def select_cmdstager(opts = {}) + self.flavor = select_flavor(opts) + raise ArgumentError, "Unable to select CMD Stager" if flavor.nil? + raise ArgumentError, "The CMD Stager selected isn't compatible with the target" unless compatible?(flavor) + self.decoder = select_decoder(opts) + raise ArgumentError, "Unable to select decoder stub" if decoder.nil? && decoder_required? + end + + + # Returns a hash with the :decoder option if possible # + # @params opts [Hash] Input Hash. + # @return [Hash] Hash with the input data and a :decoder option when + # possible. + def opts_with_decoder(opts = {}) + return opts if opts.include?(:decoder) + return opts.merge(:decoder => decoder) if decoder + opts + end + + + # Create an instance of the flavored stager. + # + # @return [Rex::Exploitation::CmdStagerBase] The cmd stager to use. def create_stager STAGERS[flavor][:klass].new(exe) end + # Returns the default decoder stub for the current cmd stager flavor. # - # Guess the default decoder stub if there is one defined for - # the flavor - # - def guess_decoder - return nil unless STUBS.key?(flavor) - - STUBS[flavor] + # @return [Symbol] the decoder. + # @return [nil] if there isn't a default decoder to use for the current + # cmd stager flavor. + def default_decoder + DECODERS[flavor] end - def stub_required? + # Returns the better cmd stager decoder stub to use for the current flavor. + # + # @return [Symbol] the decoder to use. + # @return [nil] if there isn't a best decoder to use for the current flavor. + def decoder_required? STAGERS[flavor][:decoder] end + # Selects the correct cmd stager decoder to use based on three rules: (1) use + # the decoder provided in input options, (2) use the decoder provided by the + # user through datastore options, (3) select the default decoder for the + # current cmd stager flavor if available. # - # 1 - Use the decoder provided by the module source - # 2 - Use the decoder by the user through datastore - # 3 - Try to guess - # - def select_decoder_stub(opts) - self.decoder_stub = nil - - if opts.include?(:decoder) - self.decoder_stub = opts[:decoder].to_sym - return - end - - unless datastore['CMDSTAGER::DECODERSTUB'].blank? - self.decoder_stub = datastore['CMDSTAGER::DECODERSTUB'].to_sym - return - end - - self.decoder_stub = guess_decoder + # @param opts [Hash] Hash containing the options to select te correct + # decoder. + # @option opts :decoder [Symbol] The decoder stub to use. + # @return [Symbol] The decoder. + # @return [nil] if a decoder can not be selected. + def select_decoder(opts) + return opts[:decoder].to_sym if opts.include?(:decoder) + return datastore['CMDSTAGER::DECODER'].to_sym unless datastore['CMDSTAGER::DECODER'].blank? + default_decoder end + # Selects the correct cmd stager to use based on three rules: (1) use the + # flavor provided in options, (2) use the flavor provided by the user + # through datastore options, (3) guess the flavor using the target platform. # - # 1 - Use the flavor provided by the module source - # 2 - Use the flavor provided by the user through datastore - # 3 - Try to guess - # + # @param opts [Hash] Hash containing the options to select te correct cmd + # stager + # @option opts :flavor [Symbol] The cmd stager flavor to use. + # @return [Symbol] The flavor to use. + # @return [nil] if a flavor can not be selected. def select_flavor(opts) - self.flavor = nil - - if opts.include?(:flavor) - self.flavor = opts[:flavor].to_sym - return - end - - unless datastore['CMDSTAGER::FLAVOR'].blank? - self.flavor = datastore['CMDSTAGER::FLAVOR'].to_sym - return - end - - self.flavor = guess_flavor + return opts[:flavor].to_sym if opts.include?(:flavor) + return datastore['CMDSTAGER::FLAVOR'].to_sym unless datastore['CMDSTAGER::FLAVOR'].blank? + guess_flavor end + # Guess the cmd stager flavor to use using the target platform. + # + # @return [Symbol] The cmd stager flavor to use. + # @return [nil] if the cmd stager flavor can not be guessed. def guess_flavor return nil unless target_platform.names.length == 1 c_platform = target_platform.names.first @@ -245,23 +264,43 @@ module Exploit::CmdStager end end + # Returns the compatible stager flavors for the current target or module. + # + # @return [Array] the list of compatible cmd stager flavors. + # @return [Symbol] the compatible cmd stager flavor. + # @return [nil] if there isn't any compatible flavor defined. def target_flavor return target.opts['CmdStagerFlavor'].to_sym if target && target.opts['CMDStagerFlavor'] return module_info['CmdStagerFlavor'].to_sym if module_info['CMDStagerFlavor'] nil end - def compatible_flavor? - target_flavor.nil? || target_flavor == flavor || target_flavor.include?(flavor) + # Answers if the input flavor is compatible with the current target or module. + # + # @param f [Symbol] The flavor to check + # @returns [Boolean] true if compatible, false otherwise. + def compatible?(f) + target_flavor.nil? || target_flavor == f || target_flavor.include?(f) end + # Code to execute before the cmd stager stub. This method is designed to be + # overriden by a module this mixin. # - # Methods to override - not used internally - # + # @param opts [Hash] Hash of configuration options. def execute_cmdstager_begin(opts) end + + # Code to execute after the cmd stager stub. This method is designed to be + # overriden by a module this mixin. + # + # @param opts [Hash] Hash of configuration options. def execute_cmdstager_end(opts) end + + # Code to execute each command from the. This method is designed to be + # overriden by a module using this mixin. + # + # @param opts [Hash] Hash of configuration options. def execute_command(cmd, opts) end diff --git a/modules/exploits/windows/http/hp_sitescope_runomagentcommand.rb b/modules/exploits/windows/http/hp_sitescope_runomagentcommand.rb index 7ebc841275..d3507767ec 100644 --- a/modules/exploits/windows/http/hp_sitescope_runomagentcommand.rb +++ b/modules/exploits/windows/http/hp_sitescope_runomagentcommand.rb @@ -50,7 +50,7 @@ class Metasploit3 < Msf::Exploit::Remote 'DefaultTarget' => 0, 'DefaultOptions' => { - 'CMDSTAGER::DECODERSTUB' => File.join(Msf::Config.data_directory, "exploits", "cmdstager", "vbs_b64_noquot") + 'CMDSTAGER::DECODER' => File.join(Msf::Config.data_directory, "exploits", "cmdstager", "vbs_b64_noquot") }, 'DisclosureDate' => 'Jul 29 2013')) diff --git a/modules/exploits/windows/winrm/winrm_script_exec.rb b/modules/exploits/windows/winrm/winrm_script_exec.rb index d6a3f976d3..5a19feec32 100644 --- a/modules/exploits/windows/winrm/winrm_script_exec.rb +++ b/modules/exploits/windows/winrm/winrm_script_exec.rb @@ -41,7 +41,7 @@ class Metasploit3 < Msf::Exploit::Remote 'WfsDelay' => 30, 'EXITFUNC' => 'thread', 'InitialAutoRunScript' => 'post/windows/manage/smart_migrate', - 'CMDSTAGER::DECODERSTUB' => File.join(Msf::Config.install_root, "data", "exploits", "cmdstager", "vbs_b64_sleep") + 'CMDSTAGER::DECODER' => File.join(Msf::Config.install_root, "data", "exploits", "cmdstager", "vbs_b64_sleep") }, 'Platform' => 'win', 'Arch' => [ ARCH_X86, ARCH_X86_64 ],