Class: Msf::Exploit

Inherits:
Module show all
Defined in:
lib/msf/core/exploit.rb,
lib/msf/core/exploit/capture.rb

Overview

This module provides methods for sending and receiving raw packets. It should be preferred over the soon-to-be deprecated Rex::Socket::Ip and Msf::Exploite::Remote::Ip mixins.

Please see the pcaprub documentation for more information on how to use capture objects.

Direct Known Subclasses

Local, Remote

Defined Under Namespace

Modules: Brute, BruteTargets, Capture, CheckCode, CmdStager, CmdStagerBourne, CmdStagerDebugAsm, CmdStagerDebugWrite, CmdStagerEcho, CmdStagerPrintf, CmdStagerTFTP, CmdStagerVBS, CompatDefaults, DECT_COA, DHCPServer, EXE, Egghunter, FILEFORMAT, FileDropper, FormatString, Java, KernelMode, Lorcon, Lorcon2, NTLM, ORACLE, Omelet, PDF, PDF_Parse, PhpEXE, Powershell, RIFF, RopDb, Seh, Stance, TFTPServer, Type, WbemExec Classes: Complete, Failed, Local, Remote

Instance Attribute Summary collapse

Attributes inherited from Module

#arch, #author, #datastore, #error, #job_id, #license, #module_store, #options, #platform, #privileged, #references, #uuid

Attributes included from Framework::Offspring

#framework

Attributes included from Rex::Ui::Subscriber::Input

#user_input

Attributes included from Rex::Ui::Subscriber::Output

#user_output

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Module

#[], #[]=, #alias, #arch?, #arch_to_s, #author_to_s, #auxiliary?, cached?, #check, #comm, #compat, #compatible?, #debugging?, #description, #disclosure_date, #each_arch, #each_author, #encoder?, #exploit?, #file_path, #framework, #fullname, fullname, #import_defaults, is_usable, #name, #nop?, #orig_cls, #owner, #payload?, #platform?, #platform_to_s, #post?, #print_error, #print_good, #print_line, #print_line_prefix, #print_prefix, #print_status, #print_warning, #privileged?, #rank, rank, rank_to_h, #rank_to_h, #rank_to_s, rank_to_s, #refname, #register_parent, #replicant, #search_filter, #share_datastore, shortname, #shortname, #support_ipv6?, #target_host, #target_port, #validate, #vprint_debug, #vprint_error, #vprint_good, #vprint_line, #vprint_status, #vprint_warning, #workspace

Methods included from Rex::Ui::Subscriber

#copy_ui, #init_ui, #reset_ui

Methods included from Rex::Ui::Subscriber::Input

#gets

Methods included from Rex::Ui::Subscriber::Output

#flush, #print, #print_debug, #print_error, #print_good, #print_line, #print_status, #print_warning

Constructor Details

#initialize(info = {}) ⇒ Exploit

Creates an instance of the exploit module. Mad skillz.


269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
# File 'lib/msf/core/exploit.rb', line 269

def initialize(info = {})

  # Ghetto compat mirroring for payload compatibilities.  This mirrors
  #
  # Payload => Compat => xyz
  #
  # to
  #
  # Compat => Payload => xyz
  if (info['Payload'] and info['Payload']['Compat'])
    info['Compat'] = Hash.new if (info['Compat'] == nil)
    info['Compat']['Payload'] = Hash.new if (info['Compat']['Payload'] == nil)
    info['Compat']['Payload'].update(info['Payload']['Compat'])
  end

  # Call the parent constructor after making any necessary modifications
  # to the information hash.
  super(info)

  self.targets = Rex::Transformer.transform(info['Targets'], Array,
      [ Target ], 'Targets')
  self.default_target = info['DefaultTarget']
  self.payload_info = info['Payload'] || {}
  self.successful = false
  self.session_count = 0
  self.active_timeout = 120
  self.fail_reason = Failure::None

  if (info['Payload'] and info['Payload']['ActiveTimeout'])
    self.active_timeout = info['Payload']['ActiveTimeout'].to_i
  end

  # All exploits can increase the delay when waiting for a session.
  # However, this only applies to aggressive exploits.
  if aggressive?
    register_advanced_options(
      [
        OptInt.new('WfsDelay', [ false, "Additional delay when waiting for a session", 0 ])
      ], Msf::Exploit)
  end

  # Allow all exploits to leverage context keyed encoding
  register_advanced_options(
    [
      OptBool.new('EnableContextEncoding', [ false, "Use transient context when encoding payloads", false ]),
      OptPath.new('ContextInformationFile', [ false, "The information file that contains context information", nil ])
    ], Msf::Exploit)

  # Allow all exploits to disable their payload handlers
  register_advanced_options(
    [
      OptBool.new('DisablePayloadHandler', [ false, "Disable the handler code for the selected payload", false ])
    ], Msf::Exploit)
