Land #4177, @hmoore-r7's fix for #4169

bug/bundler_fix
Jon Hart 2014-11-13 18:29:57 -08:00
commit 57aef9a6f5
No known key found for this signature in database
GPG Key ID: 2FA9F0A3AFA8E9D3
23 changed files with 112 additions and 35 deletions

View File

@ -41,7 +41,7 @@ module Metasploit
begin begin
success = connect_login(credential.public, credential.private) success = connect_login(credential.public, credential.private)
rescue ::EOFError, Errno::ECONNRESET, Rex::AddressInUse, Rex::ConnectionError, Rex::ConnectionTimeout, ::Timeout::Error rescue ::EOFError, Errno::ECONNRESET, Rex::ConnectionError, Rex::ConnectionTimeout, ::Timeout::Error
result_options[:status] = Metasploit::Model::Login::Status::UNABLE_TO_CONNECT result_options[:status] = Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
success = false success = false
end end

View File

@ -92,7 +92,7 @@ module Metasploit
end end
end end
rescue ::EOFError, Errno::ECONNRESET, Rex::AddressInUse, Rex::ConnectionError, Rex::ConnectionTimeout, ::Timeout::Error rescue ::EOFError, Errno::ECONNRESET, Rex::ConnectionError, Rex::ConnectionTimeout, ::Timeout::Error
result_options[:status] = Metasploit::Model::Login::Status::UNABLE_TO_CONNECT result_options[:status] = Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
end end

View File

@ -35,7 +35,7 @@ module Auxiliary::RServices
begin begin
sd = connect(true, { 'CPORT' => cport }) sd = connect(true, { 'CPORT' => cport })
rescue Rex::AddressInUse rescue Rex::BindFailed
# Ignore and try again # Ignore and try again
#vprint_error("Unable to connect: #{$!}") #vprint_error("Unable to connect: #{$!}")

View File

