Class: Msf::Payload

Inherits:
Module show all
Defined in:
lib/msf/core/payload.rb

Overview

This class represents the base class for a logical payload. The framework automatically generates payload combinations at runtime which are all extended from this Payload as a base class.

Defined Under Namespace

Modules: Adapter, Aix, Android, Bsd, Custom, Firefox, Generic, Hardware, JSP, Java, Linux, Mainframe, Multi, Netware, NodeJS, Osx, Php, Pingback, Python, R, Ruby, Single, Solaris, Stager, TransportConfig, Type, Windows Classes: Apk, MachO, UUID

Constant Summary

Constants inherited from Module

Module::REPLICANT_EXTENSION_DS_KEY

Constants included from Module::ModuleInfo

Module::ModuleInfo::UpdateableOptions

Instance Attribute Summary collapse

Attributes inherited from Module

#error, #job_id, #license, #platform, #privileged, #references, #user_data

Attributes included from Framework::Offspring

#framework

Attributes included from Module::UUID

#uuid

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

#user_input

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

#user_output

Attributes included from Module::Privileged

#priveli, #privileged

Attributes included from Module::Options

#options

Attributes included from Module::ModuleStore

#module_store

Attributes included from Module::ModuleInfo

#module_info

Attributes included from Module::FullName

#aliased_as

Attributes included from Module::DataStore

#datastore

Attributes included from Module::Author

#author

Attributes included from Module::Arch

#arch

Attributes included from Module::Alert

#alerts, #you_have_been_warned

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Module

#adapted_refname, #adapter_refname, #black_listed_auth_filenames, cached?, #debugging?, #default_cred?, #default_options, #fail_with, #file_path, #framework, #has_check?, #orig_cls, #owner, #perform_extensions, #platform?, #platform_to_s, #post_auth?, #register_extensions, #register_parent, #replicant, #required_cred_options, #set_defaults, #stage_refname, #stager_refname, #workspace

Methods included from Module::Reliability

#reliability, #reliability_to_s

Methods included from Module::Stability

#stability, #stability_to_s

Methods included from Module::SideEffects

#side_effects, #side_effects_to_s

Methods included from Module::UUID

#generate_uuid

Methods included from Module::UI

#init_ui

Methods included from Module::UI::Message

#print_error, #print_good, #print_prefix, #print_status, #print_warning

Methods included from Module::UI::Message::Verbose

#vprint_error, #vprint_good, #vprint_status, #vprint_warning

Methods included from Module::UI::Line

#print_line, #print_line_prefix

Methods included from Module::UI::Line::Verbose

#vprint_line

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_blank_line, #print_error, #print_good, #print_line, #print_status, #print_warning

Methods included from Module::Type

#auxiliary?, #encoder?, #evasion?, #exploit?, #nop?, #payload?, #post?

Methods included from Module::Ranking

#rank, #rank_to_h, #rank_to_s

Methods included from Module::Privileged

#privileged?

Methods included from Module::Options

#deregister_option_group, #deregister_options, #register_advanced_options, #register_evasion_options, #register_option_group, #register_options, #validate

Methods included from Module::Network

#comm, #support_ipv6?, #target_host, #target_port

Methods included from Module::ModuleStore

#[], #[]=

Methods included from Module::ModuleInfo

#alias, #description, #disclosure_date, #info_fixups, #merge_check_key, #merge_info, #merge_info_advanced_options, #merge_info_alias, #merge_info_description, #merge_info_evasion_options, #merge_info_name, #merge_info_options, #merge_info_string, #merge_info_version, #name, #notes, #update_info

Methods included from Module::FullName

#aliases, #fullname, #promptname, #realname, #refname, #shortname

Methods included from Module::DataStore

#import_defaults, #import_target_defaults, #share_datastore

Methods included from Module::Compatibility

#compat, #compatible?, #init_compat

Methods included from Module::Author

#author_to_s, #each_author

Methods included from Module::Auth

#store_valid_credential

Methods included from Module::Arch

#arch?, #arch_to_s, #each_arch

Methods included from Module::Alert

#add_alert, #add_error, #add_info, #add_warning, #alert_user, #errors, #get_alerts, included, #infos, #is_usable?, #warnings, #without_prompt

Constructor Details