end

Instance Attribute Details

#default_targetObject

The default target.


1295
1296
1297
# File 'lib/msf/core/exploit.rb', line 1295

def default_target
  @default_target
end

#fail_detailObject

Detailed exception string indicating why the exploit was not successful


1286
1287
1288
# File 'lib/msf/core/exploit.rb', line 1286

def fail_detail
  @fail_detail
end

#fail_reasonObject

The reason why the exploit was not successful (one of Msf::Exploit::FailReason)


1281
1282
1283
# File 'lib/msf/core/exploit.rb', line 1281

def fail_reason
  @fail_reason
end

#payloadObject

The encoded payload instance. An instance of an EncodedPayload object.


1308
1309
1310
# File 'lib/msf/core/exploit.rb', line 1308

def payload
  @payload
end

#payload_infoObject

The payload requirement hash.


1299
1300
1301
# File 'lib/msf/core/exploit.rb', line 1299

def payload_info
  @payload_info
end

#payload_instanceObject

The active payload instance.


1303
1304
1305
# File 'lib/msf/core/exploit.rb', line 1303

def payload_instance
  @payload_instance
end

#session_countObject

The number of active sessions created by this instance


1313
1314
1315
# File 'lib/msf/core/exploit.rb', line 1313

def session_count
  @session_count
end

#successfulObject

The boolean indicating whether the exploit succeeded


1318
1319
1320
# File 'lib/msf/core/exploit.rb', line 1318

def successful
  @successful
end

#targetsObject

The list of targets.


1291
1292
1293
# File 'lib/msf/core/exploit.rb', line 1291

def targets
  @targets
end

Class Method Details

.mixinsArray

Returns an array of all of the exploit mixins. Lame algorithm right now. We search the Msf::Exploit namespace for all modules that do not have any constants in them. In the future we can replace this with a better algorithm. It's just important that it returns an array of all of the mixin modules.


234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
# File 'lib/msf/core/exploit.rb', line 234

def self.mixins
  mixins  = []
  wl      = [ Msf::Exploit ]
  visited = {}

  until wl.length == 0
    wl.delete_if { |mod|
      mod.constants.each { |const|
        child = mod.const_get(const)

        next if child.to_s !~ /^Msf::Exploit/

        next if visited[child]

        next if child.kind_of?(::Module) == false

        visited[child] = true

        if child.constants.length > 0
          wl << child
        else
          mixins << child
        end
      }

      true
    }
  end

  return mixins
end

.typeObject

Returns MODULE_EXPLOIT to indicate that this is an exploit module.


623
624
625
# File 'lib/msf/core/exploit.rb', line 623

def self.type
  MODULE_EXPLOIT
end

Instance Method Details

#add_handler(opts = {}) ⇒ Object

Allows the payload handler to spawn a new monitor


468
469
470
471
472
# File 'lib/msf/core/exploit.rb', line 468

def add_handler(opts={})
  return if not payload_instance
  return if not handler_enabled?
  payload_instance.add_handler(opts)
end

#aggressive?Boolean

Returns true if the exploit has an aggressive stance.


651
652
653
# File 'lib/msf/core/exploit.rb', line 651

def aggressive?
  (stance == Stance::Aggressive)
end

#autofilterObject

Performs last-minute sanity checking of auxiliary parameters. This method is called during automated exploitation attempts and allows an auxiliary module to filter bad attempts, obtain more information, and choose better parameters based on the available data. Returning anything that evaluates to “false” will cause this specific auxiliary attempt to be skipped. This method can and will change datastore values and may interact with the backend database.


354
355
356
# File 'lib/msf/core/exploit.rb', line 354

def autofilter
  true
end

#autofilter_portsObject

Provides a list of ports that can be used for matching this module against target systems.


362
363
364
# File 'lib/msf/core/exploit.rb', line 362

def autofilter_ports
  @autofilter_ports || []
end

#autofilter_servicesObject

Provides a list of services that can be used for matching this module against target systems.


370
371
372
# File 'lib/msf/core/exploit.rb', line 370

def autofilter_services
  @autofilter_services || []
end

#capabilitiesObject

