Enforce a timeout in the ssh handshake (avoid hangs in some cases)

unstable
HD Moore 2012-06-12 15:19:01 -05:00
parent 6290bba71b
commit f5533c5298
3 changed files with 28 additions and 16 deletions

View File

@ -53,7 +53,8 @@ class Metasploit3 < Msf::Auxiliary
OptBool.new('SSH_DEBUG', [ false, 'Enable SSH debugging output (Extreme verbosity!)', false]),
OptBool.new('SSH_BYPASS', [ false, 'Verify that authentication was not bypassed when keys are found', false]),
OptString.new('SSH_KEYFILE_B64', [false, 'Raw data of an unencrypted SSH public key. This should be used by programmatic interfaces to this module only.', '']),
OptPath.new('KEY_DIR', [false, 'Directory of several keys. Filenames must not begin with a dot in order to be read.'])
OptPath.new('KEY_DIR', [false, 'Directory of several keys. Filenames must not begin with a dot in order to be read.']),
OptInt.new('SSH_TIMEOUT', [ false, 'Specify the maximum time to negotiate a SSH session', 30])
]
)
@ -208,9 +209,10 @@ class Metasploit3 < Msf::Auxiliary
opt_hash.merge!(:verbose => :debug) if datastore['SSH_DEBUG']
begin
ssh_socket = Net::SSH.start(ip, user, opt_hash)
ssh_socket = nil
::Timeout.timeout(datastore['SSH_TIMEOUT']) { ssh_socket = Net::SSH.start(ip, user, opt_hash) } rescue nil
if datastore['SSH_BYPASS']
if datastore['SSH_BYPASS'] and ssh_socket
data = nil
print_status("#{ip}:#{rport} SSH - User #{user} is being tested for authentication bypass...")
@ -223,7 +225,7 @@ class Metasploit3 < Msf::Auxiliary
print_brute(:level => :good, :msg => "User #{user} successfully bypassed authentication: #{data.inspect} ") if data
end
::Timeout.timeout(1) { ssh_socket.close } rescue nil
::Timeout.timeout(1) { ssh_socket.close if ssh_socket } rescue nil
rescue Rex::ConnectionError, Rex::AddressInUse
return :connection_error

View File

@ -47,7 +47,8 @@ class Metasploit3 < Msf::Auxiliary
register_advanced_options(
[
OptBool.new('SSH_DEBUG', [ false, 'Enable SSH debugging output (Extreme verbosity!)', false])
OptBool.new('SSH_DEBUG', [ false, 'Enable SSH debugging output (Extreme verbosity!)', false]),
OptInt.new('SSH_TIMEOUT', [ false, 'Specify the maximum time to negotiate a SSH session', 30])
]
)
@ -75,15 +76,19 @@ class Metasploit3 < Msf::Auxiliary
opt_hash.merge!(:verbose => :debug) if datastore['SSH_DEBUG']
begin
self.ssh_socket = Net::SSH.start(
ip,
user,
opt_hash
)
::Timeout.timeout(datastore['SSH_TIMEOUT']) do
self.ssh_socket = Net::SSH.start(
ip,
user,
opt_hash
)
end
rescue Rex::ConnectionError, Rex::AddressInUse
return :connection_error
rescue Net::SSH::Disconnect, ::EOFError
return :connection_disconnect
rescue ::Timeout::Error
return :connection_disconnect
rescue Net::SSH::Exception
return [:fail,nil] # For whatever reason. Can't tell if passwords are on/off without timing responses.
end

View File

@ -55,7 +55,8 @@ class Metasploit3 < Msf::Auxiliary
[
OptBool.new('SSH_DEBUG', [ false, 'Enable SSH debugging output (Extreme verbosity!)', false]),
OptString.new('SSH_KEYFILE_B64', [false, 'Raw data of an unencrypted SSH public key. This should be used by programmatic interfaces to this module only.', '']),
OptPath.new('KEY_DIR', [false, 'Directory of several cleartext private keys. Filenames must not begin with a dot, or end in ".pub" in order to be read.'])
OptPath.new('KEY_DIR', [false, 'Directory of several cleartext private keys. Filenames must not begin with a dot, or end in ".pub" in order to be read.']),
OptInt.new('SSH_TIMEOUT', [ false, 'Specify the maximum time to negotiate a SSH session', 30])
]
)
@ -182,15 +183,19 @@ class Metasploit3 < Msf::Auxiliary
}
opt_hash.merge!(:verbose => :debug) if datastore['SSH_DEBUG']
begin
self.ssh_socket = Net::SSH.start(
ip,
user,
opt_hash
)
::Timeout.timeout(datastore['SSH_TIMEOUT']) do
self.ssh_socket = Net::SSH.start(
ip,
user,
opt_hash
)
end
rescue Rex::ConnectionError, Rex::AddressInUse
return :connection_error
rescue Net::SSH::Disconnect, ::EOFError
return :connection_disconnect
rescue ::Timeout::Error
return :connection_disconnect
rescue Net::SSH::AuthenticationFailed
# Try, try, again
if @key_files