CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/metasploit/framework/login_scanner/ssh.rb
Views: 1904
1
require 'net/ssh'
2
require 'metasploit/framework/login_scanner/base'
3
require 'metasploit/framework/ssh/platform'
4
require 'rex/socket/ssh_factory'
5
6
module Metasploit
7
module Framework
8
module LoginScanner
9
10
# This is the LoginScanner class for dealing with the Secure Shell protocol.
11
# It is responsible for taking a single target, and a list of credentials
12
# and attempting them. It then saves the results.
13
#
14
class SSH
15
include Metasploit::Framework::LoginScanner::Base
16
include Msf::Exploit::Remote::SSH
17
#
18
# CONSTANTS
19
#
20
21
CAN_GET_SESSION = true
22
DEFAULT_PORT = 22
23
LIKELY_PORTS = [ DEFAULT_PORT ]
24
LIKELY_SERVICE_NAMES = [ 'ssh' ]
25
PRIVATE_TYPES = [ :password, :ssh_key ]
26
REALM_KEY = nil
27
28
VERBOSITIES = [
29
:debug,
30
:info,
31
:warn,
32
:error,
33
:fatal
34
]
35
# @!attribute ssh_socket
36
# @return [Net::SSH::Connection::Session] The current SSH connection
37
attr_accessor :ssh_socket
38
# @!attribute verbosity
39
# The verbosity level for the SSH client.
40
#
41
# @return [Symbol] An element of {VERBOSITIES}.
42
attr_accessor :verbosity
43
# @!attribute skip_gather_proof
44
# @return [Boolean] Whether to skip calling gather_proof
45
attr_accessor :skip_gather_proof
46
47
validates :verbosity,
48
presence: true,
49
inclusion: { in: VERBOSITIES }
50
51
# (see {Base#attempt_login})
52
# @note The caller *must* close {#ssh_socket}
53
def attempt_login(credential)
54
self.ssh_socket = nil
55
opt_hash = ssh_client_defaults.merge({
56
:port => port,
57
:verbose => verbosity
58
})
59
case credential.private_type
60
when :password, nil
61
opt_hash.update(
62
:auth_methods => ['password','keyboard-interactive'],
63
:password => credential.private,
64
)
65
when :ssh_key
66
opt_hash.update(
67
:auth_methods => ['publickey'],
68
:key_data => credential.private,
69
)
70
end
71
72
result_options = {
73
credential: credential
74
}
75
begin
76
::Timeout.timeout(connection_timeout) do
77
self.ssh_socket = Net::SSH.start(
78
host,
79
credential.public,
80
opt_hash
81
)
82
end
83
rescue OpenSSL::Cipher::CipherError, ::EOFError, Net::SSH::Disconnect, Rex::ConnectionError, ::Timeout::Error, Errno::ECONNRESET, Errno::EPIPE => e
84
result_options.merge!(status: Metasploit::Model::Login::Status::UNABLE_TO_CONNECT, proof: e)
85
rescue Net::SSH::Exception => e
86
status = Metasploit::Model::Login::Status::INCORRECT
87
status = Metasploit::Model::Login::Status::UNABLE_TO_CONNECT if e.message.split("\n").first == 'could not settle on kex algorithm'
88
89
result_options.merge!(status: status, proof: e)
90
end
91
92
unless result_options.has_key? :status
93
if ssh_socket
94
begin
95
proof = gather_proof unless skip_gather_proof
96
rescue StandardError => e
97
elog('Failed to gather SSH proof', error: e)
98
proof = nil
99
end
100
result_options.merge!(status: Metasploit::Model::Login::Status::SUCCESSFUL, proof: proof)
101
else
102
result_options.merge!(status: Metasploit::Model::Login::Status::INCORRECT, proof: nil)
103
end
104
end
105
106
result = ::Metasploit::Framework::LoginScanner::Result.new(result_options)
107
result.host = host
108
result.port = port
109
result.protocol = 'tcp'
110
result.service_name = 'ssh'
111
result
112
end
113
114
private
115
116
# This method attempts to gather proof that we successfully logged in.
117
# @return [String] The proof of a connection, May be empty.
118
def gather_proof
119
Metasploit::Framework::Ssh::Platform.get_platform_info(ssh_socket)
120
end
121
122
def set_sane_defaults
123
self.connection_timeout = 30 if self.connection_timeout.nil?
124
self.port = DEFAULT_PORT if self.port.nil?
125
self.verbosity = :fatal if self.verbosity.nil?
126
end
127
128
public
129
130
def get_platform(proof)
131
Metasploit::Framework::Ssh::Platform.get_platform_from_info(proof)
132
end
133
end
134
end
135
end
136
end
137
138