@ -57,6 +57,7 @@ def run
threads_max = datastore['THREADS'].to_i threads_max = datastore['THREADS'].to_i
@tl = [] @tl = []
@scan_errors = []
# #
# Sanity check threading given different conditions # Sanity check threading given different conditions
@ -87,17 +88,22 @@ def run
begin begin
if (self.respond_to?('run_range')) if (self.respond_to?('run_range'))
# No automated progress reporting for run_range # No automated progress reporting or error handling for run_range
return run_range(datastore['RHOSTS']) return run_range(datastore['RHOSTS'])
end end
if (self.respond_to?('run_host')) if (self.respond_to?('run_host'))
@tl = []
loop do loop do
# Stop scanning if we hit a fatal error
break if has_fatal_errors?
# Spawn threads for each host # Spawn threads for each host
while (@tl.length < threads_max) while (@tl.length < threads_max)
# Stop scanning if we hit a fatal error
break if has_fatal_errors?
ip = ar.next_ip ip = ar.next_ip
break if not ip break if not ip
@ -108,6 +114,10 @@ def run
begin begin
nmod.run_host(targ) nmod.run_host(targ)
rescue ::Rex::BindFailed
if datastore['CHOST']
@scan_errors << "The source IP (CHOST) value of #{datastore['CHOST']} was not usable"
end
rescue ::Rex::ConnectionError, ::Rex::ConnectionProxyError, ::Errno::ECONNRESET, ::Errno::EINTR, ::Rex::TimeoutError, ::Timeout::Error, ::EOFError rescue ::Rex::ConnectionError, ::Rex::ConnectionProxyError, ::Errno::ECONNRESET, ::Errno::EINTR, ::Rex::TimeoutError, ::Timeout::Error, ::EOFError
rescue ::Interrupt,::NoMethodError, ::RuntimeError, ::ArgumentError, ::NameError rescue ::Interrupt,::NoMethodError, ::RuntimeError, ::ArgumentError, ::NameError
raise $! raise $!
@ -120,6 +130,9 @@ def run
end end
end end
# Stop scanning if we hit a fatal error
break if has_fatal_errors?
# Exit once we run out of hosts # Exit once we run out of hosts
if(@tl.length == 0) if(@tl.length == 0)
break break
@ -139,6 +152,7 @@ def run
scanner_show_progress() if @show_progress scanner_show_progress() if @show_progress
end end
scanner_handle_fatal_errors
return return
end end
@ -153,10 +167,12 @@ def run
ar = Rex::Socket::RangeWalker.new(datastore['RHOSTS']) ar = Rex::Socket::RangeWalker.new(datastore['RHOSTS'])
@tl = []
while(true) while(true)
nohosts = false nohosts = false
# Stop scanning if we hit a fatal error
break if has_fatal_errors?
while (@tl.length < threads_max) while (@tl.length < threads_max)
batch = [] batch = []
@ -178,6 +194,10 @@ def run
mybatch = bat.dup mybatch = bat.dup
begin begin
nmod.run_batch(mybatch) nmod.run_batch(mybatch)
rescue ::Rex::BindFailed
if datastore['CHOST']
@scan_errors << "The source IP (CHOST) value of #{datastore['CHOST']} was not usable"
end
rescue ::Rex::ConnectionError, ::Rex::ConnectionProxyError, ::Errno::ECONNRESET, ::Errno::EINTR, ::Rex::TimeoutError, ::Timeout::Error rescue ::Rex::ConnectionError, ::Rex::ConnectionProxyError, ::Errno::ECONNRESET, ::Errno::EINTR, ::Rex::TimeoutError, ::Timeout::Error
rescue ::Interrupt,::NoMethodError, ::RuntimeError, ::ArgumentError, ::NameError rescue ::Interrupt,::NoMethodError, ::RuntimeError, ::ArgumentError, ::NameError
raise $! raise $!
@ -197,6 +217,9 @@ def run
end end
end end
# Stop scanning if we hit a fatal error
break if has_fatal_errors?
# Exit if there are no more pending threads # Exit if there are no more pending threads
if (@tl.length == 0) if (@tl.length == 0)
break break
@ -218,6 +241,7 @@ def run
scanner_show_progress() if @show_progress scanner_show_progress() if @show_progress
end end
scanner_handle_fatal_errors
return return
end end
@ -240,12 +264,33 @@ def seppuko!
end end
end end
def has_fatal_errors?
@scan_errors && !@scan_errors.empty?
end
def scanner_handle_fatal_errors
return unless has_fatal_errors?
return unless @tl
# First kill any running threads
@tl.each {|t| t.kill if t.alive? }
# Show the unique errors triggered by the scan
uniq_errors = @scan_errors.uniq
uniq_errors.each do |emsg|
print_error("Fatal: #{emsg}")
end
print_error("Scan terminated due to #{uniq_errors.size} fatal error(s)")
end
def scanner_progress def scanner_progress
return 0 unless @range_done and @range_count return 0 unless @range_done and @range_count
pct = (@range_done / @range_count.to_f) * 100 pct = (@range_done / @range_count.to_f) * 100
end end
def scanner_show_progress def scanner_show_progress
# it should already be in the process of shutting down if there are fatal errors
return if has_fatal_errors?
pct = scanner_progress pct = scanner_progress
if pct >= (@range_percent + @show_percent) if pct >= (@range_percent + @show_percent)
@range_percent = @range_percent + @show_percent @range_percent = @range_percent + @show_percent

View File

