Module: Msf::Module::Alert

Included in:
Msf::Module
Defined in:
lib/msf/core/module/alert.rb

Defined Under Namespace

Modules: ClassMethods

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#alertsObject (protected)

Returns the value of attribute alerts.



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

def alerts
  @alerts
end

#you_have_been_warnedObject (protected)

Returns the value of attribute you_have_been_warned.



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

def you_have_been_warned
  @you_have_been_warned
end

Class Method Details

.included(base) ⇒ Object



124
125
126
# File 'lib/msf/core/module/alert.rb', line 124

def self.included(base)
  base.extend(ClassMethods)
end

Instance Method Details

#add_alert(level, msg, &block) ⇒ Object (protected)

Add an alert for _this instance_ of a module (see Msf::Module::Alert::ClassMethods#add_alert)



228
229
230
231
232
233
234
235
236
237
238
# File 'lib/msf/core/module/alert.rb', line 228

def add_alert(level, msg, &block)
  self.alerts ||= {}
  self.alerts[level] ||= []
  if block
    self.alerts[level] << block
    true
  elsif msg
    self.alerts[level] << msg
    true
  end
end

#add_error(msg = nil, &block) ⇒ true?

Add a error that will be provided to the user as early possible when using this instance of a module, either when they select it with the `use` command, when the module is about to start running, or when the module generates its output. Adding an error will cause #is_usable to return `false`.

Parameters:

  • msg (String) (defaults to: nil)

    an optional error message

  • block (Proc)

    an optional block that will be executed in the context of the module instance at alert time to generate the error message. If provided the msg parameter is ignored.

Returns:

  • (true, nil)

    whether or not the message was added to the list of errors



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

def add_error(msg = nil, &block)
  add_alert(:error, msg, &block)
end

#add_info(msg = nil, &block) ⇒ true?

Add an info message that will be provided to the user as early possible when using this instance of a module, either when they select it with the `use` command, when the module is about to start running, or when the module generates its output.

Parameters:

  • msg (String) (defaults to: nil)

    an optional info message

  • block (Proc)

    an optional block that will be executed in the context of the module instance at alert time to generate the message. If provided the msg parameter is ignored.

Returns:

  • (true, nil)

    whether or not the message was added to the list of info messages



170
171
172
# File 'lib/msf/core/module/alert.rb', line 170

def add_info(msg = nil, &block)
  add_alert(:info, msg, &block)
end

#add_warning(msg = nil, &block) ⇒ true?

Add a warning that will be provided to the user as early possible when using this instance of a module, either when they select it with the `use` command, when the module is about to start running, or when the module generates its output.

Parameters:

  • msg (String) (defaults to: nil)

    an optional warning message

  • block (Proc)

    an optional block that will be executed in the context of the module instance at alert time to generate the warning message. If provided the msg parameter is ignored.

Returns:

  • (true, nil)

    whether or not the message was added to the list of warnings



139
140
141
# File 'lib/msf/core/module/alert.rb', line 139

def add_warning(msg = nil, &block)
  add_alert(:warning, msg, &block)
end

#alert_userObject (protected)

Display alerts with `print_warning` for warnings and `print_error` for errors. Alerts that have already been displayed by this module instance with this method will not be displayed again.



243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
# File 'lib/msf/core/module/alert.rb', line 243

def alert_user
  self.you_have_been_warned ||= {}
  errors.each do |msg|
    if msg && !self.you_have_been_warned[msg.hash]
      without_prompt { print_error(msg, prefix: '') }
      self.you_have_been_warned[msg.hash] = true
    end
  end

  warnings.each do |msg|
    if msg && !self.you_have_been_warned[msg.hash]
      without_prompt { print_warning(msg, prefix: '') }
      self.you_have_been_warned[msg.hash] = true
    end
  end

  infos.each do |msg|
    if msg && !self.you_have_been_warned[msg.hash]
      # Make prefix an empty string to avoid adding clutter (timestamps, rhost, rport, etc.) to the output
      without_prompt { print_status(msg, prefix: '') }
      self.you_have_been_warned[msg.hash] = true
    end
  end
end

#errorsArray<String>

Returns a list of error strings to show the user.

Returns:

  • (Array<String>)

    a list of error strings to show the user



195
196
197
# File 'lib/msf/core/module/alert.rb', line 195

def errors
  get_alerts(:error)
end

#get_alerts(level) ⇒ Array<String>

Similar to Msf::Module::Alert::ClassMethods#get_alerts, but executes each registered block in the context of this module instance and returns a flattened list of strings. (see Msf::Module::Alert::ClassMethods#get_alerts)

Parameters:

  • level (Symbol)

    The alert level to return

Returns:

  • (Array<String>)


209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/msf/core/module/alert.rb', line 209

def get_alerts(level)
  self.alerts ||= {}
  self.alerts[level] ||= []
  all_alerts = self.class.get_alerts(level) + self.alerts[level]
  all_alerts.map do |alert|
    case alert
    when Proc
      self.instance_exec &alert
    else
      alert
    end
  end.flatten.compact
end

#infosArray<String>

Returns a list of info strings to show the user.

Returns:

  • (Array<String>)

    a list of info strings to show the user



200
201
202
# File 'lib/msf/core/module/alert.rb', line 200

def infos
  get_alerts(:info)
end

#is_usable?true, false

This method allows modules to tell the framework if they are usable on the system that they are being loaded on in a generic fashion. By default, all modules are indicated as being usable. An example of where this is useful is if the module depends on something external to ruby, such as a binary.

This looks to have been abandoned at some point in the past, but it may be time to resurrect it.

Returns:

  • (true, false)

    whether or not the module has encountered any fatal errors thus far.



185
186
187
# File 'lib/msf/core/module/alert.rb', line 185

def is_usable?
  errors.empty?
end

#warningsArray<String>

Returns a list of warning strings to show the user.

Returns:

  • (Array<String>)

    a list of warning strings to show the user



190
191
192
# File 'lib/msf/core/module/alert.rb', line 190

def warnings
  get_alerts(:warning)
end

#without_prompt(&block) ⇒ Object (protected)

Temporarily set the prompt mode to false to ensure that there are not additional lines printed A workaround for the prompting bug spotted in github.com/rapid7/metasploit-framework/pull/18761#issuecomment-1916645095



270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
# File 'lib/msf/core/module/alert.rb', line 270

def without_prompt(&block)
  # Some user outputs cannot have their prompting value configured, i.e. WebConsolePipe
  return yield unless user_output.respond_to?(:prompting)

  begin
    if user_output
      previous_prompting_value = user_output.prompting?
      user_output.prompting(false)
    end

    yield
  ensure
    user_output.prompting(previous_prompting_value) if user_output
  end
end