NexposeRunner 0.0.16b → 0.0.16

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: f8e89ef4d3e80c11b69a9ac7c428b5364038fa69
4
- data.tar.gz: 14fa8331a41d2e546427779f0980db6805d78f0d
3
+ metadata.gz: dba55e03de0483d335ea8587e78cf98fd592d822
4
+ data.tar.gz: 17d89e707f96cefae4c27781d5c4804913e58f8a
5
5
  SHA512:
6
- metadata.gz: 3b0a68bafb364870344cd0d3ccc0bd38a06fcf701321ec300c35b8ac9146d9c59e9b45de51cffec1b3a3f193511fb29332d3668d133ea94f26f6cf5c37fb030b
7
- data.tar.gz: 43bf8f648747b2c00a33103c427fcfe08be560668833cdc72e40d6d3268b6bdd962ab0012df7ef6d8d19c2b3097ee6c36475896589f58a00505a6ed1be84948f
6
+ metadata.gz: a12740921d51d353c6d49cba1b63244f07ae4de715843153da931bb934c4efdb0a67439f98d16f23df7124553068bddff75b8db1ca3e6db1a34eb8c87d77fb16
7
+ data.tar.gz: ab7c13e940e0cfe7057ba77c6944ec6dc9a8a99216126fb5d738cc6a08e8bf016a16e1a5914646947cf7ee5243210c54e251916e3c12b784c263c62ad89ccf5f
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ['lib']
20
20
 
21
- spec.add_dependency 'nexpose', '7.1.1'
21
+ spec.add_dependency 'nexpose', '0.8.3'
22
22
 
23
23
  spec.add_development_dependency 'bundler', '~> 1.6'
24
24
  spec.add_development_dependency 'rake', '< 11.0'
data/bin/scan CHANGED
@@ -13,9 +13,8 @@ if ARGV.grep(/^--/).empty?
13
13
  'site_name' => ARGV[4],
14
14
  'ip_addresses' => ARGV[5],
15
15
  'scan_template' => ARGV[6],
16
- 'engine' => ARGV[7],
17
- 'timeout' => ARGV[8],
18
- 'open_timeout' => ARGV[9]})
16
+ 'engine' => ARGV[7]
17
+ })
19
18
  else
20
19
  NexposeRunner::Scan.start(ARGV)
21
20
  end
@@ -6,5 +6,3 @@ site_name: ''
6
6
  ip_addresses: ''
7
7
  scan_template: ''
8
8
  engine: ''
9
- timeout: ''
10
- open_timeout: ''
@@ -1,4 +1,3 @@
1
1
  module NexposeRunner
2
- VERSION = '0.0.16b'
2
+ VERSION = '0.0.16'
3
3
  end
4
-
@@ -8,10 +8,8 @@ module CONSTANTS
8
8
  REQUIRED_SCAN_TEMPLATE_MESSAGE = 'OOPS! Looks like you forgot to give me a Scan Template to use'
9
9
  VULNERABILITY_FOUND_MESSAGE = '---------All YOUR BASE ARE BELONG TO US---------------\nVulnerabilities were found, breaking build'
10
10
  DEFAULT_PORT = '3780'
11
- DEFAULT_TIMEOUT = '120'
12
- DEFAULT_OPEN_TIMEOUT = '120'
13
11
  VULNERABILITY_REPORT_NAME = 'nexpose-vulnerability-report.csv'
14
- VULNERABILITY_DETAIL_REPORT_NAME = 'nexpose-vulnerability-detail-report.csv'
12
+ VULNERABILITY_DETAIL_REPORT_NAME = 'nexpose-vulnerability-detail-report.csv'
15
13
  SOFTWARE_REPORT_NAME = 'nexpose-software-report.csv'
16
14
  POLICY_REPORT_NAME = 'nexpose-policy-report.csv'
17
15
 
@@ -8,7 +8,7 @@ require 'nexpose-runner/scan_run_description'
8
8
 
