CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/msf/core/module_manager.rb
Views: 1904
1
# -*- coding: binary -*-
2
#
3
# Core
4
#
5
require 'pathname'
6
7
#
8
# Project
9
#
10
module Msf
11
# Upper management decided to throw in some middle management
12
# because the modules were getting out of hand. This bad boy takes
13
# care of the work of managing the interaction with modules in terms
14
# of loading and instantiation.
15
#
16
# @todo add unload support
17
class ModuleManager
18
include Msf::Framework::Offspring
19
20
21
# require here so that Msf::ModuleManager is already defined
22
include Msf::ModuleManager::Cache
23
include Msf::ModuleManager::Loading
24
include Msf::ModuleManager::ModulePaths
25
include Msf::ModuleManager::ModuleSets
26
include Msf::ModuleManager::Reloading
27
28
include Enumerable
29
30
31
def [](key)
32
names = key.split("/")
33
type = names.shift
34
35
module_set = module_set_by_type[type]
36
37
return unless module_set
38
39
module_reference_name = names.join("/")
40
module_set[module_reference_name]
41
end
42
43
# Creates a module instance using the supplied reference name.
44
#
45
# @param name [String] A module reference name. It may optionally
46
# be prefixed with a "<type>/", in which case the module will be
47
# created from the {Msf::ModuleSet} for the given <type>.
48
# Otherwise, we step through all sets until we find one that
49
# matches.
50
# @return (see Msf::ModuleSet#create)
51
def create(name, aliased_as: nil)
52
# First, a direct alias check
53
return create(self.aliases[name], aliased_as: name) if self.aliases[name]
54
55
# Check to see if it has a module type prefix. If it does,
56
# try to load it from the specific module set for that type.
57
names = name.split("/")
58
potential_type_or_directory = names.first
59
60
# if first name is a type
61
if DIRECTORY_BY_TYPE.has_key? potential_type_or_directory
62
type = potential_type_or_directory
63
# if first name is a type directory
64
else
65
type = TYPE_BY_DIRECTORY[potential_type_or_directory]
66
end
67
68
module_instance = nil
69
if type
70
module_set = module_set_by_type[type]
71
72
# First element in names is the type, so skip it
73
module_reference_name = names[1 .. -1].join("/")
74
module_instance = module_set.create(module_reference_name)
75
else
76
# Then we don't have a type, so we have to step through each set
77
# to see if we can create this module.
78
module_set_by_type.each do |type, set|
79
if aliased = self.aliases["#{type}/#{name}"]
80
module_instance = create(aliased, aliased_as: "#{type}/#{name}")
81
else
82
module_reference_name = names.join("/")
83
module_instance = set.create(module_reference_name)
84
end
85
break if module_instance
86
end
87
end
88
89
if module_instance
90
# If the module instance is populated by one of the recursive `create`
91
# calls this field may be set and we'll want to keep its original value
92
module_instance.aliased_as ||= aliased_as
93
end
94
95
module_instance
96
end
97
98
99
# Iterate over all modules in all sets
100
#
101
# @yieldparam name [String] The module's reference name
102
# @yieldparam mod_class [Msf::Module] A module class
103
def each
104
module_set_by_type.each do |type, set|
105
set.each do |name, mod_class|
106
yield name, mod_class
107
end
108
end
109
end
110
111
112
# @param [Msf::Framework] framework The framework for which this instance is managing the modules.
113
# @param [Array<String>] types List of module types to load. Defaults to all module types in {Msf::MODULE_TYPES}.
114
def initialize(framework, types=Msf::MODULE_TYPES)
115
#
116
# defaults
117
#
118
119
self.module_info_by_path = {}
120
self.enablement_by_type = {}
121
self.module_load_error_by_path = {}
122
self.module_load_warnings = {}
123
self.module_paths = []
124
self.module_set_by_type = {}
125
self.aliases = {}
126
self.inv_aliases = self.aliases.invert
127
128
#
129
# from arguments
130
#
131
132
self.framework = framework
133
134
types.each { |type|
135
init_module_set(type)
136
}
137
end
138
139
protected
140
141
attr_accessor :aliases, :inv_aliases
142
143
# This method automatically subscribes a module to whatever event
144
# providers it wishes to monitor. This can be used to allow modules
145
# to automatically execute or perform other tasks when certain
146
# events occur. For instance, when a new host is detected, other
147
# auxiliary modules may wish to run such that they can collect more
148
# information about the host that was detected.
149
#
150
# @param klass [Class<Msf::Module>] The module class
151
# @return [void]
152
def auto_subscribe_module(klass)
153
154
# If auto-subscription is enabled (which it is by default), figure out
155
# if it subscribes to any particular interfaces.
156
inst = nil
157
158
#
159
# Exploit event subscriber check
160
#
161
if (klass.include?(Msf::ExploitEvent) == true)
162
framework.events.add_exploit_subscriber((inst) ? inst : (inst = klass.new))
163
end
164
165
#
166
# Session event subscriber check
167
#
168
if (klass.include?(Msf::SessionEvent) == true)
169
framework.events.add_session_subscriber((inst) ? inst : (inst = klass.new))
170
end
171
end
172
173
end
174
end
175
176