ssh_scan 0.0.6 → 0.0.7

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
  SHA1:
3
- metadata.gz: 7d2c9bf22bc6a5d8add93c53017b015ef4c93d34
4
- data.tar.gz: 1e8b0e0240aa1bbec27895aab4df439ba393d99b
3
+ metadata.gz: 523f33ca35c02c11f2a59a1cab89e06cc6dbed10
4
+ data.tar.gz: e94e1d5cfb9df79e4e32e09e34d7e2670bafe223
5
5
  SHA512:
6
- metadata.gz: 03dccca8b8627bced9051658a17614e37d01bbf7f9331be5938479347c671aaa2d0736ddb520916ce08d6fa7285c76201162f57d36998f6dd54fc4cbf60223f1
7
- data.tar.gz: d1f61dd9ab0b18114817ca086ec0fe06930a36bd9ca14247dac43b829ef4119a2688adb1902673394acd9e8b4210a0a34d709ed7d92b4fbc869fc39923ab7044
6
+ metadata.gz: 499ca37ef4d13b353074a9ee3ea03484c87f1f633a8e4b02b93f4014f5b9be2cf4700ff0b28ab2b101e2ab491bdb7a85672379bb691b98b20d388be41ab38d33
7
+ data.tar.gz: a82121192d78b156c218bd53ecc27edf661f417c3deb028f999ae6dda7ee7b017db3af2113628e31d89c6446a4c0a4044b9cda309f2e73e9a1e59440a2e7b1a4
data/README.md CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  [![Build Status](https://secure.travis-ci.org/claudijd/ssh_scan.png)](http://travis-ci.org/claudijd/ssh_scan)
4
4
  [![Code Climate](https://codeclimate.com/github/claudijd/ssh_scan.png)](https://codeclimate.com/github/claudijd/ssh_scan)
5
+ [![Gem Version](https://badge.fury.io/rb/ssh_scan.svg)](https://badge.fury.io/rb/ssh_scan)
5
6
 
6
7
  A SSH configuration and policy scanner
7
8
 
@@ -34,10 +35,10 @@ gem install bindata
34
35
 
35
36
  Run `ssh_scan -h` to get this
36
37
 
37
- ssh_scan v0.0.5 (https://github.com/claudijd/ssh_scan)
38
+ ssh_scan v0.0.6 (https://github.com/claudijd/ssh_scan)
38
39
 
39
40
  Usage: ssh_scan [options]
40
- -t, --target [IP] IP
41
+ -t, --target [IP/Hostname] IP/Hostname
41
42
  -p, --port [PORT] Port (Default: 22)
42
43
  -P, --policy [FILE] Policy file (Default: Mozilla Modern)
43
44
  -h, --help Show this message
@@ -45,8 +46,9 @@ Run `ssh_scan -h` to get this
45
46
  Examples:
46
47
 
47
48
  ssh_scan -t 192.168.1.1
48
- ssh_scan -t 192.168.1.1 -p 22222
49
- ssh_scan -t 192.168.1.1 -P custom_policy.yml
49
+ ssh_scan -t server.example.com
50
+ ssh_scan -t server.example.com -p 22222
51
+ ssh_scan -t server.example.com -P custom_policy.yml
50
52
 
51
53
  See here for [example output](https://github.com/claudijd/ssh_scan/blob/master/examples/192.168.1.1.json)
52
54
 
data/bin/ssh_scan CHANGED
@@ -10,14 +10,15 @@ require 'optparse'
10
10
  options = {
11
11
  :target => nil,
12
12
  :port => 22,
13
- :policy => File.expand_path("../../policies/mozilla_modern.yml", __FILE__)
13
+ :policy => File.expand_path("../../policies/mozilla_modern.yml", __FILE__),
14
+ :unit_test => false
14
15
  }
15
16
  opt_parser = OptionParser.new do |opts|
16
17
  opts.banner = "ssh_scan v#{SSHScan::VERSION} (https://github.com/claudijd/ssh_scan)\n\n" +
17
18
  "Usage: ssh_scan [options]"
18
19
 
19
- opts.on("-t", "--target [IP]",
20
- "IP") do |ip|
20
+ opts.on("-t", "--target [IP/Hostname]",
21
+ "IP/Hostname") do |ip|
21
22
  options[:target] = ip
22
23
  end
23
24
 
@@ -31,12 +32,26 @@ opt_parser = OptionParser.new do |opts|
31
32
  options[:policy] = policy
32
33
  end
33
34
 
35
+ opts.on("-u", "--unit-test [FILE]",
36
+ "Throw appropriate exit codes based on compliance status") do
37
+ options[:unit_test] = true
38
+ end
39
+
40
+ opts.on("-v", "--version",
41
+ "Display just version info") do
42
+ puts SSHScan::VERSION
43
+ exit
44
+ end
45
+
34
46
  opts.on_tail("-h", "--help", "Show this message") do
35
47
  puts opts
36
48
  puts "\nExamples:"
37
49
  puts "\n ssh_scan -t 192.168.1.1"
50
+ puts " ssh_scan -t server.example.com"
38
51
  puts " ssh_scan -t 192.168.1.1 -p 22222"
39
52
  puts " ssh_scan -t 192.168.1.1 -P custom_policy.yml"
53
+ puts " ssh_scan -t 192.168.1.1 --unit-test -P custom_policy.yml"
54
+ puts ""
40
55
  exit
41
56
  end
42
57
  end
@@ -49,6 +64,12 @@ if options[:target].nil?
49
64
  exit
50
65
  end
51
66
 
67
+ unless options[:target].ip_addr? || options[:target].fqdn?
68
+ puts opt_parser.help
69
+ puts "\nReason: #{options[:target]} is not a valid target"
70
+ exit
71
+ end
72
+
52
73
  unless (0..65535).include?(options[:port])
53
74
  puts opt_parser.help
54
75
  puts "\nReason: port supplied is not within acceptable range"
@@ -61,10 +82,16 @@ unless File.exists?(options[:policy])
61
82
  exit
62
83
  end
63
84
 
64
- policy = SSHScan::Policy.from_file(options[:policy])
85
+ options[:policy_file] = SSHScan::Policy.from_file(options[:policy])
65
86
 
66
87
  # Perform scan and get results
67
88
  scan_engine = SSHScan::ScanEngine.new()
68
- result = scan_engine.scan(options[:target], options[:port], policy)
89
+ result = scan_engine.scan(options)
69
90
 
70
91
  puts JSON.pretty_generate(result)
92
+
93
+ if result["compliance"] && result["compliance"][:compliant] == false
94
+ exit 1 #non-zero means a false
95
+ else
96
+ exit 0 #non-zero means pass
97
+ end
@@ -4,8 +4,15 @@ require 'ssh_scan/protocol'
4
4
 
5
5
  module SSHScan
6
6
  class Client
7
- def initialize(ip, port)
8
- @ip = ip
7
+ def initialize(target, port)
8
+ @target = target
9
+
10
+ if @target.ip_addr?
11
+ @ip = @target
12
+ else
13
+ @ip = @target.resolve_fqdn()
14
+ end
15
+
9
16
  @port = port
10
17
  @client_protocol = SSHScan::Constants::DEFAULT_CLIENT_PROTOCOL
11
18
  @server_protocol = nil
@@ -27,11 +34,12 @@ module SSHScan
27
34
  kex_exchange_init = SSHScan::KeyExchangeInit.read(resp)
28
35
 
29
36
  # Assemble and print results
30
- result = {
31
- :ip => @ip,
32
- :port => @port,
33
- :server_banner => @server_protocol
34
- }
37
+ result = {}
38
+ result[:ssh_scan_version] = SSHScan::VERSION
39
+ result[:hostname] = @target.fqdn? ? @target : ""
40
+ result[:ip] = @ip
41
+ result[:port] = @port
42
+ result[:server_banner] = @server_protocol
35
43
  result.merge!(kex_exchange_init.to_hash)
36
44
 
37
45
  return result
@@ -96,7 +96,7 @@ module SSHScan
96
96
  missing_policy_encryption.empty? &&
97
97
  missing_policy_macs.empty? &&
98
98
  missing_policy_kex.empty? &&
99
- missing_policy_compression?
99
+ missing_policy_compression.empty?
100
100
  end
101
101
 
102
102
  def recommendations
@@ -4,9 +4,13 @@ require 'ssh_scan/client'
4
4
  module SSHScan
5
5
  class ScanEngine
6
6
 
7
- def scan(ip, port, policy = nil)
7
+ def scan(opts)
8
+ target = opts[:target]
9
+ port = opts[:port]
10
+ policy = opts[:policy_file]
11
+
8
12
  # Connect and get results
9
- client = SSHScan::Client.new(ip, port)
13
+ client = SSHScan::Client.new(target, port)
10
14
  client.connect()
11
15
  result = client.get_kex_result()
12
16
 
@@ -1,3 +1,3 @@
1
1
  module SSHScan
2
- VERSION = '0.0.6'
2
+ VERSION = '0.0.7'
3
3
  end
data/lib/string_ext.rb CHANGED
@@ -1,6 +1,39 @@
1
+ require 'ipaddr'
2
+
1
3
  # Extend string to include some helpful stuff
2
4
  class String
3
5
  def unhexify
4
6
  [self].pack("H*")
5
7
  end
8
+
9
+ def ip_addr?
10
+ begin
11
+ IPAddr.new(self)
12
+
13
+ # Using ArgumentError instead of IPAddr::InvalidAddressError for 1.9.3 backward compatability
14
+ rescue ArgumentError
15
+ return false
16
+ end
17
+
18
+ return true
19
+ end
20
+
21
+ def resolve_fqdn
22
+ @fqdn ||= TCPSocket.gethostbyname(self)[3]
23
+ end
24
+
25
+ def fqdn?
26
+ begin
27
+ resolve_fqdn
28
+ rescue SocketError
29
+ return false
30
+ end
31
+
32
+ if ip_addr?
33
+ return false
34
+ else
35
+ return true
36
+ end
37
+ end
38
+
6
39
  end
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.6
4
+ version: 0.0.7
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-03-01 00:00:00.000000000 Z
11
+ date: 2016-03-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bindata