ssh_scan 0.0.16 → 0.0.17.pre

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.
@@ -1,6 +1,8 @@
1
1
  module SSHScan
2
2
  module SSHLib
3
3
  class Dropbear
4
+ attr_reader :version
5
+
4
6
  class Version
5
7
  def initialize(version_string)
6
8
  if version_string == nil
@@ -33,10 +35,6 @@ module SSHScan
33
35
  def cpe
34
36
  "a:dropbear:dropbear" << (":" + version.to_s) unless version.nil?
35
37
  end
36
-
37
- def version
38
- @version
39
- end
40
38
  end
41
39
  end
42
40
  end
@@ -19,7 +19,7 @@ module SSHScan
19
19
  upper = NetAddr::CIDR.create(octets.join('.') + "." + range[1])
20
20
  ip_array = NetAddr.range(lower, upper,:Inclusive => true)
21
21
  if !port.nil?
22
- ip_array.map! { |ip| ip.concat(":").concat(port.to_s) }
22
+ ip_array.map! { |i| i.concat(":").concat(port.to_s) }
23
23
  end
24
24
  return ip_array
25
25
  elsif ip.include? "/"
@@ -28,7 +28,7 @@ module SSHScan
28
28
  ip_array.delete(cidr.network)
29
29
  ip_array.delete(cidr.last)
30
30
  if !port.nil?
31
- ip_array.map! { |ip| ip.concat(":").concat(port.to_s) }
31
+ ip_array.map! { |i| i.concat(":").concat(port.to_s) }
32
32
  end
33
33
  return ip_array
34
34
  else
@@ -42,4 +42,4 @@ module SSHScan
42
42
  end
43
43
  end
44
44
  end
45
- end
45
+ end
@@ -18,7 +18,7 @@ module SSHScan
18
18
  end
19
19
 
20
20
  def next_minor_version(version = SSHScan::VERSION)
21
- major, minor, patch = version.split(".")
21
+ major, minor = version.split(".")[0, 2]
22
22
  minor_num = minor.to_i
23
23
  minor_num += 1
24
24
 
@@ -26,7 +26,7 @@ module SSHScan
26
26
  end
27
27
 
28
28
  def next_major_version(version = SSHScan::VERSION)
29
- major, minor, patch = version.split(".")
29
+ major = version.split(".")[0]
30
30
  major_num = major.to_i
31
31
  major_num += 1
32
32
 
@@ -38,7 +38,7 @@ module SSHScan
38
38
 
39
39
  begin
40
40
  res = Net::HTTP.get_response(uri)
41
- rescue Exception => e
41
+ rescue SocketError => e
42
42
  @errors << e.message
43
43
  return false
44
44
  end
@@ -1,4 +1,3 @@
1
1
  module SSHScan
2
- VERSION = '0.0.16'
3
- API_VERSION = '0.0.1'
2
+ VERSION = '0.0.17.pre'
4
3
  end
