Class: Msf::ModuleSet

Inherits:
Hash
  • Object
show all
Includes:
Framework::Offspring
Defined in:
lib/msf/core/module_set.rb

Overview

A module set contains zero or more named module classes of an arbitrary type.

Direct Known Subclasses

PayloadSet

Instance Attribute Summary collapse

Attributes included from Framework::Offspring

#framework

Instance Method Summary collapse

Constructor Details

#initialize(type = nil) ⇒ ModuleSet

Initializes a module set that will contain modules of a specific type and expose the mechanism necessary to create instances of them.

Parameters:

  • type (String) (defaults to: nil)

    The type of modules cached by this Msf::ModuleSet.



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/msf/core/module_set.rb', line 126

def initialize(type = nil)
  #
  # Defaults
  #
  self.ambiguous_module_reference_name_set = Set.new
  # Hashes that convey the supported architectures and platforms for a
  # given module
  self.architectures_by_module     = {}
  self.platforms_by_module = {}
  self.mod_sorted        = nil
  self.mod_extensions    = []

  #
  # Arguments
  #
  self.module_type = type
end

Instance Attribute Details

#ambiguous_module_reference_name_setSet<String> (protected)

Set of module reference names that are ambiguous because two or more paths have modules with the same reference name

Returns:

  • (Set<String>)

    set of module reference names loaded from multiple paths.



277
278
279
# File 'lib/msf/core/module_set.rb', line 277

def ambiguous_module_reference_name_set
  @ambiguous_module_reference_name_set
end

#architectures_by_moduleHash{Class => Array<String>} (protected)

Maps a module to the list of architectures it supports.

Returns:

  • (Hash{Class => Array<String>})

    Maps module class to Array of architecture Strings.



282
283
284
# File 'lib/msf/core/module_set.rb', line 282

def architectures_by_module
  @architectures_by_module
end

#mod_extensionsObject (protected)

Returns the value of attribute mod_extensions.



283
284
285
# File 'lib/msf/core/module_set.rb', line 283

def mod_extensions
  @mod_extensions
end

#mod_sortedArray<Array<String, Class>> (protected)

Array of module names and module classes ordered by their names.

Returns:

  • (Array<Array<String, Class>>)

    Array of arrays where the inner array is a pair of the module reference name and the module class.



294
295
296
# File 'lib/msf/core/module_set.rb', line 294

def mod_sorted
  @mod_sorted
end

#module_typeObject

Returns the value of attribute module_type.



148
149
150
# File 'lib/msf/core/module_set.rb', line 148

def module_type
  @module_type
end

#platforms_by_moduleHash{Class => Array<String>} (protected)

Maps a module to the list of platforms it supports.

Returns:

  • (Hash{Class => Array<String>})

    Maps module class to Array of platform Strings.



288
289
290
# File 'lib/msf/core/module_set.rb', line 288

def platforms_by_module
  @platforms_by_module
end

Instance Method Details

#[](name) ⇒ Msf::Module

Wrapper that detects if a symbolic module is in use. If it is, it creates an instance to demand load the module and then returns the now-loaded class afterwards.

Parameters:

  • name (String)

    the module reference name

Returns:

  • (Msf::Module)

    instance of the of the Msf::Module subclass with the given reference name



24
25
26
27
28
29
30
31
# File 'lib/msf/core/module_set.rb', line 24

def [](name)
  module_instance = super
  if module_instance == Msf::SymbolicModule || module_instance.nil?
    create(name)
  end

  super
end

#add_module(klass, reference_name, info = {}) ⇒ Class

Adds a module with a the supplied reference_name.

Parameters:

  • klass (Class<Msf::Module>)

    The module class.

  • reference_name (String)

    The module reference name.

  • info (Hash{String => Object}) (defaults to: {})

    optional module information.

Options Hash (info):

  • 'files' (Array<String>)

    List of paths to files that defined klass.

Returns:

  • (Class)

    The klass parameter modified to have Msf::Module.framework, Msf::Module#refname, Msf::Module#file_path, and Msf::Module#orig_cls set.



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/msf/core/module_set.rb', line 183

def add_module(klass, reference_name, info = {})
  # Set the module's reference_name so that it can be referenced when
  # instances are created.
  klass.framework = framework
  klass.refname   = reference_name
  klass.file_path = ((info and info['files']) ? info['files'][0] : nil)
  klass.orig_cls  = klass

  # don't want to trigger a create, so use fetch
  cached_module = self.fetch(reference_name, nil)

  if (cached_module and cached_module != Msf::SymbolicModule)
    ambiguous_module_reference_name_set.add(reference_name)

    # TODO this isn't terribly helpful since the refnames will always match, that's why they are ambiguous.
    wlog("The module #{klass.refname} is ambiguous with #{self[reference_name].refname}.")
  end

  self[reference_name] = klass

  klass