Returns a hash of the capabilities this exploit module has support for, such as whether or not it supports check and exploit.


605
606
607
608
609
610
# File 'lib/msf/core/exploit.rb', line 605

def capabilities
  {
    'check'       => supports_check?,
    'exploit'     => supports_exploit?
  }
end

#cleanupObject

Performs any cleanup that may be necessary, such as disconnecting connections and any other such fun things. If a payload is active then its handler cleanup routines are called as well.


420
421
422
423
424
425
# File 'lib/msf/core/exploit.rb', line 420

def cleanup
  if (payload_instance and handler_enabled?)
    payload_instance.cleanup_handler
  end
  self.abort_sockets if self.respond_to?(:abort_sockets)
end

#compatible_encodersObject

Returns a list of compatible encoders based on architecture


744
745
746
747
748
749
750
751
752
753
754
755
756
757
# File 'lib/msf/core/exploit.rb', line 744

def compatible_encoders
  encoders = []

  c_platform = (target and target.platform) ? target.platform : platform
  c_arch     = (target and target.arch)     ? target.arch     : (arch == []) ? nil : arch

  framework.encoders.each_module_ranked(
    'Arch' => c_arch, 'Platform' => c_platform) { |name, mod|

    encoders << [ name, mod ]
  }

  return encoders;
end

#compatible_payloadsObject

Returns a list of compatible payloads based on platform, architecture, and size requirements.


705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
# File 'lib/msf/core/exploit.rb', line 705

def compatible_payloads
  payloads = []


  c_platform = (target and target.platform) ? target.platform : platform
  c_arch     = (target and target.arch)     ? target.arch     : (arch == []) ? nil : arch
  c_arch   ||= [ ARCH_X86 ]

  framework.payloads.each_module(
    'Platform' => c_platform,
    'Arch'     => c_arch ) { |name, mod|

    # Skip over payloads that are too big
    if ((payload_space) and
        (framework.payloads.sizes[name]) and
        (framework.payloads.sizes[name] > payload_space))
      dlog("#{refname}: Skipping payload #{name} for being too large", 'core',
        LEV_1)
      next
    end

    # Are we compatible in terms of conventions and connections and
    # what not?
    next if (compatible?(framework.payloads.instance(name)) == false)

    # If the payload is privileged but the exploit does not give
    # privileged access, then fail it.
    next if (self.privileged == false and framework.payloads.instance(name).privileged == true)

    # This one be compatible!
    payloads << [ name, mod ]
  }

  return payloads;
end

#encode_begin(real_payload, reqs) ⇒ Object

Called prior to encoding a payload.


566
567
# File 'lib/msf/core/exploit.rb', line 566

def encode_begin(real_payload, reqs)
end

#encode_end(real_payload, reqs, encoded) ⇒ Object

Called after an encoded payload has been generated. This gives exploits or mixins a chance to alter the encoded payload.


573
574
575
# File 'lib/msf/core/exploit.rb', line 573

def encode_end(real_payload, reqs, encoded)
  encoded
end

#encode_shellcode_stub(code, badchars = payload_badchars) ⇒ Object

Allows arbitrary shellcode to be encoded from within an exploit


449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
# File 'lib/msf/core/exploit.rb', line 449

def encode_shellcode_stub(code, badchars=payload_badchars)
  platform = self.platform
  if(self.payload_instance)
    self.payload_instance.platform
  end
  compatible_encoders.each do |name, mod|
    begin
      enc = framework.encoders.create(name)
      raw = enc.encode(code, badchars, nil, platform)
      return raw if raw
    rescue ::Exception
    end
  end
  nil
end

#exploitObject

Kicks off the actual exploit. Prior to this call, the framework will have validated the data store using the options associated with this exploit module. It will also pre-generate the desired payload, though exploits can re-generate the payload if necessary.

This method is designed to be overriden by exploit modules.


342
343
# File 'lib/msf/core/exploit.rb', line 342

def exploit
end

#exploit_typeObject

If we don't know the exploit type, then I guess it's omnipresent!


637
638
639
# File 'lib/msf/core/exploit.rb', line 637

def exploit_type
  Type::Omni
end

#fail_with(reason, msg = nil) ⇒ Object

Failure tracking


1221
1222
1223
1224
1225
# File 'lib/msf/core/exploit.rb', line 1221

def fail_with(reason,msg=nil)
  self.fail_reason = reason
  self.fail_detail = msg
  raise Msf::Exploit::Failed, (msg || "No reason given")
end

#generate_payload(pinst = nil) ⇒ Object

