Module: Metasploit::Model::Module::Class
- Extended by:
- ActiveModel::Naming, ActiveSupport::Autoload, ActiveSupport::Concern
- Includes:
- Translation
- Defined in:
- lib/metasploit/model/module/class.rb
Overview
Code shared between Mdm::Module::Class
and Metasploit::Framework::Module::Class
.
Defined Under Namespace
Modules: Spec
Constant Summary collapse
- PAYLOAD_TYPES =
Valid values for #payload_type when #payload? is
true
. [ 'single', 'staged' ]
- STAGED_ANCESTOR_PAYLOAD_TYPES =
The Ancestor#payload_type when #payload_type is 'staged'.
[ 'stage', 'stager' ]
Instance Attribute Summary collapse
-
#ancestors ⇒ Array<Metasploit::Model::Module::Ancestor>
readonly
The Class or Modules that were loaded to make this module Class.
-
#full_name ⇒ String
The full name (type + reference) for the ClassMsf::Module.
-
#module_type ⇒ String
A denormalized cache of the ancestors' module_types, which must all be the same.
-
#payload_type ⇒ String?
For payload modules, the type of payload, either 'single' or 'staged'.
-
#rank ⇒ Metasploit::Model::Module::Rank
The reliability of the module and likelyhood that the module won't knock over the service or host being exploited.
-
#reference_name ⇒ String
The reference name for the ClassMsf::Module.
Instance Method Summary collapse
-
#ancestor_module_types ⇒ void
private
Validates that #ancestors all have the same Ancestor#module_type as #module_type.
-
#ancestor_payload_types ⇒ void
private
Validates that #ancestors have correct payload_types for the #module_type and #payload_type.
-
#ancestors_size ⇒ void
private
Validates that number of #ancestors is correct for the #module_type.
-
#derived_module_type ⇒ String?
Derives #module_type from the consensus of ancestors' module_types.
-
#derived_payload_type ⇒ 'single', ...
Derives #payload_type based on ancestor's payload_type.
-
#derived_reference_name ⇒ String?
Derives #reference_name from #ancestors.
-
#derived_single_payload_reference_name ⇒ String?
private
Derives #reference_name for single payload.
-
#derived_staged_payload_reference_name ⇒ String?
private
Derives #reference_name for staged payload.
-
#payload? ⇒ true, false
Returns whether this represents a ClassMsf::Payload.
-
#staged_payload_type_count(ancestors_by_payload_type, ancestor_payload_type) ⇒ void
private
Validates that only 1 ancestor with the given payload_type exists.
Instance Attribute Details
#ancestors ⇒ Array<Metasploit::Model::Module::Ancestor> (readonly)
The Class or Modules that were loaded to make this module Class.
|
# File 'lib/metasploit/model/module/class.rb', line 95
|
#full_name ⇒ String
The full name (type + reference) for the ClassMsf::Module. This is merely a denormalized cache of
"#{{#module_type}}/#{{#reference_name}}"
as full_name is used in numerous queries and reports.
|
# File 'lib/metasploit/model/module/class.rb', line 104
|
#module_type ⇒ String
A denormalized cache of the ancestors' module_types, which must all be the same. This cache exists so that queries for modules of a given type don't need include the #ancestors.
|
# File 'lib/metasploit/model/module/class.rb', line 110
|
#payload_type ⇒ String?
For payload modules, the type of payload, either 'single' or 'staged'.
|
# File 'lib/metasploit/model/module/class.rb', line 117
|
#rank ⇒ Metasploit::Model::Module::Rank
The reliability of the module and likelyhood that the module won't knock over the service or host being exploited. Bigger values is better.
|
# File 'lib/metasploit/model/module/class.rb', line 89
|
#reference_name ⇒ String
The reference name for the ClassMsf::Module. For non-payloads, this will just be Ancestor#reference_name for the only element in #ancestors. For payloads composed of a stage and stager, the reference name will be derived from the Ancestor#reference_name of each element #ancestors or an alias defined in those Modules.
|
# File 'lib/metasploit/model/module/class.rb', line 123
|
Instance Method Details
#ancestor_module_types ⇒ void (private)
This method returns an undefined value.
Validates that #ancestors all have the same Ancestor#module_type as #module_type.
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 |
# File 'lib/metasploit/model/module/class.rb', line 238 def ancestor_module_types ancestor_module_type_set = Set.new ancestors.each do |ancestor| if module_type and ancestor.module_type != module_type errors[:ancestors] << "can contain ancestors only with same module_type (#{module_type}); " \ "#{ancestor.full_name} cannot be an ancestor due to its module_type " \ "(#{ancestor.module_type})" end ancestor_module_type_set.add ancestor.module_type end if ancestor_module_type_set.length > 1 ancestor_module_type_sentence = ancestor_module_type_set.sort.to_sentence errors[:ancestors] << "can only contain ancestors with one module_type, " \ "but contains multiple module_types (#{ancestor_module_type_sentence})" end end |
#ancestor_payload_types ⇒ void (private)
This method returns an undefined value.
Validates that #ancestors have correct payload_types for the #module_type and #payload_type.
262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 |
# File 'lib/metasploit/model/module/class.rb', line 262 def ancestor_payload_types if payload? case payload_type when 'single' ancestors.each do |ancestor| unless ancestor.payload_type == 'single' errors[:ancestors] << "cannot have an ancestor (#{ancestor.full_name}) " \ "with payload_type (#{ancestor.payload_type}) " \ "for class payload_type (#{payload_type})" end end when 'staged' ancestors_by_payload_type = ancestors.group_by(&:payload_type) STAGED_ANCESTOR_PAYLOAD_TYPES.each do |ancestor_payload_type| staged_payload_type_count(ancestors_by_payload_type, ancestor_payload_type) end ancestors_by_payload_type.each do |ancestor_payload_type, ancestors| unless STAGED_ANCESTOR_PAYLOAD_TYPES.include? ancestor_payload_type full_names = ancestors.map(&:full_name) full_name_sentence = full_names.to_sentence errors[:ancestors] << "cannot have ancestors (#{full_name_sentence}) " \ "with payload_type (#{ancestor_payload_type}) " \ "for class payload_type (#{payload_type}); " \ "only one stage and one stager ancestor is allowed" end end end else ancestors.each do |ancestor| if ancestor.payload_type errors[:ancestors] << "cannot have an ancestor (#{ancestor.full_name}) " \ "with a payload_type (#{ancestor.payload_type}) " \ "for class module_type (#{module_type})" end end end end |
#ancestors_size ⇒ void (private)
This method returns an undefined value.
Validates that number of #ancestors is correct for the #module_type.
306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 |
# File 'lib/metasploit/model/module/class.rb', line 306 def ancestors_size if payload? case payload_type when 'single' unless ancestors.size == 1 errors[:ancestors] << 'must have exactly one ancestor for single payload module class' end when 'staged' unless ancestors.size == 2 errors[:ancestors] << 'must have exactly two ancestors (stager + stage) for staged payload module class' end # other (invalid) types are handled by validation on payload_type end else unless ancestors.size == 1 errors[:ancestors] << 'must have exactly one ancestor as a non-payload module class' end end end |
#derived_module_type ⇒ String?
Derives #module_type from the consensus of ancestors' module_types.
144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/metasploit/model/module/class.rb', line 144 def derived_module_type module_type_consensus = nil module_type_set = Set.new ancestors.each do |ancestor| module_type_set.add ancestor.module_type end if module_type_set.length == 1 module_type_consensus = module_type_set.to_a.first end module_type_consensus end |
#derived_payload_type ⇒ 'single', ...
Derives #payload_type based on ancestor's payload_type.
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/metasploit/model/module/class.rb', line 168 def derived_payload_type derived = nil if payload? case ancestors.length when 1 if ancestors.first.payload_type == 'single' derived = 'single' end when 2 payload_type_set = Set.new ancestors.each do |ancestor| payload_type_set.add ancestor.payload_type end if payload_type_set.include? 'stager' and payload_type_set.include? 'stage' derived = 'staged' end end end derived end |
#derived_reference_name ⇒ String?
Derives #reference_name from #ancestors.
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/metasploit/model/module/class.rb', line 201 def derived_reference_name derived = nil if payload? case payload_type when 'single' derived = derived_single_payload_reference_name when 'staged' derived = derived_staged_payload_reference_name end else if ancestors.length == 1 derived = ancestors.first.reference_name end end derived end |
#derived_single_payload_reference_name ⇒ String? (private)
Caller should check that #payload? is true
and #payload_type is 'single' before calling
#derived_single_payload_reference_name.
Derives #reference_name for single payload.
334 335 336 337 338 339 340 341 342 343 344 345 346 |
# File 'lib/metasploit/model/module/class.rb', line 334 def derived_single_payload_reference_name derived = nil if ancestors.length == 1 ancestor = ancestors.first if ancestor.payload_type == 'single' derived = ancestor.payload_name end end derived end |
#derived_staged_payload_reference_name ⇒ String? (private)
Caller should check that #payload? is true
and #payload_type is 'staged' before calling
#derived_staged_payload_reference_name.
Derives #reference_name for staged payload.
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 |
# File 'lib/metasploit/model/module/class.rb', line 358 def derived_staged_payload_reference_name derived = nil if ancestors.length == 2 ancestors_by_payload_type = ancestors.group_by(&:payload_type) stage_ancestors = ancestors_by_payload_type.fetch('stage', []) # length can be 0..2 if stage_ancestors.length == 1 stage_ancestor = stage_ancestors.first if stage_ancestor.payload_name stager_ancestors = ancestors_by_payload_type.fetch('stager', []) # length can be 0..1 if stager_ancestors.length == 1 stager_ancestor = stager_ancestors.first if stager_ancestor.payload_name derived = "#{stage_ancestor.payload_name}/#{stager_ancestor.payload_name}" end end end end end derived end |
#payload? ⇒ true, false
Returns whether this represents a ClassMsf::Payload.
224 225 226 227 228 229 230 |
# File 'lib/metasploit/model/module/class.rb', line 224 def payload? if module_type == 'payload' true else false end end |
#staged_payload_type_count(ancestors_by_payload_type, ancestor_payload_type) ⇒ void (private)
This method returns an undefined value.
Validates that only 1 ancestor with the given payload_type exists.
394 395 396 397 398 399 400 401 402 403 404 405 406 407 |
# File 'lib/metasploit/model/module/class.rb', line 394 def staged_payload_type_count(ancestors_by_payload_type, ancestor_payload_type) payload_type_ancestors = ancestors_by_payload_type.fetch(ancestor_payload_type, []) payload_type_ancestor_count = payload_type_ancestors.length if payload_type_ancestor_count < 1 errors[:ancestors] << "needs exactly one ancestor with payload_type (#{ancestor_payload_type}), " \ "but there are none." elsif payload_type_ancestor_count > 1 full_names = payload_type_ancestors.map(&:full_name).sort full_name_sentence = full_names.to_sentence errors[:ancestors] << "needs exactly one ancestor with payload_type (#{ancestor_payload_type}), " \ "but there are #{payload_type_ancestor_count} (#{full_name_sentence})" end end |