end

#create(reference_name, cache_type: Msf::ModuleManager::Cache::FILESYSTEM) ⇒ Msf::Module?

Create an instance of the supplied module by its reference name

Parameters:

  • reference_name (String)

    The module reference name.

Returns:

  • (Msf::Module, nil)

    Instance of the named module or nil if it could not be created.



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/msf/core/module_set.rb', line 38

def create(reference_name, cache_type: Msf::ModuleManager::Cache::FILESYSTEM)
  klass = fetch(reference_name, nil)
  instance = nil
  # If there is no module associated with this class, then try to demand load it.
  if klass.nil? or klass == Msf::SymbolicModule
    framework.modules.load_cached_module(module_type, reference_name, cache_type: cache_type)
    klass = fetch(reference_name, nil)
  end

  # If the klass is valid for this reference_name, try to create it
  unless klass.nil? or klass == Msf::SymbolicModule
    instance = klass.new
  end

  # Notify any general subscribers of the creation event
  if instance
    self.framework.events.on_module_created(instance)
  else
    self.delete(reference_name)
  end

  return instance
end

#demand_load_modulesvoid (protected)

This method returns an undefined value.

Load all modules that are marked as being symbolic.



211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/msf/core/module_set.rb', line 211

def demand_load_modules
  found_symbolics = false
  # Pre-scan the module list for any symbolic modules
  self.each_pair { |name, mod|
    if (mod == Msf::SymbolicModule)
      found_symbolics = true
      mod = create(name)
      next if (mod.nil?)
    end
  }

  # If we found any symbolic modules, then recalculate.
  if (found_symbolics)
    recalculate
  end
end

#each {|module_reference_name, module| ... } ⇒ void

This method returns an undefined value.

Overrides the builtin 'each' operator to avoid the following exception on Ruby 1.9.2+ “can't add a new key into hash during iteration”

Yields:

  • (module_reference_name, module)

Yield Parameters:

  • module_reference_name (String)

    the reference_name of the module.

  • module (Class)

    The module class: a subclass of Msf::Module.



69
70
71
72
73
74
75
# File 'lib/msf/core/module_set.rb', line 69

def each(&block)
  list = []
  self.keys.sort.each do |sidx|
    list << [sidx, self[sidx]]
  end
  list.each(&block)
end

#each_module(opts = {}) {|module_reference_name, module| ... } ⇒ void

This method returns an undefined value.

Enumerates each module class in the set.

Parameters:

  • opts (Hash{String => Object}) (defaults to: {})

Yields:

  • (module_reference_name, module)

Yield Parameters:

  • module_reference_name (String)

    the name of module

  • module (Class)

    The module class: a subclass of Msf::Module.



83
84
85
86
87
88
89
# File 'lib/msf/core/module_set.rb', line 83

def each_module(opts = {}, &block)
  demand_load_modules

  self.mod_sorted = self.sort

  each_module_list(mod_sorted, opts, &block)
end

#each_module_filter(opts, name, entry) ⇒ false, true

Custom each_module filtering if an advanced set supports doing extended filtering.

Parameters:

  • name (String)

    the module reference name

  • entry (Array<String, Class>)

    pair of the module reference name and the module class.

  • opts (Hash{String => Object})

Returns:

  • (false)

    if the module should not be filtered; it should be yielded by #each_module_list.

  • (true)

    if the module should be filtered; it should not be yielded by #each_module_list.



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

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

#each_module_list(ary, opts) {|module_reference_name, module| ... } ⇒ void (protected)

This method returns an undefined value.

Enumerates the modules in the supplied array with possible limiting factors.

Parameters:

  • ary (Array<Array<String, Class>>)

    Array of module reference name and module class pairs

  • opts (Hash{String => Object})

Options Hash (opts):

  • 'Arch' (Array<String>)

    List of 1 or more architectures that the module must support. The module need only support one of the architectures in the array to be included, not all architectures.

  • 'Platform' (Array<String>)

    List of 1 or more platforms that the module must support. The module need only support one of the platforms in the array to be include, not all platforms.

Yields:

  • (module_reference_name, module)

Yield Parameters:

  • module_reference_name (String)

    the name of module

  • module (Class)

    The module class: a subclass of Msf::Module.



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