Generates the encoded version of the supplied payload using the payload requirements specific to this exploit. The encoded instance is returned to the caller. This method is exposed in the manner that it is such that passive exploits and re-generate an encoded payload on the fly rather than having to use the pre-generated one.

The return value is an EncodedPayload instance.


436
437
438
439
440
441
442
443
444
# File 'lib/msf/core/exploit.rb', line 436

def generate_payload(pinst = nil)
  # Set the encoded payload to the result of the encoding process
  self.payload = generate_single_payload(pinst)

  # Save the payload instance
  self.payload_instance = (pinst) ? pinst : self.payload_instance

  return self.payload
end

#generate_single_payload(pinst = nil, platform = nil, arch = nil, explicit_target = nil) ⇒ Object

This method generates a non-cached payload which is typically useful for passive exploits that will have more than one client.


478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
# File 'lib/msf/core/exploit.rb', line 478

def generate_single_payload(pinst = nil, platform = nil, arch = nil, explicit_target = nil)
  explicit_target ||= target

  if (explicit_target == nil)
    raise MissingTargetError, "No target has been specified.",
      caller
  end

  # If a payload instance was supplied, use it, otherwise
  # use the active payload instance
  real_payload = (pinst) ? pinst : self.payload_instance

  if (real_payload == nil)
    raise MissingPayloadError, "No payload has been selected.",
      caller
  end

  # If this is a generic payload, then we should specify the platform
  # and architecture so that it knows how to pass things on.
  if real_payload.kind_of?(Msf::Payload::Generic)
    # Convert the architecture specified into an array.
    if arch and arch.kind_of?(String)
      arch = [ arch ]
    end

    # Define the explicit platform and architecture information only if
    # it's been specified.
    if platform
      real_payload.explicit_platform = Msf::Module::PlatformList.transform(platform)
    end

    if arch
      real_payload.explicit_arch = arch
    end

    # Force it to reset so that it will find updated information.
    real_payload.reset
  end

  # Duplicate the exploit payload requirements
  reqs = self.payload_info.dup

  # Pass save register requirements to the NOP generator
  reqs['Space']           = payload_space(explicit_target)
  reqs['SaveRegisters']   = nop_save_registers(explicit_target)
  reqs['Prepend']         = payload_prepend(explicit_target)
  reqs['PrependEncoder']  = payload_prepend_encoder(explicit_target)
  reqs['BadChars']        = payload_badchars(explicit_target)
  reqs['Append']          = payload_append(explicit_target)
  reqs['AppendEncoder']   = payload_append_encoder(explicit_target)
  reqs['MaxNops']         = payload_max_nops(explicit_target)
  reqs['MinNops']         = payload_min_nops(explicit_target)
  reqs['Encoder']         = datastore['ENCODER']
  reqs['Nop']             = datastore['NOP']
  reqs['EncoderType']     = payload_encoder_type(explicit_target)
  reqs['EncoderOptions']  = payload_encoder_options(explicit_target)
  reqs['ExtendedOptions'] = payload_extended_options(explicit_target)
  reqs['Exploit']         = self

  # Pass along the encoder don't fall through flag
  reqs['EncoderDontFallThrough'] = datastore['EncoderDontFallThrough']

  # Incorporate any context encoding requirements that are needed
  define_context_encoding_reqs(reqs)

  # Call the encode begin routine.
  encode_begin(real_payload, reqs)

  # Generate the encoded payload.
  encoded = EncodedPayload.create(real_payload, reqs)

  # Call the encode end routine which is expected to return the actual
  # encoded payload instance.
  return encode_end(real_payload, reqs, encoded)
end

#handler(*args) ⇒ Object

Passes the connection to the associated payload handler to see if the exploit succeeded and a connection has been established. The return value can be one of the Handler::constants.


1181
1182
1183
1184
1185
# File 'lib/msf/core/exploit.rb', line 1181

def handler(*args)
  return if not payload_instance
  return if not handler_enabled?
  return payload_instance.handler(*args)
end

#handler_enabled?Boolean

Allow the user to disable the payload handler


1166
1167
1168
# File 'lib/msf/core/exploit.rb', line 1166

def handler_enabled?
  not datastore['DisablePayloadHandler']
end

#make_nops(count) ⇒ Object

Generates a nop sled of a supplied length and returns it to the caller.


994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
# File 'lib/msf/core/exploit.rb', line 994

