diff --git a/documentation/plan.txt b/documentation/plan.txt index 8b95e52663..af9e9b00fd 100644 --- a/documentation/plan.txt +++ b/documentation/plan.txt @@ -28,8 +28,6 @@ X - stack requirements X - make payload prepend target specific X - sessions X - logging session activity - - handler sharing - - exploits using the same payload/handler can share (ref count) - modules needing ports (above other modules) - encoders - shikata @@ -42,10 +40,10 @@ X - logging session activity - user interfaces - general - add concept of EVASION option (high, normal, low) - - logging improvements - - provide log file setting interface +X - logging improvements +X - provide log file setting interface X - log by default in the LogDir - - msfcli +X - msfcli - msfweb X - msfpayload X - msfencode @@ -100,6 +98,9 @@ Things that would be useful to have completed, but not a requirement: - basic range/port scanner - basic service identifier - basic OS fingerprinting +- framework-core + - handler sharing + - exploits using the same payload/handler can share (ref count) - framework-base - event correlation - recon events correlations diff --git a/lib/msf/base/serializer/readable_text.rb b/lib/msf/base/serializer/readable_text.rb index 8614767925..5e821296e1 100644 --- a/lib/msf/base/serializer/readable_text.rb +++ b/lib/msf/base/serializer/readable_text.rb @@ -35,6 +35,43 @@ class ReadableText end end + # + # Dumps an exploit's targets. + # + def self.dump_exploit_targets(mod, indent = '', h = nil) + tbl = Rex::Ui::Text::Table.new( + 'Indent' => indent.length, + 'Header' => h, + 'Columns' => + [ + 'Id', + 'Name', + ]) + + mod.targets.each_with_index { |target, idx| + tbl << [ idx.to_s, target.name || 'All' ] + } + + tbl.to_s + "\n" + end + + def self.dump_compatible_payloads(exploit, indent = '', h = nil) + tbl = Rex::Ui::Text::Table.new( + 'Indent' => indent.length, + 'Header' => h, + 'Columns' => + [ + 'Name', + 'Description', + ]) + + exploit.compatible_payloads.each { |entry| + tbl << [ entry[0], entry[1].new.description ] + } + + tbl.to_s + "\n" + end + # # Dumps information about an exploit module. # @@ -54,32 +91,20 @@ class ReadableText output += "\n" # Targets - tbl = Rex::Ui::Text::Table.new( - 'Indent' => indent.length, - 'Columns' => - [ - 'Id', - 'Name', - ]) - output += "Available targets:\n" - mod.targets.each_with_index { |target, idx| - tbl << [ idx.to_s, target.name || 'All' ] - } - output += tbl.to_s - output += "\n" - + output += dump_exploit_targets(mod, indent) + # Options if (mod.options.has_options?) output += "Available options:\n" - output += dump_options(mod) + output += dump_options(mod, indent) output += "\n" end # Advanced options if (mod.options.has_advanced_options?) output += "Advanced options:\n" - output += dump_advanced_options(mod) + output += dump_advanced_options(mod, indent) output += "\n" end @@ -198,9 +223,9 @@ class ReadableText # Dumps the list of options associated with the # supplied module. # - def self.dump_options(mod, indent = DefaultIndent) + def self.dump_options(mod, indent = '') tbl = Rex::Ui::Text::Table.new( - 'Indent' => indent, + 'Indent' => indent.length, 'Columns' => [ 'Name', @@ -222,9 +247,9 @@ class ReadableText return tbl.to_s end - def self.dump_advanced_options(mod, indent = DefaultIndent) + def self.dump_advanced_options(mod, indent = '') output = '' - pad = ' ' * indent + pad = indent mod.options.sorted.each { |entry| name, opt = entry @@ -235,7 +260,7 @@ class ReadableText output += pad + "Name : #{name}\n" output += pad + "Default: #{val}\n\n" - output += word_wrap(opt.desc, indent + 3) + output += word_wrap(opt.desc, indent.length + 3) } return output diff --git a/lib/msf/base/simple/exploit.rb b/lib/msf/base/simple/exploit.rb index 9f62015918..b7bafcae91 100644 --- a/lib/msf/base/simple/exploit.rb +++ b/lib/msf/base/simple/exploit.rb @@ -40,6 +40,11 @@ module Exploit driver.target_idx = target_idx driver.payload = exploit.framework.modules.create(opts['Payload']) + # 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) + # Was the payload valid? if (driver.payload == nil) raise MissingPayloadError, diff --git a/lib/msf/core/exploit_driver.rb b/lib/msf/core/exploit_driver.rb index ec202f3ede..9ce761a05f 100644 --- a/lib/msf/core/exploit_driver.rb +++ b/lib/msf/core/exploit_driver.rb @@ -16,10 +16,11 @@ module Msf class ExploitDriver def initialize(framework) - self.payload = nil - self.exploit = nil - self.target_idx = nil - self.use_job = false + self.payload = nil + self.exploit = nil + self.target_idx = nil + self.use_job = false + self.force_wait_for_session = false end # @@ -144,6 +145,7 @@ class ExploitDriver attr_accessor :exploit attr_accessor :payload attr_accessor :use_job + attr_accessor :force_wait_for_session protected @@ -161,11 +163,12 @@ protected # Launch the exploit exploit.exploit - + # Wait the payload to acquire a session if this isn't a passive-style - # exploit - if (exploit.passive? == false) - self.session = payload.wait_for_session + # exploit. + if (exploit.passive? == false or force_wait_for_session == true) + self.session = payload.wait_for_session( + (exploit.passive? == true) ? nil : payload.wfs_delay) end rescue elog("Exploit failed: #{$!}", 'core', LEV_0)