Class: Msf::Module

Inherits:
Object
  • Object
show all
Extended by:
Framework::Offspring
Includes:
Alert, Arch, Auth, Author, Compatibility, DataStore, FullName, ModuleInfo, ModuleStore, Network, Options, Privileged, Ranking, Reliability, SideEffects, Stability, Type, UI, UUID
Defined in:
lib/msf/core/module.rb

Overview

The module base class is responsible for providing the common interface that is used to interact with modules at the most basic levels, such as by inspecting a given module’s attributes (name, description, version, authors, etc) and by managing the module’s data store.

Direct Known Subclasses

Auxiliary, Encoder, Evasion, Exploit, Nop, Payload, Post

Defined Under Namespace

Modules: Alert, Arch, Auth, Author, Compatibility, DataStore, Deprecated, External, Failure, FullName, HasActions, ModuleInfo, ModuleStore, Network, Options, Privileged, Ranking, Reliability, SideEffects, Stability, Type, UI, UUID Classes: AuxiliaryAction, Platform, PlatformList, Reference, SiteReference, Target

Constant Summary collapse

REPLICANT_EXTENSION_DS_KEY =

The key where a comma-separated list of Ruby module names will live in the datastore, consumed by #replicant to allow clean override of MSF module methods.

'ReplicantExtensions'

Constants included from ModuleInfo

ModuleInfo::UpdateableOptions

Class Attribute Summary collapse

Instance Attribute Summary collapse

Attributes included from UUID

#uuid

Attributes included from Rex::Ui::Subscriber::Input

#user_input

Attributes included from Rex::Ui::Subscriber::Output

#user_output

Attributes included from Privileged

#priveli, #privileged

Attributes included from Options

#options

Attributes included from ModuleStore

#module_store

Attributes included from ModuleInfo

#module_info

Attributes included from FullName

#aliased_as

Attributes included from DataStore

#datastore

Attributes included from Author

#author

Attributes included from Arch

#arch

Attributes included from Alert

#alerts, #you_have_been_warned

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Reliability

#reliability, #reliability_to_s

Methods included from Stability

#stability, #stability_to_s

Methods included from SideEffects

#side_effects, #side_effects_to_s

Methods included from UUID

#generate_uuid

Methods included from UI

#init_ui

Methods included from UI::Message

#print_error, #print_good, #print_prefix, #print_status, #print_warning

Methods included from UI::Message::Verbose

#vprint_error, #vprint_good, #vprint_status, #vprint_warning

Methods included from UI::Line

#print_line, #print_line_prefix

Methods included from UI::Line::Verbose

#vprint_line

Methods included from Rex::Ui::Subscriber

#copy_ui, #init_ui, #reset_ui

Methods included from Rex::Ui::Subscriber::Input

#gets

Methods included from Rex::Ui::Subscriber::Output

#flush, #print, #print_blank_line, #print_error, #print_good, #print_line, #print_status, #print_warning

Methods included from Type

#auxiliary?, #encoder?, #evasion?, #exploit?, #nop?, #payload?, #post?, #type

Methods included from Ranking

#rank, #rank_to_h, #rank_to_s

Methods included from Privileged

#privileged?

Methods included from Options

#deregister_option_group, #deregister_options, #register_advanced_options, #register_evasion_options, #register_option_group, #register_options, #validate

Methods included from Network

#comm, #support_ipv6?, #target_host, #target_port

Methods included from ModuleStore

#[], #[]=

Methods included from ModuleInfo

#alias, #description, #disclosure_date, #info_fixups, #merge_check_key, #merge_info, #merge_info_advanced_options, #merge_info_alias, #merge_info_description, #merge_info_evasion_options, #merge_info_name, #merge_info_options, #merge_info_string, #merge_info_version, #name, #notes, #update_info

Methods included from FullName

#aliases, #fullname, #promptname, #realname, #refname, #shortname

Methods included from DataStore

#import_defaults, #import_target_defaults, #share_datastore

Methods included from Compatibility

#compat, #compatible?, #init_compat

Methods included from Author

#author_to_s, #each_author

Methods included from Auth

#store_valid_credential

Methods included from Arch

#arch?, #arch_to_s, #each_arch

Methods included from Alert

#add_alert, #add_error, #add_info, #add_warning, #alert_user, #errors, #get_alerts, included, #infos, #is_usable?, #warnings, #without_prompt

Constructor Details

#initialize(info = {}) ⇒ Module

Creates an instance of an abstract module using the supplied information hash.



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/msf/core/module.rb', line 112