def make_nops(count)
  # If we're debugging, then make_nops will return a safe sled.  We
  # currently assume x86.
  if debugging?
    return "\x90" * count
  end

  nop_sled = nil

  # If there is no payload instance then we can't succeed.
  return nil if (!payload_instance)

  payload_instance.compatible_nops.each { |nopname, nopmod|
    # Create an instance of the nop module
    nop = nopmod.new

    # The list of save registers
    save_regs = nop_save_registers || []

    if (save_regs.empty? == true)
      save_regs = nil
    end

    begin
      nop.copy_ui(self)

      nop_sled = nop.generate_sled(count,
        'BadChars'      => payload_badchars || '',
        'SaveRegisters' => save_regs)
    rescue
      wlog("#{self.refname}: Nop generator #{nop.refname} failed to generate sled for exploit: #{$!}",
        'core', LEV_0)
    end

    break
  }

  nop_sled
end

#nop_generatorObject

Returns the first compatible NOP generator for this exploit's payload instance.


983
984
985
986
987
988
989
# File 'lib/msf/core/exploit.rb', line 983

def nop_generator
  return nil if (!payload_instance)

  payload_instance.compatible_nops.each { |nopname, nopmod|
    return nopmod.new
  }
end

#nop_save_registers(explicit_target = nil) ⇒ Object

Returns the list of registers that the NOP generator should save, if any. It will use the current target's save registers in precedence over those defined globally for the exploit module.

If there are no save registers, nil is returned.


969
970
971
972
973
974
975
976
977
# File 'lib/msf/core/exploit.rb', line 969

def nop_save_registers(explicit_target = nil)
  explicit_target ||= target

  if (explicit_target and explicit_target.save_registers)
    return explicit_target.save_registers
  else
    return module_info['SaveRegisters']
  end
end

#on_new_session(session) ⇒ Object

This is called by the payload when a new session is created


1196
1197
1198
1199
# File 'lib/msf/core/exploit.rb', line 1196

def on_new_session(session)
  self.session_count += 1
  self.successful = true
end

#passive?Boolean

Returns if the exploit has a passive stance.


658
659
660
# File 'lib/msf/core/exploit.rb', line 658

def passive?
  (stance == Stance::Passive)
end

#pattern_create(length, sets = nil) ⇒ Object

Generate a non-repeating static random string


1152
1153
1154
# File 'lib/msf/core/exploit.rb', line 1152

def pattern_create(length, sets = nil)
  Rex::Text.pattern_create(length, sets)
end

#payload_append(explicit_target = nil) ⇒ Object

Return any text that should be appended to the payload. The payload module is passed so that the exploit can take a guess at architecture and platform if it's a multi exploit.


809
810
811
812
813
814
815
816
817
# File 'lib/msf/core/exploit.rb', line 809

def payload_append(explicit_target = nil)
  explicit_target ||= target

  if (explicit_target and explicit_target.payload_append)
    explicit_target.payload_append
  else
    payload_info['Append'] || ''
  end
end

#payload_append_encoder(explicit_target = nil) ⇒ Object

Return any text that should be appended to the encoder of the payload. The payload module is passed so that the exploit can take a guess at architecture and platform if it's a multi exploit.


841
842
843
844
845
846
847
848
849
850
851
# File 'lib/msf/core/exploit.rb', line 841

def payload_append_encoder(explicit_target = nil)
  explicit_target ||= target

  if (explicit_target and explicit_target.payload_append_encoder)
    p = explicit_target.payload_append_encoder
  else
    p = payload_info['AppendEncoder'] || ''
  end

  p
end

#payload_badchars(explicit_target = nil) ⇒ Object

Returns the bad characters that cannot be in any payload used by this exploit.


900
901
902
903
904
905
906
907
908
# File 'lib/msf/core/exploit.rb', line 900

def payload_badchars(explicit_target = nil)
  explicit_target ||= target

  if (explicit_target and explicit_target.payload_badchars)
    explicit_target.payload_badchars
  else
    payload_info['BadChars']
  end
end

#payload_encoder_options(explicit_target = nil) ⇒ Object

Returns the payload encoder option hash that is used to initialize the datastore of the encoder that is selected when generating an encoded payload.


929
930
931
932
933
934
935
936
937
# File 'lib/msf/core/exploit.rb', line 929

def payload_encoder_options(explicit_target = nil)
  explicit_target ||= target

  if (explicit_target and explicit_target.payload_encoder_options)
    explicit_target.payload_encoder_options
  else
    payload_info['EncoderOptions']
  end
end

#payload_encoder_type(explicit_target = nil) ⇒ Object

Returns the payload encoder type that is associated with either the current target of the exploit in general.