@ -213,25 +213,57 @@ class ConnectionTimeout < ConnectionError
end end
end end
###
#
# This connection error is raised when an attempt is made to connect
# to a broadcast or network address.
#
###
class InvalidDestination < ConnectionError
include SocketError
include HostCommunicationError
def to_s
"The destination is invalid: #{addr_to_s}."
end
end
### ###
# #
# This exception is raised when an attempt to use an address or port that is # This exception is raised when an attempt to use an address or port that is
# already in use occurs, such as binding to a host on a given port that is # already in use or onot available occurs. such as binding to a host on a
# already in use. Note that Windows raises this in some cases when attempting # given port that is already in use, or when a bind address is specified that
# to connect to addresses that it can't handle, e.g. "0.0.0.0". Thus, this is # is not available to the host.
# a ConnectionError.
# #
### ###
class BindFailed < ::ArgumentError
include SocketError
include HostCommunicationError
def to_s
"The address is already in use or unavailable: #{addr_to_s}."
end
end
##
#
# This exception is listed for backwards compatibility. We had been
# using AddressInUse as the exception for both bind errors and connection
# errors triggered by connection attempts to broadcast and network addresses.
# The two classes above have split this into their respective sources, but
# callers may still expect the old behavior.
#
##
class AddressInUse < ConnectionError class AddressInUse < ConnectionError
include SocketError include SocketError
include HostCommunicationError include HostCommunicationError
def to_s def to_s
"The address is already in use #{addr_to_s}." "The address is already in use or unavailable: #{addr_to_s}."
end end
end end
### ###
# #
# This exception is raised when an unsupported internet protocol is specified. # This exception is raised when an unsupported internet protocol is specified.

View File

@ -106,7 +106,7 @@ class Console
log_error("Operation timed out.") log_error("Operation timed out.")
rescue RequestError => info rescue RequestError => info
log_error(info.to_s) log_error(info.to_s)
rescue Rex::AddressInUse => e rescue Rex::InvalidDestination => e
log_error(e.message) log_error(e.message)
rescue ::Errno::EPIPE, ::OpenSSL::SSL::SSLError, ::IOError rescue ::Errno::EPIPE, ::OpenSSL::SSL::SSLError, ::IOError
self.client.kill self.client.kill

View File

@ -195,7 +195,7 @@ class Rex::Socket::Comm::Local
rescue ::Errno::EADDRNOTAVAIL,::Errno::EADDRINUSE rescue ::Errno::EADDRNOTAVAIL,::Errno::EADDRINUSE
sock.close sock.close
raise Rex::AddressInUse.new(param.localhost, param.localport), caller raise Rex::BindFailed.new(param.localhost, param.localport), caller
end end
end end
@ -295,7 +295,7 @@ class Rex::Socket::Comm::Local
rescue ::Errno::EADDRNOTAVAIL,::Errno::EADDRINUSE rescue ::Errno::EADDRNOTAVAIL,::Errno::EADDRINUSE
sock.close sock.close
raise Rex::AddressInUse.new(ip, port), caller raise Rex::InvalidDestination.new(ip, port), caller
rescue Errno::ETIMEDOUT rescue Errno::ETIMEDOUT
sock.close sock.close

View File