def initialize(info = {})
  @module_info_copy = info.dup

  self.module_info = info
  generate_uuid

  set_defaults

  # Initialize module compatibility hashes
  init_compat

  # Fixup module fields as needed
  info_fixups

  # Transform some of the fields to arrays as necessary
  self.author = Msf::Author.transform(module_info['Author'])
  self.arch = Rex::Transformer.transform(module_info['Arch'], Array, [ String ], 'Arch')
  self.platform = PlatformList.transform(module_info['Platform'])
  self.references = Rex::Transformer.transform(module_info['References'], Array, [ SiteReference, Reference ], 'Ref')

  # Create and initialize the option container for this module
  self.options = Msf::OptionContainer.new
  self.options.add_options(info['Options'], self.class)
  self.options.add_advanced_options(info['AdvancedOptions'], self.class)
  self.options.add_evasion_options(info['EvasionOptions'], self.class)

  # Create and initialize the data store for this module
  self.datastore = ModuleDataStore.new(self)

  # Import default options into the datastore
  import_defaults

  self.privileged = module_info['Privileged'] || false
  self.license = module_info['License'] || MSF_LICENSE

  # Allow all modules to track their current workspace
  register_advanced_options(
    [
      OptString.new('WORKSPACE', [ false, "Specify the workspace for this module" ]),
      OptBool.new('VERBOSE',     [ false, 'Enable detailed status messages', false ])
    ], Msf::Module)

end

Class Attribute Details

.adapted_refnameString?

Returns Reference name of the payload being adapted.

Returns:

  • (String, nil)

    Reference name of the payload being adapted



88
89
90
# File 'lib/msf/core/module.rb', line 88

def adapted_refname
  @adapted_refname
end

.adapter_refnameString?

Returns Reference name of the payloads adapter.

Returns:

  • (String, nil)

    Reference name of the payloads adapter



91
92
93
# File 'lib/msf/core/module.rb', line 91

def adapter_refname
  @adapter_refname
end

.file_pathObject

The path from which the module was loaded.



85
86
87
# File 'lib/msf/core/module.rb', line 85

def file_path
  @file_path
end

.orig_clsObject

This attribute holds the non-duplicated copy of the module implementation. This attribute is used for reloading purposes so that it can be re-duplicated.



80
81
82
# File 'lib/msf/core/module.rb', line 80

def orig_cls
  @orig_cls
end

.stage_refnameString?

Returns Reference name of the payload stage.

Returns:

  • (String, nil)

    Reference name of the payload stage



94
95
96
# File 'lib/msf/core/module.rb', line 94

def stage_refname
  @stage_refname
end

.stager_refnameString?

Returns Reference name of the payloads stager.

Returns:

  • (String, nil)

    Reference name of the payloads stager



97
98
99
# File 'lib/msf/core/module.rb', line 97

def stager_refname
  @stager_refname
end

Instance Attribute Details

#errorObject

The last exception to occur using this module



427
428
429
# File 'lib/msf/core/module.rb', line 427

def error
  @error
end

#job_idObject

The job identifier that this module is running as, if any.



422
423
424
# File 'lib/msf/core/module.rb', line 422

def job_id
  @job_id
end

#licenseObject

The license under which this module is provided.



417
418
419
# File 'lib/msf/core/module.rb', line 417

def license
  @license
end

#platformObject

The array of zero or more platforms.



407
408
409
# File 'lib/msf/core/module.rb', line 407

def platform
  @platform
end

#privileged=(value) ⇒ Object (writeonly, protected)

:nodoc:



459
460
461
# File 'lib/msf/core/module.rb', line 459

def privileged=(value)
  @privileged = value
end

#referencesObject

The reference count for the module.



412
413
414
# File 'lib/msf/core/module.rb', line 412

def references
  @references
end

#user_dataObject

An opaque bag of data to attach to a module. This is useful for attaching some piece of identifying info on to a module before calling Simple::Exploit#exploit_simple or Simple::Auxiliary#run_simple for correlating where modules came from.



435
436
437
# File 'lib/msf/core/module.rb', line 435

def user_data
  @user_data
end

Class Method Details

.cached?Boolean

Returns false since this is the real module

Returns:

  • (Boolean)


332
333
334
# File 'lib/msf/core/module.rb', line 332

def self.cached?
  false
end

Instance Method Details

#adapted_refnameString?

Returns Reference name of the payload being adapted.

Returns:

  • (String, nil)

    Reference name of the payload being adapted



224
225
226
# File 'lib/msf/core/module.rb', line 224

def adapted_refname
  self.class.adapted_refname
