ssh_scan 0.0.13 → 0.0.14
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/ssh_scan/client.rb +5 -2
- data/lib/ssh_scan/crypto.rb +38 -0
- data/lib/ssh_scan/policy.rb +2 -1
- data/lib/ssh_scan/policy_manager.rb +16 -1
- data/lib/ssh_scan/scan_engine.rb +15 -14
- data/lib/ssh_scan/version.rb +1 -1
- data/policies/mozilla_intermediate.yml +1 -0
- data/policies/mozilla_modern.yml +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3d541b6a665e8adbd86013e68cea159cb42a514b
|
4
|
+
data.tar.gz: cbbb3ba9b9e169091ca8db560ccfb06780781f39
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 70218de598e768b46841299ebe891980ece0080792d2eac5fcf8d879e13c15c841a817bbf148968cf6ec2117d232c80c7f676eada7b1d812014109bfe5b31c34
|
7
|
+
data.tar.gz: e1fe1bdb16ea13623741607d54e3102af8a4e26c0b94adaebbbc90736c5587a3b2b427057e866cf73e3a66ec7cb58c52a67f6f9ec39a196f6e3cd0bb3c35bb95
|
data/lib/ssh_scan/client.rb
CHANGED
@@ -28,6 +28,9 @@ module SSHScan
|
|
28
28
|
rescue Errno::ENETUNREACH => e
|
29
29
|
@error = SSHScan::Error::ConnectionRefused.new(e.message)
|
30
30
|
@sock = nil
|
31
|
+
rescue Errno::ECONNRESET => e
|
32
|
+
@error = SSHScan::Error::ConnectionRefused.new(e.message)
|
33
|
+
@sock = nil
|
31
34
|
rescue Errno::EACCES => e
|
32
35
|
@error = SSHScan::Error::ConnectionRefused.new(e.message)
|
33
36
|
@sock = nil
|
@@ -61,7 +64,7 @@ module SSHScan
|
|
61
64
|
end
|
62
65
|
|
63
66
|
# Assemble and print results
|
64
|
-
result[:server_banner] = @server_banner
|
67
|
+
result[:server_banner] = @server_banner.to_s
|
65
68
|
result[:ssh_version] = @server_banner.ssh_version
|
66
69
|
result[:os] = @server_banner.os_guess.common
|
67
70
|
result[:os_cpe] = @server_banner.os_guess.cpe
|
@@ -76,7 +79,7 @@ module SSHScan
|
|
76
79
|
@sock = nil
|
77
80
|
return result
|
78
81
|
end
|
79
|
-
|
82
|
+
|
80
83
|
resp += @sock.read(resp.unpack("N").first)
|
81
84
|
@sock.close
|
82
85
|
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
|
3
|
+
module SSHScan
|
4
|
+
module Crypto
|
5
|
+
class PublicKey
|
6
|
+
def initialize(key)
|
7
|
+
@key = key
|
8
|
+
@supported = check_supported
|
9
|
+
if @key.is_a?(OpenSSL::PKey::RSA)
|
10
|
+
@data_string = OpenSSL::ASN1::Sequence([
|
11
|
+
OpenSSL::ASN1::Integer.new(@key.public_key.n),
|
12
|
+
OpenSSL::ASN1::Integer.new(@key.public_key.e)
|
13
|
+
])
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def check_supported
|
18
|
+
@key and @key.is_a?(OpenSSL::PKey::RSA)
|
19
|
+
end
|
20
|
+
|
21
|
+
def is_supported?
|
22
|
+
@supported
|
23
|
+
end
|
24
|
+
|
25
|
+
def fingerprint_md5
|
26
|
+
OpenSSL::Digest::MD5.hexdigest(@data_string.to_der).scan(/../).join(':')
|
27
|
+
end
|
28
|
+
|
29
|
+
def fingerprint_sha1
|
30
|
+
OpenSSL::Digest::SHA1.hexdigest(@data_string.to_der).scan(/../).join(':')
|
31
|
+
end
|
32
|
+
|
33
|
+
def fingerprint_sha256
|
34
|
+
OpenSSL::Digest::SHA256.hexdigest(@data_string.to_der).scan(/../).join(':')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/ssh_scan/policy.rb
CHANGED
@@ -2,7 +2,7 @@ require 'yaml'
|
|
2
2
|
|
3
3
|
module SSHScan
|
4
4
|
class Policy
|
5
|
-
attr_reader :name, :kex, :macs, :encryption, :compression, :references, :auth_methods
|
5
|
+
attr_reader :name, :kex, :macs, :encryption, :compression, :references, :auth_methods, :ssh_version
|
6
6
|
|
7
7
|
def initialize(opts = {})
|
8
8
|
@name = opts['name'] || []
|
@@ -12,6 +12,7 @@ module SSHScan
|
|
12
12
|
@compression = opts['compression'] || []
|
13
13
|
@references = opts['references'] || []
|
14
14
|
@auth_methods = opts['auth_methods'] || []
|
15
|
+
@ssh_version = opts['ssh_version'] || false
|
15
16
|
end
|
16
17
|
|
17
18
|
def self.from_file(file)
|
@@ -104,6 +104,16 @@ module SSHScan
|
|
104
104
|
return outliers
|
105
105
|
end
|
106
106
|
|
107
|
+
def out_of_policy_ssh_version
|
108
|
+
target_ssh_version = @result[:ssh_version]
|
109
|
+
if @policy.ssh_version
|
110
|
+
if target_ssh_version < @policy.ssh_version
|
111
|
+
return true
|
112
|
+
end
|
113
|
+
end
|
114
|
+
return false
|
115
|
+
end
|
116
|
+
|
107
117
|
def compliant?
|
108
118
|
out_of_policy_encryption.empty? &&
|
109
119
|
out_of_policy_macs.empty? &&
|
@@ -113,7 +123,8 @@ module SSHScan
|
|
113
123
|
missing_policy_macs.empty? &&
|
114
124
|
missing_policy_kex.empty? &&
|
115
125
|
missing_policy_compression.empty? &&
|
116
|
-
out_of_policy_auth_methods.empty?
|
126
|
+
out_of_policy_auth_methods.empty? &&
|
127
|
+
out_of_policy_ssh_version
|
117
128
|
end
|
118
129
|
|
119
130
|
def recommendations
|
@@ -131,6 +142,10 @@ module SSHScan
|
|
131
142
|
recommendations << "Remove these Encryption Ciphers: #{out_of_policy_encryption.join(", ")}" unless out_of_policy_encryption.empty?
|
132
143
|
recommendations << "Remove these Compression Algos: #{out_of_policy_compression.join(", ")}" unless out_of_policy_compression.empty?
|
133
144
|
recommendations << "Remove these Authentication Methods: #{out_of_policy_auth_methods.join(", ")}" unless out_of_policy_auth_methods.empty?
|
145
|
+
|
146
|
+
# Update these items to be compliant
|
147
|
+
recommendations << "Update your ssh version to: #{@policy.ssh_version}" if out_of_policy_ssh_version
|
148
|
+
|
134
149
|
return recommendations
|
135
150
|
end
|
136
151
|
|
data/lib/ssh_scan/scan_engine.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'socket'
|
2
2
|
require 'ssh_scan/client'
|
3
|
+
require 'ssh_scan/crypto'
|
3
4
|
require 'net/ssh'
|
4
5
|
|
5
6
|
module SSHScan
|
@@ -14,6 +15,8 @@ module SSHScan
|
|
14
15
|
timeout = opts[:timeout]
|
15
16
|
result = []
|
16
17
|
|
18
|
+
start_time = Time.now
|
19
|
+
|
17
20
|
if target.fqdn?
|
18
21
|
if target.resolve_fqdn_as_ipv6.nil?
|
19
22
|
client = SSHScan::Client.new(target.resolve_fqdn_as_ipv4.to_s, port, timeout)
|
@@ -63,21 +66,12 @@ module SSHScan
|
|
63
66
|
raise e
|
64
67
|
end
|
65
68
|
else
|
66
|
-
|
67
|
-
if
|
68
|
-
data_string = OpenSSL::ASN1::Sequence([
|
69
|
-
OpenSSL::ASN1::Integer.new(host_key.public_key.n),
|
70
|
-
OpenSSL::ASN1::Integer.new(host_key.public_key.e)
|
71
|
-
])
|
72
|
-
|
73
|
-
fingerprint_md5 = OpenSSL::Digest::MD5.hexdigest(data_string.to_der).scan(/../).join(':')
|
74
|
-
fingerprint_sha1 = OpenSSL::Digest::SHA1.hexdigest(data_string.to_der).scan(/../).join(':')
|
75
|
-
fingerprint_sha256 = OpenSSL::Digest::SHA256.hexdigest(data_string.to_der).scan(/../).join(':')
|
76
|
-
|
69
|
+
pkey = SSHScan::Crypto::PublicKey.new(host_key)
|
70
|
+
if pkey.is_supported?
|
77
71
|
result['fingerprints'] = {
|
78
|
-
|
79
|
-
|
80
|
-
|
72
|
+
"md5" => pkey.fingerprint_md5,
|
73
|
+
"sha1" => pkey.fingerprint_sha1,
|
74
|
+
"sha256" => pkey.fingerprint_sha256,
|
81
75
|
}
|
82
76
|
end
|
83
77
|
end
|
@@ -98,6 +92,13 @@ module SSHScan
|
|
98
92
|
result['compliance'] = policy_mgr.compliance_results
|
99
93
|
end
|
100
94
|
|
95
|
+
# Add scan times
|
96
|
+
end_time = Time.now
|
97
|
+
|
98
|
+
result['start_time'] = start_time.to_s
|
99
|
+
result['end_time'] = end_time.to_s
|
100
|
+
result['scan_duration_seconds'] = end_time - start_time
|
101
|
+
|
101
102
|
return result
|
102
103
|
end
|
103
104
|
|
data/lib/ssh_scan/version.rb
CHANGED
data/policies/mozilla_modern.yml
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ssh_scan
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.14
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonathan Claudius
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-09-
|
12
|
+
date: 2016-09-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bindata
|
@@ -128,6 +128,7 @@ files:
|
|
128
128
|
- lib/ssh_scan/banner.rb
|
129
129
|
- lib/ssh_scan/client.rb
|
130
130
|
- lib/ssh_scan/constants.rb
|
131
|
+
- lib/ssh_scan/crypto.rb
|
131
132
|
- lib/ssh_scan/error.rb
|
132
133
|
- lib/ssh_scan/error/closed_connection.rb
|
133
134
|
- lib/ssh_scan/error/connect_timeout.rb
|