ssh_scan 0.0.39 → 0.0.44

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 913c588395b88fe25aae08930d7ef15984f75eab0c6976ef868d9c6fbe062f1c
4
- data.tar.gz: '0166380a16b6e1f380e4af64d610440bf668b6741985f320fbe6e1dc916cf55f'
3
+ metadata.gz: 6174ee5e2ad23ab2ba83ecb51af937fba17db13e8dba7590ccf4b2cdb93c9aa5
4
+ data.tar.gz: dbad23e44d2f0b06625a8ae62eae20e7a7bc94a0aecadf01d143e0c9c1d4d373
5
5
  SHA512:
6
- metadata.gz: 072a07a4d37cf493a5f295e757cd6b330ceeae98b3dd989500a27df4faa6be29def8ff5e6f48ece3b0784e80571b4bfbb873b6fbdb4900c2f1deb66f7c9b5666
7
- data.tar.gz: 7b8c97061c7a57b30c8d77544abe8626209196a55808a990f3dc28dc8e6f1fdf94fd1dad73853a0adc98a8b8cccfdd42d3303e3d3a92478fe9ff34eca186315f
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.5.1
14
+ - rvm: 2.6.7
15
15
  env:
16
16
  - LABEL=unit_tests
17
- - rvm: 2.4.4
17
+ - rvm: 2.7.3
18
18
  env:
19
19
  - LABEL=unit_tests
20
- - rvm: 2.3.6
20
+ - rvm: 3.0.1
21
21
  env:
22
22
  - LABEL=unit_tests
23
- - rvm: 2.5.1
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.4.4
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: 2.5.0
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: 2.5.0
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: 2.5.0
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!**](http://rspec.info/) Your patch won't be accepted (or will be delayed) if it doesn't have 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**](http://yardoc.org/) Make sure the README and any other
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**](http://stackoverflow.com/questions/6934752/git-combining-multiple-commits-before-pushing) Make sure each individual commit in your pull
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 Dependancies** - Uses native Ruby and BinData to do its work, no heavy dependancies.
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 /app/bin/ssh_scan -t sshscan.rubidus.com
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 soley for ssh_scan engine/command-line usage.
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" => "json"
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
- $stdout.reopen(file, "w")
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
@@ -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(
@@ -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
- SSHKey.sha256_fingerprint(@key_string)
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
@@ -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 keys
165
- @keys
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,
@@ -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
- :paranoid => false
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
- cidr = NetAddr::CIDR.create(ip)
22
+ ip_net = NetAddr::IPv4Net.parse(ip)
33
23
  rescue
34
24
  raise ArgumentError, "Invalid target: #{ip}"
35
25
  end
36
- ip_array = cidr.enumerate
37
- ip_array.delete(cidr.network)
38
- ip_array.delete(cidr.last)
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
- ip_array.map! { |i| i.concat(":").concat(port.to_s) }
33
+ sock_array.map! { |i| i.concat(":").concat(port.to_s) }
41
34
  end
42
- return ip_array
35
+ return sock_array
43
36
  else
44
37
  if port.nil?
45
38
  socket = ip
@@ -1,3 +1,3 @@
1
1
  module SSHScan
2
- VERSION = '0.0.39'
2
+ VERSION = '0.0.44'
3
3
  end
data/lib/string_ext.rb CHANGED
@@ -55,7 +55,11 @@ class String
55
55
  end
56
56
 
57
57
  def resolve_fqdn
58
- TCPSocket.gethostbyname(self)[3]
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', '1.5.1')
35
- s.add_dependency('net-ssh', '5.0.2')
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('rake', '12.3.1')
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.39
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: 2019-01-18 00:00:00.000000000 Z
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: 1.5.1
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: 1.5.1
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: 5.0.2
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: 5.0.2
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.1
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.1
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.0.2
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: []