@ -96,7 +96,7 @@ class Metasploit3 < Msf::Auxiliary
begin begin
connect(true, 'RPORT' => jport) connect(true, 'RPORT' => jport)
sock.put(create_print_job) sock.put(create_print_job)
rescue ::Timeout::Error, Rex::ConnectionError, Rex::ConnectionRefused, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::AddressInUse rescue ::Timeout::Error, Rex::ConnectionError, Rex::ConnectionRefused, Rex::HostUnreachable, Rex::ConnectionTimeout
print_error("#{rhost}:#{jport} - Error connecting to #{rhost}") print_error("#{rhost}:#{jport} - Error connecting to #{rhost}")
ensure ensure
disconnect disconnect
@ -113,7 +113,7 @@ class Metasploit3 < Msf::Auxiliary
res = sock.get_once || '' res = sock.get_once || ''
passwd = res.match(/\r\n\s(.+?)\n/) passwd = res.match(/\r\n\s(.+?)\n/)
return passwd ? passwd[1] : '' return passwd ? passwd[1] : ''
rescue ::EOFError, ::Timeout::Error, Rex::ConnectionError, Rex::ConnectionRefused, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::AddressInUse, EOFError rescue ::EOFError, ::Timeout::Error, Rex::ConnectionError, Rex::ConnectionRefused, Rex::HostUnreachable, Rex::ConnectionTimeout, ::EOFError
print_error("#{rhost}:#{jport} - Error getting password from #{rhost}") print_error("#{rhost}:#{jport} - Error getting password from #{rhost}")
return return
ensure ensure
@ -150,7 +150,7 @@ class Metasploit3 < Msf::Auxiliary
begin begin
connect(true, 'RPORT' => jport) connect(true, 'RPORT' => jport)
sock.put(remove_print_job) sock.put(remove_print_job)
rescue ::Timeout::Error, Rex::ConnectionError, Rex::ConnectionRefused, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::AddressInUse rescue ::Timeout::Error, Rex::ConnectionError, Rex::ConnectionRefused, Rex::HostUnreachable, Rex::ConnectionTimeout
print_error("#{rhost}:#{jport} - Error removing print job from #{rhost}") print_error("#{rhost}:#{jport} - Error removing print job from #{rhost}")
ensure ensure
disconnect disconnect

View File

@ -151,7 +151,7 @@ class Metasploit3 < Msf::Auxiliary
begin begin
sd = Rex::Socket.create_tcp_server('LocalPort' => stderr_port) sd = Rex::Socket.create_tcp_server('LocalPort' => stderr_port)
rescue Rex::AddressInUse rescue Rex::BindFailed
# Ignore and try again # Ignore and try again
end end

View File

@ -201,7 +201,7 @@ class Metasploit3 < Msf::Auxiliary
begin begin
sd = Rex::Socket.create_tcp_server('LocalPort' => lport) sd = Rex::Socket.create_tcp_server('LocalPort' => lport)
rescue Rex::AddressInUse rescue Rex::BindFailed
# Ignore and try again # Ignore and try again
end end

View File

@ -80,7 +80,7 @@ class Metasploit3 < Msf::Auxiliary
begin begin
transport = Net::SSH::Transport::Session.new(ip, options) transport = Net::SSH::Transport::Session.new(ip, options)
rescue Rex::ConnectionError, Rex::AddressInUse rescue Rex::ConnectionError
return :connection_error return :connection_error
end end
@ -130,7 +130,7 @@ class Metasploit3 < Msf::Auxiliary
:fail :fail
end end
end end
rescue Rex::ConnectionError, Rex::AddressInUse rescue Rex::ConnectionError
return :connection_error return :connection_error
rescue Net::SSH::Disconnect, ::EOFError rescue Net::SSH::Disconnect, ::EOFError
return :success return :success

View File

@ -99,7 +99,7 @@ class Metasploit3 < Msf::Auxiliary
::Timeout.timeout(datastore['SSH_TIMEOUT']) do ::Timeout.timeout(datastore['SSH_TIMEOUT']) do
Net::SSH.start(ip, user, opt_hash) Net::SSH.start(ip, user, opt_hash)
end end
rescue Rex::ConnectionError, Rex::AddressInUse rescue Rex::ConnectionError
return :connection_error return :connection_error
rescue Net::SSH::Disconnect, ::EOFError rescue Net::SSH::Disconnect, ::EOFError
return :success return :success

View File

@ -226,7 +226,7 @@ class Metasploit3 < Msf::Auxiliary
::Timeout.timeout(1) { ssh_socket.close if ssh_socket } rescue nil ::Timeout.timeout(1) { ssh_socket.close if ssh_socket } rescue nil
rescue Rex::ConnectionError, Rex::AddressInUse rescue Rex::ConnectionError
return :connection_error return :connection_error
rescue Net::SSH::Disconnect, ::EOFError rescue Net::SSH::Disconnect, ::EOFError
return :connection_disconnect return :connection_disconnect