def each_module_list(ary, opts, &block)
  ary.each { |entry|
    name, mod = entry

    # Skip any lingering symbolic modules.
    next if (mod == Msf::SymbolicModule)

    # Filter out incompatible architectures
    if (opts['Arch'])
      if (!architectures_by_module[mod])
        architectures_by_module[mod] = mod.new.arch
      end

      next if ((architectures_by_module[mod] & opts['Arch']).empty? == true)
    end

    # Filter out incompatible platforms
    if (opts['Platform'])
      if (!platforms_by_module[mod])
        platforms_by_module[mod] = mod.new.platform
      end

      next if ((platforms_by_module[mod] & opts['Platform']).empty? == true)
    end

    # Custom filtering
    next if (each_module_filter(opts, name, entry) == true)

    block.call(name, mod)
  }
end

#each_module_ranked(opts = {}) {|module_reference_name, module| ... } ⇒ void

This method returns an undefined value.

Enumerates each module class in the set based on their relative ranking to one another. Modules that are ranked higher are shown first.

Parameters:

  • opts (Hash{String => Object}) (defaults to: {})

Yields:

  • (module_reference_name, module)

Yield Parameters:

  • module_reference_name (String)

    the name of module

  • module (Class)

    The module class: a subclass of Msf::Module.



109
110
111
112
113
# File 'lib/msf/core/module_set.rb', line 109

def each_module_ranked(opts = {}, &block)
  demand_load_modules

  each_module_list(rank_modules, opts, &block)
end

#force_load_setvoid

This method returns an undefined value.

Forces all modules in this set to be loaded.



118
119
120
# File 'lib/msf/core/module_set.rb', line 118

def force_load_set
  each_module { |name, mod| }
end

#module_rank(reference_name, metasploit_module_class) ⇒ Integer (protected)

Retrieves the rank from a loaded, not-yet-loaded, or unloadable Metasploit Module.

Parameters:

  • reference_name (String)

    The reference name of the Metasploit Module

  • metasploit_module_class (Class<Msf::Module>, Msf::SymbolicModule)

    The loaded `Class` for the Metasploit Module, or SymbolicModule if the Metasploit Module is not loaded yet.

Returns:

  • (Integer)

    an `Msf::*Ranking`. `Msf::ManualRanking` if `metasploit_module_class` is `nil` or SymbolicModule and it could not be loaded by #create. Otherwise, the `Rank` constant of the `metasploit_module_class` or NormalRanking if `metasploit_module_class` does not define `Rank`.



318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
# File 'lib/msf/core/module_set.rb', line 318

def module_rank(reference_name, metasploit_module_class)
  if metasploit_module_class.nil?
    Msf::ManualRanking
  elsif metasploit_module_class == Msf::SymbolicModule
    # TODO don't create an instance just to get the Class.
    created_metasploit_module_instance = create(reference_name)

    if created_metasploit_module_instance.nil?
      module_rank(reference_name, nil)
    else
      module_rank(reference_name, created_metasploit_module_instance.class)
    end
  elsif metasploit_module_class.const_defined? :Rank
    metasploit_module_class.const_get :Rank
  else
    Msf::NormalRanking
  end
end

#on_module_reload(mod) ⇒ void

This method returns an undefined value.

Gives the module set an opportunity to handle a module reload event

Parameters:

  • mod (Class)

    the module class: a subclass of Msf::Module



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

def on_module_reload(mod)
end

#rank_modulesArray<Array<String, Class>> (protected)

Ranks modules based on their constant rank value, if they have one. Modules without a Rank are treated as if they had NormalRanking for Rank.

Returns:

  • (Array<Array<String, Class>>)

    Array of arrays where the inner array is a pair of the module reference name and the module class.



306
307
308
# File 'lib/msf/core/module_set.rb', line 306

def rank_modules
  self.sort_by { |pair| module_rank(*pair) }.reverse!
end

#recalculatevoid

This method returns an undefined value.

Dummy placeholder to recalculate aliases and other fun things.



160
161
# File 'lib/msf/core/module_set.rb', line 160

def recalculate
end

#valid?(reference_name) ⇒ true, false

Checks to see if the supplied module reference name is valid.

Parameters:

  • reference_name (String)

    The module reference name.

Returns:

  • (true)

    if the module can be created and cached.

  • (false)

    otherwise



168
169
170
171
# File 'lib/msf/core/module_set.rb', line 168

def valid?(reference_name)
  create(reference_name)
  (self[reference_name]) ? true : false
end