ssh_scan 0.0.38 → 0.0.39
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/public_key.rb +59 -0
- data/lib/ssh_scan/result.rb +7 -7
- data/lib/ssh_scan/scan_engine.rb +15 -34
- data/lib/ssh_scan/version.rb +1 -1
- metadata +3 -3
- data/lib/ssh_scan/crypto.rb +0 -60
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 913c588395b88fe25aae08930d7ef15984f75eab0c6976ef868d9c6fbe062f1c
|
4
|
+
data.tar.gz: '0166380a16b6e1f380e4af64d610440bf668b6741985f320fbe6e1dc916cf55f'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 072a07a4d37cf493a5f295e757cd6b330ceeae98b3dd989500a27df4faa6be29def8ff5e6f48ece3b0784e80571b4bfbb873b6fbdb4900c2f1deb66f7c9b5666
|
7
|
+
data.tar.gz: 7b8c97061c7a57b30c8d77544abe8626209196a55808a990f3dc28dc8e6f1fdf94fd1dad73853a0adc98a8b8cccfdd42d3303e3d3a92478fe9ff34eca186315f
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'sshkey'
|
3
|
+
require 'base64'
|
4
|
+
|
5
|
+
module SSHScan
|
6
|
+
# All cryptography related methods.
|
7
|
+
module Crypto
|
8
|
+
# House methods helpful in analysing SSH public keys.
|
9
|
+
class PublicKey
|
10
|
+
def initialize(key_string)
|
11
|
+
@key_string = key_string
|
12
|
+
end
|
13
|
+
|
14
|
+
def valid?
|
15
|
+
SSHKey.valid_ssh_public_key?(@key_string)
|
16
|
+
end
|
17
|
+
|
18
|
+
def type
|
19
|
+
if @key_string.start_with?("ssh-rsa")
|
20
|
+
return "rsa"
|
21
|
+
elsif @key_string.start_with?("ssh-dss")
|
22
|
+
return "dsa"
|
23
|
+
else
|
24
|
+
return "unknown"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def length
|
29
|
+
SSHKey.ssh_public_key_bits(@key_string)
|
30
|
+
end
|
31
|
+
|
32
|
+
def fingerprint_md5
|
33
|
+
SSHKey.fingerprint(@key_string)
|
34
|
+
end
|
35
|
+
|
36
|
+
def fingerprint_sha1
|
37
|
+
SSHKey.sha1_fingerprint(@key_string)
|
38
|
+
end
|
39
|
+
|
40
|
+
def fingerprint_sha256
|
41
|
+
SSHKey.sha256_fingerprint(@key_string)
|
42
|
+
end
|
43
|
+
|
44
|
+
def to_hash
|
45
|
+
{
|
46
|
+
self.type => {
|
47
|
+
"raw" => @key_string,
|
48
|
+
"length" => self.length,
|
49
|
+
"fingerprints" => {
|
50
|
+
"md5" => self.fingerprint_md5,
|
51
|
+
"sha1" => self.fingerprint_sha1,
|
52
|
+
"sha256" => self.fingerprint_sha256
|
53
|
+
}
|
54
|
+
}
|
55
|
+
}
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/lib/ssh_scan/result.rb
CHANGED
@@ -8,7 +8,7 @@ module SSHScan
|
|
8
8
|
class Result
|
9
9
|
def initialize()
|
10
10
|
@version = SSHScan::VERSION
|
11
|
-
@
|
11
|
+
@keys = nil
|
12
12
|
@duplicate_host_key_ips = Set.new()
|
13
13
|
@compliance = {}
|
14
14
|
end
|
@@ -157,12 +157,12 @@ module SSHScan
|
|
157
157
|
@auth_methods = auth_methods
|
158
158
|
end
|
159
159
|
|
160
|
-
def
|
161
|
-
@
|
160
|
+
def keys=(keys)
|
161
|
+
@keys = keys
|
162
162
|
end
|
163
163
|
|
164
|
-
def
|
165
|
-
@
|
164
|
+
def keys
|
165
|
+
@keys
|
166
166
|
end
|
167
167
|
|
168
168
|
def duplicate_host_key_ips=(duplicate_host_key_ips)
|
@@ -249,8 +249,8 @@ module SSHScan
|
|
249
249
|
"languages_client_to_server" => self.languages_client_to_server,
|
250
250
|
"languages_server_to_client" => self.languages_server_to_client,
|
251
251
|
"auth_methods" => self.auth_methods,
|
252
|
-
"
|
253
|
-
"duplicate_host_key_ips" => self.duplicate_host_key_ips,
|
252
|
+
"keys" => self.keys,
|
253
|
+
"duplicate_host_key_ips" => self.duplicate_host_key_ips.uniq,
|
254
254
|
"compliance" => @compliance,
|
255
255
|
"start_time" => self.start_time,
|
256
256
|
"end_time" => self.end_time,
|
data/lib/ssh_scan/scan_engine.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'socket'
|
2
2
|
require 'ssh_scan/client'
|
3
|
-
require 'ssh_scan/
|
3
|
+
require 'ssh_scan/public_key'
|
4
4
|
require 'ssh_scan/fingerprint_database'
|
5
5
|
require 'ssh_scan/subprocess'
|
6
6
|
require 'net/ssh'
|
@@ -119,7 +119,7 @@ module SSHScan
|
|
119
119
|
end
|
120
120
|
|
121
121
|
# Figure out what rsa or dsa fingerprints exist
|
122
|
-
|
122
|
+
keys = {}
|
123
123
|
|
124
124
|
output = ""
|
125
125
|
|
@@ -136,31 +136,17 @@ module SSHScan
|
|
136
136
|
|
137
137
|
for i in 0..host_keys_len
|
138
138
|
if host_keys[i].eql? "ssh-dss"
|
139
|
-
|
140
|
-
|
141
|
-
"dsa" => {
|
142
|
-
"known_bad" => pkey.bad_key?.to_s,
|
143
|
-
"md5" => pkey.fingerprint_md5,
|
144
|
-
"sha1" => pkey.fingerprint_sha1,
|
145
|
-
"sha256" => pkey.fingerprint_sha256,
|
146
|
-
}
|
147
|
-
})
|
139
|
+
key = SSHScan::Crypto::PublicKey.new([host_keys[i], host_keys[i + 1]].join(" "))
|
140
|
+
keys.merge!(key.to_hash)
|
148
141
|
end
|
149
142
|
|
150
143
|
if host_keys[i].eql? "ssh-rsa"
|
151
|
-
|
152
|
-
|
153
|
-
"rsa" => {
|
154
|
-
"known_bad" => pkey.bad_key?.to_s,
|
155
|
-
"md5" => pkey.fingerprint_md5,
|
156
|
-
"sha1" => pkey.fingerprint_sha1,
|
157
|
-
"sha256" => pkey.fingerprint_sha256,
|
158
|
-
}
|
159
|
-
})
|
144
|
+
key = SSHScan::Crypto::PublicKey.new([host_keys[i], host_keys[i + 1]].join(" "))
|
145
|
+
keys.merge!(key.to_hash)
|
160
146
|
end
|
161
147
|
end
|
162
148
|
|
163
|
-
result.
|
149
|
+
result.keys = keys
|
164
150
|
result.set_end_time
|
165
151
|
|
166
152
|
return result
|
@@ -200,12 +186,10 @@ module SSHScan
|
|
200
186
|
results.each do |result|
|
201
187
|
fingerprint_db.clear_fingerprints(result.ip)
|
202
188
|
|
203
|
-
if result.
|
204
|
-
result.
|
205
|
-
host_key_algo.each do |fingerprint|
|
206
|
-
|
207
|
-
next if key == "known_bad"
|
208
|
-
fingerprint_db.add_fingerprint(value, result.ip)
|
189
|
+
if result.keys
|
190
|
+
result.keys.values.each do |host_key_algo|
|
191
|
+
host_key_algo['fingerprints'].values.each do |fingerprint|
|
192
|
+
fingerprint_db.add_fingerprint(fingerprint, result.ip)
|
209
193
|
end
|
210
194
|
end
|
211
195
|
end
|
@@ -213,20 +197,17 @@ module SSHScan
|
|
213
197
|
|
214
198
|
# Decorate all the results with duplicate keys
|
215
199
|
results.each do |result|
|
216
|
-
if result.
|
200
|
+
if result.keys
|
217
201
|
ip = result.ip
|
218
202
|
result.duplicate_host_key_ips = []
|
219
|
-
result.
|
220
|
-
host_key_algo.each do |fingerprint|
|
221
|
-
|
222
|
-
next if key == "known_bad"
|
223
|
-
fingerprint_db.find_fingerprints(value).each do |other_ip|
|
203
|
+
result.keys.values.each do |host_key_algo|
|
204
|
+
host_key_algo["fingerprints"].values.each do |fingerprint|
|
205
|
+
fingerprint_db.find_fingerprints(fingerprint).each do |other_ip|
|
224
206
|
next if ip == other_ip
|
225
207
|
result.duplicate_host_key_ips << other_ip
|
226
208
|
end
|
227
209
|
end
|
228
210
|
end
|
229
|
-
result.duplicate_host_key_ips
|
230
211
|
end
|
231
212
|
end
|
232
213
|
|
data/lib/ssh_scan/version.rb
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.39
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonathan Claudius
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2019-01-
|
15
|
+
date: 2019-01-18 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: bindata
|
@@ -163,7 +163,6 @@ files:
|
|
163
163
|
- lib/ssh_scan/banner.rb
|
164
164
|
- lib/ssh_scan/client.rb
|
165
165
|
- lib/ssh_scan/constants.rb
|
166
|
-
- lib/ssh_scan/crypto.rb
|
167
166
|
- lib/ssh_scan/error.rb
|
168
167
|
- lib/ssh_scan/error/closed_connection.rb
|
169
168
|
- lib/ssh_scan/error/connect_timeout.rb
|
@@ -188,6 +187,7 @@ files:
|
|
188
187
|
- lib/ssh_scan/policy.rb
|
189
188
|
- lib/ssh_scan/policy_manager.rb
|
190
189
|
- lib/ssh_scan/protocol.rb
|
190
|
+
- lib/ssh_scan/public_key.rb
|
191
191
|
- lib/ssh_scan/result.rb
|
192
192
|
- lib/ssh_scan/scan_engine.rb
|
193
193
|
- lib/ssh_scan/ssh_lib.rb
|
data/lib/ssh_scan/crypto.rb
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
require 'openssl'
|
2
|
-
require 'sshkey'
|
3
|
-
require 'base64'
|
4
|
-
|
5
|
-
module SSHScan
|
6
|
-
# All cryptography related methods.
|
7
|
-
module Crypto
|
8
|
-
# House methods helpful in analysing SSH public keys.
|
9
|
-
class PublicKey
|
10
|
-
def initialize(key)
|
11
|
-
@key = key
|
12
|
-
end
|
13
|
-
|
14
|
-
# Is the current key known to be in our known bad key list
|
15
|
-
# @return [Boolean] true if this {SSHScan::Crypto::PublicKey}
|
16
|
-
# instance's key is also in {SSHScan::Crypto}'s
|
17
|
-
# bad_public_keys, otherwise false
|
18
|
-
def bad_key?
|
19
|
-
SSHScan::Crypto.bad_public_keys.each do |other_key|
|
20
|
-
if self.fingerprint_sha256 == other_key.fingerprint_sha256
|
21
|
-
return true
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
return false
|
26
|
-
end
|
27
|
-
|
28
|
-
# Generate MD5 fingerprint for this {SSHScan::Crypto::PublicKey} instance.
|
29
|
-
# @return [String] formatted MD5 fingerprint
|
30
|
-
def fingerprint_md5
|
31
|
-
OpenSSL::Digest::MD5.hexdigest(::Base64.decode64(@key)).scan(/../).join(':')
|
32
|
-
end
|
33
|
-
|
34
|
-
# Generate SHA1 fingerprint for this {SSHScan::Crypto::PublicKey} instance.
|
35
|
-
# @return [String] formatted SHA1 fingerprint
|
36
|
-
def fingerprint_sha1
|
37
|
-
OpenSSL::Digest::SHA1.hexdigest(::Base64.decode64(@key)).scan(/../).join(':')
|
38
|
-
end
|
39
|
-
|
40
|
-
# Generate SHA256 fingerprint for this {SSHScan::Crypto::PublicKey} instance.
|
41
|
-
# @return [String] formatted SHA256 fingerprint
|
42
|
-
def fingerprint_sha256
|
43
|
-
OpenSSL::Digest::SHA256.hexdigest(::Base64.decode64(@key)).scan(/../).join(':')
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def self.bad_public_keys
|
48
|
-
bad_keys = []
|
49
|
-
|
50
|
-
Dir.glob("data/ssh-badkeys/host/*.key").each do |file_path|
|
51
|
-
file = File.read(File.expand_path(file_path))
|
52
|
-
key = SSHKey.new(file)
|
53
|
-
bad_keys << SSHScan::Crypto::PublicKey.new(key.ssh_public_key.split[1])
|
54
|
-
end
|
55
|
-
|
56
|
-
return bad_keys
|
57
|
-
end
|
58
|
-
|
59
|
-
end
|
60
|
-
end
|