ssh_scan 0.0.2 → 0.0.3
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/bin/ssh_scan +2 -1
- data/lib/ssh_scan.rb +1 -0
- data/lib/ssh_scan/basic_server.rb +2 -6
- data/lib/ssh_scan/policy.rb +16 -66
- data/lib/ssh_scan/policy_manager.rb +127 -0
- data/lib/ssh_scan/scan_engine.rb +0 -1
- data/lib/ssh_scan/version.rb +1 -1
- 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: fa0b0404e66c6e6f45d68662e315de4016b97c01
|
4
|
+
data.tar.gz: 69d1d439decc01dd1c25c3cf9d6737a5a8b08f74
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cbbb0d49a507a8bda9fb29798e15f9d6a0349f3bc5f2e585280351cfc4ca4ba0aac79034d8c8ca57348184ebab4ec8440826f57d5f4af3b37f2b4047c8dab669
|
7
|
+
data.tar.gz: 000b50df34fd9df7ae3679dd67b084ace205a33c2f93f797fe3047073f10197b40dec602d6daa385e2d433e881ad8286e196d077a8c55b7f8136623400e85fe1
|
data/bin/ssh_scan
CHANGED
@@ -18,7 +18,8 @@ end
|
|
18
18
|
# Populate the info we need to perform a scan
|
19
19
|
ip = ARGV[0].chomp
|
20
20
|
port = ARGV[1].nil? ? 22 : ARGV[1].to_i
|
21
|
-
|
21
|
+
|
22
|
+
policy = SSHScan::Policy.from_file(File.expand_path("../../policies/mozilla_modern.yml", __FILE__))
|
22
23
|
|
23
24
|
# Perform scan and get results
|
24
25
|
scan_engine = SSHScan::ScanEngine.new()
|
data/lib/ssh_scan.rb
CHANGED
@@ -1,13 +1,9 @@
|
|
1
1
|
require 'sinatra'
|
2
|
-
require '
|
3
|
-
require 'socket'
|
4
|
-
require 'policy'
|
5
|
-
require 'constants'
|
6
|
-
require 'scan_engine'
|
2
|
+
require 'ssh_scan'
|
7
3
|
|
8
4
|
get '/api/v1/scan/:ip' do
|
9
5
|
if ip = params['ip']
|
10
|
-
policy = SSHScan::
|
6
|
+
policy = SSHScan::Policy.from_file(File.expand_path("../../policies/mozilla_intermediate.yml", __FILE__))
|
11
7
|
scan_engine = SSHScan::ScanEngine.new()
|
12
8
|
result = scan_engine.scan(ip, 22, policy)
|
13
9
|
content_type :json
|
data/lib/ssh_scan/policy.rb
CHANGED
@@ -1,75 +1,25 @@
|
|
1
|
-
|
2
|
-
class IntermediatePolicy
|
3
|
-
def name
|
4
|
-
self.class.to_s
|
5
|
-
end
|
6
|
-
|
7
|
-
def macs
|
8
|
-
["hmac-sha2-512","hmac-sha2-256"]
|
9
|
-
end
|
10
|
-
|
11
|
-
def encryption
|
12
|
-
["aes256-ctr","aes192-ctr","aes128-ctr"]
|
13
|
-
end
|
14
|
-
|
15
|
-
def kexs
|
16
|
-
["diffie-hellman-group-exchange-sha256"]
|
17
|
-
end
|
18
|
-
end
|
1
|
+
require 'yaml'
|
19
2
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
@result = result
|
24
|
-
end
|
25
|
-
|
26
|
-
def out_of_policy_encryption
|
27
|
-
target_encryption = @result[:encryption_algorithms_client_to_server] | @result[:encryption_algorithms_server_to_client]
|
28
|
-
outliers = []
|
29
|
-
target_encryption.each do |target_enc|
|
30
|
-
outliers << target_enc unless @policy.encryption.include?(target_enc)
|
31
|
-
end
|
32
|
-
return outliers
|
33
|
-
end
|
34
|
-
|
35
|
-
def out_of_policy_macs
|
36
|
-
target_macs = @result[:mac_algorithms_server_to_client] | @result[:mac_algorithms_client_to_server]
|
37
|
-
outliers = []
|
38
|
-
target_macs.each do |target_mac|
|
39
|
-
outliers << target_mac unless @policy.macs.include?(target_mac)
|
40
|
-
end
|
41
|
-
return outliers
|
42
|
-
end
|
43
|
-
|
44
|
-
def out_of_policy_kex
|
45
|
-
target_kexs = @result[:key_algorithms]
|
46
|
-
outliers = []
|
47
|
-
target_kexs.each do |target_kex|
|
48
|
-
outliers << target_kex unless @policy.kexs.include?(target_kex)
|
49
|
-
end
|
50
|
-
return outliers
|
51
|
-
end
|
3
|
+
module SSHScan
|
4
|
+
class Policy
|
5
|
+
attr_reader :name, :kex, :macs, :encryption, :compression
|
52
6
|
|
53
|
-
def
|
54
|
-
|
55
|
-
|
56
|
-
|
7
|
+
def initialize(opts = {})
|
8
|
+
@name = opts['name'] || []
|
9
|
+
@kex = opts['kex'] || []
|
10
|
+
@macs = opts['macs'] || []
|
11
|
+
@encryption = opts['encryption'] || []
|
12
|
+
@compression = opts['compression'] || []
|
57
13
|
end
|
58
14
|
|
59
|
-
def
|
60
|
-
|
61
|
-
|
62
|
-
recommendations << "Remove these MAC Algos: #{out_of_policy_macs.join(", ")}" unless out_of_policy_macs.empty?
|
63
|
-
recommendations << "Remove these Encryption Ciphers: #{out_of_policy_encryption.join(", ")}" unless out_of_policy_encryption.empty?
|
64
|
-
return recommendations
|
15
|
+
def self.from_file(file)
|
16
|
+
opts = YAML.load_file(file)
|
17
|
+
self.new(opts)
|
65
18
|
end
|
66
19
|
|
67
|
-
def
|
68
|
-
|
69
|
-
|
70
|
-
:compliant => compliant?,
|
71
|
-
:recommendations => recommendations
|
72
|
-
}
|
20
|
+
def self.from_string(string)
|
21
|
+
opts = YAML.load(string)
|
22
|
+
self.new(opts)
|
73
23
|
end
|
74
24
|
end
|
75
25
|
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
module SSHScan
|
2
|
+
class PolicyManager
|
3
|
+
def initialize(result, policy)
|
4
|
+
@policy = policy
|
5
|
+
@result = result
|
6
|
+
end
|
7
|
+
|
8
|
+
def out_of_policy_encryption
|
9
|
+
target_encryption = @result[:encryption_algorithms_client_to_server] | @result[:encryption_algorithms_server_to_client]
|
10
|
+
outliers = []
|
11
|
+
target_encryption.each do |target_enc|
|
12
|
+
outliers << target_enc unless @policy.encryption.include?(target_enc)
|
13
|
+
end
|
14
|
+
return outliers
|
15
|
+
end
|
16
|
+
|
17
|
+
def missing_policy_encryption
|
18
|
+
target_encryption = @result[:encryption_algorithms_client_to_server] | @result[:encryption_algorithms_server_to_client]
|
19
|
+
outliers = []
|
20
|
+
@policy.encryption.each do |encryption|
|
21
|
+
if target_encryption.include?(encryption) == false
|
22
|
+
outliers << encryption
|
23
|
+
end
|
24
|
+
end
|
25
|
+
return outliers
|
26
|
+
end
|
27
|
+
|
28
|
+
def out_of_policy_macs
|
29
|
+
target_macs = @result[:mac_algorithms_server_to_client] | @result[:mac_algorithms_client_to_server]
|
30
|
+
outliers = []
|
31
|
+
target_macs.each do |target_mac|
|
32
|
+
outliers << target_mac unless @policy.macs.include?(target_mac)
|
33
|
+
end
|
34
|
+
return outliers
|
35
|
+
end
|
36
|
+
|
37
|
+
def missing_policy_macs
|
38
|
+
target_macs = @result[:mac_algorithms_server_to_client] | @result[:mac_algorithms_client_to_server]
|
39
|
+
outliers = []
|
40
|
+
|
41
|
+
@policy.macs.each do |mac|
|
42
|
+
if target_macs.include?(mac) == false
|
43
|
+
outliers << mac
|
44
|
+
end
|
45
|
+
end
|
46
|
+
return outliers
|
47
|
+
end
|
48
|
+
|
49
|
+
def out_of_policy_kex
|
50
|
+
target_kexs = @result[:key_algorithms]
|
51
|
+
outliers = []
|
52
|
+
target_kexs.each do |target_kex|
|
53
|
+
outliers << target_kex unless @policy.kex.include?(target_kex)
|
54
|
+
end
|
55
|
+
return outliers
|
56
|
+
end
|
57
|
+
|
58
|
+
def missing_policy_kex
|
59
|
+
target_kex = @result[:key_algorithms]
|
60
|
+
outliers = []
|
61
|
+
|
62
|
+
@policy.kex.each do |kex|
|
63
|
+
if target_kex.include?(kex) == false
|
64
|
+
outliers << kex
|
65
|
+
end
|
66
|
+
end
|
67
|
+
return outliers
|
68
|
+
end
|
69
|
+
|
70
|
+
def out_of_policy_compression
|
71
|
+
target_compressions = @result[:compression_algorithms_server_to_client] | @result[:compression_algorithms_client_to_server]
|
72
|
+
outliers = []
|
73
|
+
target_compressions.each do |target_compression|
|
74
|
+
outliers << target_compression unless @policy.compression.include?(target_compression)
|
75
|
+
end
|
76
|
+
return outliers
|
77
|
+
end
|
78
|
+
|
79
|
+
def missing_policy_compression
|
80
|
+
target_compressions = @result[:compression_algorithms_server_to_client] | @result[:compression_algorithms_client_to_server]
|
81
|
+
outliers = []
|
82
|
+
|
83
|
+
@policy.compression.each do |compression|
|
84
|
+
if target_compressions.include?(compression) == false
|
85
|
+
outliers << compression
|
86
|
+
end
|
87
|
+
end
|
88
|
+
return outliers
|
89
|
+
end
|
90
|
+
|
91
|
+
def compliant?
|
92
|
+
out_of_policy_encryption.empty? &&
|
93
|
+
out_of_policy_macs.empty? &&
|
94
|
+
out_of_policy_kex.empty? &&
|
95
|
+
out_of_policy_compression.empty? &&
|
96
|
+
missing_policy_encryption.empty? &&
|
97
|
+
missing_policy_macs.empty? &&
|
98
|
+
missing_policy_kex.empty? &&
|
99
|
+
missing_policy_compression?
|
100
|
+
end
|
101
|
+
|
102
|
+
def recommendations
|
103
|
+
recommendations = []
|
104
|
+
|
105
|
+
# Add these items to be compliant
|
106
|
+
recommendations << "Add these Key Exchange Algos: #{missing_policy_kex.join(", ")}" unless missing_policy_kex.empty?
|
107
|
+
recommendations << "Add these MAC Algos: #{missing_policy_macs.join(", ")}" unless missing_policy_macs.empty?
|
108
|
+
recommendations << "Add these Encryption Ciphers: #{missing_policy_encryption.join(", ")}" unless missing_policy_encryption.empty?
|
109
|
+
recommendations << "Add these Compression Algos: #{missing_policy_compression.join(", ")}" unless missing_policy_compression.empty?
|
110
|
+
|
111
|
+
# Remove these items to be compliant
|
112
|
+
recommendations << "Remove these Key Exchange Algos: #{out_of_policy_kex.join(", ")}" unless out_of_policy_kex.empty?
|
113
|
+
recommendations << "Remove these MAC Algos: #{out_of_policy_macs.join(", ")}" unless out_of_policy_macs.empty?
|
114
|
+
recommendations << "Remove these Encryption Ciphers: #{out_of_policy_encryption.join(", ")}" unless out_of_policy_encryption.empty?
|
115
|
+
recommendations << "Remove these Compression Algos: #{out_of_policy_compression.join(", ")}" unless out_of_policy_compression.empty?
|
116
|
+
return recommendations
|
117
|
+
end
|
118
|
+
|
119
|
+
def compliance_results
|
120
|
+
{
|
121
|
+
:policy => @policy.name,
|
122
|
+
:compliant => compliant?,
|
123
|
+
:recommendations => recommendations
|
124
|
+
}
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
data/lib/ssh_scan/scan_engine.rb
CHANGED
data/lib/ssh_scan/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
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.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonathan Claudius
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-02-
|
11
|
+
date: 2016-02-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bindata
|
@@ -99,6 +99,7 @@ files:
|
|
99
99
|
- lib/ssh_scan/basic_server.rb
|
100
100
|
- lib/ssh_scan/constants.rb
|
101
101
|
- lib/ssh_scan/policy.rb
|
102
|
+
- lib/ssh_scan/policy_manager.rb
|
102
103
|
- lib/ssh_scan/protocol.rb
|
103
104
|
- lib/ssh_scan/scan_engine.rb
|
104
105
|
- lib/ssh_scan/version.rb
|