Files
metasploit-gs/lib/msf/core/exploit_driver.rb
T
Matt Miller f1691c5470 worked on payload encoding, exploit driver wrapper, platforms updates, spoon would probably hate it
git-svn-id: file:///home/svn/incoming/trunk@2744 4d416f70-5f16-0410-b530-b9f4589650da
2005-07-13 18:06:12 +00:00

186 lines
4.3 KiB
Ruby

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)
self.payloads = {}
self.payload = nil
self.exploit = nil
self.target = nil
end
#
# Stores the supplied exploit as the active exploit and filters compatible
# payloads and architectures based on the exploit's target platform
# information.
#
def exploit=(exploit)
@exploit = exploit
filter_payloads
end
#
# Specification of the exploit target index
#
def target_idx=(target_idx)
# Make sure the target index is valid
if (target_idx >= exploit.targets.length)
raise Rex::ArgumentError, "Invalid target index.", caller
end
# Set the active target
target = exploit.targets[target_idx]
end
#
# Sets the active target instance for the specified exploit module. This
# causes the driver to filter payloads again.
#
def target=(target)
@target = target
filter_payloads
end
#
# Sets the active payload and performs one last sanity check
#
def payload=(payload)
# Don't allow payload selection to occur until a target has been
# specified.
if (target == nil)
raise MissingTargetError,
"A payload cannot be selected until a target is specified.",
caller
end
# Make sure the payload is compatible after all
if (compatible_payload?(payload) == false)
raise IncompatiblePayloadError.new(payload.refname),
"Incompatible payload", caller
end
@payload = payload
end
#
# Checks to see if the supplied payload is compatible with the
# current exploit.
#
def compatible_payload?(payload)
return ((payload.platform & exploit.platform).empty? == false)
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
if (target == nil)
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
# Finally, validate options on the exploit module to ensure that things
# are ready to operate as they should.
exploit.options.validate()
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
exploit.target = target
# Generate the encoded version of the supplied payload on the exploit
# module instance
exploit.generate_payload(payload)
end
attr_reader :exploit
attr_reader :target
attr_reader :payloads
attr_reader :payload
protected
#
# Filters out compatible payloads based on the current
#
def filter_payloads
payloads = {}
# Enumerate each target for this exploit
exploit.targets.each { |curr_target|
# If there's an active target, then skip all other targets
next if (target && target != curr_target)
# Enumerate each payload module, intersecting the supported platforms
# to see if there is any match at all. If so, the payload name is
# added to the list of acceptable payloads.
framework.payloads.each_module(
'Platform' => target.platforms) { |name, pmod|
# If the payload's size is larger than the amount of available space,
# then we can't allow it
if (exploit.payload_space > 0 and
exploit.payload_space < framework.payloads.sizes[name])
dlog("Payload #{name} is too big for exploit #{exploit.refname} (#{exploit.payload_space} < #{framework.payloads.sizes[name]})",
'core', LEV_2)
next
end
payloads[name] = pmod
}
}
end
attr_writer :payloads
end
end