Class: Msf::Ui::Console::CommandDispatcher::Exploit

Inherits:
Object
  • Object
show all
Includes:
ModuleArgumentParsing, ModuleCommandDispatcher, ModuleOptionTabCompletion
Defined in:
lib/msf/ui/console/command_dispatcher/exploit.rb

Overview

Exploit module command dispatcher.

Instance Attribute Summary

Attributes included from Msf::Ui::Console::CommandDispatcher

#driver

Attributes included from Rex::Ui::Text::DispatcherShell::CommandDispatcher

#shell, #tab_complete_items

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ModuleOptionTabCompletion

#option_values_actions, #option_values_dispatch, #option_values_encoders, #option_values_nops, #option_values_payloads, #option_values_sessions, #option_values_target_addrs, #option_values_target_ports, #option_values_targets, #tab_complete_datastore_names, #tab_complete_module_datastore_names, #tab_complete_option, #tab_complete_option_names, #tab_complete_option_values, #tab_complete_source_interface

Methods included from ModuleArgumentParsing

#append_datastore_option, #parse_check_opts, #parse_exploit_opts, #parse_opts, #parse_run_opts, #print_module_run_or_check_usage, #quote_whitespaced_value, #resembles_datastore_assignment?, #resembles_rhost_value?

Methods included from ModuleCommandDispatcher

#check_multiple, #check_progress, #check_show_progress, #check_simple, #cmd_check, #cmd_check_help, #cmd_reload, #cmd_reload_help, #mod, #mod=, #reload, #report_vuln

Methods included from Msf::Ui::Console::CommandDispatcher

#active_module, #active_module=, #active_session, #active_session=, #build_range_array, #docs_dir, #framework, #initialize, #load_config, #log_error, #remove_lines

Methods included from Rex::Ui::Text::DispatcherShell::CommandDispatcher

#cmd_help, #cmd_help_help, #cmd_help_tabs, #deprecated_cmd, #deprecated_commands, #deprecated_help, #docs_dir, #help_to_s, included, #initialize, #print, #print_error, #print_good, #print_line, #print_status, #print_warning, #tab_complete_directory, #tab_complete_filenames, #tab_complete_generic, #tab_complete_source_address, #unknown_command, #update_prompt

Class Method Details

.choose_payload(mod) ⇒ Object

Select a reasonable default payload and minimally configure it

Parameters:



291
292
293
# File 'lib/msf/ui/console/command_dispatcher/exploit.rb', line 291

def self.choose_payload(mod)
  Msf::Payload.choose_payload(mod)
end

Instance Method Details

#cmd_exploit(*args, opts: {}) ⇒ Object Also known as: cmd_run

Launches exploitation attempts.



94
95
96
97
98
99
100
101
102
103
104
105
106
107
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'lib/msf/ui/console/command_dispatcher/exploit.rb', line 94