9
9
  module NexposeRunner
10
10
  module Scan
11
-
11
+
12
12
  def self.allow_vulnerabilities?(vulnerabilities, run_details)
13
13
  vuln_array = []
14
14
  exceptions_array = get_exceptions(run_details)
@@ -33,8 +33,13 @@ module NexposeRunner
33
33
  end
34
34
 
35
35
  def self.get_exceptions(run_details)
36
- uri = URI("#{run_details.exceptions_list_url}")
37
- ex = Net::HTTP.get(uri).split("\n")
36
+ path = "#{run_details.exceptions_list_url}"
37
+ uri = URI(path)
38
+ if path.include? "http:"
39
+ ex = Net::HTTP.get(uri).split("\n")
40
+ elsif (File.file?(path))
41
+ ex = File.read(path).split("\n")
42
+ end
38
43
  ex
39
44
  end
40
45
 
@@ -58,7 +63,7 @@ module NexposeRunner
58
63
  puts "Scan complete for #{run_details.site_name}, Generating Vulnerability Report"
59
64
  vulnerabilities = generate_report(CONSTANTS::VULNERABILITY_REPORT_QUERY, site.id, nsc)
60
65
  generate_csv(vulnerabilities, CONSTANTS::VULNERABILITY_REPORT_NAME)
61
-
66
+
62
67
  puts "Scan complete for #{run_details.site_name}, Generating Vulnerability Detail Report"
63
68
  vuln_details = generate_report(CONSTANTS:: VULNERABILITY_DETAIL_REPORT_QUERY, site.id, nsc)
64
69
  generate_csv(vuln_details, CONSTANTS::VULNERABILITY_DETAIL_REPORT_NAME)
@@ -73,7 +78,7 @@ module NexposeRunner
73
78
 
74
79
  puts "Scan complete for #{run_details.site_name}, Generating Audit Report"
75
80
  generate_template_report(nsc, site.id, CONSTANTS::AUDIT_REPORT_FILE_NAME, CONSTANTS::AUDIT_REPORT_NAME, CONSTANTS::AUDIT_REPORT_FORMAT)
76
-
81
+
77
82
  puts "Scan complete for #{run_details.site_name}, Generating Xml Report"
78
83
  generate_template_report(nsc, site.id, CONSTANTS::XML_REPORT_FILE_NAME, CONSTANTS::XML_REPORT_NAME, CONSTANTS::XML_REPORT_FORMAT)
79
84
 
@@ -83,7 +88,7 @@ module NexposeRunner
83
88
  def self.verify_run(vulnerabilities, run_details)
84
89
 
85
90
  if run_details.exceptions_list_url.to_s.empty? and vulnerabilities.count > 0
86
- raise StandardError, CONSTANTS::VULNERABILITY_FOUND_MESSAGE
91
+ raise StandardError, CONSTANTS::VULNERABILITY_FOUND_MESSAGE
87
92
 
88
93
  elsif vulnerabilities.count == 0
89
94
  puts "No vulnerabilities found!"
@@ -118,7 +123,7 @@ module NexposeRunner
118
123
  end
119
124
  site.save nsc
120
125
  puts "Created site #{run_details.site_name} successfully with the following host(s) #{run_details.ip_addresses.join(', ')}"
121
-
126
+
122
127
  site
123
128
  end
124
129
 
@@ -5,8 +5,6 @@ class ScanRunDescription
5
5
  attr_accessor :connection_url, :exceptions_list_url, :username, :password, :port, :site_name, :ip_addresses, :scan_template, :engine
6
6
  @@port_value = ''
7
7
  @@ip_addresses = []
8
- @@timeout = ''
9
- @@open_timeout =''
10
8
  exceptions_list_url_value = ''
11
9
 
12
10
  def initialize(options)
@@ -25,8 +23,6 @@ class ScanRunDescription
25
23
  self.ip_addresses = options['ip_addresses']
26
24
  self.scan_template = options['scan_template']