#initialize(info = {}) ⇒ Payload

Creates an instance of a payload module using the supplied information.



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/msf/core/payload.rb', line 53

def initialize(info = {})
  super

  #
  # Gets the Dependencies if the payload requires external help
  # to work
  #
  self.module_info['Dependencies'] = self.module_info['Dependencies'] || []

  # If this is an adapted or staged payload but there is no stage information,
  # then this is actually a stager + single combination.  Set up the
  # information hash accordingly.
  if (self.class.include?(Msf::Payload::Adapter) || self.class.include?(Msf::Payload::Single)) and self.class.include?(Msf::Payload::Stager)

    if self.module_info['Payload']
      self.module_info['Stage']['Payload']  = self.module_info['Payload']['Payload'] || ""
      self.module_info['Stage']['Assembly'] = self.module_info['Payload']['Assembly'] || ""
      self.module_info['Stage']['Offsets']  = self.module_info['Payload']['Offsets'] || {}
    elsif !self.module_info['Stage']
      self.module_info['Stage'] = {}
      self.module_info['Stage']['Payload']  = ""
      self.module_info['Stage']['Assembly'] = ""
      self.module_info['Stage']['Offsets']  = {}
    end

    @staged = true
  else
    @staged = false
  end

  # Update the module info hash with the connection type
  # that is derived from the handler for this payload.  This is
  # used for compatibility filtering purposes.
  self.module_info['ConnectionType'] = connection_type
end

Instance Attribute Details

#appendObject

This attribute holds the string that should be appended to the buffer when it’s generated.



586
587
588
# File 'lib/msf/core/payload.rb', line 586

def append
  @append
end

#assoc_exploitObject

If this payload is associated with an exploit, the assoc_exploit attribute will point to that exploit instance.



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

def assoc_exploit
  @assoc_exploit
end

#available_spaceObject

The amount of space available to the payload, which may be nil, indicating that the smallest possible payload should be used.



603
604
605
# File 'lib/msf/core/payload.rb', line 603

def available_space
  @available_space
end

#prependObject

This attribute holds the string that should be prepended to the buffer when it’s generated.



581
582
583
# File 'lib/msf/core/payload.rb', line 581

def prepend
  @prepend
end

#prepend_encoderObject

This attribute holds the string that should be prepended to the encoded version of the payload (in front of the encoder as well).



591
592
593
# File 'lib/msf/core/payload.rb', line 591

def prepend_encoder
  @prepend_encoder
end

Class Method Details

.cached_sizeObject

This method returns an optional cached size value



161
162
163
164
# File 'lib/msf/core/payload.rb', line 161

def self.cached_size
  csize = (const_defined?('CachedSize')) ? const_get('CachedSize') : nil
  csize == :dynamic ? nil : csize
end

.choose_payload(mod) ⇒ Object

Select a reasonable default payload and minimally configure it

Parameters:



469
470
471
472
473
474
475
476
477
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
# File 'lib/msf/core/payload.rb', line 469

def self.choose_payload(mod)
  compatible_payloads = mod.compatible_payloads(
    excluded_platforms: ['Multi'] # We don't want to select a multi payload
  ).map(&:first)

  # XXX: Determine LHOST based on global LHOST, RHOST or an arbitrary internet address
  lhost = mod.datastore['LHOST'] || Rex::Socket.source_address(mod.datastore['RHOST'] || '50.50.50.50')

  configure_payload = lambda do |payload|
    if mod.datastore.is_a?(Msf::DataStoreWithFallbacks)
      payload_defaults = { 'PAYLOAD' => payload }

      # Set LHOST if this is a reverse payload
      if payload.index('reverse')
        payload_defaults['LHOST'] = lhost
      end
      mod.datastore.import_defaults_from_hash(payload_defaults, imported_by: 'choose_payload')
    else
      mod.datastore['PAYLOAD'] = payload
      # Set LHOST if this is a reverse payload
      if payload.index('reverse')
        mod.datastore['LHOST'] = lhost
      end
    end

    payload
  end

  # If there is only one compatible payload, return it immediately
  if compatible_payloads.length == 1
    return configure_payload.call(compatible_payloads.first)
  end

  # XXX: This approach is subpar, and payloads should really be ranked!
  preferred_payloads = [
    # These payloads are generally reliable and common enough in practice
    '/meterpreter/reverse_tcp',
    '/shell/reverse_tcp',
    'cmd/unix/reverse_bash',
    'cmd/unix/reverse_netcat',
    'cmd/windows/powershell_reverse_tcp',
    # Fall back on a generic payload to autoselect a specific payload
    'generic/shell_reverse_tcp',
    'generic/shell_bind_tcp'
  ]

  # XXX: This is not efficient in the slightest
  preferred_payloads.each do |type|
    payload = compatible_payloads.find { |name| name.end_with?(type) }

    next unless payload

    return configure_payload.call(payload)
  end

  nil