914
915
916
917
918
919
920
921
922
# File 'lib/msf/core/exploit.rb', line 914

def payload_encoder_type(explicit_target = nil)
  explicit_target ||= target

  if (explicit_target and explicit_target.payload_encoder_type)
    explicit_target.payload_encoder_type
  else
    payload_info['EncoderType']
  end
end

#payload_extended_options(explicit_target = nil) ⇒ Object

Returns the payload extended options hash which is used to provide a location to store extended information that may be useful to a particular type of payload or mixin.


944
945
946
947
948
949
950
951
952
# File 'lib/msf/core/exploit.rb', line 944

def payload_extended_options(explicit_target = nil)
  explicit_target ||= target

  if explicit_target and explicit_target.payload_extended_options
    explicit_target.payload_extended_options
  else
    payload_info['ExtendedOptions']
  end
end

#payload_max_nops(explicit_target = nil) ⇒ Object

Maximum number of nops to use as a hint to the framework. Nil signifies that the framework should decide.


857
858
859
860
861
862
863
864
865
# File 'lib/msf/core/exploit.rb', line 857

def payload_max_nops(explicit_target = nil)
  explicit_target ||= target

  if (explicit_target and explicit_target.payload_max_nops)
    explicit_target.payload_max_nops
  else
    payload_info['MaxNops'] || nil
  end
end

#payload_min_nops(explicit_target = nil) ⇒ Object

Minimum number of nops to use as a hint to the framework. Nil snigifies that the framework should decide.


871
872
873
874
875
876
877
878
879
# File 'lib/msf/core/exploit.rb', line 871

def payload_min_nops(explicit_target = nil)
  explicit_target ||= target

  if (explicit_target and explicit_target.payload_min_nops)
    explicit_target.payload_min_nops
  else
    payload_info['MinNops'] || nil
  end
end

#payload_prepend(explicit_target = nil) ⇒ Object

Return any text that should be prepended to the payload. The payload module is passed so that the exploit can take a guess at architecture and platform if it's a multi exploit. This automatically takes into account any require stack adjustments.


792
793
794
795
796
797
798
799
800
801
802
# File 'lib/msf/core/exploit.rb', line 792

def payload_prepend(explicit_target = nil)
  explicit_target ||= target

  if (explicit_target and explicit_target.payload_prepend)
    p = explicit_target.payload_prepend
  else
    p = payload_info['Prepend'] || ''
  end

  stack_adjustment + p
end

#payload_prepend_encoder(explicit_target = nil) ⇒ Object

Return any text that should be prepended to the encoder of the payload. The payload module is passed so that the exploit can take a guess at architecture and platform if it's a multi exploit.


824
825
826
827
828
829
830
831
832
833
834
# File 'lib/msf/core/exploit.rb', line 824

def payload_prepend_encoder(explicit_target = nil)
  explicit_target ||= target

  if (explicit_target and explicit_target.payload_prepend_encoder)
    p = explicit_target.payload_prepend_encoder
  else
    p = payload_info['PrependEncoder'] || ''
  end

  p
end

#payload_space(explicit_target = nil) ⇒ Object

Returns the maximum amount of room the exploit has for a payload.


884
885
886
887
888
889
890
891
892
893
894
# File 'lib/msf/core/exploit.rb', line 884

def payload_space(explicit_target = nil)
  explicit_target ||= target

  if (explicit_target and explicit_target.payload_space)
    explicit_target.payload_space
  elsif (payload_info['Space'])
    payload_info['Space'].to_i
  else
    nil
  end
end

#rand_char(bad = payload_badchars) ⇒ Object

Generate a random character avoiding the exploit's bad characters.


1141
1142
1143
1144
1145
1146
1147
# File 'lib/msf/core/exploit.rb', line 1141

def rand_char(bad=payload_badchars)
  if debugging?
    "A"
  else
    Rex::Text.rand_char(bad)
  end
end

#rand_text(length, bad = payload_badchars) ⇒ Object

Generate random text characters avoiding the exploit's bad characters.


1045
1046
1047
1048
1049
1050
1051
# File 'lib/msf/core/exploit.rb', line 1045

def rand_text(length, bad=payload_badchars)
  if debugging?
    "A" * length
  else
    Rex::Text.rand_text(length, bad)
  end
end

#rand_text_alpha(length, bad = payload_badchars) ⇒ Object

Generate random alpha characters avoiding the exploit's bad characters.


1081
1082
1083
1084
1085
1086
1087
# File 'lib/msf/core/exploit.rb', line 1081

