ssh_scan 0.0.39 → 0.0.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +15 -8
- data/CONTRIBUTING.md +3 -3
- data/README.md +3 -4
- data/bin/ssh_scan +19 -5
- data/config/policies/just_etm_macs.yaml +24 -0
- data/lib/ssh_scan/client.rb +3 -0
- data/lib/ssh_scan/public_key.rb +7 -2
- data/lib/ssh_scan/result.rb +11 -2
- data/lib/ssh_scan/scan_engine.rb +22 -2
- data/lib/ssh_scan/ssh_fp.rb +57 -0
- data/lib/ssh_scan/target_parser.rb +11 -18
- data/lib/ssh_scan/version.rb +1 -1
- data/lib/string_ext.rb +30 -1
- data/ssh_scan.gemspec +5 -3
- metadata +44 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6174ee5e2ad23ab2ba83ecb51af937fba17db13e8dba7590ccf4b2cdb93c9aa5
|
4
|
+
data.tar.gz: dbad23e44d2f0b06625a8ae62eae20e7a7bc94a0aecadf01d143e0c9c1d4d373
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1acd0b7879e43c38b9ff19487a7a4c4c8e6bb1598a27977dfb13d1c9559d5a222d7cf1a2762325deb29536ce055f6295cbc49382f858f9211639d1de5b0891e9
|
7
|
+
data.tar.gz: 0e880c12f64ece3ba79880f880ff7b7e1fa5b916636518b373bf40985ea4f7be3a3dfca0da9fd1d974364ca26bf8ef52dda798a9357b40f2dc896520cc0ef9b2
|
data/.travis.yml
CHANGED
@@ -11,37 +11,44 @@ matrix:
|
|
11
11
|
- LABEL=unit_tests
|
12
12
|
after_success:
|
13
13
|
- coveralls
|
14
|
-
- rvm: 2.
|
14
|
+
- rvm: 2.6.7
|
15
15
|
env:
|
16
16
|
- LABEL=unit_tests
|
17
|
-
- rvm: 2.
|
17
|
+
- rvm: 2.7.3
|
18
18
|
env:
|
19
19
|
- LABEL=unit_tests
|
20
|
-
- rvm:
|
20
|
+
- rvm: 3.0.1
|
21
21
|
env:
|
22
22
|
- LABEL=unit_tests
|
23
|
-
- rvm: 2.
|
23
|
+
- rvm: 2.6.7
|
24
24
|
env:
|
25
25
|
- LABEL=gem_integration_tests
|
26
26
|
script:
|
27
27
|
- gem install ssh_scan
|
28
28
|
- chmod 755 ./spec/ssh_scan/integration.sh
|
29
29
|
- ./spec/ssh_scan/integration.sh
|
30
|
-
- rvm: 2.
|
30
|
+
- rvm: 2.7.3
|
31
31
|
env:
|
32
32
|
- LABEL=gem_integration_tests
|
33
33
|
script:
|
34
34
|
- gem install ssh_scan
|
35
35
|
- chmod 755 ./spec/ssh_scan/integration.sh
|
36
36
|
- ./spec/ssh_scan/integration.sh
|
37
|
-
- rvm:
|
37
|
+
- rvm: 3.0.1
|
38
|
+
env:
|
39
|
+
- LABEL=gem_integration_tests
|
40
|
+
script:
|
41
|
+
- gem install ssh_scan
|
42
|
+
- chmod 755 ./spec/ssh_scan/integration.sh
|
43
|
+
- ./spec/ssh_scan/integration.sh
|
44
|
+
- rvm: 2.7.3
|
38
45
|
env:
|
39
46
|
- LABEL=src_integration_tests
|
40
47
|
script:
|
41
48
|
- bundle install
|
42
49
|
- chmod 755 ./spec/ssh_scan/integration.sh
|
43
50
|
- ./spec/ssh_scan/integration.sh
|
44
|
-
- rvm:
|
51
|
+
- rvm: 3.0.1
|
45
52
|
env:
|
46
53
|
- LABEL=docker_integration_tests
|
47
54
|
services:
|
@@ -49,7 +56,7 @@ matrix:
|
|
49
56
|
script:
|
50
57
|
- docker build -t mozilla/ssh_scan .
|
51
58
|
- docker run -it mozilla/ssh_scan /app/spec/ssh_scan/integration.sh
|
52
|
-
- rvm:
|
59
|
+
- rvm: 3.0.1
|
53
60
|
env:
|
54
61
|
- LABEL=docker_build_and_push
|
55
62
|
services:
|
data/CONTRIBUTING.md
CHANGED
@@ -27,9 +27,9 @@ inclusion, but sending a pull request is much more awesome.
|
|
27
27
|
|
28
28
|
If you want your pull requests to be accepted, please follow the following guidelines:
|
29
29
|
|
30
|
-
- [**Add tests!**](
|
30
|
+
- [**Add tests!**](https://rspec.info/) Your patch won't be accepted (or will be delayed) if it doesn't have tests.
|
31
31
|
|
32
|
-
- [**Document any change in behaviour**](
|
32
|
+
- [**Document any change in behaviour**](https://yardoc.org/) Make sure the README and any other
|
33
33
|
relevant documentation are kept up-to-date.
|
34
34
|
|
35
35
|
- [**Create topic branches**](https://github.com/dchelimsky/rspec/wiki/Topic-Branches) Don't ask us to pull from your master branch.
|
@@ -37,7 +37,7 @@ If you want your pull requests to be accepted, please follow the following guide
|
|
37
37
|
- [**One pull request per feature**](https://help.github.com/articles/using-pull-requests) If you want to do more than one thing, send
|
38
38
|
multiple pull requests.
|
39
39
|
|
40
|
-
- [**Send coherent history**](
|
40
|
+
- [**Send coherent history**](https://stackoverflow.com/questions/6934752/git-combining-multiple-commits-before-pushing) Make sure each individual commit in your pull
|
41
41
|
request is meaningful. If you had to make multiple intermediate commits while
|
42
42
|
developing, please squash them before sending them to us.
|
43
43
|
|
data/README.md
CHANGED
@@ -9,7 +9,7 @@ A SSH configuration and policy scanner
|
|
9
9
|
|
10
10
|
## Key Benefits
|
11
11
|
|
12
|
-
- **Minimal
|
12
|
+
- **Minimal Dependencies** - Uses native Ruby and BinData to do its work, no heavy dependencies.
|
13
13
|
- **Not Just a Script** - Implementation is portable for use in another project or for automation of tasks.
|
14
14
|
- **Simple** - Just point `ssh_scan` at an SSH service and get a JSON report of what it supports and its policy status.
|
15
15
|
- **Configurable** - Make your own custom policies that fit your unique policy requirements.
|
@@ -27,7 +27,7 @@ To run from a docker container, type:
|
|
27
27
|
|
28
28
|
```bash
|
29
29
|
docker pull mozilla/ssh_scan
|
30
|
-
docker run -it mozilla/ssh_scan
|
30
|
+
docker run -it mozilla/ssh_scan -t sshscan.rubidus.com
|
31
31
|
```
|
32
32
|
|
33
33
|
To install and run from source, type:
|
@@ -83,13 +83,12 @@ Examples:
|
|
83
83
|
ssh_scan -t 192.168.1.1 --unit-test -P custom_policy.yml
|
84
84
|
```
|
85
85
|
|
86
|
-
- See here for [example video](https://asciinema.org/a/7pliiw5zqhj7eqvz7q437u6vx)
|
87
86
|
- See here for [example output](https://github.com/mozilla/ssh_scan/blob/master/examples/192.168.1.1.json)
|
88
87
|
- See here for [example policies](https://github.com/mozilla/ssh_scan/blob/master/config/policies)
|
89
88
|
|
90
89
|
## ssh_scan as a service/api?
|
91
90
|
|
92
|
-
This project is
|
91
|
+
This project is solely for ssh_scan engine/command-line usage.
|
93
92
|
|
94
93
|
If you would like to run ssh_scan as a service, please refer to [the ssh_scan_api project](https://github.com/mozilla/ssh_scan_api)
|
95
94
|
|
data/bin/ssh_scan
CHANGED
@@ -4,7 +4,6 @@
|
|
4
4
|
$:.unshift File.join(File.dirname(__FILE__), "../lib")
|
5
5
|
|
6
6
|
require 'json'
|
7
|
-
require 'netaddr'
|
8
7
|
require 'optparse'
|
9
8
|
require 'ssh_scan'
|
10
9
|
require 'logger'
|
@@ -20,7 +19,7 @@ options = {
|
|
20
19
|
"verbosity" => nil,
|
21
20
|
"logger" => Logger.new(STDERR),
|
22
21
|
"fingerprint_database" => ENV['HOME']+'/.ssh_scan_fingerprints.yml',
|
23
|
-
"output_type" =>
|
22
|
+
"output_type" => nil
|
24
23
|
}
|
25
24
|
|
26
25
|
# Reorder arguments before parsing
|
@@ -106,7 +105,8 @@ scan") do |file|
|
|
106
105
|
|
107
106
|
opts.on("-o", "--output [FilePath]",
|
108
107
|
"File to write JSON output to") do |file|
|
109
|
-
|
108
|
+
options["output"] = file
|
109
|
+
# $stdout.reopen(file, "w")
|
110
110
|
end
|
111
111
|
|
112
112
|
opts.on("--output-type [json, yaml]",
|
@@ -238,9 +238,23 @@ options["policy_file"] = SSHScan::Policy.from_file(options["policy"])
|
|
238
238
|
scan_engine = SSHScan::ScanEngine.new()
|
239
239
|
results = scan_engine.scan(options)
|
240
240
|
|
241
|
-
if options["output_type"] == "yaml"
|
241
|
+
if options["output_type"] == "yaml" && (options["output"].nil? || options["output"].empty?)
|
242
242
|
puts YAML.dump(results)
|
243
|
-
elsif options["output_type"] == "json"
|
243
|
+
elsif options["output_type"] == "json" && (options["output"].nil? || options["output"].empty?)
|
244
|
+
puts JSON.pretty_generate(results)
|
245
|
+
elsif (options["output_type"].nil? || options["output_type"].empty?) && (!options["output"].nil? && options["output"].split(".").last.downcase == "yml")
|
246
|
+
open(options["output"], 'w') do |f|
|
247
|
+
f.puts YAML.dump(results)
|
248
|
+
end
|
249
|
+
elsif (options["output_type"].nil? || options["output_type"].empty?) && (!options["output"].nil? && options["output"].split(".").last.downcase == "json")
|
250
|
+
open(options["output"], 'w') do |f|
|
251
|
+
f.puts JSON.pretty_generate(results)
|
252
|
+
end
|
253
|
+
elsif (options["output_type"].nil? || options["output_type"].empty?) && options["output"]
|
254
|
+
open(options["output"], 'w') do |f|
|
255
|
+
f.puts JSON.pretty_generate(results)
|
256
|
+
end
|
257
|
+
else
|
244
258
|
puts JSON.pretty_generate(results)
|
245
259
|
end
|
246
260
|
|
@@ -0,0 +1,24 @@
|
|
1
|
+
---
|
2
|
+
name: Mozilla Modern - with just ETM macs
|
3
|
+
ssh_version: 2.0
|
4
|
+
auth_methods:
|
5
|
+
- publickey
|
6
|
+
kex:
|
7
|
+
- curve25519-sha256@libssh.org
|
8
|
+
- ecdh-sha2-nistp521
|
9
|
+
- ecdh-sha2-nistp384
|
10
|
+
- ecdh-sha2-nistp256
|
11
|
+
- diffie-hellman-group-exchange-sha256
|
12
|
+
encryption:
|
13
|
+
- chacha20-poly1305@openssh.com
|
14
|
+
- aes256-gcm@openssh.com
|
15
|
+
- aes128-gcm@openssh.com
|
16
|
+
- aes256-ctr
|
17
|
+
- aes192-ctr
|
18
|
+
- aes128-ctr
|
19
|
+
macs:
|
20
|
+
- hmac-sha2-512-etm@openssh.com
|
21
|
+
- hmac-sha2-256-etm@openssh.com
|
22
|
+
- umac-128-etm@openssh.com
|
23
|
+
references:
|
24
|
+
- https://example.com/custom_policy
|
data/lib/ssh_scan/client.rb
CHANGED
@@ -70,6 +70,9 @@ module SSHScan
|
|
70
70
|
rescue Errno::EHOSTUNREACH => e
|
71
71
|
@error = SSHScan::Error::ConnectionRefused.new(e.message)
|
72
72
|
@sock = nil
|
73
|
+
rescue Errno::ENOPROTOOPT => e
|
74
|
+
@error = SSHScan::Error::ConnectionRefused.new(e.message)
|
75
|
+
@sock = nil
|
73
76
|
else
|
74
77
|
if @raw_server_banner.nil?
|
75
78
|
@error = SSHScan::Error::NoBanner.new(
|
data/lib/ssh_scan/public_key.rb
CHANGED
@@ -20,6 +20,10 @@ module SSHScan
|
|
20
20
|
return "rsa"
|
21
21
|
elsif @key_string.start_with?("ssh-dss")
|
22
22
|
return "dsa"
|
23
|
+
elsif @key_string.start_with?("ecdsa-sha2-nistp256")
|
24
|
+
return "ecdsa-sha2-nistp256"
|
25
|
+
elsif @key_string.start_with?("ssh-ed25519")
|
26
|
+
return "ed25519"
|
23
27
|
else
|
24
28
|
return "unknown"
|
25
29
|
end
|
@@ -35,10 +39,11 @@ module SSHScan
|
|
35
39
|
|
36
40
|
def fingerprint_sha1
|
37
41
|
SSHKey.sha1_fingerprint(@key_string)
|
38
|
-
end
|
42
|
+
end
|
39
43
|
|
40
44
|
def fingerprint_sha256
|
41
|
-
|
45
|
+
# We're translating this to hex because the SSHKEY default isn't as useful for comparing with SSHFP records
|
46
|
+
Base64.decode64(SSHKey.sha256_fingerprint(@key_string)).hexify(:delim => ":")
|
42
47
|
end
|
43
48
|
|
44
49
|
def to_hash
|
data/lib/ssh_scan/result.rb
CHANGED
@@ -157,12 +157,20 @@ module SSHScan
|
|
157
157
|
@auth_methods = auth_methods
|
158
158
|
end
|
159
159
|
|
160
|
+
def keys
|
161
|
+
@keys || {}
|
162
|
+
end
|
163
|
+
|
160
164
|
def keys=(keys)
|
161
165
|
@keys = keys
|
162
166
|
end
|
163
167
|
|
164
|
-
def
|
165
|
-
@
|
168
|
+
def dns_keys
|
169
|
+
@dns_keys
|
170
|
+
end
|
171
|
+
|
172
|
+
def dns_keys=(dns_keys)
|
173
|
+
@dns_keys = dns_keys
|
166
174
|
end
|
167
175
|
|
168
176
|
def duplicate_host_key_ips=(duplicate_host_key_ips)
|
@@ -250,6 +258,7 @@ module SSHScan
|
|
250
258
|
"languages_server_to_client" => self.languages_server_to_client,
|
251
259
|
"auth_methods" => self.auth_methods,
|
252
260
|
"keys" => self.keys,
|
261
|
+
"dns_keys" => self.dns_keys,
|
253
262
|
"duplicate_host_key_ips" => self.duplicate_host_key_ips.uniq,
|
254
263
|
"compliance" => @compliance,
|
255
264
|
"start_time" => self.start_time,
|
data/lib/ssh_scan/scan_engine.rb
CHANGED
@@ -3,6 +3,7 @@ require 'ssh_scan/client'
|
|
3
3
|
require 'ssh_scan/public_key'
|
4
4
|
require 'ssh_scan/fingerprint_database'
|
5
5
|
require 'ssh_scan/subprocess'
|
6
|
+
require 'ssh_scan/ssh_fp'
|
6
7
|
require 'net/ssh'
|
7
8
|
require 'logger'
|
8
9
|
require 'open3'
|
@@ -97,7 +98,7 @@ module SSHScan
|
|
97
98
|
target,
|
98
99
|
:port => port,
|
99
100
|
:timeout => timeout,
|
100
|
-
:
|
101
|
+
:verify_host_key => :never
|
101
102
|
)
|
102
103
|
raise SSHScan::Error::ClosedConnection.new if net_ssh_session.closed?
|
103
104
|
auth_session = Net::SSH::Authentication::Session.new(
|
@@ -123,7 +124,7 @@ module SSHScan
|
|
123
124
|
|
124
125
|
output = ""
|
125
126
|
|
126
|
-
cmd = ['ssh-keyscan', '-t', 'rsa,dsa', '-p', port.to_s, target].join(" ")
|
127
|
+
cmd = ['ssh-keyscan', '-t', 'rsa,dsa,ecdsa,ed25519', '-p', port.to_s, target].join(" ")
|
127
128
|
|
128
129
|
Utils::Subprocess.new(cmd) do |stdout, stderr, thread|
|
129
130
|
if stdout
|
@@ -144,6 +145,16 @@ module SSHScan
|
|
144
145
|
key = SSHScan::Crypto::PublicKey.new([host_keys[i], host_keys[i + 1]].join(" "))
|
145
146
|
keys.merge!(key.to_hash)
|
146
147
|
end
|
148
|
+
|
149
|
+
if host_keys[i].eql? "ecdsa-sha2-nistp256"
|
150
|
+
key = SSHScan::Crypto::PublicKey.new([host_keys[i], host_keys[i + 1]].join(" "))
|
151
|
+
keys.merge!(key.to_hash)
|
152
|
+
end
|
153
|
+
|
154
|
+
if host_keys[i].eql? "ssh-ed25519"
|
155
|
+
key = SSHScan::Crypto::PublicKey.new([host_keys[i], host_keys[i + 1]].join(" "))
|
156
|
+
keys.merge!(key.to_hash)
|
157
|
+
end
|
147
158
|
end
|
148
159
|
|
149
160
|
result.keys = keys
|
@@ -211,6 +222,15 @@ module SSHScan
|
|
211
222
|
end
|
212
223
|
end
|
213
224
|
|
225
|
+
# Decorate all the results with SSHFP records
|
226
|
+
sshfp = SSHScan::SshFp.new()
|
227
|
+
results.each do |result|
|
228
|
+
if !result.hostname.empty?
|
229
|
+
dns_keys = sshfp.query(result.hostname)
|
230
|
+
result.dns_keys = dns_keys
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
214
234
|
# Decorate all the results with compliance information
|
215
235
|
results.each do |result|
|
216
236
|
# Do this only when we have all the information we need
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'resolv'
|
2
|
+
|
3
|
+
module SSHScan
|
4
|
+
class SshFp
|
5
|
+
|
6
|
+
ALGO_MAP = {
|
7
|
+
0 => "reserved", # Reference: https://tools.ietf.org/html/rfc4255#section-2.4
|
8
|
+
1 => "rsa", # Reference: https://tools.ietf.org/html/rfc4255#section-2.4
|
9
|
+
2 => "dss", # Reference: https://tools.ietf.org/html/rfc4255#section-2.4
|
10
|
+
3 => "ecdsa", # Reference: https://tools.ietf.org/html/rfc6594#section-5.3.1
|
11
|
+
4 => "ed25519" # Reference: https://tools.ietf.org/html/rfc7479
|
12
|
+
}
|
13
|
+
|
14
|
+
|
15
|
+
FPTYPE_MAP = {
|
16
|
+
0 => "reserved", # Reference: https://tools.ietf.org/html/rfc4255#section-2.4
|
17
|
+
1 => "sha1", # Reference: https://tools.ietf.org/html/rfc4255#section-2.4
|
18
|
+
2 => "sha256" # Reference: https://tools.ietf.org/html/rfc6594#section-5.1.2
|
19
|
+
}
|
20
|
+
|
21
|
+
|
22
|
+
def query(fqdn)
|
23
|
+
sshfp_records = []
|
24
|
+
|
25
|
+
# try up to 5 times to resolve ssh_fp's
|
26
|
+
5.times do
|
27
|
+
|
28
|
+
# Reference: https://stackoverflow.com/questions/28867626/how-to-use-resolvdnsresourcegeneric
|
29
|
+
# Note: this includes some fixes too, I'll post a direct link back to the SO article.
|
30
|
+
Resolv::DNS.open do |dns|
|
31
|
+
all_records = dns.getresources(fqdn, Resolv::DNS::Resource::IN::ANY ) rescue nil
|
32
|
+
all_records.each do |rr|
|
33
|
+
if rr.is_a? Resolv::DNS::Resource::Generic then
|
34
|
+
classname = rr.class.name.split('::').last
|
35
|
+
if classname == "Type44_Class1"
|
36
|
+
data = rr.data.bytes
|
37
|
+
algo = data[0].to_s
|
38
|
+
fptype = data[1].to_s
|
39
|
+
fp = data[2..-1]
|
40
|
+
hex = fp.map{|b| b.to_s(16).rjust(2,'0') }.join(':')
|
41
|
+
sshfp_records << {"fptype" => FPTYPE_MAP[fptype.to_i], "algo" => ALGO_MAP[algo.to_i], "hex" => hex}
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
if sshfp_records.any?
|
48
|
+
return sshfp_records.sort_by { |k| k["hex"] }
|
49
|
+
end
|
50
|
+
|
51
|
+
sleep 0.5
|
52
|
+
end
|
53
|
+
|
54
|
+
return sshfp_records
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -8,7 +8,7 @@ module SSHScan
|
|
8
8
|
# @param ip [String] IP address
|
9
9
|
# @param port [Fixnum] port
|
10
10
|
# @return [Array] array of enumerated addresses
|
11
|
-
def enumerateIPRange(ip,port)
|
11
|
+
def enumerateIPRange(ip,port=nil)
|
12
12
|
if ip.fqdn?
|
13
13
|
if port.nil?
|
14
14
|
socket = ip
|
@@ -17,29 +17,22 @@ module SSHScan
|
|
17
17
|
end
|
18
18
|
return [socket]
|
19
19
|
else
|
20
|
-
if ip.include? "
|
21
|
-
octets = ip.split('.')
|
22
|
-
range = octets.pop.split('-')
|
23
|
-
lower = NetAddr::CIDR.create(octets.join('.') + "." + range[0])
|
24
|
-
upper = NetAddr::CIDR.create(octets.join('.') + "." + range[1])
|
25
|
-
ip_array = NetAddr.range(lower, upper,:Inclusive => true)
|
26
|
-
if !port.nil?
|
27
|
-
ip_array.map! { |i| i.concat(":").concat(port.to_s) }
|
28
|
-
end
|
29
|
-
return ip_array
|
30
|
-
elsif ip.include? "/"
|
20
|
+
if ip.include? "/"
|
31
21
|
begin
|
32
|
-
|
22
|
+
ip_net = NetAddr::IPv4Net.parse(ip)
|
33
23
|
rescue
|
34
24
|
raise ArgumentError, "Invalid target: #{ip}"
|
35
25
|
end
|
36
|
-
|
37
|
-
|
38
|
-
|
26
|
+
|
27
|
+
sock_array = []
|
28
|
+
1.upto(ip_net.len - 2) do |i|
|
29
|
+
sock_array << ip_net.nth(i).to_s
|
30
|
+
end
|
31
|
+
|
39
32
|
if !port.nil?
|
40
|
-
|
33
|
+
sock_array.map! { |i| i.concat(":").concat(port.to_s) }
|
41
34
|
end
|
42
|
-
return
|
35
|
+
return sock_array
|
43
36
|
else
|
44
37
|
if port.nil?
|
45
38
|
socket = ip
|
data/lib/ssh_scan/version.rb
CHANGED
data/lib/string_ext.rb
CHANGED
@@ -55,7 +55,11 @@ class String
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def resolve_fqdn
|
58
|
-
|
58
|
+
begin
|
59
|
+
IPSocket.getaddress(self)
|
60
|
+
rescue SocketError
|
61
|
+
nil # Can return anything you want here
|
62
|
+
end
|
59
63
|
end
|
60
64
|
|
61
65
|
def resolve_ptr(timeout = 3)
|
@@ -69,6 +73,31 @@ class String
|
|
69
73
|
end
|
70
74
|
end
|
71
75
|
|
76
|
+
# Stolen from: https://github.com/emonti/rbkb/blob/master/lib/rbkb/extends/string.rb
|
77
|
+
def hexify(opts={})
|
78
|
+
delim = opts[:delim]
|
79
|
+
pre = (opts[:prefix] || "")
|
80
|
+
suf = (opts[:suffix] || "")
|
81
|
+
|
82
|
+
if (rx=opts[:rx]) and not rx.kind_of? Regexp
|
83
|
+
raise "rx must be a regular expression for a character class"
|
84
|
+
end
|
85
|
+
|
86
|
+
hx = [("0".."9").to_a, ("a".."f").to_a].flatten
|
87
|
+
|
88
|
+
out=Array.new
|
89
|
+
|
90
|
+
self.each_byte do |c|
|
91
|
+
hc = if (rx and not rx.match c.chr)
|
92
|
+
c.chr
|
93
|
+
else
|
94
|
+
pre + (hx[(c >> 4)] + hx[(c & 0xf )]) + suf
|
95
|
+
end
|
96
|
+
out << (hc)
|
97
|
+
end
|
98
|
+
out.join(delim)
|
99
|
+
end
|
100
|
+
|
72
101
|
def fqdn?
|
73
102
|
begin
|
74
103
|
resolve_fqdn
|
data/ssh_scan.gemspec
CHANGED
@@ -31,12 +31,14 @@ Gem::Specification.new do |s|
|
|
31
31
|
s.metadata["yard.run"] = "yri" # use "yard" to build full HTML docs
|
32
32
|
|
33
33
|
s.add_dependency('bindata', '2.4.3')
|
34
|
-
s.add_dependency('netaddr', '
|
35
|
-
s.add_dependency('net-ssh', '
|
34
|
+
s.add_dependency('netaddr', '2.0.4')
|
35
|
+
s.add_dependency('net-ssh', '6.0.2')
|
36
|
+
s.add_dependency('ed25519', '1.2.4')
|
37
|
+
s.add_dependency('bcrypt_pbkdf', '1.0.1')
|
36
38
|
s.add_dependency('sshkey')
|
37
39
|
s.add_development_dependency('pry', '0.11.3')
|
38
40
|
s.add_development_dependency('rspec', '3.7.0')
|
39
41
|
s.add_development_dependency('rspec-its', '1.2.0')
|
40
|
-
s.add_development_dependency
|
42
|
+
s.add_development_dependency "rake", ">= 12.3.3"
|
41
43
|
s.add_development_dependency('rubocop')
|
42
44
|
end
|
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.44
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonathan Claudius
|
@@ -9,10 +9,10 @@ authors:
|
|
9
9
|
- Harsh Vardhan
|
10
10
|
- Rishabh Saxena
|
11
11
|
- Ashish Gaurav
|
12
|
-
autorequire:
|
12
|
+
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date:
|
15
|
+
date: 2021-05-20 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: bindata
|
@@ -34,28 +34,56 @@ dependencies:
|
|
34
34
|
requirements:
|
35
35
|
- - '='
|
36
36
|
- !ruby/object:Gem::Version
|
37
|
-
version:
|
37
|
+
version: 2.0.4
|
38
38
|
type: :runtime
|
39
39
|
prerelease: false
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
41
|
requirements:
|
42
42
|
- - '='
|
43
43
|
- !ruby/object:Gem::Version
|
44
|
-
version:
|
44
|
+
version: 2.0.4
|
45
45
|
- !ruby/object:Gem::Dependency
|
46
46
|
name: net-ssh
|
47
47
|
requirement: !ruby/object:Gem::Requirement
|
48
48
|
requirements:
|
49
49
|
- - '='
|
50
50
|
- !ruby/object:Gem::Version
|
51
|
-
version:
|
51
|
+
version: 6.0.2
|
52
52
|
type: :runtime
|
53
53
|
prerelease: false
|
54
54
|
version_requirements: !ruby/object:Gem::Requirement
|
55
55
|
requirements:
|
56
56
|
- - '='
|
57
57
|
- !ruby/object:Gem::Version
|
58
|
-
version:
|
58
|
+
version: 6.0.2
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: ed25519
|
61
|
+
requirement: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - '='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: 1.2.4
|
66
|
+
type: :runtime
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - '='
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 1.2.4
|
73
|
+
- !ruby/object:Gem::Dependency
|
74
|
+
name: bcrypt_pbkdf
|
75
|
+
requirement: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - '='
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: 1.0.1
|
80
|
+
type: :runtime
|
81
|
+
prerelease: false
|
82
|
+
version_requirements: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - '='
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: 1.0.1
|
59
87
|
- !ruby/object:Gem::Dependency
|
60
88
|
name: sshkey
|
61
89
|
requirement: !ruby/object:Gem::Requirement
|
@@ -116,16 +144,16 @@ dependencies:
|
|
116
144
|
name: rake
|
117
145
|
requirement: !ruby/object:Gem::Requirement
|
118
146
|
requirements:
|
119
|
-
- -
|
147
|
+
- - ">="
|
120
148
|
- !ruby/object:Gem::Version
|
121
|
-
version: 12.3.
|
149
|
+
version: 12.3.3
|
122
150
|
type: :development
|
123
151
|
prerelease: false
|
124
152
|
version_requirements: !ruby/object:Gem::Requirement
|
125
153
|
requirements:
|
126
|
-
- -
|
154
|
+
- - ">="
|
127
155
|
- !ruby/object:Gem::Version
|
128
|
-
version: 12.3.
|
156
|
+
version: 12.3.3
|
129
157
|
- !ruby/object:Gem::Dependency
|
130
158
|
name: rubocop
|
131
159
|
requirement: !ruby/object:Gem::Requirement
|
@@ -155,6 +183,7 @@ files:
|
|
155
183
|
- README.md
|
156
184
|
- Rakefile
|
157
185
|
- bin/ssh_scan
|
186
|
+
- config/policies/just_etm_macs.yaml
|
158
187
|
- config/policies/mozilla_intermediate.yml
|
159
188
|
- config/policies/mozilla_modern.yml
|
160
189
|
- data/README
|
@@ -190,6 +219,7 @@ files:
|
|
190
219
|
- lib/ssh_scan/public_key.rb
|
191
220
|
- lib/ssh_scan/result.rb
|
192
221
|
- lib/ssh_scan/scan_engine.rb
|
222
|
+
- lib/ssh_scan/ssh_fp.rb
|
193
223
|
- lib/ssh_scan/ssh_lib.rb
|
194
224
|
- lib/ssh_scan/ssh_lib/ciscossh.rb
|
195
225
|
- lib/ssh_scan/ssh_lib/cryptlib.rb
|
@@ -217,7 +247,7 @@ licenses:
|
|
217
247
|
- ruby
|
218
248
|
metadata:
|
219
249
|
yard.run: yri
|
220
|
-
post_install_message:
|
250
|
+
post_install_message:
|
221
251
|
rdoc_options: []
|
222
252
|
require_paths:
|
223
253
|
- lib
|
@@ -232,8 +262,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
232
262
|
- !ruby/object:Gem::Version
|
233
263
|
version: '0'
|
234
264
|
requirements: []
|
235
|
-
rubygems_version: 3.
|
236
|
-
signing_key:
|
265
|
+
rubygems_version: 3.2.15
|
266
|
+
signing_key:
|
237
267
|
specification_version: 4
|
238
268
|
summary: Ruby-based SSH Scanner
|
239
269
|
test_files: []
|