From 0490d9b23f6983dc46d5ca57c62c274c5592518c Mon Sep 17 00:00:00 2001 From: Jonathan Claudius Date: Fri, 25 Aug 2017 14:29:03 -0400 Subject: [PATCH 1/3] Add exception handling for Net::SSH resets --- lib/ssh_scan/scan_engine.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ssh_scan/scan_engine.rb b/lib/ssh_scan/scan_engine.rb index 6b45eda8..b1b67a5f 100644 --- a/lib/ssh_scan/scan_engine.rb +++ b/lib/ssh_scan/scan_engine.rb @@ -107,7 +107,7 @@ def scan_target(socket, opts) net_ssh_session.close rescue Net::SSH::ConnectionTimeout => e result.error = SSHScan::Error::ConnectTimeout.new(e.message) - rescue Net::SSH::Disconnect => e + rescue Net::SSH::Disconnect, Errno::ECONNRESET => e result.error = SSHScan::Error::Disconnected.new(e.message) rescue Net::SSH::Exception => e if e.to_s.match(/could not settle on/) From 3834e0e7922ff4e9b0e1843dc3a32888b8942226 Mon Sep 17 00:00:00 2001 From: Jonathan Claudius Date: Fri, 25 Aug 2017 14:50:48 -0400 Subject: [PATCH 2/3] Make client actually observe timeout requirements --- lib/ssh_scan/client.rb | 43 ++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/lib/ssh_scan/client.rb b/lib/ssh_scan/client.rb index cf7eb3dc..697d7be3 100644 --- a/lib/ssh_scan/client.rb +++ b/lib/ssh_scan/client.rb @@ -1,4 +1,5 @@ require 'socket' +require 'timeout' require 'ssh_scan/constants' require 'ssh_scan/protocol' require 'ssh_scan/banner' @@ -43,12 +44,15 @@ def connect() @error = nil begin - @sock = Socket.tcp(@ip, @port, connect_timeout: @timeout) - @raw_server_banner = @sock.gets + Timeout::timeout(@timeout) { + @sock = Socket.tcp(@ip, @port, connect_timeout: @timeout) + @raw_server_banner = @sock.gets + } rescue SocketError => e @error = SSHScan::Error::ConnectionRefused.new(e.message) @sock = nil - rescue Errno::ETIMEDOUT => e + rescue Errno::ETIMEDOUT, + Timeout::Error => e @error = SSHScan::Error::ConnectTimeout.new(e.message) @sock = nil rescue Errno::ECONNREFUSED => e @@ -95,22 +99,25 @@ def get_kex_result(kex_init_raw = @kex_init_raw) end begin - @sock.write(kex_init_raw) - resp = @sock.read(4) - - if resp.nil? - @error = SSHScan::Error::NoKexResponse.new( - "service did not respond to our kex init request" - ) - @sock = nil - return nil - end - - resp += @sock.read(resp.unpack("N").first) - @sock.close + Timeout::timeout(@timeout) { + @sock.write(kex_init_raw) + resp = @sock.read(4) + + if resp.nil? + @error = SSHScan::Error::NoKexResponse.new( + "service did not respond to our kex init request" + ) + @sock = nil + return nil + end + + resp += @sock.read(resp.unpack("N").first) + @sock.close - kex_exchange_init = SSHScan::KeyExchangeInit.read(resp) - rescue Errno::ETIMEDOUT => e + kex_exchange_init = SSHScan::KeyExchangeInit.read(resp) + } + rescue Errno::ETIMEDOUT, + Timeout::Error => e @error = SSHScan::Error::ConnectTimeout.new(e.message) @sock = nil return nil From 27b977f48e8677167bc5c029bb02cc64bb1edc77 Mon Sep 17 00:00:00 2001 From: Jonathan Claudius Date: Fri, 25 Aug 2017 14:58:28 -0400 Subject: [PATCH 3/3] Fix scoping issue with kex_exchange_init --- lib/ssh_scan/client.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/ssh_scan/client.rb b/lib/ssh_scan/client.rb index 697d7be3..ac83c227 100644 --- a/lib/ssh_scan/client.rb +++ b/lib/ssh_scan/client.rb @@ -98,6 +98,8 @@ def get_kex_result(kex_init_raw = @kex_init_raw) return nil end + kex_exchange_init = nil + begin Timeout::timeout(@timeout) { @sock.write(kex_init_raw)