def rand_text_alpha(length, bad=payload_badchars)
  if debugging?
    "A" * length
  else
    Rex::Text.rand_text_alpha(length, bad)
  end
end

#rand_text_alpha_lower(length, bad = payload_badchars) ⇒ Object

Generate random alpha lower characters avoiding the exploit's bad characters.


1105
1106
1107
1108
1109
1110
1111
# File 'lib/msf/core/exploit.rb', line 1105

def rand_text_alpha_lower(length, bad=payload_badchars)
  if debugging?
    "a" * length
  else
    Rex::Text.rand_text_alpha_lower(length, bad)
  end
end

#rand_text_alpha_upper(length, bad = payload_badchars) ⇒ Object

Generate random alpha upper characters avoiding the exploit's bad characters.


1093
1094
1095
1096
1097
1098
1099
# File 'lib/msf/core/exploit.rb', line 1093

def rand_text_alpha_upper(length, bad=payload_badchars)
  if debugging?
    "A" * length
  else
    Rex::Text.rand_text_alpha_upper(length, bad)
  end
end

#rand_text_alphanumeric(length, bad = payload_badchars) ⇒ Object

Generate random alphanumeric characters avoiding the exploit's bad characters.


1117
1118
1119
1120
1121
1122
1123
# File 'lib/msf/core/exploit.rb', line 1117

def rand_text_alphanumeric(length, bad=payload_badchars)
  if debugging?
    "A" * length
  else
    Rex::Text.rand_text_alphanumeric(length, bad)
  end
end

#rand_text_english(length, bad = payload_badchars) ⇒ Object

Generate random english-like avoiding the exploit's bad characters.


1057
1058
1059
1060
1061
1062
1063
# File 'lib/msf/core/exploit.rb', line 1057

def rand_text_english(length, bad=payload_badchars)
  if debugging?
    "A" * length
  else
    Rex::Text.rand_text_english(length, bad)
  end
end

#rand_text_highascii(length, bad = payload_badchars) ⇒ Object

Generate random high ascii characters avoiding the exploit's bad characters.


1069
1070
1071
1072
1073
1074
1075
# File 'lib/msf/core/exploit.rb', line 1069

def rand_text_highascii(length, bad=payload_badchars)
  if debugging?
    "A" * length
  else
    Rex::Text.rand_text_highascii(length, bad)
  end
end

#rand_text_numeric(length, bad = payload_badchars) ⇒ Object

Generate random numeric characters avoiding the exploit's bad characters.


1129
1130
1131
1132
1133
1134
1135
# File 'lib/msf/core/exploit.rb', line 1129

def rand_text_numeric(length, bad=payload_badchars)
  if debugging?
    "0" * length
  else
    Rex::Text.rand_text_numeric(length, bad)
  end
end

#regenerate_payload(platform = nil, arch = nil, explicit_target = nil) ⇒ Object Also known as: exploit_regenerate_payload

Re-generates an encoded payload, typically called after something in the datastore has changed. An optional platform and architecture can be supplied as well.


559
560
561
# File 'lib/msf/core/exploit.rb', line 559

def regenerate_payload(platform = nil, arch = nil, explicit_target = nil)
  generate_single_payload(nil, platform, arch, explicit_target)
end

#register_autofilter_ports(ports = []) ⇒ Object

Adds a port into the list of ports


377
378
379
380
381
382
# File 'lib/msf/core/exploit.rb', line 377

def register_autofilter_ports(ports=[])
  @autofilter_ports ||= []
  @autofilter_ports << ports
  @autofilter_ports.flatten!
  @autofilter_ports.uniq!
end

#register_autofilter_services(services = []) ⇒ Object


384
385
386
387
388
389
# File 'lib/msf/core/exploit.rb', line 384

def register_autofilter_services(services=[])
  @autofilter_services ||= []
  @autofilter_services << services
  @autofilter_services.flatten!
  @autofilter_services.uniq!
end

#report_failureObject


1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
# File 'lib/msf/core/exploit.rb', line 1227

def report_failure

  return unless framework.db and framework.db.active

  info = {
    :timestamp   => Time.now.utc,
    :workspace   => framework.db.find_workspace(self.workspace),
    :module      => self.fullname,
    :fail_reason => self.fail_reason,
    :fail_detail => self.fail_detail,
    :target_name => self.target.name,
    :username    => self.owner,
    :refs        => self.references
  }

  if self.datastore['RHOST'] and self.options['RHOST']
    info[:host] = self.datastore['RHOST']
  end

  if self.datastore['RPORT'] and self.options['RPORT']
    info[:port] = self.datastore['RPORT']
    if self.class.ancestors.include?(Msf::Exploit::Remote::Tcp)
      info[:proto] = 'tcp'
    end
  end

  framework.db.report_exploit_failure(info)