@@ -0,0 +1,119 @@
1
+ require 'ssh_scan/scan_engine'
2
+ require 'openssl'
3
+ require 'net/https'
4
+
5
+ module SSHScan
6
+ class Worker
7
+ def initialize(opts = {})
8
+ @server = opts["server"] || "127.0.0.1"
9
+ @scheme = opts["scheme"] || "http"
10
+ @verify = opts["verify"] || "false"
11
+ @port = opts["port"] || 8000
12
+ @logger = setup_logger(opts["logger"])
13
+ @poll_interval = 5 # seconds
14
+ @worker_id = SecureRandom.uuid
15
+ @verify_ssl = false
16
+ @auth_token = opts["auth_token"] || nil
17
+ end
18
+
19
+ def setup_logger(logger)
20
+ case logger
21
+ when Logger
22
+ return logger
23
+ when String
24
+ return Logger.new(logger)
25
+ end
26
+
27
+ return Logger.new(STDOUT)
28
+ end
29
+
30
+ def self.from_config_file(file_string)
31
+ opts = YAML.load_file(file_string)
32
+ SSHScan::Worker.new(opts)
33
+ end
34
+
35
+ def run!
36
+ loop do
37
+ begin
38
+ response = retrieve_work
39
+ if response["work"]
40
+ job = response["work"]
41
+ results = perform_work(job)
42
+ post_results(results, job)
43
+ else
44
+ @logger.info("No jobs available (waiting 5 seconds)")
45
+ sleep 5
46
+ next
47
+ end
48
+ rescue Errno::ECONNREFUSED
49
+ @logger.error("Cannot reach API endpoint, waiting 5 seconds")
50
+ sleep 5
51
+ rescue RuntimeError => e
52
+ @logger.error(e.inspect)
53
+ end
54
+ end
55
+ end
56
+
57
+ def retrieve_work
58
+ (Net::HTTP::SSL_IVNAMES << :@ssl_options).uniq!
59
+ (Net::HTTP::SSL_ATTRIBUTES << :options).uniq!
60
+
61
+ Net::HTTP.class_eval do
62
+ attr_accessor :ssl_options
63
+ end
64
+
65
+ uri = URI(
66
+ "#{@scheme}://#{@server}:#{@port}/api/v#{SSHScan::API_VERSION}/\
67
+ work?worker_id=#{@worker_id}"
68
+ )
69
+ http = Net::HTTP.new(uri.host, uri.port)
70
+
71
+ if @scheme == "https"
72
+ http.use_ssl = true
73
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE if @verify == false
74
+ options_mask =
75
+ OpenSSL::SSL::OP_NO_SSLv2 +
76
+ OpenSSL::SSL::OP_NO_SSLv3 +
77
+ OpenSSL::SSL::OP_NO_COMPRESSION
78
+ http.ssl_options = options_mask
79
+ end
80
+
81
+ request = Net::HTTP::Get.new(uri.path)
82
+ request.add_field("SSH_SCAN_AUTH_TOKEN", @auth_token) unless @auth_token.nil?
83
+ response = http.request(request)
84
+ JSON.parse(response.body)
85
+ end
86
+
87
+ def perform_work(job)
88
+ @logger.info("Started job: #{job["uuid"]}")
89
+ scan_engine = SSHScan::ScanEngine.new
90
+ results = scan_engine.scan(job)
91
+ @logger.info("Completed job: #{job["uuid"]}")
92
+ return results
93
+ end
94
+
95
+ def post_results(results, job)
96
+ uri = URI(
97
+ "#{@scheme}://#{@server}:#{@port}/api/v#{SSHScan::API_VERSION}/\
98
+ work/results/#{@worker_id}/#{job["uuid"]}"
99
+ )
100
+ http = Net::HTTP.new(uri.host, uri.port)
101
+
102
+ if @scheme == "https"
103
+ http.use_ssl = true
104
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE if @verify == false
105
+ options_mask =
106
+ OpenSSL::SSL::OP_NO_SSLv2 +
107
+ OpenSSL::SSL::OP_NO_SSLv3 +
108
+ OpenSSL::SSL::OP_NO_COMPRESSION
109
+ http.ssl_options = options_mask
110
+ end
111
+
112
+ request = Net::HTTP::Post.new(uri.path)
113
+ request.add_field("SSH_SCAN_AUTH_TOKEN", @auth_token) unless @auth_token.nil?
114
+ request.body = results.to_json
115
+ http.request(request)
116
+ @logger.info("Posted job: #{job["uuid"]}")
117
+ end
118
+ end
119
+ end
@@ -16,7 +16,8 @@ class String
16
16
  begin
17
17
  IPAddr.new(self)
18
18
 
19
- # Using ArgumentError instead of IPAddr::InvalidAddressError for 1.9.3 backward compatability
19
+ # Using ArgumentError instead of IPAddr::InvalidAddressError
20
+ # for 1.9.3 backward compatability
20
21
  rescue ArgumentError
21
22
  return false
22
23
  end
@@ -1,12 +1,13 @@
1
1
  $: << "lib"
2
2
  require 'ssh_scan/version'
3
+ require 'date'
3
4
 
4
5
  Gem::Specification.new do |s|
5
6
  s.name = 'ssh_scan'
6
7
  s.version = SSHScan::VERSION
7
- s.authors = ["Jonathan Claudius", "Jinank Jain"]
8
+ s.authors = ["Jonathan Claudius", "Jinank Jain", "Harsh Vardhan", "Rishabh Saxena", "Ashish Gaurav"]
8
9
  s.date = Date.today.to_s
9
- s.email = 'claudijd@yahoo.com'
10
+ s.email = 'jclaudius@mozilla.com'
10
11
  s.platform = Gem::Platform::RUBY
11
12
  s.files = Dir.glob("lib/**/*") +