end

.dynamic_size?Boolean

This method returns whether the payload generates variable-sized output

Returns:

  • (Boolean)


169
170
171
172
# File 'lib/msf/core/payload.rb', line 169

def self.dynamic_size?
  csize = (const_defined?('CachedSize')) ? const_get('CachedSize') : nil
  csize == :dynamic
end

.typeObject

Returns MODULE_PAYLOAD to indicate that this is a payload module.



98
99
100
# File 'lib/msf/core/payload.rb', line 98

def self.type
  return Msf::MODULE_PAYLOAD
end

Instance Method Details

#apply_prepends(raw) ⇒ Object

A placeholder stub, to be overridden by mixins



530
531
532
# File 'lib/msf/core/payload.rb', line 530

def apply_prepends(raw)
  raw
end

#assemblyObject

Returns the assembly string that describes the payload if one exists.



214
215
216
# File 'lib/msf/core/payload.rb', line 214

def assembly
  return module_info['Payload'] ? module_info['Payload']['Assembly'] : nil
end

#assembly=(asm) ⇒ Object

Sets the assembly string that describes the payload If this method is used to define the payload, a payload with no offsets will be created



222
223
224
225
# File 'lib/msf/core/payload.rb', line 222

def assembly=(asm)
  module_info['Payload'] ||= {'Offsets' => {} }
  module_info['Payload']['Assembly'] = asm
end

#badcharsObject

Returns the string of bad characters for this payload, if any.



112
113
114
# File 'lib/msf/core/payload.rb', line 112

def badchars
  return self.module_info['BadChars']
end

#build(asm, off = {}, opts = {}) ⇒ String (protected)

If the payload has assembly that needs to be compiled, do so now.

Blobs will be cached in the framework’s PayloadSet

Parameters:

  • asm (String)

    Assembly code to be assembled into a raw payload

  • opts (Hash) (defaults to: {})

Returns:

  • (String)

    The final, assembled payload

Raises:

  • ArgumentError if asm is blank

See Also:



617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
# File 'lib/msf/core/payload.rb', line 617