View File

@ -95,7 +95,7 @@ class Metasploit3 < Msf::Exploit::Remote
::Timeout.timeout(datastore['SSH_TIMEOUT']) do ::Timeout.timeout(datastore['SSH_TIMEOUT']) do
ssh = Net::SSH.start(rhost, user, opts) ssh = Net::SSH.start(rhost, user, opts)
end end
rescue Rex::ConnectionError, Rex::AddressInUse rescue Rex::ConnectionError
return return
rescue Net::SSH::Disconnect, ::EOFError rescue Net::SSH::Disconnect, ::EOFError
print_error "#{rhost}:#{rport} SSH - Disconnected during negotiation" print_error "#{rhost}:#{rport} SSH - Disconnected during negotiation"

View File

@ -88,7 +88,7 @@ class Metasploit3 < Msf::Exploit::Remote
::Timeout.timeout(datastore['SSH_TIMEOUT']) do ::Timeout.timeout(datastore['SSH_TIMEOUT']) do
ssh_socket = Net::SSH.start(rhost, user, opt_hash) ssh_socket = Net::SSH.start(rhost, user, opt_hash)
end end
rescue Rex::ConnectionError, Rex::AddressInUse rescue Rex::ConnectionError
return return
rescue Net::SSH::Disconnect, ::EOFError rescue Net::SSH::Disconnect, ::EOFError
print_error "#{rhost}:#{rport} SSH - Disconnected during negotiation" print_error "#{rhost}:#{rport} SSH - Disconnected during negotiation"

View File

@ -85,7 +85,7 @@ class Metasploit3 < Msf::Exploit::Remote
::Timeout.timeout(datastore['SSH_TIMEOUT']) do ::Timeout.timeout(datastore['SSH_TIMEOUT']) do
ssh_socket = Net::SSH.start(rhost, user, opt_hash) ssh_socket = Net::SSH.start(rhost, user, opt_hash)
end end
rescue Rex::ConnectionError, Rex::AddressInUse rescue Rex::ConnectionError
return nil return nil
rescue Net::SSH::Disconnect, ::EOFError rescue Net::SSH::Disconnect, ::EOFError
print_error "#{rhost}:#{rport} SSH - Disconnected during negotiation" print_error "#{rhost}:#{rport} SSH - Disconnected during negotiation"

View File

@ -83,7 +83,7 @@ class Metasploit3 < Msf::Exploit::Remote
::Timeout.timeout(datastore['SSH_TIMEOUT']) do ::Timeout.timeout(datastore['SSH_TIMEOUT']) do
ssh_socket = Net::SSH.start(rhost, user, opt_hash) ssh_socket = Net::SSH.start(rhost, user, opt_hash)
end end
rescue Rex::ConnectionError, Rex::AddressInUse rescue Rex::ConnectionError
return nil return nil
rescue Net::SSH::Disconnect, ::EOFError rescue Net::SSH::Disconnect, ::EOFError
print_error "#{rhost}:#{rport} SSH - Disconnected during negotiation" print_error "#{rhost}:#{rport} SSH - Disconnected during negotiation"

View File

@ -98,7 +98,7 @@ class Metasploit3 < Msf::Exploit::Remote
::Timeout.timeout(datastore['SSH_TIMEOUT']) do ::Timeout.timeout(datastore['SSH_TIMEOUT']) do
ssh = Net::SSH.start(rhost, user, opts) ssh = Net::SSH.start(rhost, user, opts)
end end
rescue Rex::ConnectionError, Rex::AddressInUse rescue Rex::ConnectionError
return nil return nil
rescue Net::SSH::Disconnect, ::EOFError rescue Net::SSH::Disconnect, ::EOFError
print_error "#{rhost}:#{rport} SSH - Disconnected during negotiation" print_error "#{rhost}:#{rport} SSH - Disconnected during negotiation"

