2005-07-13 18:06:12 +00:00
|
|
|
require 'msf/core'
|
|
|
|
|
|
|
|
module Msf
|
|
|
|
|
|
|
|
###
|
|
|
|
#
|
|
|
|
# ExploitDriver
|
|
|
|
# -------------
|
|
|
|
#
|
|
|
|
# This class drives the exploitation process from start to finish for a given
|
|
|
|
# exploit module instance. It's responsible for payload generation, encoding,
|
|
|
|
# and padding as well as initialization handlers and finally launching the
|
|
|
|
# exploit.
|
|
|
|
#
|
|
|
|
###
|
|
|
|
class ExploitDriver
|
|
|
|
|
|
|
|
def initialize(framework)
|
2005-07-15 22:30:04 +00:00
|
|
|
self.payload = nil
|
|
|
|
self.exploit = nil
|
|
|
|
self.target_idx = nil
|
2005-07-13 18:06:12 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
#
|
|
|
|
# Specification of the exploit target index
|
|
|
|
#
|
|
|
|
def target_idx=(target_idx)
|
2005-07-15 22:30:04 +00:00
|
|
|
if (target_idx)
|
|
|
|
# Make sure the target index is valid
|
|
|
|
if (target_idx >= exploit.targets.length)
|
|
|
|
raise Rex::ArgumentError, "Invalid target index.", caller
|
|
|
|
end
|
2005-07-13 18:06:12 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# Set the active target
|
2005-07-15 22:30:04 +00:00
|
|
|
@target_idx = target_idx
|
2005-07-13 18:06:12 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
#
|
|
|
|
# Checks to see if the supplied payload is compatible with the
|
2005-07-15 22:30:04 +00:00
|
|
|
# current exploit. Assumes that target_idx is valid.
|
2005-07-13 18:06:12 +00:00
|
|
|
#
|
|
|
|
def compatible_payload?(payload)
|
2005-07-15 22:30:04 +00:00
|
|
|
return ((payload.platform & exploit.targets[target_idx].platform).empty? == false)
|
2005-07-13 18:06:12 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
##
|
|
|
|
#
|
|
|
|
# Exploit execution
|
|
|
|
#
|
|
|
|
##
|
|
|
|
|
|
|
|
#
|
|
|
|
# Makes sure everything's in tip-top condition prior to launching the
|
|
|
|
# exploit. For things that aren't good to go, an exception is thrown.
|
|
|
|
#
|
|
|
|
def validate
|
|
|
|
# First, validate that a target has been selected
|
2005-07-15 22:30:04 +00:00
|
|
|
if (target_idx == nil)
|
2005-07-13 18:06:12 +00:00
|
|
|
raise MissingTargetError,
|
|
|
|
"A payload cannot be selected until a target is specified.",
|
|
|
|
caller
|
|
|
|
end
|
|
|
|
|
|
|
|
# Next, validate that a payload has been selected
|
|
|
|
if (payload == nil)
|
|
|
|
raise MissingPayloadError,
|
|
|
|
"A payload has not been selected.", caller
|
|
|
|
end
|
|
|
|
|
2005-07-15 22:30:04 +00:00
|
|
|
# Make sure the payload is compatible after all
|
|
|
|
if (compatible_payload?(payload) == false)
|
|
|
|
raise IncompatiblePayloadError.new(payload.refname),
|
|
|
|
"Incompatible payload", caller
|
|
|
|
end
|
|
|
|
|
2005-07-13 18:06:12 +00:00
|
|
|
# Finally, validate options on the exploit module to ensure that things
|
|
|
|
# are ready to operate as they should.
|
2005-07-15 22:30:04 +00:00
|
|
|
exploit.options.validate(exploit.datastore)
|
2005-07-13 18:06:12 +00:00
|
|
|
|
2005-07-18 02:01:36 +00:00
|
|
|
# Validate the payload's options. The payload's datastore is
|
|
|
|
# most likely shared against the exploit's datastore, but in case it
|
|
|
|
# isn't.
|
|
|
|
payload.options.validate(payload.datastore)
|
|
|
|
|
2005-07-13 18:06:12 +00:00
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
#
|
|
|
|
# Kicks off an exploitation attempt and performs the following four major
|
|
|
|
# operations:
|
|
|
|
#
|
|
|
|
# - Generates the payload
|
|
|
|
# - Initializes & monitors the handler
|
|
|
|
# - Launches the exploit
|
|
|
|
# - Cleans up the handler
|
|
|
|
#
|
|
|
|
def run
|
|
|
|
# First thing's first -- validate the state. Make sure all requirement
|
|
|
|
# parameters are set, including those that are derived from the
|
|
|
|
# datastore.
|
|
|
|
validate()
|
|
|
|
|
|
|
|
# After validation has occurred, it's time to set some values on the
|
|
|
|
# exploit instance and begin preparing the payload
|
2005-07-15 22:30:04 +00:00
|
|
|
exploit.datastore['TARGET'] = @target_idx
|
2005-07-13 18:06:12 +00:00
|
|
|
|
|
|
|
# Generate the encoded version of the supplied payload on the exploit
|
|
|
|
# module instance
|
|
|
|
exploit.generate_payload(payload)
|
|
|
|
|
2005-07-16 07:32:11 +00:00
|
|
|
# Default the session to nil
|
|
|
|
session = nil
|
|
|
|
|
2005-07-15 23:46:05 +00:00
|
|
|
begin
|
|
|
|
# Set the exploit up the bomb
|
|
|
|
exploit.setup
|
|
|
|
|
|
|
|
# Launch the exploit
|
|
|
|
exploit.exploit
|
|
|
|
|
2005-07-16 07:32:11 +00:00
|
|
|
# Wait the payload to acquire a session
|
|
|
|
session = payload.wait_for_session
|
2005-07-15 23:46:05 +00:00
|
|
|
ensure
|
|
|
|
# Ensure that, no matter what, clean up of the handler occurs
|
|
|
|
payload.stop_handler
|
|
|
|
|
|
|
|
# Allow the exploit to cleanup after itself, that messy bugger.
|
|
|
|
exploit.cleanup
|
|
|
|
end
|
2005-07-13 18:06:12 +00:00
|
|
|
|
2005-07-17 06:01:11 +00:00
|
|
|
# Set the vector through which this session was created
|
|
|
|
if (session)
|
|
|
|
session.set_via(
|
|
|
|
'Exploit' => exploit.refname,
|
|
|
|
'Payload' => payload.refname)
|
|
|
|
end
|
|
|
|
|
2005-07-16 07:32:11 +00:00
|
|
|
return session
|
2005-07-13 18:06:12 +00:00
|
|
|
end
|
|
|
|
|
2005-07-15 22:30:04 +00:00
|
|
|
attr_reader :target_idx
|
|
|
|
attr_accessor :exploit
|
|
|
|
attr_accessor :payload
|
2005-07-13 18:06:12 +00:00
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|