27
25
  self.engine = options['engine']
28
- self.timeout = options['timeout']
29
- self.open_timeout = options['open_timeout']
30
26
  end
31
27
 
32
28
  def verify
@@ -47,22 +43,6 @@ class ScanRunDescription
47
43
  get_value(@@port_value, CONSTANTS::DEFAULT_PORT)
48
44
  end
49
45
 
50
- def timeout=(value)
51
- @@timeout = value
52
- end
53
-
54
- def timeout
55
- get_value(@@timeout, CONSTANTS::DEFAULT_TIMEOUT)
56
- end
57
-
58
- def open_timeout=(value)
59
- @@open_timeout = value
60
- end
61
-
62
- def open_timeout
63
- get_value(@@open_timeout, CONSTANTS::DEFAULT_OPEN_TIMEOUT)
64
- end
65
-
66
46
  def exceptions_list_url=(value)
67
47
  @@exceptions_list_url_value = value
68
48
  end
@@ -0,0 +1,2 @@
1
+ Database Open Access
2
+ MySQL Obsolete Version
data/spec/scan_spec.rb CHANGED
@@ -21,8 +21,6 @@ describe 'nexpose-runner' do
21
21
  @expected_site_name = 'my_cool_software_build-28'
22
22
  @expected_ips = '10.5.0.15,10.5.0.20,10.5.0.35'
23
23
  @expected_scan_template = 'full-audit-widget-corp'
24
- @timeout = '120'
25
- @open_timeout = '120'
26
24
 
27
25
  @mock_scan_id = '12'
28
26
  @mock_site_id = '1'
@@ -31,8 +29,8 @@ describe 'nexpose-runner' do
31
29
  @mock_vuln_report = 'ip_address,title,date_published,severity,summary,fix
32
30
  10.5.0.15,Database Open Access,2010-01-01,Severe,Restrict database access,<p><p>Configure the database server to only allow access to trusted systems. For example, the PCI DSS standard requires you to place the database in an internal network zone, segregated from the DMZ </p></p>
33
31
  10.5.0.15.180,MySQL Obsolete Version,2007-07-25,Critical,Upgrade to the latest version of Oracle MySQL,<p>Download and apply the upgrade from: <a href=http://dev.mysql.com/downloads/mysql>http://dev.mysql.com/downloads/mysql</a></p>'.chomp
34
- @mock_exceptions = "Database Open Access\nMySQL Obsolete Version"
35
-
32
+ @mock_exceptions = "Database Open Access\nMySQL Obsolete Version"
33
+
36
34
  @mock_vuln_detail_report = 'stuff'.chomp
37
35
 
38
36
  @mock_software_report = 'name,ip_address,host_name,description,description,vendor,name,version
@@ -65,8 +63,6 @@ describe 'nexpose-runner' do
65
63
  'site_name' => @expected_site_name,
66
64
  'ip_addresses' => @expected_ips,
67
65
  'scan_template' => @expected_scan_template,
68
- 'timeout' => @timeout,
69
- 'open_timeout' => @open_timeout
70
66
  }
71
67
 
72
68
  end
@@ -74,10 +70,9 @@ describe 'nexpose-runner' do
74
70
  it 'should create a session with the nexpose server' do
75
71
  expect(Nexpose::Connection).to receive(:new)
76
72
  .with(@options['connection_url'],
77
- @options['username'],
78
- @options['password'],
79
- @options['port']
80
- )
73
+ @options['username'],
74
+ @options['password'],
75
+ @options['port'])
81
76
  .and_return(@mock_nexpose_client)
82
77
 
83
78
  expect(@mock_nexpose_client).to receive(:login)
@@ -89,56 +84,56 @@ describe 'nexpose-runner' do
89
84
  it 'should throw an error if no connection url is passed' do
90
85
  options = @options.clone
91
86
  options['connection_url'] = nil