View File

@ -103,7 +103,7 @@ class Metasploit3 < Msf::Exploit::Remote
::Timeout.timeout(datastore['SSH_TIMEOUT']) do ::Timeout.timeout(datastore['SSH_TIMEOUT']) do
ssh = Net::SSH.start(rhost, user, opts) ssh = Net::SSH.start(rhost, user, opts)
end end
rescue Rex::ConnectionError, Rex::AddressInUse rescue Rex::ConnectionError
return return
rescue Net::SSH::Disconnect, ::EOFError rescue Net::SSH::Disconnect, ::EOFError
print_error "#{rhost}:#{rport} SSH - Disconnected during negotiation" print_error "#{rhost}:#{rport} SSH - Disconnected during negotiation"

View File

@ -108,7 +108,7 @@ class Metasploit3 < Msf::Exploit::Remote
begin begin
self.ssh_socket = Net::SSH.start(ip, user, opt_hash) self.ssh_socket = Net::SSH.start(ip, user, opt_hash)
rescue Rex::ConnectionError, Rex::AddressInUse rescue Rex::ConnectionError
fail_with(Failure::Unreachable, 'Disconnected during negotiation') fail_with(Failure::Unreachable, 'Disconnected during negotiation')
rescue Net::SSH::Disconnect, ::EOFError rescue Net::SSH::Disconnect, ::EOFError
fail_with(Failure::Disconnected, 'Timed out during negotiation') fail_with(Failure::Disconnected, 'Timed out during negotiation')

View File

@ -89,7 +89,7 @@ class Metasploit3 < Msf::Exploit::Remote
connect connect
sock.put(firmcode) sock.put(firmcode)
handler handler
rescue ::Timeout::Error, Rex::ConnectionError, Rex::ConnectionRefused, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::AddressInUse => e rescue ::Timeout::Error, Rex::ConnectionError, Rex::ConnectionRefused, Rex::HostUnreachable, Rex::ConnectionTimeout => e
print_error("#{rhost}:#{rport} - #{e.message}") print_error("#{rhost}:#{rport} - #{e.message}")
ensure ensure
disconnect disconnect

View File

@ -169,7 +169,7 @@ class Metasploit3 < Msf::Exploit::Remote
::Timeout.timeout(datastore['SSH_TIMEOUT']) do ::Timeout.timeout(datastore['SSH_TIMEOUT']) do
ssh = Net::SSH.start(rhost, user, opts) ssh = Net::SSH.start(rhost, user, opts)
end end
rescue Rex::ConnectionError, Rex::AddressInUse rescue Rex::ConnectionError
fail_with(Failure::Unreachable, "#{rhost}:#{rport} SSH - Connection error or address in use") fail_with(Failure::Unreachable, "#{rhost}:#{rport} SSH - Connection error or address in use")
rescue Net::SSH::Disconnect, ::EOFError rescue Net::SSH::Disconnect, ::EOFError
fail_with(Failure::Disconnected, "#{rhost}:#{rport} SSH - Disconnected during negotiation") fail_with(Failure::Disconnected, "#{rhost}:#{rport} SSH - Disconnected during negotiation")

View File

@ -212,7 +212,7 @@ class Metasploit3 < Msf::Exploit::Remote
::Timeout.timeout(datastore['SSH_TIMEOUT']) do ::Timeout.timeout(datastore['SSH_TIMEOUT']) do
c = do_login(datastore['USERNAME']) c = do_login(datastore['USERNAME'])
end end
rescue Rex::ConnectionError, Rex::AddressInUse rescue Rex::ConnectionError
return return
rescue Net::SSH::Disconnect, ::EOFError rescue Net::SSH::Disconnect, ::EOFError
print_error "#{rhost}:#{rport} SSH - Timed out during negotiation" print_error "#{rhost}:#{rport} SSH - Timed out during negotiation"