Skip to content

Commit 358e79b

Browse files
committed
Handle SSH errors by closing the session
1 parent f6a5161 commit 358e79b

File tree

3 files changed

+30
-15
lines changed

3 files changed

+30
-15
lines changed

lib/msf/base/sessions/aws_instance_connect_command_shell_bind.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ def desc
7676
end
7777

7878
def bootstrap(datastore = {}, handler = nil)
79-
@ssh_command_stream = Net::SSH::CommandStream.new(ssh_connection)
79+
@ssh_command_stream = Net::SSH::CommandStream.new(ssh_connection, session: self)
8080

8181
@ssh_command_stream.verify_channel
8282
# set remote_window_size to 32 which seems to help stability

lib/msf/base/sessions/ssh_command_shell_bind.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ def bootstrap(datastore = {}, handler = nil)
243243
# shells accessed through SSH may respond to the echo command issued for verification as expected
244244
datastore['AutoVerifySession'] &= @platform.blank?
245245

246-
@rstream = Net::SSH::CommandStream.new(ssh_connection).lsock
246+
@rstream = Net::SSH::CommandStream.new(ssh_connection, session: self).lsock
247247
super
248248

249249
@info = "SSH #{username} @ #{@peer_info}"

lib/net/ssh/command_stream.rb

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
class Net::SSH::CommandStream
44

5-
attr_accessor :channel, :thread, :error, :ssh
5+
attr_accessor :channel, :thread, :error, :ssh, :session
66
attr_accessor :lsock, :rsock, :monitor
77

88
module PeerInfo
@@ -13,7 +13,9 @@ module PeerInfo
1313

1414
def shell_requested(channel, success)
1515
unless success
16-
raise Net::SSH::ChannelRequestFailed, 'Shell/exec channel request failed'
16+
error = Net::SSH::ChannelRequestFailed, 'Shell/exec channel request failed'
17+
handle_error(error: error)
18+
raise error
1719
end
1820

1921
self.channel = channel
@@ -40,7 +42,8 @@ def shell_requested(channel, success)
4042
end
4143
end
4244

43-
def initialize(ssh, cmd = nil, pty: false, cleanup: false)
45+
def initialize(ssh, cmd = nil, pty: false, cleanup: false, session: nil)
46+
self.session = session
4447
self.lsock, self.rsock = Rex::Socket.tcp_socket_pair()
4548
self.lsock.extend(Rex::IO::Stream)
4649
self.lsock.extend(PeerInfo)
@@ -74,31 +77,42 @@ def initialize(ssh, cmd = nil, pty: false, cleanup: false)
7477
end
7578

7679
channel.on_open_failed do |ch, code, desc|
77-
raise Net::SSH::ChannelOpenFailed.new(code, 'Session channel open failed')
80+
error = Net::SSH::ChannelOpenFailed.new(code, 'Session channel open failed')
81+
handle_error(error: error)
82+
raise error
7883
end
7984

8085
self.monitor = Thread.new do
81-
while(true)
82-
next if not self.rsock.has_read_data?(1.0)
83-
buff = self.rsock.read(16384)
84-
break if not buff
85-
verify_channel
86-
self.channel.send_data(buff) if buff
86+
begin
87+
Kernel.loop do
88+
next if not self.rsock.has_read_data?(1.0)
89+
90+
buff = self.rsock.read(16384)
91+
break if not buff
92+
93+
verify_channel
94+
self.channel.send_data(buff) if buff
95+
end
96+
rescue ::StandardError => e
97+
handle_error(error: e)
8798
end
8899
end
89100

90-
while true
91-
rssh.process(0.5) { true }
101+
begin
102+
Kernel.loop { rssh.process(0.5) { true } }
103+
rescue ::StandardError => e
104+
handle_error(error: e)
92105
end
93106

94107
# Shut down the SSH session if requested
95108
if !rcmd.nil? && rcleanup
96109
rssh.close
97110
end
98111
end
112+
self.thread.abort_on_exception = true
99113
rescue ::StandardError => e
100114
# XXX: This won't be set UNTIL there's a failure from a thread
101-
self.error = e
115+
handle_error(error: e)
102116
ensure
103117
self.monitor.kill if self.monitor
104118
end
@@ -119,6 +133,7 @@ def handle_error(error: nil)
119133
end
120134

121135
def cleanup
136+
self.session.alive = false if self.session
122137
self.monitor.kill
123138
self.lsock.close rescue nil
124139
self.rsock.close rescue nil

0 commit comments

Comments
 (0)