12
13
  Dir.glob("bin/**/*") +
@@ -29,14 +30,9 @@ Gem::Specification.new do |s|
29
30
  s.add_dependency('bindata', '~> 2.0')
30
31
  s.add_dependency('netaddr')
31
32
  s.add_dependency('net-ssh')
32
- s.add_dependency('sqlite3')
33
- s.add_dependency('sinatra')
34
- s.add_dependency('sinatra-contrib')
35
- s.add_dependency('haml')
36
- s.add_dependency('secure_headers')
37
- s.add_development_dependency('rack-test')
38
33
  s.add_development_dependency('pry')
39
34
  s.add_development_dependency('rspec', '~> 3.0')
40
35
  s.add_development_dependency('rspec-its', '~> 1.2')
41
36
  s.add_development_dependency('rake', '~> 10.3')
37
+ s.add_development_dependency('rubocop')
42
38
  end
metadata CHANGED
@@ -1,15 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ssh_scan
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.16
4
+ version: 0.0.17.pre
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Claudius
8
8
  - Jinank Jain
9
+ - Harsh Vardhan
10
+ - Rishabh Saxena
11
+ - Ashish Gaurav
9
12
  autorequire:
10
13
  bindir: bin
11
14
  cert_chain: []
12
- date: 2016-10-19 00:00:00.000000000 Z
15
+ date: 2017-03-02 00:00:00.000000000 Z
13
16
  dependencies:
14
17
  - !ruby/object:Gem::Dependency
15
18
  name: bindata
@@ -53,90 +56,6 @@ dependencies:
53
56
  - - ">="
54
57
  - !ruby/object:Gem::Version
55
58
  version: '0'
56
- - !ruby/object:Gem::Dependency
57
- name: sqlite3
58
- requirement: !ruby/object:Gem::Requirement
59
- requirements:
60
- - - ">="
61
- - !ruby/object:Gem::Version
62
- version: '0'
63
- type: :runtime
64
- prerelease: false
65
- version_requirements: !ruby/object:Gem::Requirement
66
- requirements:
67
- - - ">="
68
- - !ruby/object:Gem::Version
69
- version: '0'
70
- - !ruby/object:Gem::Dependency
71
- name: sinatra
72
- requirement: !ruby/object:Gem::Requirement
73
- requirements:
74
- - - ">="
75
- - !ruby/object:Gem::Version
76
- version: '0'
77
- type: :runtime
78
- prerelease: false
79
- version_requirements: !ruby/object:Gem::Requirement
80
- requirements:
81
- - - ">="
82
- - !ruby/object:Gem::Version
83
- version: '0'
84
- - !ruby/object:Gem::Dependency
85
- name: sinatra-contrib
86
- requirement: !ruby/object:Gem::Requirement
87
- requirements:
88
- - - ">="
89
- - !ruby/object:Gem::Version
90
- version: '0'
91
- type: :runtime
92
- prerelease: false
93
- version_requirements: !ruby/object:Gem::Requirement
94
- requirements:
95
- - - ">="
96
- - !ruby/object:Gem::Version
97
- version: '0'
98
- - !ruby/object:Gem::Dependency
99
- name: haml
100
- requirement: !ruby/object:Gem::Requirement
101
- requirements:
102
- - - ">="
103
- - !ruby/object:Gem::Version
104
- version: '0'
105
- type: :runtime
106
- prerelease: false
107
- version_requirements: !ruby/object:Gem::Requirement
108
- requirements:
109
- - - ">="
110
- - !ruby/object:Gem::Version
111
- version: '0'
112
- - !ruby/object:Gem::Dependency
113
- name: secure_headers
114
- requirement: !ruby/object:Gem::Requirement
115
- requirements:
116
- - - ">="
117
- - !ruby/object:Gem::Version
118
- version: '0'
119
- type: :runtime
120
- prerelease: false
121
- version_requirements: !ruby/object:Gem::Requirement
122
- requirements:
123
- - - ">="
124
- - !ruby/object:Gem::Version
125
- version: '0'
126
- - !ruby/object:Gem::Dependency
127
- name: rack-test
128
- requirement: !ruby/object:Gem::Requirement
129
- requirements:
130
- - - ">="
131
- - !ruby/object:Gem::Version
132
- version: '0'
133
- type: :development
134
- prerelease: false
135
- version_requirements: !ruby/object:Gem::Requirement
136
- requirements:
137
- - - ">="
138
- - !ruby/object:Gem::Version
139
- version: '0'
140
59
  - !ruby/object:Gem::Dependency
