Class: Msf::PayloadSet

Inherits:
ModuleSet show all
Defined in:
lib/msf/core/payload_set.rb

Overview

This class is a special case of the generic module set class because payloads are generated in terms of combinations between various components, such as a stager and a stage. As such, the payload set needs to be built on the fly and cannot be simply matched one-to-one with a payload module. Yeah, the term module is kind of overloaded here, but eat it!

Instance Attribute Summary collapse

Attributes inherited from ModuleSet

#ambiguous_module_reference_name_set, #architectures_by_module, #mod_extensions, #mod_sorted, #module_type, #platforms_by_module

Attributes included from Framework::Offspring

#framework

Instance Method Summary collapse

Methods inherited from ModuleSet

#[], #create, #demand_load_modules, #each, #each_module, #each_module_list, #each_module_ranked, #force_load_set, #module_rank, #rank_modules, #valid?

Constructor Details

#initializePayloadSet

Creates an instance of a payload set which is just a specialized module set class that has custom handling for payloads.



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/msf/core/payload_set.rb', line 20

def initialize
  super(Msf::MODULE_PAYLOAD)

  # A hash of each of the payload types that holds an array
  # for all of the associated modules
  self.payload_type_modules = {}

  # Initialize the hash entry for each type to an empty list
  [
    Payload::Type::Single,
    Payload::Type::Stager,
    Payload::Type::Stage,
    Payload::Type::Adapter
  ].each { |type|
    self.payload_type_modules[type] = {}
  }

  # Initialize hashes for each of the stages and singles.  Stagers
  # never exist independent.  The stages hash will have entries that
  # point to another hash that point to the per-stager implementation
  # payload class.  For instance:
  #
  # ['windows/shell']['reverse_tcp']
  #
  # Singles will simply point to the single payload class.
  self.stages  = {}
  self.singles = {}

  # Single instance cache of modules for use with doing quick referencing
  # of attributes that would require an instance.
  self._instances = {}

  # Initializes an empty blob cache
  @blob_cache = {}
end

Instance Attribute Details

#_instancesObject (protected)

:nodoc:



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

def _instances
  @_instances
end

#payload_type_modulesObject (protected)

:nodoc:



642
643
644
# File 'lib/msf/core/payload_set.rb', line 642

def payload_type_modules
  @payload_type_modules
end

#singlesObject

The list of singles that have been loaded.



587
588
589
# File 'lib/msf/core/payload_set.rb', line 587

def singles
  @singles
end

#stagesObject

The list of stages that have been loaded.



583
584
585
# File 'lib/msf/core/payload_set.rb', line 583

def stages
  @stages
end

Instance Method Details

#_adaptersObject (protected)



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

def _adapters
  return payload_type_modules[Payload::Type::Adapter] || {}
end

#_singlesObject (protected)

Return the hash of single payloads



598
599
600
# File 'lib/msf/core/payload_set.rb', line 598

def _singles
  return payload_type_modules[Payload::Type::Single] || {}
end

#_stagersObject (protected)

Return the hash of stager payloads



605
606
607
# File 'lib/msf/core/payload_set.rb', line 605

def _stagers
  return payload_type_modules[Payload::Type::Stager] || {}
end

#_stagesObject (protected)

Return the hash of stage payloads



612
613
614
# File 'lib/msf/core/payload_set.rb', line 612

def _stages
  return payload_type_modules[Payload::Type::Stage] || {}
end

#add_blob_cache(key, blob, offsets) ⇒ Object

Adds a blob to the blob cache so that the payload does not have to be recompiled in the future



561
562
563
# File 'lib/msf/core/payload_set.rb', line 561

def add_blob_cache(key, blob, offsets)
  @blob_cache[key] = [ blob, offsets ]
end

#add_cached_module(cached_module_metadata) ⇒ Object



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
# File 'lib/msf/core/payload_set.rb', line 352