def cmd_exploit(*args, opts: {})
  if (args.include?('-r') || args.include?('--reload-libs')) && !opts[:previously_reloaded]
    driver.run_single('reload_lib -a')
  end

  return false unless (args = parse_exploit_opts(args))

  any_session = false
  force = args[:force] || false

  minrank = RankingName.invert[framework.datastore['MinimumRank']] || 0
  if minrank > mod.rank
    if force
      print_status("Forcing #{mod.refname} to run despite MinimumRank '#{framework.datastore['MinimumRank']}'")
      ilog("Forcing #{mod.refname} to run despite MinimumRank '#{framework.datastore['MinimumRank']}'", 'core')
    else
      print_error("This exploit is below the minimum rank, '#{framework.datastore['MinimumRank']}'.")
      print_error("If you really want to run it, do 'exploit -f' or")
      print_error("setg MinimumRank to something lower ('manual' is")
      print_error("the lowest and would allow running all exploits).")
      return
    end
  end

  mod_with_opts = mod.replicant
  mod_with_opts.datastore.import_options_from_hash(args[:datastore_options])
  rhosts = mod_with_opts.datastore['RHOSTS']
  has_rhosts_option = mod.options.include?('RHOSTS') ||
    mod.options.include?('RHOST') ||
    mod.options.include?('rhost') ||
    mod.options.include?('rhosts')

  opts = {
    'Encoder'     => args[:encoder] || mod_with_opts.datastore['ENCODER'],
    'Payload'     => args[:payload] || mod_with_opts.datastore['PAYLOAD'],
    'Target'      => args[:target] || mod_with_opts.datastore['TARGET'],
    'Nop'         => args[:nop] || mod_with_opts.datastore['NOP'],
    'LocalInput'  => driver.input,
    'LocalOutput' => driver.output,
    'RunAsJob'    => args[:jobify] || mod_with_opts.passive?,
    'Background'  => args[:background] || false,
    'Force'       => force,
    'Quiet'       => args[:quiet] || false
  }

  begin
    mod_with_opts.validate
  rescue ::Msf::OptionValidateError => e
    ::Msf::Ui::Formatter::OptionValidateError.print_error(mod_with_opts, e)
    return false
  end

  driver.run_single('reload_lib -a') if args[:reload_libs]

  if rhosts && has_rhosts_option
    rhosts_walker = Msf::RhostsWalker.new(rhosts, mod_with_opts.datastore)
    rhosts_walker_count = rhosts_walker.count
    rhosts_walker = rhosts_walker.to_enum
  end

  # For multiple targets exploit attempts.
  if rhosts_walker && rhosts_walker_count > 1
    opts[:multi] = true
    rhosts_walker.with_index do |datastore, index|
      nmod = mod_with_opts.replicant
      nmod.datastore.merge!(datastore)
      # If rhost is the last target, let exploit handler stop.
      is_last_target = (index + 1) == rhosts_walker_count
      opts["multi"] = false if is_last_target
      # Catch the interrupt exception to stop the whole module during exploit
      begin
        print_status("Exploiting target #{datastore['RHOSTS']}")
        session = exploit_single(nmod, opts)
      rescue ::Interrupt
        print_status("Stopping exploiting current target #{datastore['RHOSTS']}...")
        print_status("Control-C again to force quit exploiting all targets.")
        begin
          Rex.sleep(1)
        rescue ::Interrupt
          raise $!
        end
      end
      # If we were given a session, report it.
      if session
        print_status("Session #{session.sid} created in the background.")
        any_session = true
      end
    end
  # For single target or no rhosts option.
  else
    nmod = mod_with_opts.replicant
    if rhosts_walker && rhosts_walker_count == 1
      nmod.datastore.merge!(rhosts_walker.next)
    end
    session = exploit_single(nmod, opts)
    # If we were given a session, let's see what we can do with it
    if session
      any_session = true
      if !opts['Background'] && session.interactive?
        # If we aren't told to run in the background and the session can be
        # interacted with, start interacting with it by issuing the session
        # interaction command.
        print_line

        driver.run_single("sessions -q -i #{session.sid}")
      # Otherwise, log that we created a session
      else
        # Otherwise, log that we created a session
        print_status("Session #{session.sid} created in the background.")
      end

    elsif opts['RunAsJob'] && nmod.job_id
      # Indicate if he exploit as a job, indicate such so the user doesn't
      # wonder what's up.
      print_status("Exploit running as background job #{nmod.job_id}.")
      # Worst case, the exploit ran but we got no session, bummer.
    end
  end

  # If we didn't get any session and exploit ended launch.
  unless any_session
  # If we didn't run a payload handler for this exploit it doesn't
  # make sense to complain to the user that we didn't get a session
    unless mod_with_opts.datastore["DisablePayloadHandler"]
      fail_msg = 'Exploit completed, but no session was created.'
      print_status(fail_msg)
      begin
        framework.events.on_session_fail(fail_msg)
      rescue ::Exception => e
        wlog("Exception in on_session_open event handler: #{e.class}: #{e}")
        wlog("Call Stack\n#{e.backtrace.join("\n")}")
      end
    end
  end
end

#cmd_exploit_helpObject Also known as: cmd_run_help



232
233
234
# File 'lib/msf/ui/console/command_dispatcher/exploit.rb', line 232

def cmd_exploit_help
  print_module_run_or_check_usage(command: :run, options: @@exploit_opts)
end

