Refactor the rhosts for exploit modules.
parent
5ddbf6fd11
commit
90b98a193c
|
@ -78,6 +78,9 @@ module Exploit
|
|||
# Start it up
|
||||
driver = ExploitDriver.new(exploit.framework)
|
||||
|
||||
# Keep the handler of driver running if exploit multi targets.
|
||||
driver.keep_handler = true if opts["multi"]
|
||||
|
||||
# Initialize the driver instance
|
||||
driver.exploit = exploit
|
||||
driver.payload = exploit.framework.payloads.create(opts['Payload'])
|
||||
|
|
|
@ -1410,6 +1410,12 @@ class Exploit < Msf::Module
|
|||
self.print_error("Exploit failed [#{self.fail_reason}]: #{msg}")
|
||||
elog("Exploit failed (#{self.refname}): #{msg}", 'core', LEV_0)
|
||||
dlog("Call stack:\n#{e.backtrace.join("\n")}", 'core', LEV_3)
|
||||
|
||||
when ::Interrupt
|
||||
self.fail_reason = Msf::Exploit::Failure::UserInterrupt
|
||||
self.print_error("Exploit failed [#{self.fail_reason}]: #{msg}")
|
||||
elog("Exploit failed (#{self.refname}): #{msg}", 'core', LEV_0)
|
||||
dlog("Call stack:\n#{e.backtrace.join("\n")}", 'core', LEV_3)
|
||||
else
|
||||
|
||||
# Compare as a string since not all error classes may be loaded
|
||||
|
@ -1451,6 +1457,8 @@ class Exploit < Msf::Module
|
|||
|
||||
# Interrupt any session waiters in the handler
|
||||
self.interrupt_handler
|
||||
|
||||
return self.fail_reason
|
||||
end
|
||||
|
||||
def report_failure
|
||||
|
|
|
@ -22,6 +22,7 @@ class ExploitDriver
|
|||
self.use_job = false
|
||||
self.job_id = nil
|
||||
self.force_wait_for_session = false
|
||||
self.keep_handler = false
|
||||
self.semaphore = Mutex.new
|
||||
end
|
||||
|
||||
|
@ -164,8 +165,15 @@ class ExploitDriver
|
|||
# settings until after they're done.
|
||||
ctx = [ exploit, payload ]
|
||||
|
||||
job_run_proc(ctx)
|
||||
job_cleanup_proc(ctx)
|
||||
begin
|
||||
job_run_proc(ctx)
|
||||
# For multi exploit targets.
|
||||
# Keep the payload handler until last target or interrupt
|
||||
job_cleanup_proc(ctx) unless keep_handler
|
||||
rescue ::Interrupt
|
||||
job_cleanup_proc(ctx)
|
||||
raise $!
|
||||
end
|
||||
end
|
||||
|
||||
return session
|
||||
|
@ -181,6 +189,7 @@ class ExploitDriver
|
|||
attr_accessor :job_id
|
||||
attr_accessor :force_wait_for_session # :nodoc:
|
||||
attr_accessor :session # :nodoc:
|
||||
attr_accessor :keep_handler # :nodoc:
|
||||
|
||||
# To synchronize threads cleaning up the exploit and the handler
|
||||
attr_accessor :semaphore
|
||||
|
@ -211,7 +220,7 @@ protected
|
|||
delay = 0.01
|
||||
end
|
||||
|
||||
exploit.handle_exception e
|
||||
fail_reason = exploit.handle_exception(e)
|
||||
end
|
||||
|
||||
# Start bind handlers after exploit completion
|
||||
|
@ -237,6 +246,10 @@ protected
|
|||
exploit.fail_detail = "No session created"
|
||||
exploit.report_failure
|
||||
end
|
||||
|
||||
if fail_reason && fail_reason == Msf::Exploit::Failure::UserInterrupt
|
||||
raise ::Interrupt
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
|
|
|
@ -47,6 +47,9 @@ class Exploit
|
|||
"Exploit"
|
||||
end
|
||||
|
||||
#
|
||||
# Launches an exploitation single attempt.
|
||||
#
|
||||
def exploit_single(mod, opts)
|
||||
begin
|
||||
session = mod.exploit_simple(opts)
|
||||
|
@ -63,41 +66,7 @@ class Exploit
|
|||
end
|
||||
end
|
||||
|
||||
# If we were given a session, let's see what we can do with it
|
||||
if session
|
||||
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'] && mod.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 #{mod.job_id}.")
|
||||
# Worst case, the exploit ran but we got no session, bummer.
|
||||
|
||||
else
|
||||
# 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.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
|
||||
return session
|
||||
end
|
||||
|
||||
def cmd_exploit_tabs(str, words)
|
||||
|
@ -117,11 +86,12 @@ class Exploit
|
|||
end
|
||||
|
||||
#
|
||||
# Launches an exploitation attempt.
|
||||
# Launches exploitation attempts.
|
||||
#
|
||||
def cmd_exploit(*args)
|
||||
force = false
|
||||
module_opts = []
|
||||
any_session = false
|
||||
opts = {
|
||||
'Encoder' => mod.datastore['ENCODER'],
|
||||
'Payload' => mod.datastore['PAYLOAD'],
|
||||
|
@ -195,14 +165,75 @@ class Exploit
|
|||
end
|
||||
|
||||
rhosts = mod.datastore['RHOSTS']
|
||||
# For mutilple targets exploit attempts.
|
||||
if rhosts
|
||||
Rex::Socket::RangeWalker.new(rhosts).each do |rhost|
|
||||
opts[:multi] = true
|
||||
rhosts_range = Rex::Socket::RangeWalker.new(rhosts)
|
||||
rhosts_range.each do |rhost|
|
||||
nmod = mod.replicant
|
||||
nmod.datastore['RHOST'] = rhost
|
||||
exploit_single(nmod, opts)
|
||||
# If rhost is the last target, let exploit handler stop.
|
||||
opts["multi"] = false if rhost == (Rex::Socket.addr_itoa(rhosts_range.ranges.first.stop))
|
||||
# Catch the interrupt exception to stop the whole module during exploit
|
||||
begin
|
||||
print_status("Exploiting target #{rhost}")
|
||||
session = exploit_single(nmod, opts)
|
||||
rescue ::Interrupt
|
||||
print_status("Stopping exploiting current target #{rhost}...")
|
||||
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.
|
||||
else
|
||||
exploit_single(mod, opts)
|
||||
session = exploit_single(mod, 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'] && mod.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 #{mod.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 luanch.
|
||||
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.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
|
||||
|
||||
|
|
Loading…
Reference in New Issue