def build(asm, off={}, opts = {})
  if(asm.nil? or asm.empty?)
    raise ArgumentError, "Assembly must not be empty"
  end

  # Use the refname so blobs can be flushed when the module gets
  # reloaded and use the hash value to ensure that we're actually
  # getting the right blob for the given assembly.
  cache_key   = refname + asm.hash.to_s
  cache_entry = framework.payloads.check_blob_cache(cache_key)

  off.each_pair { |option, val|
    if (val[1] == 'RAW')
      asm = asm.gsub(/#{option}/){ datastore[option] }
      off.delete(option)
    end
  }

  # If there is a valid cache entry, then we don't need to worry about
  # rebuilding the assembly
  if cache_entry
    # Update the local offsets from the cache
    off.each_key { |option|
      off[option] = cache_entry[1][option]
    }

    # Return the cached payload blob
    return cache_entry[0].dup
  end

  # Assemble the payload from the assembly
  a = opts[:arch] || self.arch
  if a.kind_of? Array
    a = self.arch.first
  end
  cpu = case a
    when ARCH_X86    then Metasm::Ia32.new
    when ARCH_X64    then Metasm::X86_64.new
    when ARCH_PPC    then Metasm::PowerPC.new
    when ARCH_ARMLE  then Metasm::ARM.new
    when ARCH_MIPSLE then Metasm::MIPS.new(:little)
    when ARCH_MIPSBE then Metasm::MIPS.new(:big)
    else
      elog("Broken payload #{refname} has arch unsupported with assembly: #{module_info["Arch"].inspect}")
      elog("Call stack:\n#{caller.join("\n")}")
      return ""
    end
  sc = Metasm::Shellcode.assemble(cpu, asm).encoded

  # Calculate the actual offsets now that it's been built
  off.each_pair { |option, val|
    off[option] = [ sc.offset_of_reloc(option) || val[0], val[1] ]
  }

  # Cache the payload blob
  framework.payloads.add_blob_cache(cache_key, sc.data, off)

  # Return a duplicated copy of the assembled payload
  sc.data.dup
end

#cached_sizeObject

This method returns an optional cached size value



177
178
179
# File 'lib/msf/core/payload.rb', line 177

def cached_size
    self.class.cached_size
end

#compatible_encodersObject

Returns the array of compatible encoders for this payload instance.



442
443
444
445
446
447
448
449
450
451
# File 'lib/msf/core/payload.rb', line 442

def compatible_encoders
  encoders = []

  framework.encoders.each_module_ranked(
    'Arch' => self.arch, 'Platform' => self.platform) { |name, mod|
    encoders << [ name, mod ]
  }

  return encoders
end

#compatible_nopsObject

Returns the array of compatible nops for this payload instance.



456
457
458
459
460
461
462
463
464
465
# File 'lib/msf/core/payload.rb', line 456

def compatible_nops
  nops = []

  framework.nops.each_module_ranked(
    'Arch' => self.arch) { |name, mod|
    nops << [ name, mod ]
  }

  return nops
end

#connection_typeObject

Returns the module’s connection type, such as reverse, bind, noconn, or whatever else the case may be.



255
256
257
# File 'lib/msf/core/payload.rb', line 255

def connection_type
  handler_klass.general_handler_type
end

#conventionObject

Returns the staging convention that the payload uses, if any. This is used to make sure that only compatible stagers and stages are built (where assumptions are made about register/environment initialization state and hand-off).



247
248
249
# File 'lib/msf/core/payload.rb', line 247

def convention
  module_info['Convention']
end

#dependenciesObject

Returns the compiler dependencies if the payload has one



237
238
239
# File 'lib/msf/core/payload.rb', line 237

def dependencies
  module_info['Dependencies']
end

#dynamic_size?Boolean

This method returns whether the payload generates variable-sized output

Returns:

  • (Boolean)


184
185
186
# File 'lib/msf/core/payload.rb', line 184

def dynamic_size?
    self.class.dynamic_size?
end

#generate(opts = {}) ⇒ Object

Generates the payload and returns the raw buffer to the caller.

Parameters:

  • opts (Hash) (defaults to: {})


292
293
294
# File 'lib/msf/core/payload.rb', line 292

def generate(opts = {})
  internal_generate(opts)
end

#generate_completeObject

Generates the payload and returns the raw buffer to the caller, handling any post-processing tasks, such as prepended code stubs.



299
300
301
# File 'lib/msf/core/payload.rb', line 299

def generate_complete
  apply_prepends(generate)
end

#handler_klassObject

Return the connection associated with this payload, or none if there isn’t one.



271
272
273
# File 'lib/msf/core/payload.rb', line 271

def handler_klass
  return module_info['Handler'] || Msf::Handler::None
end

#internal_generate(opts = {}) ⇒ Object (protected)

Generate the payload using our local payload blob and offsets



681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
# File 'lib/msf/core/payload.rb', line 681

def internal_generate(opts = {})
  # Build the payload, either by using the raw payload blob defined in the
  # module or by actually assembling it
  if assembly and !assembly.empty?
    raw = build(assembly, offsets, opts)
  else
    raw = payload.dup
  end

  # If the payload is generated and there are offsets to substitute,
  # do that now.
  if (raw and offsets)
    substitute_vars(raw, offsets)
  end

  return raw
end

#merge_name(info, val) ⇒ Object (protected)

Merge the name to prefix the existing one and separate them with a comma



709
710
711
712
713
714
715
# File 'lib/msf/core/payload.rb', line 709

def merge_name(info, val)
  if (info['Name'])
    info['Name'] = val + ',' + info['Name']
  else
    info['Name'] = val
  end
end

#offsetsObject

Returns the offsets to variables that must be substitute, if any.



230
231
232
# File 'lib/msf/core/payload.rb', line 230

def offsets
  return module_info['Payload'] ? module_info['Payload']['Offsets'] : nil
end

#on_session(session) ⇒ Object

Once an exploit completes and a session has been created on behalf of the payload, the framework will call the payload’s on_session notification routine to allow it to manipulate the session prior to handing off control to the user.



546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
# File 'lib/msf/core/payload.rb', line 546

def on_session(session)

  # If this payload is associated with an exploit, inform the exploit
  # that a session has been created and potentially shut down any
  # open sockets. This allows active exploits to continue hammering
  # on a service until a session is created.
  if (assoc_exploit)

    # Signal that a new session is created by calling the exploit's
    # on_new_session handler. The default behavior is to set an
    # instance variable, which the exploit will have to check.
    begin
      assoc_exploit.on_new_session(session)
    rescue ::Exception => e
      dlog("#{assoc_exploit.refname}: on_new_session handler triggered exception: #{e.class} #{e} #{e.backtrace}", 'core', LEV_1)	rescue nil
    end

    # Set the abort sockets flag only if the exploit is not passive
    # and the connection type is not 'find'
    if (
      (assoc_exploit.exploit_type == Exploit::Type::Remote) and
      (assoc_exploit.passive? == false) and
      (connection_type != 'find')
       )
       assoc_exploit.abort_sockets
    end

  end

end

#payloadObject

Returns the raw payload that has not had variable substitution occur.



207
208
209
# File 'lib/msf/core/payload.rb', line 207

def payload
  return module_info['Payload'] ? module_info['Payload']['Payload'] : nil
end

#payload_typeObject

Returns the type of payload, either single or staged. Stage is the default because singles and stagers are encouraged to include the Single and Stager mixin which override the payload_type.



129
130
131
# File 'lib/msf/core/payload.rb', line 129

def payload_type
  return Type::Stage
end

#payload_type_sObject

Returns the string version of the payload type



136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/msf/core/payload.rb', line 136

def payload_type_s
  case payload_type
    when Type::Adapter
      return "adapter"
    when Type::Stage
      return "stage"
    when Type::Stager
      return "stager"
    when Type::Single
      return "single"
    else
      return "unknown"
  end
end

#raw_to_db(raw) ⇒ Object

Convert raw bytes to metasm-ready ‘db’ encoding format eg. “x90xCC” => “db 0x90,0xCC”

Parameters:

  • raw (Array)

    Byte array to encode.



309
310
311
# File 'lib/msf/core/payload.rb', line 309

def raw_to_db(raw)
  raw.unpack("C*").map {|c| "0x%.2x" % c}.join(",")
end

#replace_var(raw, name, offset, pack) ⇒ Object

Replaces an individual variable in the supplied buffer at an offset using the given pack type. This is here to allow derived payloads the opportunity to replace advanced variables.



428
429
430
# File 'lib/msf/core/payload.rb', line 428

def replace_var(raw, name, offset, pack)
  return false
end

#save_registersObject

The list of registers that should be saved by any NOP generators or encoders, if possible.



120
121
122
# File 'lib/msf/core/payload.rb', line 120

def save_registers
  return self.module_info['SaveRegisters']
end

#sessionObject

Returns the session class that is associated with this payload and will be used to create a session as necessary.



279
280
281
# File 'lib/msf/core/payload.rb', line 279

def session
  return module_info['Session']
end

#sizeObject

Returns the payload’s size. If the payload is staged, the size of the first stage is returned.



192
193
194
195
196
197
198
199
200
201
202
# File 'lib/msf/core/payload.rb', line 192

def size
  pl = nil
  begin
    pl = generate()
  rescue Metasploit::Framework::Compiler::Mingw::UncompilablePayloadError
  rescue NoCompatiblePayloadError
  rescue PayloadItemSizeError
  end
  pl ||= ''
  pl.length
end

#staged?Boolean

This method returns whether or not this payload uses staging.

Returns:

  • (Boolean)


154
155
156
# File 'lib/msf/core/payload.rb', line 154

def staged?
  (@staged or payload_type == Type::Stager or payload_type == Type::Stage)
end

#substitute_vars(raw, offsets) ⇒ Object

Substitutes variables with values from the module’s datastore in the supplied raw buffer for a given set of named offsets. For instance, RHOST is substituted with the RHOST value from the datastore which will have been populated by the framework.

Supported packing types:

  • ADDR (foo.com, 1.2.3.4)

  • ADDR6 (foo.com, fe80::1234:5678:8910:1234)

  • ADDR16MSB, ADD16LSB, ADDR22MSB, ADD22LSB (foo.com, 1.2.3.4) Advanced packing types for 16/16 and 22/10 bits substitution. The 16 bits types uses two offsets indicating where the 16 bits pair will be substituted, while the 22 bits types uses two offsets indicating the instructions where the 22/10 bits pair will be substituted. Normally these are offsets to “sethi” and “or” instructions on SPARC architecture.

  • HEX (0x12345678, “x41x42x43x44”)

  • RAW (raw bytes)



332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
# File 'lib/msf/core/payload.rb', line 332

def substitute_vars(raw, offsets)
  offsets.each_pair { |name, info|
    offset, pack = info

    # Give the derived class a chance to substitute this variable
    next if (replace_var(raw, name, offset, pack) == true)

    # Now it's our turn...
    if ((val = datastore[name]))
      if (pack == 'ADDR')
        val = Rex::Socket.resolv_nbo(val)

        # Someone gave us a funky address (ipv6?)
        if(val.length == 16)
          raise RuntimeError, "IPv6 address specified for IPv4 payload."
        end
      elsif (pack == 'ADDR6')
        val = Rex::Socket.resolv_nbo(val)

        # Convert v4 to the v6ish address
        if(val.length == 4)
          nip = "fe80::5efe:" + val.unpack("C*").join(".")
          val = Rex::Socket.resolv_nbo(nip)
        end
      elsif (['ADDR16MSB', 'ADDR16LSB', 'ADDR22MSB', 'ADDR22LSB'].include?(pack))
        val = Rex::Socket.resolv_nbo(val)

        # Someone gave us a funky address (ipv6?)
        if(val.length == 16)
          raise RuntimeError, "IPv6 address specified for IPv4 payload."
        end
      elsif (pack == 'RAW')
        # Just use the raw value...
      else
        # Check to see if the value is a hex string.  If so, convert
        # it.
        if val.kind_of?(String)
          if val =~ /^\\x/n
            val = [ val.gsub(/\\x/n, '') ].pack("H*").unpack(pack)[0]
          elsif val =~ /^0x/n
            val = val.hex
          end
        end

        # NOTE:
        # Packing assumes integer format at this point, should fix...
        val = [ val.to_i ].pack(pack)
      end

      # Substitute it
      if (['ADDR16MSB', 'ADDR16LSB'].include?(pack))
        if (offset.length != 2)
          raise RuntimeError, "Missing value for payload offset, there must be two offsets."
        end

        if (pack == 'ADDR16LSB')
          val = val.unpack('N').pack('V')
        end

        raw[offset[0], 2] = val[0, 2]
        raw[offset[1], 2] = val[2, 2]

      elsif (['ADDR22MSB', 'ADDR22LSB'].include?(pack))
        if (offset.length != 2)
          raise RuntimeError, "Missing value for payload offset, there must be two offsets."
        end

        if (pack == 'ADDR22LSB')
          val = val.unpack('N').pack('V')
        end

        hi = (0xfffffc00 & val) >> 10
        lo = 0x3ff & val

        ins = raw[offset[0], 4]
        raw[offset[0], 4] = ins | hi

        ins = raw[offset[1], 4]
        raw[offset[1], 4] = ins | lo

      else
        raw[offset, val.length] = val

      end
    else
      wlog("Missing value for payload offset #{name}, skipping.",
        'core', LEV_3)
    end
  }
end

#symbol_lookupObject

Returns the method used by the payload to resolve symbols for the purpose of calling functions, such as ws2ord.



263
264
265
# File 'lib/msf/core/payload.rb', line 263

def symbol_lookup
  module_info['SymbolLookup']
end

#typeObject

Returns MODULE_PAYLOAD to indicate that this is a payload module.



105
106
107
# File 'lib/msf/core/payload.rb', line 105

def type
  return Msf::MODULE_PAYLOAD
end