ssh_scan 0.0.16 → 0.0.17.pre

Sign up to get free protection for your applications and to get access to all the features.
@@ -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])