def add_cached_module()
  case .payload_type
  when Payload::Type::Single
    single_name = .ref_name
    single_info = load_payload_component(Payload::Type::Single, single_name)
    calculate_single_payload(single_name: single_name, single_info: single_info)
  when Payload::Type::Stager
    stager_refname = .stager_refname
    stager_info = load_payload_component(Payload::Type::Stager, stager_refname)
    stage_name = .stage_refname
    stage_info = load_payload_component(Payload::Type::Stage, stage_name)

    calculate_staged_payload(stage_name: stage_name,
                             stager_name: stager_refname,
                             stage_info: stage_info,
                             stager_info: stager_info)

  when Payload::Type::Adapter
    adapter_name = .adapter_refname
    adapter_info = load_payload_component(Payload::Type::Adapter, adapter_name)

    if .staged
      stage_name = .stage_refname

      stage_info = load_payload_component(Payload::Type::Stage, stage_name)
      stager_name= .stager_refname
      stager_info = load_payload_component(Payload::Type::Stager, stager_name)

      staged_payload = self[.adapted_refname]

      calculate_adapted_staged_payload(staged_payload: staged_payload,
                                       adapter_name: adapter_name,
                                       stage_info: stage_info,
                                       stager_info: stager_info,
                                       adapter_info: adapter_info)
    else
      single_name = .adapted_refname
      single_info = load_payload_component(Payload::Type::Single, single_name)
      single_payload = self[single_name]
      calculate_adapted_single_payload(adapter_name: adapter_name,
                                       adapter_info: adapter_info,
                                       single_info: single_info,
                                       single_payload: single_payload)
    end
  end
rescue ::Msf::MissingPayloadError => e
  elog("Missing payload component for #{.ref_name}", error: e)
  return nil
rescue StandardError => e
  elog("#{.ref_name} failed to load", error: e)
  return nil
end

#add_module(payload_module, reference_name, modinfo = {}) ⇒ void

This method returns an undefined value.

This method is called when a new payload module class is loaded up. For the payload set we simply create an instance of the class and do some magic to figure out if it’s a single, stager, or stage. Depending on which it is, we add it to the appropriate list.

Parameters:

  • payload_module (::Module)

    The module name.

  • reference_name (String)

    The module reference name.

  • modinfo (Hash{String => Array}) (defaults to: {})

    additional information about the module.

Options Hash (modinfo):

  • 'files' (Array<String>)

    List of paths to the ruby source files where class_or_module is defined.

  • 'paths' (Array<String>)

    List of module reference names.

  • 'type' (String)

    The module type, should match positional type argument.



316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
# File 'lib/msf/core/payload_set.rb', line 316