end

#reset_session_countsObject

Reset the session counter to zero (which occurs during set up of the exploit prior to calling exploit).


1212
1213
1214
# File 'lib/msf/core/exploit.rb', line 1212

def reset_session_counts
  self.session_count = 0
end

#session_created?Boolean

A boolean for whether a session has been created yet


1204
1205
1206
# File 'lib/msf/core/exploit.rb', line 1204

def session_created?
  (self.session_count > 0) ? true : false
end

#setupObject

Prepares the module for exploitation, initializes any state, and starts the payload handler.


395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
# File 'lib/msf/core/exploit.rb', line 395

def setup
  # Reset the session counts to zero.
  reset_session_counts

  return if not payload_instance
  return if not handler_enabled?

  # Configure the payload handler
  payload_instance.exploit_config = {
    'active_timeout' => self.active_timeout
  }

  # Set up the payload handlers
  payload_instance.setup_handler

  # Start the payload handler
  payload_instance.start_handler

end

#stack_adjustmentObject

This method returns the number of bytes that should be adjusted to the stack pointer prior to executing any code. The number of bytes to adjust is indicated to the routine through the payload 'StackAdjustment' attribute or through a target's payload 'StackAdjustment' attribute.


765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
# File 'lib/msf/core/exploit.rb', line 765

def stack_adjustment
  if (target and target.payload_stack_adjustment)
    adj = target.payload_stack_adjustment
  else
    adj = payload_info['StackAdjustment']
  end

  # Get the architecture for the current target or use the one specific to
  # this exploit
  arch = (target and target.arch) ? target.arch : self.arch

  # Default to x86 if we can't find a list of architectures
  if (arch and arch.empty? == false)
    arch = arch.join(", ")
  else
    arch = 'x86'
  end

  (adj != nil) ? Rex::Arch::adjust_stack_pointer(arch, adj) || '' : ''
end

#stanceObject

Generally, all exploits take an aggressive stance.


644
645
646
# File 'lib/msf/core/exploit.rb', line 644

def stance
  module_info['Stance'] || Stance::Aggressive
end

#supports_check?Boolean

Returns true if the exploit module supports the check method.


590
591
592
# File 'lib/msf/core/exploit.rb', line 590

def supports_check?
  derived_implementor?(Msf::Exploit, 'check')
end

#supports_exploit?Boolean

Returns true if the exploit module supports the exploit method.


597
598
599
# File 'lib/msf/core/exploit.rb', line 597

def supports_exploit?
  derived_implementor?(Msf::Exploit, 'exploit')
end

#targetObject

Returns the active target for this exploit. If not target has been defined, nil is returned. If no target was defined but there is a default target, that one will be automatically used.


667
668
669
670
671
# File 'lib/msf/core/exploit.rb', line 667

def target
  target_idx = target_index

  return (target_idx) ? targets[target_idx.to_i] : nil
end

#target_archObject

Returns the target's architecture, or the one assigned to the module itself.


697
698
699
# File 'lib/msf/core/exploit.rb', line 697

def target_arch
  (target and target.arch) ? target.arch : (arch == []) ? nil : arch
end

#target_indexObject

The target index that has been selected.


676
677
678
679
680
681
682
683
684
# File 'lib/msf/core/exploit.rb', line 676

def target_index
  target_idx = datastore['TARGET']

  # Use the default target if one was not supplied.
  if (target_idx == nil and default_target and default_target >= 0)
    target_idx = default_target
  end
  return (target_idx) ? target_idx.to_i : nil
end

#target_platformObject

Returns the target's platform, or the one assigned to the module itself.


689
690
691
# File 'lib/msf/core/exploit.rb', line 689

def target_platform
  (target and target.platform) ? target.platform : platform
end

#typeObject

Returns MODULE_EXPLOIT to indicate that this is an exploit module.


630
631
632
# File 'lib/msf/core/exploit.rb', line 630

def type
  MODULE_EXPLOIT
end

#wfs_delayObject

The default “wait for session” delay is zero for all exploits.


1159
1160
1161
# File 'lib/msf/core/exploit.rb', line 1159

def wfs_delay
  (datastore['WfsDelay'] || 0).to_i
end