diff --git a/lib/msf/base/sessions/aws_instance_connect_command_shell_bind.rb b/lib/msf/base/sessions/aws_instance_connect_command_shell_bind.rb index 0cbd7fee5b2bb..7c8c20b0744e8 100644 --- a/lib/msf/base/sessions/aws_instance_connect_command_shell_bind.rb +++ b/lib/msf/base/sessions/aws_instance_connect_command_shell_bind.rb @@ -76,7 +76,7 @@ def desc end def bootstrap(datastore = {}, handler = nil) - @ssh_command_stream = Net::SSH::CommandStream.new(ssh_connection, session: self) + @ssh_command_stream = Net::SSH::CommandStream.new(ssh_connection, session: self, error_callback: method(:print_error)) @ssh_command_stream.verify_channel # set remote_window_size to 32 which seems to help stability diff --git a/lib/msf/base/sessions/ssh_command_shell_bind.rb b/lib/msf/base/sessions/ssh_command_shell_bind.rb index 2526d6c37dd21..9a22f5e82f821 100644 --- a/lib/msf/base/sessions/ssh_command_shell_bind.rb +++ b/lib/msf/base/sessions/ssh_command_shell_bind.rb @@ -243,7 +243,7 @@ def bootstrap(datastore = {}, handler = nil) # shells accessed through SSH may respond to the echo command issued for verification as expected datastore['AutoVerifySession'] &= @platform.blank? - @rstream = Net::SSH::CommandStream.new(ssh_connection, session: self).lsock + @rstream = Net::SSH::CommandStream.new(ssh_connection, session: self, error_callback: method(:print_error)).lsock super @info = "SSH #{username} @ #{@peer_info}" diff --git a/lib/net/ssh/command_stream.rb b/lib/net/ssh/command_stream.rb index 30f6edc25040c..3c17d7376a330 100644 --- a/lib/net/ssh/command_stream.rb +++ b/lib/net/ssh/command_stream.rb @@ -2,7 +2,7 @@ class Net::SSH::CommandStream - attr_accessor :channel, :thread, :error, :ssh, :session + attr_accessor :channel, :thread, :error, :ssh, :session, :error_callback attr_accessor :lsock, :rsock, :monitor module PeerInfo @@ -13,7 +13,7 @@ module PeerInfo def shell_requested(channel, success) unless success - error = Net::SSH::ChannelRequestFailed, 'Shell/exec channel request failed' + error = Net::SSH::ChannelRequestFailed.new('Shell/exec channel request failed') handle_error(error: error) raise error end @@ -42,8 +42,9 @@ def shell_requested(channel, success) end end - def initialize(ssh, cmd = nil, pty: false, cleanup: false, session: nil) + def initialize(ssh, cmd = nil, pty: false, cleanup: false, session: nil, error_callback: nil) self.session = session + self.error_callback = error_callback self.lsock, self.rsock = Rex::Socket.tcp_socket_pair() self.lsock.extend(Rex::IO::Stream) self.lsock.extend(PeerInfo) @@ -129,6 +130,11 @@ def verify_channel def handle_error(error: nil) self.error = error if error + + if self.error_callback + self.error_callback.call("SSH Command Stream encountered an error: #{self.error} (Server Version: #{self.ssh.transport.server_version.version})") + end + cleanup end diff --git a/modules/auxiliary/scanner/ssh/eaton_xpert_backdoor.rb b/modules/auxiliary/scanner/ssh/eaton_xpert_backdoor.rb index 31832116bdc0f..2be96519f268c 100644 --- a/modules/auxiliary/scanner/ssh/eaton_xpert_backdoor.rb +++ b/modules/auxiliary/scanner/ssh/eaton_xpert_backdoor.rb @@ -84,7 +84,7 @@ def run_host(ip) info: version ) - shell = Net::SSH::CommandStream.new(ssh) + shell = Net::SSH::CommandStream.new(ssh, error_callback: method(:print_error)) # XXX: Wait for CommandStream to log a channel request failure sleep 0.1 diff --git a/modules/auxiliary/scanner/ssh/fortinet_backdoor.rb b/modules/auxiliary/scanner/ssh/fortinet_backdoor.rb index 7f874e63e9dde..8f344692675f9 100644 --- a/modules/auxiliary/scanner/ssh/fortinet_backdoor.rb +++ b/modules/auxiliary/scanner/ssh/fortinet_backdoor.rb @@ -77,7 +77,7 @@ def run_host(ip) info: version ) - shell = Net::SSH::CommandStream.new(ssh) + shell = Net::SSH::CommandStream.new(ssh, error_callback: method(:print_error)) # XXX: Wait for CommandStream to log a channel request failure sleep 0.1 diff --git a/modules/auxiliary/scanner/ssh/libssh_auth_bypass.rb b/modules/auxiliary/scanner/ssh/libssh_auth_bypass.rb index b5341b2b95857..2ae817c2467a5 100644 --- a/modules/auxiliary/scanner/ssh/libssh_auth_bypass.rb +++ b/modules/auxiliary/scanner/ssh/libssh_auth_bypass.rb @@ -120,7 +120,7 @@ def run_host(ip) info: version ) - shell = Net::SSH::CommandStream.new(ssh, datastore['CMD'], pty: datastore['SPAWN_PTY']) + shell = Net::SSH::CommandStream.new(ssh, datastore['CMD'], pty: datastore['SPAWN_PTY'], error_callback: method(:print_error)) # XXX: Wait for CommandStream to log a channel request failure sleep 0.1 diff --git a/modules/exploits/apple_ios/ssh/cydia_default_ssh.rb b/modules/exploits/apple_ios/ssh/cydia_default_ssh.rb index 4ab55b0fce97e..61b5a1174fe51 100644 --- a/modules/exploits/apple_ios/ssh/cydia_default_ssh.rb +++ b/modules/exploits/apple_ios/ssh/cydia_default_ssh.rb @@ -110,7 +110,7 @@ def do_login(user, pass) end if ssh - conn = Net::SSH::CommandStream.new(ssh) + conn = Net::SSH::CommandStream.new(ssh, error_callback: method(:print_error)) ssh = nil return conn end diff --git a/modules/exploits/freebsd/http/junos_phprc_auto_prepend_file.rb b/modules/exploits/freebsd/http/junos_phprc_auto_prepend_file.rb index 6a48241c626b5..e66933717e996 100644 --- a/modules/exploits/freebsd/http/junos_phprc_auto_prepend_file.rb +++ b/modules/exploits/freebsd/http/junos_phprc_auto_prepend_file.rb @@ -349,7 +349,7 @@ def ssh_login end if ssh - Net::SSH::CommandStream.new(ssh) + Net::SSH::CommandStream.new(ssh, error_callback: method(:print_error)) end end diff --git a/modules/exploits/linux/http/ubiquiti_airos_file_upload.rb b/modules/exploits/linux/http/ubiquiti_airos_file_upload.rb index df867f0fb842a..349f6afbe8816 100644 --- a/modules/exploits/linux/http/ubiquiti_airos_file_upload.rb +++ b/modules/exploits/linux/http/ubiquiti_airos_file_upload.rb @@ -156,7 +156,7 @@ def ssh_login private: private_key, private_type: :ssh_key ) - return Net::SSH::CommandStream.new(ssh) + return Net::SSH::CommandStream.new(ssh, error_callback: method(:print_error)) end nil diff --git a/modules/exploits/linux/ssh/ceragon_fibeair_known_privkey.rb b/modules/exploits/linux/ssh/ceragon_fibeair_known_privkey.rb index 116cad9e906bf..10a0c6b909141 100644 --- a/modules/exploits/linux/ssh/ceragon_fibeair_known_privkey.rb +++ b/modules/exploits/linux/ssh/ceragon_fibeair_known_privkey.rb @@ -111,7 +111,7 @@ def do_login(user) if ssh_socket # Create a new session from the socket, then dump it. - conn = Net::SSH::CommandStream.new(ssh_socket) + conn = Net::SSH::CommandStream.new(ssh_socket, error_callback: method(:print_error)) ssh_socket = nil return conn diff --git a/modules/exploits/linux/ssh/cisco_ucs_scpuser.rb b/modules/exploits/linux/ssh/cisco_ucs_scpuser.rb index 539e44d1795c9..dbb72d8f1b9f8 100644 --- a/modules/exploits/linux/ssh/cisco_ucs_scpuser.rb +++ b/modules/exploits/linux/ssh/cisco_ucs_scpuser.rb @@ -114,7 +114,7 @@ def do_login(user, pass) end if ssh - conn = Net::SSH::CommandStream.new(ssh) + conn = Net::SSH::CommandStream.new(ssh, error_callback: method(:print_error)) ssh = nil return conn end diff --git a/modules/exploits/linux/ssh/exagrid_known_privkey.rb b/modules/exploits/linux/ssh/exagrid_known_privkey.rb index d4cce50196d70..6f8e064e108d8 100644 --- a/modules/exploits/linux/ssh/exagrid_known_privkey.rb +++ b/modules/exploits/linux/ssh/exagrid_known_privkey.rb @@ -103,7 +103,7 @@ def do_login(ssh_options) if ssh_socket # Create a new session from the socket, then dump it. - conn = Net::SSH::CommandStream.new(ssh_socket) + conn = Net::SSH::CommandStream.new(ssh_socket, error_callback: method(:print_error)) ssh_socket = nil return conn diff --git a/modules/exploits/linux/ssh/f5_bigip_known_privkey.rb b/modules/exploits/linux/ssh/f5_bigip_known_privkey.rb index 9fabb88999cef..84d8829b00447 100644 --- a/modules/exploits/linux/ssh/f5_bigip_known_privkey.rb +++ b/modules/exploits/linux/ssh/f5_bigip_known_privkey.rb @@ -110,7 +110,7 @@ def do_login(user) return false unless ssh_socket # Create a new session from the socket, then dump it. - conn = Net::SSH::CommandStream.new(ssh_socket) + conn = Net::SSH::CommandStream.new(ssh_socket, error_callback: method(:print_error)) ssh_socket = nil conn end diff --git a/modules/exploits/linux/ssh/ibm_drm_a3user.rb b/modules/exploits/linux/ssh/ibm_drm_a3user.rb index f011ef9d17ef1..9e46e65fc1992 100644 --- a/modules/exploits/linux/ssh/ibm_drm_a3user.rb +++ b/modules/exploits/linux/ssh/ibm_drm_a3user.rb @@ -113,7 +113,7 @@ def do_login(user, pass) fail_with(Failure::Unknown, "#{peer} SSH Error: #{e.class} : #{e.message}") end - return Net::SSH::CommandStream.new(ssh) if ssh + return Net::SSH::CommandStream.new(ssh, error_callback: method(:print_error)) if ssh nil end diff --git a/modules/exploits/linux/ssh/loadbalancerorg_enterprise_known_privkey.rb b/modules/exploits/linux/ssh/loadbalancerorg_enterprise_known_privkey.rb index 750e4cb387d18..e3cc9f49019ae 100644 --- a/modules/exploits/linux/ssh/loadbalancerorg_enterprise_known_privkey.rb +++ b/modules/exploits/linux/ssh/loadbalancerorg_enterprise_known_privkey.rb @@ -108,7 +108,7 @@ def do_login(user) if ssh_socket # Create a new session from the socket, then dump it. - conn = Net::SSH::CommandStream.new(ssh_socket) + conn = Net::SSH::CommandStream.new(ssh_socket, error_callback: method(:print_error)) ssh_socket = nil return conn diff --git a/modules/exploits/linux/ssh/microfocus_obr_shrboadmin.rb b/modules/exploits/linux/ssh/microfocus_obr_shrboadmin.rb index f12ce10a97fbd..d765d41116e39 100644 --- a/modules/exploits/linux/ssh/microfocus_obr_shrboadmin.rb +++ b/modules/exploits/linux/ssh/microfocus_obr_shrboadmin.rb @@ -113,7 +113,7 @@ def do_login(user, pass) end if ssh - conn = Net::SSH::CommandStream.new(ssh) + conn = Net::SSH::CommandStream.new(ssh, error_callback: method(:print_error)) ssh = nil return conn end diff --git a/modules/exploits/linux/ssh/quantum_dxi_known_privkey.rb b/modules/exploits/linux/ssh/quantum_dxi_known_privkey.rb index ce79add91200e..39a445697357e 100644 --- a/modules/exploits/linux/ssh/quantum_dxi_known_privkey.rb +++ b/modules/exploits/linux/ssh/quantum_dxi_known_privkey.rb @@ -107,7 +107,7 @@ def do_login(user) if ssh_socket # Create a new session from the socket, then dump it. - conn = Net::SSH::CommandStream.new(ssh_socket) + conn = Net::SSH::CommandStream.new(ssh_socket, error_callback: method(:print_error)) ssh_socket = nil return conn diff --git a/modules/exploits/linux/ssh/quantum_vmpro_backdoor.rb b/modules/exploits/linux/ssh/quantum_vmpro_backdoor.rb index ac2a5674a3606..b37a5b38335f0 100644 --- a/modules/exploits/linux/ssh/quantum_vmpro_backdoor.rb +++ b/modules/exploits/linux/ssh/quantum_vmpro_backdoor.rb @@ -110,7 +110,7 @@ def do_login(user, pass) end if ssh - conn = Net::SSH::CommandStream.new(ssh, 'shell-escape') + conn = Net::SSH::CommandStream.new(ssh, 'shell-escape', error_callback: method(:print_error)) return conn end diff --git a/modules/exploits/linux/ssh/symantec_smg_ssh.rb b/modules/exploits/linux/ssh/symantec_smg_ssh.rb index 8c7f32067c284..638b0e1d1394c 100644 --- a/modules/exploits/linux/ssh/symantec_smg_ssh.rb +++ b/modules/exploits/linux/ssh/symantec_smg_ssh.rb @@ -100,7 +100,7 @@ def do_login(user, pass) end if ssh - conn = Net::SSH::CommandStream.new(ssh) + conn = Net::SSH::CommandStream.new(ssh, error_callback: method(:print_error)) ssh = nil return conn end diff --git a/modules/exploits/linux/ssh/vmware_vdp_known_privkey.rb b/modules/exploits/linux/ssh/vmware_vdp_known_privkey.rb index e1b41727d0700..3faf750d639a5 100644 --- a/modules/exploits/linux/ssh/vmware_vdp_known_privkey.rb +++ b/modules/exploits/linux/ssh/vmware_vdp_known_privkey.rb @@ -104,7 +104,7 @@ def do_login if ssh_socket # Create a new session from the socket, then dump it. - conn = Net::SSH::CommandStream.new(ssh_socket) + conn = Net::SSH::CommandStream.new(ssh_socket, error_callback: method(:print_error)) sockets.delete(ssh_socket.transport.socket) return conn diff --git a/modules/exploits/linux/ssh/vmware_vrni_known_privkey.rb b/modules/exploits/linux/ssh/vmware_vrni_known_privkey.rb index c2443ab3bbb4f..821433c053d38 100644 --- a/modules/exploits/linux/ssh/vmware_vrni_known_privkey.rb +++ b/modules/exploits/linux/ssh/vmware_vrni_known_privkey.rb @@ -141,7 +141,7 @@ def do_login(user, key_data) if ssh_socket # Create a new session from the socket, then close it. - conn = Net::SSH::CommandStream.new(ssh_socket) + conn = Net::SSH::CommandStream.new(ssh_socket, error_callback: method(:print_error)) ssh_socket = nil return conn diff --git a/modules/exploits/unix/http/schneider_electric_net55xx_encoder.rb b/modules/exploits/unix/http/schneider_electric_net55xx_encoder.rb index a26bf80f64248..22e99cd1e739b 100644 --- a/modules/exploits/unix/http/schneider_electric_net55xx_encoder.rb +++ b/modules/exploits/unix/http/schneider_electric_net55xx_encoder.rb @@ -141,7 +141,7 @@ def do_login print_error "#{rhost}:22 SSH Error: #{e.class} : #{e.message}" end if ssh - conn = Net::SSH::CommandStream.new(ssh) + conn = Net::SSH::CommandStream.new(ssh, error_callback: method(:print_error)) return conn end end diff --git a/modules/exploits/unix/ssh/array_vxag_vapv_privkey_privesc.rb b/modules/exploits/unix/ssh/array_vxag_vapv_privkey_privesc.rb index 078f2a61534ff..acee07511ead0 100644 --- a/modules/exploits/unix/ssh/array_vxag_vapv_privkey_privesc.rb +++ b/modules/exploits/unix/ssh/array_vxag_vapv_privkey_privesc.rb @@ -181,6 +181,6 @@ def exploit # Make the SSH connection and execute our commands + payload print_status("#{rhost}:#{rport} - Sending and executing payload to gain root privileges!") - Net::SSH::CommandStream.new(ssh, build_command) + Net::SSH::CommandStream.new(ssh, build_command, error_callback: method(:print_error)) end end diff --git a/modules/exploits/unix/ssh/tectia_passwd_changereq.rb b/modules/exploits/unix/ssh/tectia_passwd_changereq.rb index b08c4861e45a5..31b0824eb01c8 100644 --- a/modules/exploits/unix/ssh/tectia_passwd_changereq.rb +++ b/modules/exploits/unix/ssh/tectia_passwd_changereq.rb @@ -179,7 +179,7 @@ def userauth_passwd_change(user, transport, connection) message = transport.next_message.type if message.to_i == 6 #SSH2_MSG_SERVICE_ACCEPT - shell = Net::SSH::CommandStream.new(connection) + shell = Net::SSH::CommandStream.new(connection, error_callback: method(:print_error)) connection = nil return shell end