141
60
  name: pry
142
61
  requirement: !ruby/object:Gem::Requirement
@@ -193,11 +112,26 @@ dependencies:
193
112
  - - "~>"
194
113
  - !ruby/object:Gem::Version
195
114
  version: '10.3'
115
+ - !ruby/object:Gem::Dependency
116
+ name: rubocop
117
+ requirement: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ type: :development
123
+ prerelease: false
124
+ version_requirements: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
196
129
  description: A Ruby-based SSH scanner for configuration and policy scanning
197
- email: claudijd@yahoo.com
130
+ email: jclaudius@mozilla.com
198
131
  executables:
199
132
  - ssh_scan
200
- - ssh_scan_api
133
+ - ssh_scan_worker
134
+ - ssh_scan_worker_example_config.yml
201
135
  extensions: []
202
136
  extra_rdoc_files: []
203
137
  files:
@@ -209,9 +143,9 @@ files:
209
143
  - README.md
210
144
  - Rakefile
211
145
  - bin/ssh_scan
212
- - bin/ssh_scan_api
146
+ - bin/ssh_scan_worker
147
+ - bin/ssh_scan_worker_example_config.yml
213
148
  - lib/ssh_scan.rb
214
- - lib/ssh_scan/api.rb
215
149
  - lib/ssh_scan/banner.rb
216
150
  - lib/ssh_scan/client.rb
217
151
  - lib/ssh_scan/constants.rb
@@ -223,7 +157,6 @@ files:
223
157
  - lib/ssh_scan/error/disconnected.rb
224
158
  - lib/ssh_scan/error/no_banner.rb
225
159
  - lib/ssh_scan/error/no_kex_response.rb
226
- - lib/ssh_scan/fingerprint_database.rb
227
160
  - lib/ssh_scan/os.rb
228
161
  - lib/ssh_scan/os/centos.rb
229
162
  - lib/ssh_scan/os/cisco.rb
@@ -259,9 +192,8 @@ files:
259
192
  - lib/ssh_scan/target_parser.rb
260
193
  - lib/ssh_scan/update.rb
261
194
  - lib/ssh_scan/version.rb
195
+ - lib/ssh_scan/worker.rb
262
196
  - lib/string_ext.rb
263
- - policies/mozilla_intermediate.yml
264
- - policies/mozilla_modern.yml
265
197
  - ssh_scan.gemspec
266
198
  homepage: http://rubygems.org/gems/ssh_scan
267
199
  licenses:
@@ -278,12 +210,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
278
210
  version: '0'
279
211
  required_rubygems_version: !ruby/object:Gem::Requirement
280
212
  requirements:
281
- - - ">="
213
+ - - ">"
282
214
  - !ruby/object:Gem::Version
283
- version: '0'
215
+ version: 1.3.1
284
216
  requirements: []
285
217
  rubyforge_project:
286
- rubygems_version: 2.5.1
218
+ rubygems_version: 2.6.2
287
219
  signing_key:
288
220
  specification_version: 4
289
221
  summary: Ruby-based SSH Scanner
@@ -1,36 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- $:.unshift File.join(File.dirname(__FILE__), "../lib")
4
-
5
- require 'optparse'
6
- require 'ssh_scan'
7
-
8
- options = {
9
- :port => 8000,
10
- }
11
-
12
- opt_parser = OptionParser.new do |opts|
13
- opts.banner = "ssh_scan_api v#{SSHScan::API_VERSION} (https://github.com/mozilla/ssh_scan)\n\n" +
14
- "Usage: ssh_scan [options]"
15
-
16
- opts.on("-p", "--port [PORT]", "Listen and serve API requests on this port (Default: 8000)") do |port|
17
- options[:port] = port.to_i
18
- end
19
-
20
- opts.on("-v", "--version", "Show ssh_scan API version") do
21
- puts SSHScan::API_VERSION
22
- exit
23
- end
24
-
25
- opts.on_tail("-h", "--help", "Show help") do
26
- puts opts
27
- puts "\nExamples:\n"
28
- puts " ssh_scan_api -p 4567"
29
- puts ""
30
- exit
31
- end
32
- end
33
-
34
- opt_parser.parse!
35
-
36
- SSHScan::API.run!(:port => options[:port])