Module: Msf::Exploit::CmdStager
- Defined in:
- lib/msf/core/exploit/cmd_stager.rb,
lib/msf/core/exploit/cmd_stager/http.rb
Overview
This mixin provides an interface to generating cmdstagers
Defined Under Namespace
Modules: HTTP
Constant Summary collapse
- STAGERS =
Constant for stagers - used when creating an stager instance.
{ :bourne => Rex::Exploitation::CmdStagerBourne, :debug_asm => Rex::Exploitation::CmdStagerDebugAsm, :debug_write => Rex::Exploitation::CmdStagerDebugWrite, :echo => Rex::Exploitation::CmdStagerEcho, :printf => Rex::Exploitation::CmdStagerPrintf, :vbs => Rex::Exploitation::CmdStagerVBS, :vbs_adodb => Rex::Exploitation::CmdStagerVBS, :certutil => Rex::Exploitation::CmdStagerCertutil, :tftp => Rex::Exploitation::CmdStagerTFTP, :wget => Rex::Exploitation::CmdStagerWget, :curl => Rex::Exploitation::CmdStagerCurl, :fetch => Rex::Exploitation::CmdStagerFetch, :lwprequest => Rex::Exploitation::CmdStagerLwpRequest, :psh_invokewebrequest => Rex::Exploitation::CmdStagerPSHInvokeWebRequest }
- DECODERS =
Constant for decoders - used when checking the default flavor decoder.
{ :debug_asm => File.join(Rex::Exploitation::DATA_DIR, "exploits", "cmdstager", "debug_asm"), :debug_write => File.join(Rex::Exploitation::DATA_DIR, "exploits", "cmdstager", "debug_write"), :vbs => File.join(Rex::Exploitation::DATA_DIR, "exploits", "cmdstager", "vbs_b64"), :vbs_adodb => File.join(Rex::Exploitation::DATA_DIR, "exploits", "cmdstager", "vbs_b64_adodb") }
Instance Attribute Summary collapse
-
#cmd_list ⇒ Object
Returns the value of attribute cmd_list.
-
#decoder ⇒ Object
Returns the value of attribute decoder.
-
#exe ⇒ Object
Returns the value of attribute exe.
-
#flavor ⇒ Object
Returns the value of attribute flavor.
-
#stager_instance ⇒ Object
Returns the value of attribute stager_instance.
Attributes included from Remote::SocketServer
Instance Method Summary collapse
-
#compatible_flavor?(f) ⇒ Boolean
Answers if the input flavor is compatible with the current target or module.
-
#create_stager ⇒ Rex::Exploitation::CmdStagerBase
Create an instance of the flavored stager.
-
#default_decoder(f) ⇒ Symbol?
Returns the default decoder stub for the input flavor.
-
#execute_cmdstager(opts = {}) ⇒ void
Executes the command stager while showing the progress.
-
#execute_cmdstager_begin(opts = {}) ⇒ Object
Code to execute before the cmd stager stub.
-
#execute_cmdstager_end(opts = {}) ⇒ Object
Code to execute after the cmd stager stub.
-
#execute_command(cmd, opts = {}) ⇒ Object
Code called to execute each command via an arbitrary module-defined vector.
-
#generate_cmdstager(opts = {}, pl = nil) ⇒ Array
Generates a cmd stub based on the current target's architecture and platform.
-
#guess_flavor ⇒ Symbol?
Guess the cmd stager flavor to use using information from the module, target or platform.
-
#initialize(info = {}) ⇒ Msf::Module::Exploit
Creates an instance of an exploit that uses an CMD Stager and register the datastore options provided by the mixin.
-
#module_flavors ⇒ Array
Returns all the compatible stager flavors specified by the module and each of its targets.
-
#opts_with_decoder(opts = {}) ⇒ Hash
Returns a hash with the :decoder option if possible.
-
#progress(total, sent) ⇒ void
Show the progress of the upload while cmd staging.
-
#select_cmdstager(opts = {}) ⇒ void
Selects the correct cmd stager and decoder stub to use.
-
#select_decoder(opts = {}) ⇒ String?
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.
-
#select_flavor(opts = {}) ⇒ Symbol?
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.
-
#target_flavor ⇒ Array, ...
Returns the compatible stager flavors for the current target or module.
Methods included from HTTP
#on_request_uri, #start_service
Methods included from Remote::HttpServer
#add_resource, #add_robots_resource, #autofilter, #check_dependencies, #cleanup, #cli, #cli=, #close_client, #create_response, #fingerprint_user_agent, #get_resource, #get_uri, #hardcoded_uripath, #on_request_uri, #print_prefix, #random_uri, #regenerate_payload, #remove_resource, #report_user_agent, #resource_uri, #send_local_redirect, #send_not_found, #send_redirect, #send_response, #send_robots, #srvhost_addr, #srvport, #start_service, #use_zlib
Methods included from Auxiliary::Report
#active_db?, #create_cracked_credential, #create_credential, #create_credential_and_login, #create_credential_login, #db, #db_warning_given?, #get_client, #get_host, #inside_workspace_boundary?, #invalidate_login, #mytask, #myworkspace, #myworkspace_id, #report_auth_info, #report_client, #report_exploit, #report_host, #report_loot, #report_note, #report_service, #report_vuln, #report_web_form, #report_web_page, #report_web_site, #report_web_vuln, #store_cred, #store_local, #store_loot
Methods included from Metasploit::Framework::Require
optionally, optionally_active_record_railtie, optionally_include_metasploit_credential_creation, #optionally_include_metasploit_credential_creation, optionally_require_metasploit_db_gem_engines
Methods included from Remote::TcpServer
#on_client_close, #on_client_connect, #ssl, #ssl_cert, #ssl_cipher, #ssl_compression, #start_service
Methods included from Remote::SocketServer
#_determine_server_comm, #cleanup, #exploit, #on_client_data, #primer, #regenerate_payload, #srvhost, #srvport, #start_service, #stop_service, #via_string_for_ip
Methods included from EXE
#exe_init_options, #exe_post_generation, #generate_payload_dccw_gdiplus_dll, #generate_payload_dll, #generate_payload_exe, #generate_payload_exe_service, #generate_payload_msi, #get_custom_exe, #get_eicar_exe
Instance Attribute Details
#cmd_list ⇒ Object
Returns the value of attribute cmd_list.
41 42 43 |
# File 'lib/msf/core/exploit/cmd_stager.rb', line 41 def cmd_list @cmd_list end |
#decoder ⇒ Object
Returns the value of attribute decoder.
43 44 45 |
# File 'lib/msf/core/exploit/cmd_stager.rb', line 43 def decoder @decoder end |
#exe ⇒ Object
Returns the value of attribute exe.
44 45 46 |
# File 'lib/msf/core/exploit/cmd_stager.rb', line 44 def exe @exe end |
#flavor ⇒ Object
Returns the value of attribute flavor.
42 43 44 |
# File 'lib/msf/core/exploit/cmd_stager.rb', line 42 def flavor @flavor end |
#stager_instance ⇒ Object
Returns the value of attribute stager_instance.
40 41 42 |
# File 'lib/msf/core/exploit/cmd_stager.rb', line 40 def stager_instance @stager_instance end |
Instance Method Details
#compatible_flavor?(f) ⇒ Boolean
Answers if the input flavor is compatible with the current target or module.
320 321 322 323 324 325 326 327 328 329 330 331 |
# File 'lib/msf/core/exploit/cmd_stager.rb', line 320 def compatible_flavor?(f) return true if target_flavor.nil? case target_flavor when String return true if target_flavor == f.to_s when Array target_flavor.each { |tr| return true if tr.to_sym == f } when Symbol return true if target_flavor == f end false end |
#create_stager ⇒ Rex::Exploitation::CmdStagerBase
Create an instance of the flavored stager.
208 209 210 |
# File 'lib/msf/core/exploit/cmd_stager.rb', line 208 def create_stager STAGERS[flavor].new(exe) end |
#default_decoder(f) ⇒ Symbol?
Returns the default decoder stub for the input flavor.
218 219 220 |
# File 'lib/msf/core/exploit/cmd_stager.rb', line 218 def default_decoder(f) DECODERS[f] end |
#execute_cmdstager(opts = {}) ⇒ void
This method returns an undefined value.
Executes the command stager while showing the progress. This method should be called from exploits using this mixin.
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/msf/core/exploit/cmd_stager.rb', line 84 def execute_cmdstager(opts = {}) self.cmd_list = generate_cmdstager(opts) stager_instance.setup(self) begin execute_cmdstager_begin(opts) sent = 0 total_bytes = 0 cmd_list.each { |cmd| total_bytes += cmd.length } delay = opts[:delay] delay ||= 0.25 cmd_list.each do |cmd| execute_command(cmd, opts) sent += cmd.length # In cases where a server has multiple threads, we want to be sure that # commands we execute happen in the correct (serial) order. ::IO.select(nil, nil, nil, delay) progress(total_bytes, sent) end execute_cmdstager_end(opts) ensure stager_instance.teardown(self) end end |
#execute_cmdstager_begin(opts = {}) ⇒ Object
Code to execute before the cmd stager stub. This method is designed to be overriden by a module this mixin.
337 338 |
# File 'lib/msf/core/exploit/cmd_stager.rb', line 337 def execute_cmdstager_begin(opts = {}) end |
#execute_cmdstager_end(opts = {}) ⇒ Object
Code to execute after the cmd stager stub. This method is designed to be overriden by a module this mixin.
344 345 |
# File 'lib/msf/core/exploit/cmd_stager.rb', line 344 def execute_cmdstager_end(opts = {}) end |
#execute_command(cmd, opts = {}) ⇒ Object
Code called to execute each command via an arbitrary module-defined vector. This method needs to be overriden by modules using this mixin.
352 353 354 |
# File 'lib/msf/core/exploit/cmd_stager.rb', line 352 def execute_command(cmd, opts = {}) raise NotImplementedError end |
#generate_cmdstager(opts = {}, pl = nil) ⇒ Array
Generates a cmd stub based on the current target's architecture and platform.
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/msf/core/exploit/cmd_stager.rb', line 127 def generate_cmdstager(opts = {}, pl = nil) select_cmdstager(opts) exe_opts = {code: pl}.merge( platform: target_platform, arch: target_arch ) self.exe = generate_payload_exe(exe_opts) if exe.nil? raise ArgumentError, 'The executable could not be generated' end self.stager_instance = create_stager if datastore['CMDSTAGER::TEMP'] opts[:temp] = datastore['CMDSTAGER::TEMP'] elsif datastore['WritableDir'] opts[:temp] = datastore['WritableDir'] end if stager_instance.respond_to?(:http?) && stager_instance.http? opts[:ssl] = datastore['CMDSTAGER::SSL'] unless opts.key?(:ssl) opts[:payload_uri] = start_service(opts) end cmd_list = stager_instance.generate(opts_with_decoder(opts)) if cmd_list.nil? || cmd_list.length.zero? raise ArgumentError, 'The command stager could not be generated' end vprint_status("Generated command stager: #{cmd_list.inspect}") cmd_list end |
#guess_flavor ⇒ Symbol?
Guess the cmd stager flavor to use using information from the module, target or platform.
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 |
# File 'lib/msf/core/exploit/cmd_stager.rb', line 260 def guess_flavor # First try to guess a compatible flavor based on the module & target information. unless target_flavor.nil? case target_flavor when Array return target_flavor[0].to_sym when String return target_flavor.to_sym when Symbol return target_flavor end end # Second try to guess a compatible flavor based on the target platform. return nil unless target_platform.names.length == 1 c_platform = target_platform.names.first case c_platform when /linux/i :bourne when /osx/i :bourne when /unix/i :bourne when /win/i :vbs else nil end end |
#initialize(info = {}) ⇒ Msf::Module::Exploit
Creates an instance of an exploit that uses an CMD Stager and register the datastore options provided by the mixin.
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/msf/core/exploit/cmd_stager.rb', line 51 def initialize(info = {}) super flavors = module_flavors flavors = STAGERS.keys if flavors.empty? flavors.unshift('auto') server_conditions = ['CMDSTAGER::FLAVOR', 'in', %w{auto certutil tftp wget curl fetch lwprequest psh_invokewebrequest}] ( [ OptAddressLocal.new('SRVHOST', [true, 'The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addresses.', '0.0.0.0' ], conditions: server_conditions), OptPort.new('SRVPORT', [true, "The local port to listen on.", 8080], conditions: server_conditions) ]) ( [ OptEnum.new('CMDSTAGER::FLAVOR', [false, 'The CMD Stager to use.', 'auto', flavors]), OptString.new('CMDSTAGER::DECODER', [false, 'The decoder stub to use.']), OptString.new('CMDSTAGER::TEMP', [false, 'Writable directory for staged files']), OptBool.new('CMDSTAGER::SSL', [false, 'Use SSL/TLS for supported stagers', false]) ], self.class) end |
#module_flavors ⇒ Array
Returns all the compatible stager flavors specified by the module and each of its targets.
294 295 296 297 298 299 300 301 302 |
# File 'lib/msf/core/exploit/cmd_stager.rb', line 294 def module_flavors flavors = [] flavors += Array(module_info['CmdStagerFlavor']) if module_info['CmdStagerFlavor'] targets.each do |target| flavors += Array(target.opts['CmdStagerFlavor']) if target.opts['CmdStagerFlavor'] end flavors.uniq! flavors.map { |flavor| flavor.to_s } end |
#opts_with_decoder(opts = {}) ⇒ Hash
Returns a hash with the :decoder option if possible
197 198 199 200 201 |
# File 'lib/msf/core/exploit/cmd_stager.rb', line 197 def opts_with_decoder(opts = {}) return opts if opts.include?(:decoder) return opts.merge(:decoder => decoder) if decoder opts end |
#progress(total, sent) ⇒ void
This method returns an undefined value.
Show the progress of the upload while cmd staging
169 170 171 172 173 |
# File 'lib/msf/core/exploit/cmd_stager.rb', line 169 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 |
#select_cmdstager(opts = {}) ⇒ void
This method returns an undefined value.
Selects the correct cmd stager and decoder stub to use
184 185 186 187 188 189 |
# File 'lib/msf/core/exploit/cmd_stager.rb', line 184 def select_cmdstager(opts = {}) self.flavor = select_flavor(opts) raise ArgumentError, "Unable to select CMD Stager" if flavor.nil? raise ArgumentError, "The CMD Stager '#{flavor}' isn't compatible with the target" unless compatible_flavor?(flavor) self.decoder = select_decoder(opts) end |
#select_decoder(opts = {}) ⇒ String?
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.
232 233 234 235 236 |
# File 'lib/msf/core/exploit/cmd_stager.rb', line 232 def select_decoder(opts = {}) return opts[:decoder] if opts.include?(:decoder) return datastore['CMDSTAGER::DECODER'] unless datastore['CMDSTAGER::DECODER'].blank? default_decoder(flavor) end |
#select_flavor(opts = {}) ⇒ Symbol?
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.
247 248 249 250 251 252 253 |
# File 'lib/msf/core/exploit/cmd_stager.rb', line 247 def select_flavor(opts = {}) return opts[:flavor].to_sym if opts.include?(:flavor) unless datastore['CMDSTAGER::FLAVOR'].blank? or datastore['CMDSTAGER::FLAVOR'] == 'auto' return datastore['CMDSTAGER::FLAVOR'].to_sym end guess_flavor end |
#target_flavor ⇒ Array, ...
Returns the compatible stager flavors for the current target or module.
310 311 312 313 314 |
# File 'lib/msf/core/exploit/cmd_stager.rb', line 310 def target_flavor return target.opts['CmdStagerFlavor'] if target && target.opts['CmdStagerFlavor'] return module_info['CmdStagerFlavor'] if module_info['CmdStagerFlavor'] nil end |