end

#adapter_refnameString?

Returns Reference name of the payloads adapter.

Returns:

  • (String, nil)

    Reference name of the payloads adapter



229
230
231
# File 'lib/msf/core/module.rb', line 229

def adapter_refname
  self.class.adapter_refname
end

#black_listed_auth_filenamesObject



357
358
359
360
361
362
363
364
# File 'lib/msf/core/module.rb', line 357

def black_listed_auth_filenames
  @black_listed_auth_filenames ||= lambda {
    [
      'fileformat',
      'browser'
    ]
  }.call
end

#debugging?Boolean

Returns true if this module is being debugged.

Returns:

  • (Boolean)


300
301
302
# File 'lib/msf/core/module.rb', line 300

def debugging?
  datastore['DEBUG']
end

#default_cred?Boolean

Returns:

  • (Boolean)


386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
# File 'lib/msf/core/module.rb', line 386

def default_cred?
  return false unless post_auth?

  required_cred_options.all? do |name, opt|
    if opt.type == 'string'
      if !opt.default.blank?
        true
      else
        false
      end
    else
      true
    end
  end

  false
end

#default_optionsObject



336
337
338
# File 'lib/msf/core/module.rb', line 336

def default_options
  self.module_info['DefaultOptions']
end

#fail_with(reason, msg = nil) ⇒ void

Note:

If you are writing an exploit, you don't use this API. Instead, please refer to the API documentation from lib/msf/core/exploit.rb.

This method returns an undefined value.

Raises a RuntimeError failure message. This is meant to be used for all non-exploits, and allows specific classes to override.

Examples:

fail_with('No Access', 'Unable to login')

Parameters:

  • reason (String)

    A reason about the failure.

  • msg (String) (defaults to: nil)

    (Optional) A message about the failure.

Raises:

  • (RuntimeError)

See Also:



318
319
320
# File 'lib/msf/core/module.rb', line 318

def fail_with(reason, msg=nil)
  raise RuntimeError, "#{reason.to_s}: #{msg}"
end

#file_pathObject

The path to the file in which the module can be loaded from.



219
220
221
# File 'lib/msf/core/module.rb', line 219

def file_path
  self.class.file_path
end

#frameworkObject

Returns the class reference to the framework



104
105
106
# File 'lib/msf/core/module.rb', line 104

def framework
  self.class.framework
end

#has_check?Boolean

Returns:

  • (Boolean)


156
157
158
# File 'lib/msf/core/module.rb', line 156

def has_check?
  respond_to?(:check)
end

#orig_clsObject

Returns the unduplicated class associated with this module.



212
213
214
# File 'lib/msf/core/module.rb', line 212

def orig_cls
  self.class.orig_cls
end

#ownerObject

Returns the username that instantiated this module, this tries a handful of methods to determine what actual user ran this module.



255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/msf/core/module.rb', line 255

def owner
  # Generic method to configure a module owner
  username = self.datastore['MODULE_OWNER'].to_s.strip

  # Specific method used by the commercial products
  if username.empty?
    username = self.datastore['PROUSER'].to_s.strip
  end

  # Fallback when neither prior method is available, common for msfconsole
  if username.empty?
    username = (ENV['LOGNAME'] || ENV['USERNAME'] || ENV['USER'] || "unknown").to_s.strip
  end

  username
end

#perform_extensionsvoid

This method returns an undefined value.

Extends self with the constant list in the datastore



188
189
190
191
192
193
194
195
196
197
198
# File 'lib/msf/core/module.rb', line 188

def perform_extensions
  if datastore[REPLICANT_EXTENSION_DS_KEY].present?
    if datastore[REPLICANT_EXTENSION_DS_KEY].respond_to?(:each)
      datastore[REPLICANT_EXTENSION_DS_KEY].each do |const|
        self.extend(const)
      end
    else
      fail "Invalid settings in datastore at key #{REPLICANT_EXTENSION_DS_KEY}"
    end
  end
end

#platform?(what) ⇒ Boolean

Checks to see if this module is compatible with the supplied platform

Returns:

  • (Boolean)


293
294
295
# File 'lib/msf/core/module.rb', line 293

def platform?(what)
  (platform & what).empty? == false
end

#platform_to_sObject

Return a comma separated list of supported platforms, if any.



286
287
288
# File 'lib/msf/core/module.rb', line 286

def platform_to_s
  platform.all? ? "All" : platform.names.join(", ")
end

#post_auth?Boolean

Returns:

  • (Boolean)


366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
# File 'lib/msf/core/module.rb', line 366