def add_module(payload_module, reference_name, modinfo={})
  if modinfo['cached_metadata']
    return add_cached_module(modinfo['cached_metadata'])
  end

  if (match_data = reference_name.match(/^(adapters|singles|stagers|stages)#{File::SEPARATOR}(.*)$/))
    ptype = match_data[1]
    reference_name  = match_data[2]
  end

  # Duplicate the Payload base class and extend it with the module
  # class that is passed in.  This allows us to inspect the actual
  # module to see what type it is, and to grab other information for
  # our own evil purposes.
  instance = build_payload(payload_module).new

  # Create an array of information about this payload module
  pinfo =
    [
      payload_module,
      instance.handler_klass,
      instance.platform,
      instance.arch,
      instance,
      modinfo
    ]

  # Use the module's preferred alias if it has one
  reference_name = instance.alias if (instance.alias)

  # Store the module and alias name for this payload.  We
  # also convey other information about the module, such as
  # the platforms and architectures it supports
  payload_type_modules[instance.payload_type][reference_name] = pinfo
end

#add_single(p, name, modinfo, adapted_refname: nil, adapter_refname: nil) ⇒ Object

This method adds a single payload to the set and adds it to the singles hash.



486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
# File 'lib/msf/core/payload_set.rb', line 486

def add_single(p, name, modinfo, adapted_refname: nil, adapter_refname: nil)
  p.framework = framework
  p.refname = name
  p.file_path = modinfo['files'][0]
  p.adapted_refname = adapted_refname
  p.adapter_refname = adapter_refname

  # Associate this class with the single payload's name
  self[name] = p

  # Add the singles hash
  singles[name] = p

  dlog("Built single payload #{name}.", 'core', LEV_2)
end

#add_stage(p, full_name, stage_name, handler_type, modinfo) ⇒ Object

This method adds a stage payload to the set and adds it to the stages hash using the supplied handler type.



506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
# File 'lib/msf/core/payload_set.rb', line 506

def add_stage(p, full_name, stage_name, handler_type, modinfo)
  p.framework = framework
  p.refname = full_name
  p.file_path = modinfo['files'][0]

  # Associate this stage's full name with the payload class in the set
  self[full_name] = p

  # Create the hash entry for this stage and then create
  # the associated entry for the handler type
  stages[stage_name] = {} if (!stages[stage_name])

  # Add it to this stage's stager hash
  stages[stage_name][handler_type] = p

  dlog("Built staged payload #{full_name}.", 'core', LEV_2)
end

#build_adapted_name(aname, pname) ⇒ Object (protected)



633
634
635
636
637
638
639
640
# File 'lib/msf/core/payload_set.rb', line 633

def build_adapted_name(aname, pname)
  aparts = aname.split('/')
  pparts = pname.split('/')
  pparts.shift if aparts.last.start_with?(pparts.first)
  aparts.each { |apart| pparts.delete(apart) if pparts.include?(apart) }

  (aparts + pparts).join('/')
end

#build_payload(*modules) ⇒ Object (protected)

Builds a duplicate, extended version of the Payload base class using the supplied modules.



620
621
622
623
624
625
626
627
628
629
630
631
# File 'lib/msf/core/payload_set.rb', line 620

def build_payload(*modules)
  klass = Class.new(Payload)

  # Remove nil modules
  modules.compact!

  # Include the modules supplied to us with the mad skillz
  # spoonfu style
  klass.include(*modules.reverse)

  return klass
end

#calculate_adapted_single_payload(adapter_name:, adapter_info:, single_info:, single_payload:) ⇒ Object



152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/msf/core/payload_set.rb', line 152

def calculate_adapted_single_payload(adapter_name:, adapter_info:, single_info:, single_payload:)
  adapter_mod, _, _adapter_platform, _adapter_arch, adapter_inst, adapted_modinfo = adapter_info
  single_mod, handler, _single_platform, _single_arch, _single_inst, _single_modinfo = single_info

  return nil unless single_payload && adapter_inst.compatible?(single_payload.new)

  payload = build_payload(handler, single_mod, adapter_mod)

  adapted_name = build_adapted_name(adapter_name, single_payload.refname)
  add_single(payload, adapted_name, adapted_modinfo, adapted_refname: single_payload.refname, adapter_refname: adapter_name)

  payload
end

#calculate_adapted_staged_payload(staged_payload:, adapter_name:, stage_info:, stager_info:, adapter_info:) ⇒ Object



279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
# File 'lib/msf/core/payload_set.rb', line 279

def calculate_adapted_staged_payload(staged_payload:, adapter_name:, stage_info:, stager_info:, adapter_info:)
  stage_mod, _, _stage_platform, _stage_arch, _stage_inst = stage_info
  stager_mod, handler, _stager_platform, _stager_arch, _stager_inst, _stager_modinfo = stager_info
  adapter_mod, _, _adapter_platform, _adapter_arch, adapter_inst, adapter_modinfo = adapter_info

  return nil unless staged_payload && adapter_inst.compatible?(staged_payload.new)

  payload = build_payload(handler, stager_mod, stage_mod, adapter_mod)

  adapted_refname = build_adapted_name(adapter_name, staged_payload.refname)
  payload.refname = adapted_refname
  payload.framework = framework
  payload.file_path = adapter_modinfo['files'][0]
  payload.adapted_refname = staged_payload.refname
  payload.adapter_refname = adapter_name
  payload.stage_refname = staged_payload.stage_refname
  payload.stager_refname = staged_payload.stager_refname

  self[payload.refname] = payload
  payload
end

#calculate_single_payload(single_name:, single_info:) ⇒ Object



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/msf/core/payload_set.rb', line 130

def calculate_single_payload(single_name:, single_info:)
  mod, handler, _single_platform, _single_arch, single_inst, single_modinfo = single_info

  # if the payload has a dependency, check
  # if it is supported on the system
  payload_dependencies = single_inst.dependencies
  unless payload_dependencies.empty?
    supported = payload_dependencies.all?(&:available?)
    elog("Dependency for #{single_name} is not supported") unless supported
    return nil unless supported
  end

  # Build the payload dupe using the determined handler
  # and module
  payload = build_payload(handler, mod)

  # Add it to the set
  add_single(payload, single_name, single_modinfo)

  payload
end

#calculate_staged_payload(stage_name:, stager_name:, stage_info:, stager_info:) ⇒ Object



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
265
266
267
268
269
270
271
272
273
274
275
276
277
# File 'lib/msf/core/payload_set.rb', line 236

def calculate_staged_payload(stage_name:, stager_name:, stage_info:, stager_info:)
  # if the stager or stage has a dependency, check
  # if they are compatible
  return nil unless stage_and_stager_compatible?(stager_info: stager_info,
                                                 stage_info: stage_info,
                                                 stager_name: stager_name,
                                                 stage_name: stage_name)

  stager_mod, handler, _stager_platform, _stager_arch, _stager_inst, stager_modinfo = stager_info
  stage_mod, _, _stage_platform, _stage_arch, _stage_inst, stage_modinfo = stage_info
  # Build the payload dupe using the handler, stager,
  # and stage
  payload = build_payload(handler, stager_mod, stage_mod)

  # If the stager has an alias for the handler type (such as is the
  # case for ordinal based stagers), use it in preference of the
  # handler's actual type.
  if (stager_mod.respond_to?('handler_type_alias') == true)
    handler_type = stager_mod.handler_type_alias
  else
    handler_type = handler.handler_type
  end

  # Associate the name as a combination of the stager and stage
  staged_refname = stage_name

  # If a valid handler exists for this stager, then combine it
  staged_refname += '/' + handler_type

  # Sets the modules derived name
  payload.refname = staged_refname
  payload.stage_refname = stage_name
  payload.stager_refname = stager_name

  # Add the stage
  add_stage(payload, staged_refname, stage_name, handler_type, {
    'files' => stager_modinfo['files'] + stage_modinfo['files'],
    'paths' => stager_modinfo['paths'] + stage_modinfo['paths'],
    'type' => stager_modinfo['type'] })

  payload
end

#check_blob_cache(key) ⇒ Object

Checks to see if a payload has a blob cache entry. If it does, the blob is returned to the caller.



569
570
571
# File 'lib/msf/core/payload_set.rb', line 569

def check_blob_cache(key)
  @blob_cache[key]
end

#each_module_filter(opts, name, mod) ⇒ Object

Performs custom filtering during each_module enumeration. This allows us to filter out certain stagers as necessary.



60
61
62
# File 'lib/msf/core/payload_set.rb', line 60

def each_module_filter(opts, name, mod)
  return false
end

#find_payload(platform, arch, handler, session, payload_type) ⇒ Object

Looks for a payload that matches the specified requirements and returns an instance of that payload.



431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
# File 'lib/msf/core/payload_set.rb', line 431

def find_payload(platform, arch, handler, session, payload_type)
  # Pre-filter based on platform and architecture.
  each_module(
    'Platform' => platform,
    'Arch'     => arch) { |name, mod|

    p = mod.new

    # We can't substitute one generic with another one.
    next if (p.kind_of?(Msf::Payload::Generic))

    # Check to see if the handler classes match.
    next if (handler and not p.handler_klass.ancestors.include?(handler))

    # Check to see if the session classes match.
    next if (session and p.session and not p.session.ancestors.include?(session))

    # Check for matching payload types
    next if (payload_type and p.payload_type != payload_type)

    return p
  }

  return nil
end

#find_payload_from_set(set, platform, arch, handler, session, payload_type) ⇒ Object

Looks for a payload from a given set that matches the specified requirements and returns an instance of that payload.



461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
# File 'lib/msf/core/payload_set.rb', line 461

def find_payload_from_set(set, platform, arch, handler, session, payload_type)
  set.each do |name, mod|
    p = mod.new

    # We can't substitute one generic with another one.
    next if (p.kind_of?(Msf::Payload::Generic))

    # Check to see if the handler classes match.
    next if (handler and p.handler_klass != handler)

    # Check to see if the session classes match.
    next if (session and p.session != session)

    # Check for matching payload types
    next if (payload_type and p.payload_type != payload_type)

    return p
  end
  return nil
end

#flush_blob_cacheObject

Flushes all entries from the blob cache



576
577
578
# File 'lib/msf/core/payload_set.rb', line 576

def flush_blob_cache
  @blob_cache.clear
end

#instance(name) ⇒ Object

Returns a single read-only instance of the supplied payload name such that specific attributes, like compatibility, can be evaluated. The payload instance returned should NOT be used for anything other than reading.



530
531
532
533
534
535
536
# File 'lib/msf/core/payload_set.rb', line 530

def instance(name)
  if (self._instances[name] == nil)
    self._instances[name] = create(name)
  end

  self._instances[name]
end

#load_payload_component(payload_type, refname) ⇒ Object



405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
# File 'lib/msf/core/payload_set.rb', line 405

def load_payload_component(payload_type, refname)
  payload_type_cache, folder_name = case payload_type
                                    when Payload::Type::Single
                                      [_singles, 'singles']
                                    when Payload::Type::Stage
                                      [_stages, 'stages']
                                    when Payload::Type::Stager
                                      [_stagers, 'stagers']
                                    when Payload::Type::Adapter
                                      [_adapters, 'adapters']
                                    else
                                      raise ArgumentError("Invalid payload type: #{payload_type}")
                                    end

  payload_component_info = payload_type_cache[refname]
  unless payload_component_info
    raise Msf::MissingPayloadError, "#{refname} is not available"
  end

  payload_component_info
end

#on_module_reload(mod) ⇒ Object

When a payload module is reloaded, the blob cache entry associated with it must be removed (if one exists)



549
550
551
552
553
554
555
# File 'lib/msf/core/payload_set.rb', line 549

def on_module_reload(mod)
  @blob_cache.each_key do |key|
    if key.start_with? mod.refname
      @blob_cache.delete(key)
    end
  end
end

#recalculateObject

This method builds the hash of alias names based on all the permutations of singles, stagers, and stages.



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/msf/core/payload_set.rb', line 68

def recalculate
  old_keys = self.keys
  new_keys = []

  # Recalculate single payloads
  _singles.each_pair do |single_name, single_info|
    single_payload = calculate_single_payload(single_name: single_name, single_info: single_info)
    next unless single_payload

    new_keys.push single_name

    _adapters.each_pair do |adapter_name, adapter_info|
      adapted_single = calculate_adapted_single_payload(adapter_name: adapter_name,
                                                        adapter_info: adapter_info,
                                                        single_info: single_info,
                                                        single_payload: single_payload)
      next unless adapted_single

      new_keys.push adapted_single.refname
    end
  end

  # Recalculate staged payloads
  _stagers.each_pair do |stager_name, stager_info|
    _stager_mod, _handler, _stager_platform, _stager_arch, stager_inst, _stager_modinfo = stager_info

    next unless stager_dependencies_available?(stager_name: stager_name, stager_dependencies: stager_inst.dependencies)

    # Walk the array of stages
    _stages.each_pair do |stage_name, stage_info|

      staged_payload = calculate_staged_payload(stage_name: stage_name,
                                                stager_name: stager_name,
                                                stage_info: stage_info,
                                                stager_info: stager_info)
      next unless staged_payload

      new_keys.push staged_payload.refname

      _adapters.each_pair do |adapter_name, adapter_info|
        adapted_staged_payload = calculate_adapted_staged_payload(staged_payload: staged_payload,
                                                                  adapter_name: adapter_name,
                                                                  stage_info: stage_info,
                                                                  stager_info: stager_info,
                                                                  adapter_info: adapter_info)
        next unless adapted_staged_payload

        new_keys.push adapted_staged_payload.refname
      end
    end
  end

  # Blow away anything that was cached but didn't exist during the
  # recalculation
  self.delete_if do |k, v|
    next if v == SymbolicModule
    !!(old_keys.include?(k) and not new_keys.include?(k))
  end

  flush_blob_cache
end

#stage_and_stager_compatible?(stager_info:, stage_info:, stager_name:, stage_name:) ⇒ Boolean

Returns:

  • (Boolean)


177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/msf/core/payload_set.rb', line 177

def stage_and_stager_compatible?(stager_info:, stage_info:, stager_name:, stage_name:)
  _stager_mod, _handler, stager_platform, stager_arch, stager_inst = stager_info
  _stage_mod, _, stage_platform, stage_arch, stage_inst = stage_info

  stager_dependencies = stager_inst.dependencies
  stage_dependencies = stage_inst.dependencies

  unless stager_dependencies.empty? && stage_dependencies.empty?
    return false unless stager_dependencies == stage_dependencies
  end

  # No intersection between platforms on the payloads?
  if ((stager_platform) and
    (stage_platform) and
    (stager_platform & stage_platform).empty?)
    dlog("Stager #{stager_name} and stage #{stage_name} have incompatible platforms: #{stager_platform.names} - #{stage_platform.names}", 'core', LEV_2)
    return false
  end

  # No intersection between architectures on the payloads?
  if ((stager_arch) and
    (stage_arch) and
    ((stager_arch & stage_arch).empty?))
    dlog("Stager #{stager_name} and stage #{stage_name} have incompatible architectures: #{stager_arch.join} - #{stage_arch.join}", 'core', LEV_2)
    return false
  end

  # If the stage has a convention, make sure it's compatible with
  # the stager's
  if ((stage_inst) and (stage_inst.compatible?(stager_inst) == false))
    dlog("Stager #{stager_name} and stage #{stage_name} are incompatible.", 'core', LEV_2)
    return false
  end

  # No intersection between platforms on the payloads?
  if ((stager_platform) and
    (stage_platform) and
    (stager_platform & stage_platform).empty?)
    dlog("Stager #{stager_name} and stage #{stage_name} have incompatible platforms: #{stager_platform.names} - #{stage_platform.names}", 'core', LEV_2)
    return false
  end

  # No intersection between architectures on the payloads?
  if ((stager_arch) and
    (stage_arch) and
    ((stager_arch & stage_arch).empty?))
    dlog("Stager #{stager_name} and stage #{stage_name} have incompatible architectures: #{stager_arch.join} - #{stage_arch.join}", 'core', LEV_2)
    return false
  end

  # If the stage has a convention, make sure it's compatible with
  # the stager's
  if ((stage_inst) and (stage_inst.compatible?(stager_inst) == false))
    dlog("Stager #{stager_name} and stage #{stage_name} are incompatible.", 'core', LEV_2)
    return false
  end
  true
end

#stager_dependencies_available?(stager_name:, stager_dependencies:) ⇒ Boolean

Returns:

  • (Boolean)


166
167
168
169
170
171
172
173
174
175
# File 'lib/msf/core/payload_set.rb', line 166

def stager_dependencies_available?(stager_name:, stager_dependencies:)
  # Pass if the stager has a dependency
  # and doesn't have the dependency installed
  supported = true # Default to true for stagers with no dependencies
  unless stager_dependencies.empty?
    supported = stager_dependencies.all?(&:available?)
    elog("Dependency for #{stager_name} is not supported") unless supported
  end
  supported
end

#stagersObject

Returns the hash of payload stagers that have been loaded.



541
542
543
# File 'lib/msf/core/payload_set.rb', line 541

def stagers
  _stagers
end