#cmd_rcheck(*args) ⇒ Object Also known as: cmd_recheck

Reloads an exploit module and checks the target to see if it's vulnerable.



242
243
244
245
246
247
248
249
250
251
252
# File 'lib/msf/ui/console/command_dispatcher/exploit.rb', line 242

def cmd_rcheck(*args)
  opts = {}
  if args.include?('-r') || args.include?('--reload-libs')
    driver.run_single('reload_lib -a')
    opts[:previously_reloaded] = true
  end

  reload()

  cmd_check(*args, opts: opts)
end

#cmd_rexploit(*args) ⇒ Object Also known as: cmd_rerun

Reloads an exploit module and launches an exploit.



259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
# File 'lib/msf/ui/console/command_dispatcher/exploit.rb', line 259

def cmd_rexploit(*args)
  opts = {}
  if args.include?('-r') || args.include?('--reload-libs')
    driver.run_single('reload_lib -a')
    opts[:previously_reloaded] = true
  end

  return cmd_rexploit_help if args.include?('-h') || args.include?('--help')

  # Stop existing job and reload the module
  if reload(true)
    # Delegate to the exploit command unless the reload failed
    cmd_exploit(*args, opts: opts)
  end
end

#cmd_rexploit_helpObject Also known as: cmd_rerun_help



279
280
281
282
283
284
285
# File 'lib/msf/ui/console/command_dispatcher/exploit.rb', line 279

def cmd_rexploit_help
  print_module_run_or_check_usage(
    command: :rexploit,
    description: 'Reloads a module, stopping any associated job, and launches an exploitation attempt.',
    options: @@exploit_opts
  )
end

#cmd_run_tabs(str, words) ⇒ Object Also known as: cmd_exploit_tabs, cmd_rerun_tabs

Tab completion for the run command



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/msf/ui/console/command_dispatcher/exploit.rb', line 67

def cmd_run_tabs(str, words)
  fmt = {
      '-e' => [ framework.encoders.module_refnames                ],
      '-f' => [ nil                                               ],
      '-h' => [ nil                                               ],
      '-j' => [ nil                                               ],
      '-J' => [ nil                                               ],
      '-n' => [ framework.nops.module_refnames                    ],
      '-o' => [ true                                              ],
      '-p' => [ framework.payloads.module_refnames                ],
      '-r' => [ nil                                               ],
      '-t' => [ true                                              ],
      '-z' => [ nil                                               ]
  }
  flags = tab_complete_generic(fmt, str, words)
  options = tab_complete_option(active_module, str, words)
  flags + options
end

#commandsObject

Returns the hash of exploit module specific commands.



21
22
23
24
25
26
27
28
29
30
31
# File 'lib/msf/ui/console/command_dispatcher/exploit.rb', line 21

def commands
  super.update({
    "exploit"  => "Launch an exploit attempt",
    "rcheck"   => "Reloads the module and checks if the target is vulnerable",
    "rexploit" => "Reloads the module and launches an exploit attempt",
    "run"      => "Alias for exploit",
    "recheck"  => "Alias for rcheck",
    "rerun"    => "Alias for rexploit",
    "reload"   => "Just reloads the module"
  })
end

#exploit_single(mod, opts) ⇒ Object

Launches an exploitation single attempt.



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/msf/ui/console/command_dispatcher/exploit.rb', line 43

def exploit_single(mod, opts)
  begin
    session = mod.exploit_simple(opts)
  rescue ::Interrupt
    raise $!
  rescue ::Msf::OptionValidateError => e
   ::Msf::Ui::Formatter::OptionValidateError.print_error(mod, e)
  rescue ::Exception => e
    print_error("Exploit exception (#{mod.refname}): #{e.class} #{e}")
    if e.class.to_s != 'Msf::OptionValidateError'
      print_error("Call stack:")
      e.backtrace.each do |line|
        break if line =~ /lib.msf.base.simple/
        print_error("  #{line}")
      end
    end
  end

  return session
end

#nameObject

Returns the name of the command dispatcher.



36
37
38
# File 'lib/msf/ui/console/command_dispatcher/exploit.rb', line 36

def name
  "Exploit"
end