def post_auth?
  if self.kind_of?(Msf::Auxiliary::AuthBrute)
    return true
  else
    # Some modules will never be post auth, so let's not waste our time
    # determining it and create more potential false positives.
    # If these modules happen to be post auth for some reason, then we it
    # should manually override the post_auth? method as true.
    directory_name = self.fullname.split('/')[0..-2]
    black_listed_auth_filenames.each do |black_listed_name|
      return false if directory_name.include?(black_listed_name)
    end

    # Some modules create their own username and password datastore
    # options, not relying on the AuthBrute mixin. In that case we
    # just have to go through the options and try to identify them.
    !required_cred_options.empty?
  end
end

#register_extensions(*rb_modules) ⇒ void

This method returns an undefined value.

Parameters:

  • rb_modules (Constant)

    One or more Ruby constants



202
203
204
205
206
207
# File 'lib/msf/core/module.rb', line 202

def register_extensions(*rb_modules)
  datastore[REPLICANT_EXTENSION_DS_KEY] = [] unless datastore[REPLICANT_EXTENSION_DS_KEY].present?
  rb_modules.each do |rb_mod|
    datastore[REPLICANT_EXTENSION_DS_KEY] << rb_mod unless datastore[REPLICANT_EXTENSION_DS_KEY].include? rb_mod
  end
end

#register_parent(ref) ⇒ Object

Scans the parent module reference to populate additional information. This is used to inherit common settings (owner, workspace, parent uuid, etc).



276
277
278
279
280
281
# File 'lib/msf/core/module.rb', line 276

def register_parent(ref)
  self.datastore['WORKSPACE']    = (ref.datastore['WORKSPACE'] ? ref.datastore['WORKSPACE'].dup : nil)
  self.datastore['PROUSER']      = (ref.datastore['PROUSER']   ? ref.datastore['PROUSER'].dup   : nil)
  self.datastore['MODULE_OWNER'] = ref.owner.dup
  self.datastore['ParentUUID']   = ref.uuid.dup
end

#replicantObject

Creates a fresh copy of an instantiated module



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/msf/core/module.rb', line 163

def replicant
  obj = self.clone
  self.instance_variables.each { |k|
    old_value = instance_variable_get(k)
    begin
      new_value = old_value.is_a?(Rex::Ref) ? old_value.ref : old_value.dup
    rescue => e
      elog("#{self.class} replicant failed to dup #{k}", error: e)
      new_value = old_value
    end

    obj.instance_variable_set(k, new_value)
  }

  obj.datastore    = self.datastore.copy
  obj.user_input   = self.user_input
  obj.user_output  = self.user_output
  obj.module_store = self.module_store.clone

  obj.perform_extensions
  obj
end

#required_cred_optionsObject



340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
# File 'lib/msf/core/module.rb', line 340

def required_cred_options
  @required_cred_options ||= lambda {
    self.options.select { |name, opt|
      (
        opt.type?('string') &&
        opt.required &&
        (opt.name.match(/user(name)*$/i) || name.match(/pass(word)*$/i))
      ) ||
      (
        opt.type?('bool') &&
        opt.required &&
        opt.name.match(/^allow_guest$/i)
      )
    }
  }.call
end

#set_defaultsObject (protected)

Sets the modules unsupplied info fields to their default values.



442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
# File 'lib/msf/core/module.rb', line 442

def set_defaults
  self.module_info = {
    'Name'        => 'No module name',
    'Description' => 'No module description',
    'Version'     => '0',
    'Author'      => nil,
    'Arch'        => nil, # No architectures by default.
    'Platform'    => [],  # No platforms by default.
    'Ref'         => nil,
    'Privileged'  => false,
    'License'     => MSF_LICENSE,
    'Notes'       => {}
  }.update(self.module_info)
  self.module_store = {}
end

#stage_refnameString?

Returns Reference name of the payload stage.

Returns:

  • (String, nil)

    Reference name of the payload stage



234
235
236
# File 'lib/msf/core/module.rb', line 234

def stage_refname
  self.class.stage_refname
end

#stager_refnameString?

Returns Reference name of the payloads stager.

Returns:

  • (String, nil)

    Reference name of the payloads stager



239
240
241
# File 'lib/msf/core/module.rb', line 239

def stager_refname
  self.class.stager_refname
end

#workspaceObject

Returns the current workspace



246
247
248
249
# File 'lib/msf/core/module.rb', line 246

def workspace
  self.datastore['WORKSPACE'] ||
    (framework.db and framework.db.active and framework.db.workspace and framework.db.workspace.name)
end