92
- expect {
93
- NexposeRunner::Scan.start(options)
87
+ expect {
88
+ NexposeRunner::Scan.start(options)
94
89
  }.to raise_error(StandardError, 'OOPS! Looks like you forgot to give me the URL/IP address to your Nexpose Server')
95
90
  end
96
91
 
97
92
  it 'should throw an error if no username is passed' do
98
93
  options = @options.clone
99
94
  options['username'] = nil
100
- expect {
101
- NexposeRunner::Scan.start(options)
95
+ expect {
96
+ NexposeRunner::Scan.start(options)
102
97
  }.to raise_error(StandardError, 'OOPS! Looks like you forgot to give me a username to login to Nexpose with')
103
98
  end
104
99
 
105
100
  it 'should throw an error if no password is passed' do
106
101
  options = @options.clone
107
102
  options['password'] = nil
108
- expect {
109
- NexposeRunner::Scan.start(options)
103
+ expect {
104
+ NexposeRunner::Scan.start(options)
110
105
  }.to raise_error(StandardError, 'OOPS! Looks like you forgot to give me a password to login to Nexpose with')
111
106
  end
112
107
 
113
108
  it 'should throw an error if no site name is passed' do
114
109
  options = @options.clone
115
110
  options['site_name'] = nil
116
- expect {
117
- NexposeRunner::Scan.start(options)
111
+ expect {
112
+ NexposeRunner::Scan.start(options)
118
113
  }.to raise_error(StandardError, 'OOPS! Looks like you forgot to give me a Nexpose Site Name')
119
114
  end
120
115
 
121
116
  it 'should throw an error if no ip address is passed' do
122
117
  options = @options.clone
123
118
  options['ip_addresses'] = '';
124
- expect {
125
- NexposeRunner::Scan.start(options)
119
+ expect {
120
+ NexposeRunner::Scan.start(options)
126
121
  }.to raise_error(StandardError, 'OOPS! Looks like you forgot to give me an IP Address to scan')
127
122
  end
128
123
 
129
124
  it 'should throw an error if no scan template is passed' do
130
125
  options = @options.clone
131
126
  options['scan_template'] = nil
132
- expect {
133
- NexposeRunner::Scan.start(options)
127
+ expect {
128
+ NexposeRunner::Scan.start(options)
134
129
  }.to raise_error(StandardError, 'OOPS! Looks like you forgot to give me a Scan Template to use')
135
130
  end
136
131
 
137
132
  it 'should use 3780 as default if port is empty string' do
138
133
  expect(Nexpose::Connection).to receive(:new)
139
- .with(@options['connection_url'],
140
- @options['username'],
141
- @options['password'],
134
+ .with(@options['connection_url'],
135
+ @options['username'],
136
+ @options['password'],
142
137
  '3780')
143
138
  .and_return(@mock_nexpose_client)
144
139
 
@@ -181,37 +176,37 @@ describe 'nexpose-runner' do
181
176
  describe 'wait for the Nexpose Scan to complete' do
182
177
  it 'should call to check the status of the scan' do
183
178
  expect(@mock_nexpose_client).to receive(:scan_statistics).with(@mock_scan_id)
184
-
179
+
185
180
  NexposeRunner::Scan.start(@options)
186
181
  end
187
-
182
+
188
183
  it 'should call to check the status until it is not running' do
189
184
  expect(@mock_scan_summary).to receive(:status)
190
185
  .and_return(Nexpose::Scan::Status::RUNNING)
191
186
  .exactly(3).times
192
187
  .ordered
193
-
188
+
194
189
  expect(@mock_scan_summary).to receive(:status)
195
190
  .and_return(Nexpose::Scan::Status::FINISHED)
196
191
  .once
197
192
  .ordered
198
-
193
+
199
194
  NexposeRunner::Scan.start(@options)
200
195
  end
201
-
196
+
202
197
  it 'should sleep for 3 seconds if the status is still running' do
203
198
  expect(@mock_scan_summary).to receive(:status)
204
199
  .and_return(Nexpose::Scan::Status::RUNNING)
205
200
  .exactly(3).times
206
201
  .ordered
207
-
202
+
208
203
  expect(@mock_scan_summary).to receive(:status)
209
204
  .and_return(Nexpose::Scan::Status::FINISHED)
210
205
  .once
211
206
  .ordered
212
207
 
213
208
  expect(NexposeRunner::Scan).to receive(:sleep).with(3).exactly(4).times
214
-
209
+
215
210
  NexposeRunner::Scan.start(@options)
216
211
  end
217
212
  end
@@ -230,16 +225,16 @@ describe 'nexpose-runner' do
230
225
  expect(Nexpose::AdhocReportConfig).to receive(:new)
231
226
  .with(CONSTANTS::AUDIT_REPORT_NAME, CONSTANTS::AUDIT_REPORT_FORMAT, @mock_site_id)
232
227
  .and_return(@mock_report)
233
-
228
+
234
229
  expect(Nexpose::AdhocReportConfig).to receive(:new)
235
230
  .with(CONSTANTS::XML_REPORT_NAME, CONSTANTS::XML_REPORT_FORMAT, @mock_site_id)
236
231
  .and_return(@mock_report)
237
232
 
238
233
  expect_template_report_to_be_called_with(CONSTANTS::AUDIT_REPORT_FILE_NAME)
239
234
  expect_template_report_to_be_called_with(CONSTANTS::XML_REPORT_FILE_NAME)
240
-
241
- expect {
242
- NexposeRunner::Scan.start(@options)
235
+
236
+ expect {
237
+ NexposeRunner::Scan.start(@options)
243
238
  }.to raise_error(StandardError, CONSTANTS::VULNERABILITY_FOUND_MESSAGE)
244
239
  end
245
240
  end
@@ -247,19 +242,30 @@ describe 'nexpose-runner' do
247
242
  it 'should throw exception if vulnerability exists' do
248
243
  expect_report_to_be_called_with(CONSTANTS::VULNERABILITY_REPORT_NAME, CONSTANTS::VULNERABILITY_REPORT_QUERY, @mock_vuln_report)
249
244
 
250
- expect {
251
- NexposeRunner::Scan.start(@options)
245
+ expect {
246
+ NexposeRunner::Scan.start(@options)
252
247
  }.to raise_error(StandardError, CONSTANTS::VULNERABILITY_FOUND_MESSAGE)
253
248
  end
254
249
 
255
250
  it 'should not throw exception if exceptions exist for all vulnerabilities' do
256
251
  expect_report_to_be_called_with(CONSTANTS::VULNERABILITY_REPORT_NAME, CONSTANTS::VULNERABILITY_REPORT_QUERY, @mock_vuln_report)
257
-
252
+
258
253
  options = @options.clone
259
254
  options['exceptions_list_url'] = 'http://google.com'
260
-
255
+
261
256
  expect_exceptions_to_be_called_with(options['exceptions_list_url'])
262
-
257
+
258
+ NexposeRunner::Scan.start(options)
259
+ end
260
+
261
+ it 'should not throw exception if exceptions exist from a file for all vulnerabilities' do
262
+ expect_report_to_be_called_with(CONSTANTS::VULNERABILITY_REPORT_NAME, CONSTANTS::VULNERABILITY_REPORT_QUERY, @mock_vuln_report)
263
+
264
+ options = @options.clone
265
+ options['exceptions_list_url'] = 'spec/data/test_exclist.txt'
266
+
267
+ expect_exceptions_to_be_called_with_file(options['exceptions_list_url'])
268
+
263
269
  NexposeRunner::Scan.start(options)
264
270
  end
265
271
  end
@@ -275,6 +281,10 @@ def expect_exceptions_to_be_called_with(exceptions_list_url)
275
281
  .with(uri).and_return(@mock_exceptions)
276
282
  end
277
283
 
284
+ def expect_exceptions_to_be_called_with_file(exceptions_list_url)
285
+ expect(File.read(exceptions_list_url)).to eq "Database Open Access\nMySQL Obsolete Version\n"
286
+ end
287
+
278
288
  def expect_report_to_be_called_with(report_name, report_query, report_response)
279
289
  expect(@mock_report).to receive(:add_filter)
280
290
  .with('version', '1.3.0')
@@ -311,29 +321,29 @@ def get_mock_nexpose_client
311
321
 
312
322
  allow(Nexpose::Connection).to receive(:new)
313
323
  .and_return(mock_nexpose_client)
314
-
324
+
315
325
  allow(mock_nexpose_client).to receive(:make_xml)
316
326
  .with(any_args)
317
327
  .and_return(xml)
318
-
328
+
319
329
  allow(mock_nexpose_client).to receive(:make_xml)
320
330
  .with(any_args)
321
331
  .and_return(xml)
322
-
332
+
323
333
  allow(mock_nexpose_client).to receive(:filter)
324
334
  .with(any_args)
325
- .and_return({})
326
-
335
+ .and_return({})
336
+
327
337
  allow(mock_nexpose_client).to receive(:execute)
328
338
  .with(any_args)
329
339
  .and_return(mock_api_request)
330
-
340
+
331
341
  allow(mock_api_request).to receive(:success)
332
342
  .and_return(false) #this is just to shut up the underlying api.
333
-
343
+
334
344
  allow(mock_api_request).to receive(:attributes)
335
- .and_return(xml)
336
-
345
+ .and_return(xml)
346
+
337
347
  mock_nexpose_client
338
348
  end
339
349
 
@@ -345,9 +355,9 @@ def get_mock_scan_summary
345
355
  allow(mock_scan_summary).to receive(:tasks).and_return(tasks)
346
356
 
347
357
  allow(mock_scan_summary).to receive(:status).and_return(
348
- Nexpose::Scan::Status::RUNNING,
349
358
  Nexpose::Scan::Status::RUNNING,
350
- Nexpose::Scan::Status::RUNNING,
359
+ Nexpose::Scan::Status::RUNNING,
360
+ Nexpose::Scan::Status::RUNNING,
351
361
  Nexpose::Scan::Status::FINISHED)
352
362
  mock_scan_summary
353
363
  end
@@ -411,4 +421,3 @@ def get_mock_scan
411
421
  allow(mock_scan).to receive(:id).and_return(@mock_scan_id)
412
422
  mock_scan
413
423
  end
414
-
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: NexposeRunner
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.16b
4
+ version: 0.0.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Gibson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-27 00:00:00.000000000 Z
11
+ date: 2017-10-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nexpose
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 7.1.1
19
+ version: 0.8.3
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 7.1.1
26
+ version: 0.8.3
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -91,6 +91,7 @@ files:
91
91
  - lib/nexpose-runner/constants.rb
92
92
  - lib/nexpose-runner/scan.rb
93
93
  - lib/nexpose-runner/scan_run_description.rb
94
+ - spec/data/test_exclist.txt
94
95
  - spec/scan_config_spec.rb
95
96
  - spec/scan_spec.rb
96
97
  - spec/spec_helper.rb
@@ -109,9 +110,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
109
110
  version: '0'
110
111
  required_rubygems_version: !ruby/object:Gem::Requirement
111
112
  requirements:
112
- - - ">"
113
+ - - ">="
113
114
  - !ruby/object:Gem::Version
114
- version: 1.3.1
115
+ version: '0'
115
116
  requirements: []
116
117
  rubyforge_project:
117
118
  rubygems_version: 2.5.2
@@ -122,6 +123,7 @@ summary: This is a gem that provides the ability to create a new site, add an IP
122
123
  and finally produce a reports for vulnerabilities, installed software, and policy
123
124
  compliance.
124
125
  test_files:
126
+ - spec/data/test_exclist.txt
125
127
  - spec/scan_config_spec.rb
126
128
  - spec/scan_spec.rb
127
129
  - spec/spec_helper.rb