2012-06-29 00:18:28 -05:00
|
|
|
# -*- coding: binary -*-
|
2005-07-15 22:30:04 +00:00
|
|
|
|
2005-07-14 06:34:58 +00:00
|
|
|
module Msf
|
|
|
|
|
module Simple
|
|
|
|
|
|
|
|
|
|
###
|
|
|
|
|
#
|
|
|
|
|
# A simplified exploit wrapper.
|
|
|
|
|
#
|
|
|
|
|
###
|
2005-07-14 07:32:11 +00:00
|
|
|
module Exploit
|
2005-07-15 22:30:04 +00:00
|
|
|
|
|
|
|
|
include Module
|
2013-08-30 16:28:33 -05:00
|
|
|
|
2005-07-15 22:30:04 +00:00
|
|
|
#
|
2005-11-15 15:29:56 +00:00
|
|
|
# Wraps the exploitation process in a simple single method. The options
|
|
|
|
|
# hash can have the following values passed in it:
|
|
|
|
|
#
|
|
|
|
|
# Encoder
|
|
|
|
|
#
|
|
|
|
|
# The encoder module that should be used.
|
|
|
|
|
#
|
|
|
|
|
# Payload
|
|
|
|
|
#
|
|
|
|
|
# The payload module name that should be used.
|
|
|
|
|
#
|
|
|
|
|
# Target
|
|
|
|
|
#
|
|
|
|
|
# The selected target index.
|
|
|
|
|
#
|
|
|
|
|
# Nop
|
|
|
|
|
#
|
|
|
|
|
# The NOP generator that should be used in preference.
|
|
|
|
|
#
|
|
|
|
|
# OptionStr
|
|
|
|
|
#
|
|
|
|
|
# A string of comma separated option values that should be imported into
|
|
|
|
|
# the datastore.
|
|
|
|
|
#
|
2007-02-24 21:42:13 +00:00
|
|
|
# Options
|
2006-02-11 16:01:23 +00:00
|
|
|
#
|
|
|
|
|
# A hash of values to be imported directly into the datastore.
|
|
|
|
|
#
|
2005-11-15 15:29:56 +00:00
|
|
|
# LocalInput
|
|
|
|
|
#
|
|
|
|
|
# The local input handle that data can be read in from.
|
|
|
|
|
#
|
|
|
|
|
# LocalOutput
|
|
|
|
|
#
|
|
|
|
|
# The local output through which data can be displayed.
|
|
|
|
|
#
|
|
|
|
|
# RunAsJob
|
|
|
|
|
#
|
|
|
|
|
# Whether or not the exploit should be run in the context of a background
|
|
|
|
|
# job.
|
2005-07-15 22:30:04 +00:00
|
|
|
#
|
2012-06-14 16:21:06 -05:00
|
|
|
def self.exploit_simple(oexploit, opts, &block)
|
2016-05-31 11:46:05 -05:00
|
|
|
exploit = oexploit.replicant
|
2008-01-28 03:06:31 +00:00
|
|
|
# Trap and print errors here (makes them UI-independent)
|
|
|
|
|
begin
|
2012-02-29 01:34:29 -06:00
|
|
|
# Clone the module to prevent changes to the original instance
|
2016-05-31 11:46:05 -05:00
|
|
|
|
2021-08-19 13:04:26 +01:00
|
|
|
Msf::Simple::Framework.simplify_module(exploit)
|
2012-06-14 16:21:06 -05:00
|
|
|
yield(exploit) if block_given?
|
2013-08-30 16:28:33 -05:00
|
|
|
|
2008-01-28 03:06:31 +00:00
|
|
|
# Import options from the OptionStr or Option hash.
|
|
|
|
|
exploit._import_extra_options(opts)
|
2020-12-01 15:22:48 -05:00
|
|
|
opts['Payload'] ||= exploit.datastore['Payload']
|
2013-08-30 16:28:33 -05:00
|
|
|
|
2020-12-01 16:36:39 -05:00
|
|
|
unless opts['Quiet']
|
|
|
|
|
exploit.init_ui(opts['LocalInput'] || exploit.user_input, opts['LocalOutput'] || exploit.user_output)
|
|
|
|
|
else
|
|
|
|
|
exploit.init_ui(nil, nil)
|
|
|
|
|
end
|
|
|
|
|
|
2008-01-28 03:06:31 +00:00
|
|
|
# Make sure parameters are valid.
|
|
|
|
|
if (opts['Payload'] == nil)
|
2020-05-05 19:20:34 +01:00
|
|
|
raise MissingPayloadError, 'A payload has not been selected.', caller
|
2008-01-28 03:06:31 +00:00
|
|
|
end
|
2013-08-30 16:28:33 -05:00
|
|
|
|
2012-03-12 22:57:23 -05:00
|
|
|
# Verify the options
|
|
|
|
|
exploit.options.validate(exploit.datastore)
|
2013-08-30 16:28:33 -05:00
|
|
|
|
2008-01-28 03:06:31 +00:00
|
|
|
# Start it up
|
2024-01-16 22:35:15 +00:00
|
|
|
driver = Msf::ExploitDriver.new(exploit.framework)
|
2013-08-30 16:28:33 -05:00
|
|
|
|
2020-12-01 15:22:48 -05:00
|
|
|
# Keep the handler of driver running if exploiting multiple targets.
|
|
|
|
|
driver.keep_handler = true if opts['multi']
|
2018-09-25 11:28:59 +08:00
|
|
|
|
2008-01-28 03:06:31 +00:00
|
|
|
# Initialize the driver instance
|
|
|
|
|
driver.exploit = exploit
|
2012-12-05 12:30:55 -06:00
|
|
|
driver.payload = exploit.framework.payloads.create(opts['Payload'])
|
2013-08-30 16:28:33 -05:00
|
|
|
|
2008-01-28 03:06:31 +00:00
|
|
|
# Set the force wait for session flag if the caller requested force
|
|
|
|
|
# blocking. This is so that passive exploits can be blocked on from
|
|
|
|
|
# things like the cli.
|
|
|
|
|
driver.force_wait_for_session = true if (opts['ForceBlocking'] == true)
|
2013-08-30 16:28:33 -05:00
|
|
|
|
2008-01-28 03:06:31 +00:00
|
|
|
# Was the payload valid?
|
|
|
|
|
if (driver.payload == nil)
|
|
|
|
|
raise MissingPayloadError,
|
|
|
|
|
"You specified an invalid payload: #{opts['Payload']}", caller
|
|
|
|
|
end
|
2013-08-30 16:28:33 -05:00
|
|
|
|
2008-01-28 03:06:31 +00:00
|
|
|
# Use the supplied encoder, if any. If one was not specified, then
|
|
|
|
|
# nil will be assigned causing the exploit to default to picking the
|
|
|
|
|
# best encoder.
|
|
|
|
|
exploit.datastore['ENCODER'] = opts['Encoder'] if opts['Encoder']
|
2013-08-30 16:28:33 -05:00
|
|
|
|
2018-04-20 18:21:58 -05:00
|
|
|
# Use the supplied NOP generator, if any. If one was not specified, then
|
|
|
|
|
# nil will be assigned causing the exploit to default to picking a
|
|
|
|
|
# compatible NOP generator.
|
|
|
|
|
exploit.datastore['NOP'] = opts['Nop'] if opts['Nop']
|
|
|
|
|
|
2008-01-28 03:06:31 +00:00
|
|
|
# Force the payload to share the exploit's datastore
|
|
|
|
|
driver.payload.share_datastore(driver.exploit.datastore)
|
2013-08-30 16:28:33 -05:00
|
|
|
|
2012-03-12 22:57:23 -05:00
|
|
|
# Verify the payload options
|
|
|
|
|
driver.payload.options.validate(driver.payload.datastore)
|
2013-08-30 16:28:33 -05:00
|
|
|
|
2018-05-16 10:19:03 -05:00
|
|
|
# Set the target and then work some magic to derive index
|
|
|
|
|
exploit.datastore['TARGET'] = opts['Target'] if opts['Target']
|
|
|
|
|
target_idx = exploit.target_index
|
2013-08-30 16:28:33 -05:00
|
|
|
|
2008-01-28 03:06:31 +00:00
|
|
|
if (target_idx == nil or target_idx < 0)
|
|
|
|
|
raise MissingTargetError,
|
|
|
|
|
"You must select a target.", caller
|
|
|
|
|
end
|
2013-08-30 16:28:33 -05:00
|
|
|
|
2009-11-16 15:08:58 +00:00
|
|
|
driver.target_idx = target_idx
|
2013-08-30 16:28:33 -05:00
|
|
|
|
2008-01-28 03:06:31 +00:00
|
|
|
# Set the payload and exploit's subscriber values
|
2020-12-01 16:36:39 -05:00
|
|
|
unless opts['Quiet']
|
2010-03-08 04:47:40 +00:00
|
|
|
driver.payload.init_ui(opts['LocalInput'] || exploit.user_input, opts['LocalOutput'] || exploit.user_output)
|
|
|
|
|
else
|
|
|
|
|
driver.payload.init_ui(nil, nil)
|
|
|
|
|
end
|
2013-08-30 16:28:33 -05:00
|
|
|
|
2008-01-28 03:06:31 +00:00
|
|
|
if (opts['RunAsJob'])
|
|
|
|
|
driver.use_job = true
|
|
|
|
|
end
|
2013-08-30 16:28:33 -05:00
|
|
|
|
2008-01-28 03:06:31 +00:00
|
|
|
# Let's rock this party
|
2010-07-15 21:28:21 +00:00
|
|
|
driver.run
|
2013-08-30 16:28:33 -05:00
|
|
|
|
2008-01-28 03:06:31 +00:00
|
|
|
# Save the job identifier this exploit is running as
|
2012-03-08 16:01:32 -06:00
|
|
|
exploit.job_id = driver.job_id
|
2013-08-30 16:28:33 -05:00
|
|
|
|
2012-03-08 16:01:32 -06:00
|
|
|
# Propagate this back to the caller for console mgmt
|
2013-03-06 14:52:32 -06:00
|
|
|
oexploit.job_id = exploit.job_id
|
2008-01-28 03:06:31 +00:00
|
|
|
rescue ::Interrupt
|
2010-03-26 01:18:10 +00:00
|
|
|
exploit.error = $!
|
2008-01-28 03:06:31 +00:00
|
|
|
raise $!
|
2021-06-03 11:43:09 +01:00
|
|
|
rescue ::Msf::OptionValidateError => e
|
|
|
|
|
exploit.error = e
|
2023-05-22 12:19:35 +01:00
|
|
|
::Msf::Ui::Formatter::OptionValidateError.print_error(exploit, e)
|
|
|
|
|
return false
|
2008-01-28 03:06:31 +00:00
|
|
|
rescue ::Exception => e
|
2010-03-26 01:18:10 +00:00
|
|
|
exploit.error = e
|
2008-01-28 03:06:31 +00:00
|
|
|
exploit.print_error("Exploit failed: #{e}")
|
2020-06-11 13:09:25 +01:00
|
|
|
elog("Exploit failed (#{exploit.refname})", error: e)
|
2009-11-16 15:08:58 +00:00
|
|
|
end
|
2013-08-30 16:28:33 -05:00
|
|
|
|
2010-07-21 15:14:54 +00:00
|
|
|
return driver.session if driver
|
2010-07-21 00:50:25 +00:00
|
|
|
nil
|
2005-07-15 22:30:04 +00:00
|
|
|
end
|
2013-08-30 16:28:33 -05:00
|
|
|
|
2005-07-15 22:30:04 +00:00
|
|
|
#
|
2005-11-15 15:11:43 +00:00
|
|
|
# Calls the class method.
|
2005-07-15 22:30:04 +00:00
|
|
|
#
|
2012-06-15 14:25:47 -05:00
|
|
|
def exploit_simple(opts, &block)
|
|
|
|
|
Msf::Simple::Exploit.exploit_simple(self, opts, &block)
|
2005-07-15 22:30:04 +00:00
|
|
|
end
|
2013-08-30 16:28:33 -05:00
|
|
|
|
2023-11-14 19:28:33 +00:00
|
|
|
alias run_simple exploit_simple
|
2007-03-17 19:39:30 +00:00
|
|
|
#
|
|
|
|
|
# Initiates a check, setting up the exploit to be used. The following
|
|
|
|
|
# options can be specified:
|
|
|
|
|
#
|
|
|
|
|
# LocalInput
|
|
|
|
|
#
|
|
|
|
|
# The local input handle that data can be read in from.
|
|
|
|
|
#
|
|
|
|
|
# LocalOutput
|
|
|
|
|
#
|
|
|
|
|
# The local output through which data can be displayed.
|
|
|
|
|
#
|
2020-03-13 10:28:11 +00:00
|
|
|
def self.check_simple(mod, opts, job_listener: Msf::Simple::NoopJobListener.instance)
|
2021-08-19 13:04:26 +01:00
|
|
|
Msf::Simple::Framework.simplify_module(mod)
|
2019-10-29 12:45:09 -05:00
|
|
|
mod._import_extra_options(opts)
|
|
|
|
|
|
2007-03-17 19:39:30 +00:00
|
|
|
if opts['LocalInput']
|
|
|
|
|
mod.init_ui(opts['LocalInput'], opts['LocalOutput'])
|
|
|
|
|
end
|
2013-08-30 16:28:33 -05:00
|
|
|
|
2020-07-20 14:04:38 -05:00
|
|
|
unless mod.has_check?
|
|
|
|
|
# Bail out early if the module doesn't have check
|
2022-03-23 13:05:42 +00:00
|
|
|
raise ::NotImplementedError.new(Msf::Exploit::CheckCode::Unsupported.message)
|
2020-07-20 14:04:38 -05:00
|
|
|
end
|
2020-07-20 11:09:46 -05:00
|
|
|
|
2007-03-17 19:39:30 +00:00
|
|
|
# Validate the option container state so that options will
|
|
|
|
|
# be normalized
|
|
|
|
|
mod.validate
|
2013-08-30 16:28:33 -05:00
|
|
|
|
2019-10-29 12:45:09 -05:00
|
|
|
run_uuid = Rex::Text.rand_text_alphanumeric(24)
|
2020-03-11 17:06:37 +00:00
|
|
|
job_listener.waiting run_uuid
|
|
|
|
|
ctx = [mod, run_uuid, job_listener]
|
2019-10-29 12:45:09 -05:00
|
|
|
|
|
|
|
|
if opts['RunAsJob']
|
|
|
|
|
mod.job_id = mod.framework.jobs.start_bg_job(
|
2020-03-24 09:56:30 -05:00
|
|
|
"Exploit: #{mod.refname} check",
|
2019-10-29 12:45:09 -05:00
|
|
|
ctx,
|
|
|
|
|
Proc.new { |ctx_| self.job_check_proc(ctx_) },
|
|
|
|
|
Proc.new { |ctx_| nil }
|
|
|
|
|
)
|
|
|
|
|
[run_uuid, mod.job_id]
|
|
|
|
|
else
|
|
|
|
|
self.job_check_proc(ctx)
|
|
|
|
|
end
|
2007-03-17 19:39:30 +00:00
|
|
|
end
|
2013-08-30 16:28:33 -05:00
|
|
|
|
2007-03-17 19:39:30 +00:00
|
|
|
#
|
|
|
|
|
# Calls the class method.
|
|
|
|
|
#
|
|
|
|
|
def check_simple(opts)
|
2009-11-16 15:08:58 +00:00
|
|
|
Msf::Simple::Exploit.check_simple(self, opts)
|
2007-03-17 19:39:30 +00:00
|
|
|
end
|
|
|
|
|
|
2019-10-29 12:45:09 -05:00
|
|
|
protected
|
|
|
|
|
|
|
|
|
|
def self.job_check_proc(ctx)
|
|
|
|
|
mod = ctx[0]
|
|
|
|
|
run_uuid = ctx[1]
|
2020-03-11 17:06:37 +00:00
|
|
|
job_listener = ctx[2]
|
2019-10-29 12:45:09 -05:00
|
|
|
begin
|
2020-03-11 17:06:37 +00:00
|
|
|
job_listener.start run_uuid
|
2020-03-02 18:58:50 +00:00
|
|
|
mod.setup
|
2020-07-20 11:09:46 -05:00
|
|
|
result = mod.check
|
2020-03-11 17:06:37 +00:00
|
|
|
job_listener.completed(run_uuid, result, mod)
|
2019-10-29 12:45:09 -05:00
|
|
|
rescue => e
|
2020-03-11 17:06:37 +00:00
|
|
|
job_listener.failed(run_uuid, e, mod)
|
2019-10-29 12:45:09 -05:00
|
|
|
mod.handle_exception e
|
2021-06-21 11:51:00 +01:00
|
|
|
ensure
|
|
|
|
|
mod.cleanup
|
2019-10-29 12:45:09 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
end
|
2005-07-14 06:34:58 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
end
|
2009-10-25 16:40:19 +00:00
|
|
|
end
|