Module: Msf::ModuleManager::Reloading

Included in:
Msf::ModuleManager
Defined in:
lib/msf/core/module_manager/reloading.rb

Overview

Msf::ModuleManager::Reloading

Provides methods for reloading Metasploit modules (including payloads, stagers, adapters, stages, etc.), clearing out old aliases, and refreshing the module cache.

Instance Method Summary collapse

Instance Method Details

#manual_reload(parent_path, type, ref_name) ⇒ Object



51
52
53
# File 'lib/msf/core/module_manager/reloading.rb', line 51

def manual_reload(parent_path, type, ref_name)
  loaders.each { |loader| loader.load_module(parent_path, type, ref_name, { force: true }) }
end

#reload_module(mod) ⇒ Class, Msf::Module

Reloads the module specified in mod. This can either be an instance of a module or a module class.

Parameters:

  • mod (Msf::Module, Class)

    either an instance of a module or a module class

Returns:

  • (Class, Msf::Module)

    original_metasploit_class_or_instance if an instance of the reloaded module cannot be created.

  • (Msf::Module)

    new instance of original_metasploit_class with datastore copied from original_metasploit_instance.



13
14
15
16
17
18
19
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
# File 'lib/msf/core/module_manager/reloading.rb', line 13

def reload_module(mod)
  # if it's an instance, then get its class
  if mod.is_a? Msf::Module
    metasploit_class = mod.class
  else
    metasploit_class = mod
  end

  if (aliased_as = inv_aliases[metasploit_class.fullname])
    aliased_as.each do |a|
      aliases.delete a
    end
    inv_aliases.delete metasploit_class.fullname
  end

  if mod.payload?
    return reload_payload_module(mod)
  end

  if (aliased_as = inv_aliases[metasploit_class.fullname])
    aliased_as.each do |a|
      aliases.delete a
    end
    inv_aliases.delete metasploit_class.fullname
  end

  namespace_module = metasploit_class.module_parent

  # Check if the namespace module has a loader
  unless namespace_module.respond_to?(:loader)
    elog('Module does not have loader')
    return mod
  end

  loader = namespace_module.loader
  loader.reload_module(mod)
end

#reload_modulesHash{String => Integer}

Reloads modules from all module paths

Returns:

  • (Hash{String => Integer})

    Maps module type to number of modules loaded



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/msf/core/module_manager/reloading.rb', line 108

def reload_modules
  enablement_by_type.each_key do |type|
    module_set_by_type[type].clear
    init_module_set(type)
  end
  aliases.clear
  inv_aliases.clear

  # default the count to zero the first time a type is accessed
  count_by_type = Hash.new(0)

  framework.init_module_paths unless framework.module_paths_inited

  module_paths.each do |path|
    path_count_by_type = load_modules(path, force: true)

    # merge count with count from other paths
    path_count_by_type.each do |type, count|
      count_by_type[type] += count
    end
  end

  refresh_cache_from_module_files

  count_by_type
end

#reload_payload_module(mod) ⇒ Class, Msf::Module

Reload payload module, separately from other categories. This is due to complexity of payload module and due to the fact they don’t follow class structure as rest of the modules.

Parameters:

  • mod (Msf::Module, Class)

    either an instance of a module or a module class

Returns:

  • (Class, Msf::Module)

    original_metasploit_class_or_instance if an instance of the reloaded module cannot be created.

  • (Msf::Module)

    new instance of original_metasploit_class with datastore copied from original_metasploit_instance.



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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/msf/core/module_manager/reloading.rb', line 58

def reload_payload_module(mod)
  if mod.is_a? Msf::Module
    metasploit_class = mod.class
    original_instance = mod
  else
    metasploit_class = mod
    original_instance = nil
  end
  if (module_set = module_set_by_type.fetch(metasploit_class.type, nil))
    module_set.delete(metasploit_class.refname)
  end
  module_info = module_info_by_path[metasploit_class.file_path]
  unless module_info && (parent_path = module_info[:parent_path])
    elog('Failed to get parent_path from module object')
    return mod
  end

  # reload adapters if any
  manual_reload(parent_path, module_info[:type], File.join('adapters', mod.adapter_refname)) if mod.adapter_refname

  # reload stagers if any
  manual_reload(parent_path, module_info[:type], File.join('stagers', mod.stager_refname)) if mod.stager_refname

  # reload stages if any
  manual_reload(parent_path, module_info[:type], File.join('stages', mod.stage_refname)) if mod.stage_refname

  # reload single if any
  manual_reload(parent_path, module_info[:type], File.join('singles', module_info[:reference_name])) if original_instance.payload_type == Msf::Payload::Type::Single

  # Get reloaded module
  new_instance = framework.modules.create(metasploit_class.fullname)

  if new_instance.blank?
    elog('Failed create new instance')
    return mod
  end

  # Restore the datastore
  new_instance.datastore.merge!(original_instance.datastore)

  # Return the new instance, which the framework will make the active module.
  return new_instance
rescue StandardError => e
  elog("Failed to reload payload #{fullname}: #{e.message}")
  return mod
end