nexpose 0.8.10 → 0.8.11
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/Gemfile +4 -0
- data/Rakefile +1 -12
- data/lib/nexpose/ajax.rb +14 -0
- data/lib/nexpose/common.rb +3 -6
- data/lib/nexpose/data_table.rb +10 -4
- data/lib/nexpose/global_settings.rb +14 -7
- data/lib/nexpose/scan.rb +42 -4
- data/lib/nexpose/version.rb +4 -0
- data/lib/nexpose.rb +1 -0
- metadata +18 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9a8af56d94e621eaf5a5c7aba69a52c4b840fe72
|
4
|
+
data.tar.gz: aed5d663662dcc7364d08c3c23e80e036786b3ca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 309661c597363464b8f47162b8f31bcf0914f699938da2772bd8554b589a3217d9b10540e36b65c1188a20555fc6c2d59e0dd68143e1ab099cf8bb54bed970ce
|
7
|
+
data.tar.gz: 60e5a8f6050b052484f774ed9a32ad47a9d1046fa8551d5e0574926990e2e3327133a2c8544a668ea4461b592f69686f98a263d35697240b677a612d1dbd37f0
|
data/Gemfile
ADDED
data/Rakefile
CHANGED
@@ -1,16 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
|
3
|
-
task :build do
|
4
|
-
Rake::Task['clean'].execute
|
5
|
-
puts "[*] Building nexpose.gemspec"
|
6
|
-
system "gem build nexpose.gemspec &> /dev/null"
|
7
|
-
end
|
8
|
-
|
9
|
-
task :release => :build do
|
10
|
-
puts "[*] Pushing nexpose to rubygems.org"
|
11
|
-
system "gem push nexpose-*.gem &> /dev/null"
|
12
|
-
Rake::Task['clean'].execute
|
13
|
-
end
|
2
|
+
require 'bundler/gem_tasks'
|
14
3
|
|
15
4
|
task :clean do
|
16
5
|
system "rm *.gem &> /dev/null"
|
data/lib/nexpose/ajax.rb
CHANGED
@@ -185,5 +185,19 @@ module Nexpose
|
|
185
185
|
attr.value == '1'
|
186
186
|
end
|
187
187
|
end
|
188
|
+
|
189
|
+
def _row_pref_of(val)
|
190
|
+
if val.nil? || val > 100
|
191
|
+
500
|
192
|
+
elsif val > 50
|
193
|
+
100
|
194
|
+
elsif val > 25
|
195
|
+
50
|
196
|
+
elsif val > 10
|
197
|
+
25
|
198
|
+
else
|
199
|
+
10
|
200
|
+
end
|
201
|
+
end
|
188
202
|
end
|
189
203
|
end
|
data/lib/nexpose/common.rb
CHANGED
@@ -1,9 +1,6 @@
|
|
1
1
|
module Nexpose
|
2
|
-
|
3
|
-
# Constants
|
4
|
-
|
2
|
+
# Constants useful across the Nexpose module.
|
5
3
|
module Scope
|
6
|
-
|
7
4
|
GLOBAL = 'global'
|
8
5
|
SILO = 'silo'
|
9
6
|
end
|
@@ -27,7 +24,6 @@ module Nexpose
|
|
27
24
|
# the application will send reports via e-mail to access-list members and
|
28
25
|
# non-members.
|
29
26
|
class Email
|
30
|
-
|
31
27
|
# Send as file attachment or zipped file to individuals who are not members
|
32
28
|
# of the report access list. One of: file|zip
|
33
29
|
attr_accessor :send_as
|
@@ -164,6 +160,7 @@ module Nexpose
|
|
164
160
|
end
|
165
161
|
end
|
166
162
|
|
163
|
+
# Organization configuration, as used in Site and Silo.
|
167
164
|
class Organization
|
168
165
|
attr_accessor :name
|
169
166
|
attr_accessor :url
|
@@ -178,7 +175,7 @@ module Nexpose
|
|
178
175
|
attr_accessor :country
|
179
176
|
|
180
177
|
def initialize(&block)
|
181
|
-
instance_eval
|
178
|
+
instance_eval(&block) if block_given?
|
182
179
|
end
|
183
180
|
|
184
181
|
def self.parse(xml)
|
data/lib/nexpose/data_table.rb
CHANGED
@@ -14,11 +14,14 @@ module Nexpose
|
|
14
14
|
# @param [Connection] console API connection to a Nexpose console.
|
15
15
|
# @param [String] address Controller address relative to https://host:port
|
16
16
|
# @param [Hash] parameters Parameters that need to be sent to the controller
|
17
|
-
#
|
18
|
-
# @param [Integer] number of records to return, gets all if not specified
|
19
|
-
# The following attributes need to be provided:
|
17
|
+
# The following attributes may need to be provided:
|
20
18
|
# 'sort' Column to sort by
|
21
19
|
# 'table-id' The ID of the table to get from this controller
|
20
|
+
# @param [Fixnum] page_size Number of records to include per page.
|
21
|
+
# Value must conform to supported defaults: -1, 10, 25, 50, 100, 500.
|
22
|
+
# @param [Fixnum] records number of records to return, gets all if not
|
23
|
+
# specified.
|
24
|
+
# @param [Boolean] post Whether to use form post or get to retrieve data.
|
22
25
|
# @return [Array[Hash]] An array of hashes representing the requested table.
|
23
26
|
#
|
24
27
|
# Example usage:
|
@@ -41,8 +44,11 @@ module Nexpose
|
|
41
44
|
|
42
45
|
response = request.(parameters)
|
43
46
|
data = JSON.parse(response)
|
44
|
-
|
47
|
+
|
48
|
+
# Don't attept to grab more records than there are.
|
49
|
+
total = data['totalRecords']
|
45
50
|
return [] if total == 0
|
51
|
+
total = records.nil? ? total : [records, total].min
|
46
52
|
|
47
53
|
rows = []
|
48
54
|
parameters['results'] = page_size
|
@@ -8,7 +8,7 @@ module Nexpose
|
|
8
8
|
|
9
9
|
# Whether control scanning in enabled. A feature tied to ControlsInsight
|
10
10
|
# integration.
|
11
|
-
|
11
|
+
attr_reader :control_scanning
|
12
12
|
|
13
13
|
# XML document representing the entire configuration.
|
14
14
|
attr_reader :xml
|
@@ -19,7 +19,7 @@ module Nexpose
|
|
19
19
|
@xml = xml
|
20
20
|
|
21
21
|
@asset_exclusions = HostOrIP.parse(xml)
|
22
|
-
@control_scanning =
|
22
|
+
@control_scanning = parse_control_scanning_from_xml(xml)
|
23
23
|
end
|
24
24
|
|
25
25
|
# Returns true if controls scanning is enabled.
|
@@ -27,6 +27,11 @@ module Nexpose
|
|
27
27
|
control_scanning
|
28
28
|
end
|
29
29
|
|
30
|
+
# Enables/disables controls scanning
|
31
|
+
def control_scanning=(enabled)
|
32
|
+
add_control_scanning_to_xml(xml, enabled)
|
33
|
+
end
|
34
|
+
|
30
35
|
# Save any updates to this settings object to the Nexpose console.
|
31
36
|
#
|
32
37
|
# @param [Connection] nsc Connection to a Nexpose console.
|
@@ -39,8 +44,8 @@ module Nexpose
|
|
39
44
|
risk_model.add_attribute('recalculation_duration', 'do_not_recalculate')
|
40
45
|
end
|
41
46
|
|
42
|
-
|
43
|
-
|
47
|
+
replace_exclusions(xml, asset_exclusions)
|
48
|
+
add_control_scanning_to_xml(xml, control_scanning)
|
44
49
|
|
45
50
|
response = AJAX.post(nsc, '/data/admin/global-settings', xml)
|
46
51
|
XMLUtils.success? response
|
@@ -85,8 +90,10 @@ module Nexpose
|
|
85
90
|
new(REXML::Document.new(response))
|
86
91
|
end
|
87
92
|
|
93
|
+
private
|
94
|
+
|
88
95
|
# Internal method for updating exclusions before saving.
|
89
|
-
def
|
96
|
+
def replace_exclusions(xml, exclusions)
|
90
97
|
xml.elements.delete('//ExcludedHosts')
|
91
98
|
elem = xml.root.add_element('ExcludedHosts')
|
92
99
|
exclusions.each do |exclusion|
|
@@ -95,7 +102,7 @@ module Nexpose
|
|
95
102
|
end
|
96
103
|
|
97
104
|
# Internal method for parsing XML for whether control scanning in enabled.
|
98
|
-
def
|
105
|
+
def parse_control_scanning_from_xml(xml)
|
99
106
|
enabled = false
|
100
107
|
if elem = REXML::XPath.first(xml, '//enableControlsScan[@enabled]')
|
101
108
|
enabled = elem.attribute('enabled').value.to_i == 1
|
@@ -104,7 +111,7 @@ module Nexpose
|
|
104
111
|
end
|
105
112
|
|
106
113
|
# Internal method for updating control scanning before saving.
|
107
|
-
def
|
114
|
+
def add_control_scanning_to_xml(xml, enabled)
|
108
115
|
if elem = REXML::XPath.first(xml, '//enableControlsScan')
|
109
116
|
elem.attributes['enabled'] = enabled ? '1' : '0'
|
110
117
|
else
|
data/lib/nexpose/scan.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
module Nexpose
|
2
|
-
|
3
2
|
class Connection
|
4
3
|
include XMLUtils
|
5
4
|
|
@@ -110,7 +109,7 @@ module Nexpose
|
|
110
109
|
# @param [HostName|IPRange] asset Asset to append to XML.
|
111
110
|
#
|
112
111
|
def _append_asset!(xml, asset)
|
113
|
-
if asset.
|
112
|
+
if asset.is_a? Nexpose::IPRange
|
114
113
|
xml.add_element('range', { 'from' => asset.from, 'to' => asset.to })
|
115
114
|
else # Assume HostName
|
116
115
|
host = REXML::Element.new('host')
|
@@ -227,6 +226,26 @@ module Nexpose
|
|
227
226
|
end
|
228
227
|
end
|
229
228
|
|
229
|
+
# Get a history of past scans for this console, sorted by most recent first.
|
230
|
+
#
|
231
|
+
# Please note that for consoles with a deep history of scanning, this method
|
232
|
+
# could return an excessive amount of data (and take quite a bit of time to
|
233
|
+
# retrieve). Consider limiting the amount of data with the optional argument.
|
234
|
+
#
|
235
|
+
# @param [Fixnum] limit The maximum number of records to return from this call.
|
236
|
+
# @return [Array[CompletedScan]] List of completed scans, ordered by most
|
237
|
+
# recently completed first.
|
238
|
+
#
|
239
|
+
def past_scans(limit = nil)
|
240
|
+
uri = '/data/scan/global/scan-history'
|
241
|
+
rows = AJAX._row_pref_of(limit)
|
242
|
+
params = { 'sort' => 'endTime', 'dir' => 'DESC', 'startIndex' => 0 }
|
243
|
+
AJAX.preserving_preference(self, 'global-completed-scans') do
|
244
|
+
data = DataTable._get_json_table(self, uri, params, rows, limit)
|
245
|
+
data.map(&CompletedScan.method(:parse_json))
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
230
249
|
# Export the data associated with a single scan, and optionally store it in
|
231
250
|
# a zip-compressed file under the provided name.
|
232
251
|
#
|
@@ -276,7 +295,7 @@ module Nexpose
|
|
276
295
|
def import_scan(site_id, zip_file)
|
277
296
|
data = Rex::MIME::Message.new
|
278
297
|
data.add_part(site_id.to_s, nil, nil, 'form-data; name="siteid"')
|
279
|
-
data.add_part(
|
298
|
+
data.add_part(session_id, nil, nil, 'form-data; name="nexposeCCSessionID"')
|
280
299
|
scan = File.new(zip_file, 'rb')
|
281
300
|
data.add_part(scan.read, 'application/zip', 'binary',
|
282
301
|
"form-data; name=\"scan\"; filename=\"#{zip_file}\"")
|
@@ -316,7 +335,6 @@ module Nexpose
|
|
316
335
|
# can be rather verbose and isn't useful for many automation scenarios.
|
317
336
|
#
|
318
337
|
class ScanData
|
319
|
-
|
320
338
|
# The Scan ID of the Scan
|
321
339
|
attr_reader :scan_id
|
322
340
|
# The site that was scanned.
|
@@ -582,6 +600,10 @@ module Nexpose
|
|
582
600
|
class CompletedScan
|
583
601
|
# Unique identifier of a scan.
|
584
602
|
attr_reader :id
|
603
|
+
# Site ID for which the scan was run.
|
604
|
+
attr_reader :site_id
|
605
|
+
# Final status of the scan. One of :completed, :stopped, :aborted, :unknown.
|
606
|
+
attr_reader :status
|
585
607
|
# Start time of the scan.
|
586
608
|
attr_reader :start_time
|
587
609
|
# Completion time of the scan.
|
@@ -609,6 +631,8 @@ module Nexpose
|
|
609
631
|
def self.parse_json(json)
|
610
632
|
new do
|
611
633
|
@id = json['scanID']
|
634
|
+
@site_id = json['siteID']
|
635
|
+
@status = CompletedScan._parse_status(json['status'])
|
612
636
|
@start_time = Time.at(json['startTime'] / 1000)
|
613
637
|
@end_time = Time.at(json['endTime'] / 1000)
|
614
638
|
@duration = json['duration']
|
@@ -619,5 +643,19 @@ module Nexpose
|
|
619
643
|
@engine_name = json['scanEngineName']
|
620
644
|
end
|
621
645
|
end
|
646
|
+
|
647
|
+
# Internal method to parsing status codes.
|
648
|
+
def self._parse_status(code)
|
649
|
+
case code
|
650
|
+
when 'C'
|
651
|
+
:completed
|
652
|
+
when 'S'
|
653
|
+
:stopped
|
654
|
+
when 'A'
|
655
|
+
:aborted
|
656
|
+
else
|
657
|
+
:unknown
|
658
|
+
end
|
659
|
+
end
|
622
660
|
end
|
623
661
|
end
|
data/lib/nexpose.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nexpose
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- HD Moore
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2014-
|
14
|
+
date: 2014-11-04 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: rex
|
@@ -53,6 +53,20 @@ dependencies:
|
|
53
53
|
- - ">="
|
54
54
|
- !ruby/object:Gem::Version
|
55
55
|
version: 1.6.2
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: bundler
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '1.3'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '1.3'
|
56
70
|
description: This gem provides a Ruby API to the Nexpose vulnerability management
|
57
71
|
product by Rapid7.
|
58
72
|
email:
|
@@ -66,6 +80,7 @@ extra_rdoc_files:
|
|
66
80
|
- README.markdown
|
67
81
|
files:
|
68
82
|
- COPYING
|
83
|
+
- Gemfile
|
69
84
|
- README.markdown
|
70
85
|
- Rakefile
|
71
86
|
- lib/README.md
|
@@ -105,6 +120,7 @@ files:
|
|
105
120
|
- lib/nexpose/ticket.rb
|
106
121
|
- lib/nexpose/user.rb
|
107
122
|
- lib/nexpose/util.rb
|
123
|
+
- lib/nexpose/version.rb
|
108
124
|
- lib/nexpose/vuln.rb
|
109
125
|
- lib/nexpose/vuln_exception.rb
|
110
126
|
homepage: https://github.com/rapid7/nexpose-client
|