nexpose 0.9.0 → 0.9.1
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/lib/nexpose/connection.rb +0 -2
- data/lib/nexpose/filter.rb +33 -23
- data/lib/nexpose/site.rb +1 -1
- data/lib/nexpose/tag.rb +23 -25
- data/lib/nexpose/tag/criteria.rb +22 -30
- data/lib/nexpose/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2c31ee4438b71d0e7787d9cfad2720d477e7988a
|
4
|
+
data.tar.gz: d33c662be936d2ffd49987a3cf12d4f49899f733
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 52e8d242d94b4965f27c314b285d6a1937ba9647e646a148557961071e64271fefd6fd926ebd483126cbc5ee8fafb0828aa30cae7871d4253146d238d025c486
|
7
|
+
data.tar.gz: fc5065fe8f438171d8e2942d5e624a6e2ea22c39d851fe099adaf8f485ef8c4e04e241bbb0cc7ca282c2ec61cd61100960e329f3001c42698982433ece4f0b59
|
data/lib/nexpose/connection.rb
CHANGED
data/lib/nexpose/filter.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
module Nexpose
|
2
|
-
|
2
|
+
# Object that represents a connection to a Nexpose Security Console.
|
3
3
|
class Connection
|
4
|
-
|
5
4
|
# Perform an asset filter search that will locate assets matching the
|
6
5
|
# provided conditions.
|
7
6
|
#
|
@@ -53,9 +52,9 @@ module Nexpose
|
|
53
52
|
# Only these values are accepted for a field value.
|
54
53
|
#
|
55
54
|
module Field
|
56
|
-
|
57
55
|
# Search for an Asset by name.
|
58
|
-
# Valid Operators: IS, IS_NOT, STARTS_WITH, ENDS_WITH, CONTAINS,
|
56
|
+
# Valid Operators: IS, IS_NOT, STARTS_WITH, ENDS_WITH, CONTAINS,
|
57
|
+
# NOT_CONTAINS
|
59
58
|
ASSET = 'ASSET'
|
60
59
|
|
61
60
|
# Search for an Asset by CVE ID
|
@@ -91,7 +90,8 @@ module Nexpose
|
|
91
90
|
CVSS_SCORE = 'CVSS_SCORE'
|
92
91
|
|
93
92
|
# Valid Operators: IN, NOT_IN
|
94
|
-
# Valid Values (See Value::HostType): UNKNOWN, VIRTUAL, HYPERVISOR,
|
93
|
+
# Valid Values (See Value::HostType): UNKNOWN, VIRTUAL, HYPERVISOR,
|
94
|
+
# BARE_METAL
|
95
95
|
HOST_TYPE = 'HOST_TYPE'
|
96
96
|
|
97
97
|
# Valid Operators: IN, NOT_IN
|
@@ -138,17 +138,21 @@ module Nexpose
|
|
138
138
|
# Valid Operators: CONTAINS, NOT_CONTAINS
|
139
139
|
SOFTWARE = 'SOFTWARE'
|
140
140
|
|
141
|
-
# Valid Operators: IS, IS_NOT, GREATER_THAN, LESS_THAN, IS_APPLIED,
|
141
|
+
# Valid Operators: IS, IS_NOT, GREATER_THAN, LESS_THAN, IS_APPLIED,
|
142
|
+
# IS_NOT_APPLIED
|
142
143
|
# Valid Values: VERY_HIGH, HIGH, NORMAL, LOW, VERY_LOW
|
143
144
|
USER_ADDED_CRITICALITY_LEVEL = 'TAG_CRITICALITY'
|
144
145
|
|
145
|
-
# Valid Operators: IS, IS_NOT, STARTS_WITH, ENDS_WITH, IS_APPLIED,
|
146
|
+
# Valid Operators: IS, IS_NOT, STARTS_WITH, ENDS_WITH, IS_APPLIED,
|
147
|
+
# IS_NOT_APPLIED, CONTAINS, NOT_CONTAINS
|
146
148
|
USER_ADDED_CUSTOM_TAG = 'TAG'
|
147
149
|
|
148
|
-
# Valid Operators: IS, IS_NOT, STARTS_WITH, ENDS_WITH, IS_APPLIED,
|
150
|
+
# Valid Operators: IS, IS_NOT, STARTS_WITH, ENDS_WITH, IS_APPLIED,
|
151
|
+
# IS_NOT_APPLIED, CONTAINS, NOT_CONTAINS
|
149
152
|
USER_ADDED_TAG_LOCATION = 'TAG_LOCATION'
|
150
153
|
|
151
|
-
# Valid Operators: IS, IS_NOT, STARTS_WITH, ENDS_WITH, IS_APPLIED,
|
154
|
+
# Valid Operators: IS, IS_NOT, STARTS_WITH, ENDS_WITH, IS_APPLIED,
|
155
|
+
# IS_NOT_APPLIED, CONTAINS, NOT_CONTAINS
|
152
156
|
USER_ADDED_TAG_OWNER = 'TAG_OWNER'
|
153
157
|
|
154
158
|
# Valid Operators: ARE
|
@@ -160,11 +164,13 @@ module Nexpose
|
|
160
164
|
VULNERABILITY = 'VULNERABILITY'
|
161
165
|
|
162
166
|
# Valid Operators: INCLUDE, DO_NOT_INCLUDE
|
163
|
-
# Valid Values (See Value::VulnerabilityExposure): MALWARE, METASPLOIT,
|
167
|
+
# Valid Values (See Value::VulnerabilityExposure): MALWARE, METASPLOIT,
|
168
|
+
# DATABASE
|
164
169
|
VULNERABILITY_EXPOSURES = 'VULNERABILITY_EXPOSURES'
|
165
170
|
|
166
171
|
# Search by VULNERABILITY CATEGORY
|
167
|
-
# Valid Operators: IS, IS_NOT, CONTAINS, NOT_CONTAINS, STARTS_WITH,
|
172
|
+
# Valid Operators: IS, IS_NOT, CONTAINS, NOT_CONTAINS, STARTS_WITH,
|
173
|
+
# ENDS_WITH
|
168
174
|
VULN_CATEGORY = 'VULN_CATEGORY'
|
169
175
|
end
|
170
176
|
|
@@ -199,31 +205,35 @@ module Nexpose
|
|
199
205
|
# Specialized values used by certain search fields
|
200
206
|
#
|
201
207
|
module Value
|
202
|
-
|
208
|
+
# Constants for filtering on access complexity.
|
203
209
|
module AccessComplexity
|
204
210
|
LOW = 'L'
|
205
211
|
MEDIUM = 'M'
|
206
212
|
HIGH = 'H'
|
207
213
|
end
|
208
214
|
|
215
|
+
# Constants for filtering on access vector.
|
209
216
|
module AccessVector
|
210
217
|
LOCAL = 'L'
|
211
218
|
ADJACENT = 'A'
|
212
219
|
NETWORK = 'N'
|
213
220
|
end
|
214
221
|
|
222
|
+
# Constants for filtering on whether authentication is required.
|
215
223
|
module AuthenticationRequired
|
216
224
|
NONE = 'N'
|
217
225
|
SINGLE = 'S'
|
218
226
|
MULTIPLE = 'M'
|
219
227
|
end
|
220
228
|
|
229
|
+
# Constants for filtering on CVSS impact.
|
221
230
|
module CVSSImpact
|
222
231
|
NONE = 'N'
|
223
232
|
PARTIAL = 'P'
|
224
233
|
COMPLETE = 'C'
|
225
234
|
end
|
226
235
|
|
236
|
+
# Constants for filtering on host type.
|
227
237
|
module HostType
|
228
238
|
UNKNOWN = '0'
|
229
239
|
VIRTUAL = '1'
|
@@ -231,26 +241,31 @@ module Nexpose
|
|
231
241
|
BARE_METAL = '3'
|
232
242
|
end
|
233
243
|
|
244
|
+
# Constants for filtering on IP type.
|
234
245
|
module IPType
|
235
246
|
IPv4 = '0'
|
236
247
|
IPv6 = '1'
|
237
248
|
end
|
238
249
|
|
250
|
+
# Constants for filtering on PCI compliance.
|
239
251
|
module PCICompliance
|
240
252
|
PASS = '1'
|
241
253
|
FAIL = '0'
|
242
254
|
end
|
243
255
|
|
256
|
+
# Constants for filtering on scan date.
|
244
257
|
module ScanDate
|
245
258
|
# Pass this format to #strftime() to get expected format for requests.
|
246
259
|
FORMAT = '%m/%d/%Y'
|
247
260
|
end
|
248
261
|
|
262
|
+
# Constants for filtering on vulnerability validations.
|
249
263
|
module ValidatedVulnerability
|
250
264
|
NOT_PRESENT = 1
|
251
265
|
PRESENT = 0
|
252
266
|
end
|
253
267
|
|
268
|
+
# Constants for filtering on vulnerability exposure.
|
254
269
|
module VulnerabilityExposure
|
255
270
|
MALWARE = 'type:"malware_type", name:"malwarekit"'
|
256
271
|
# TODO: A problem in Nexpose causes these values to not be constant.
|
@@ -263,7 +278,6 @@ module Nexpose
|
|
263
278
|
# Individual search criterion.
|
264
279
|
#
|
265
280
|
class Criterion
|
266
|
-
|
267
281
|
# Search field. One of Nexpose::Search::Field
|
268
282
|
# @see Nexpose::Search::Field for any restrictions on the other attibutes.
|
269
283
|
attr_accessor :field
|
@@ -274,8 +288,8 @@ module Nexpose
|
|
274
288
|
|
275
289
|
def initialize(field, operator, value = '')
|
276
290
|
@field, @operator = field.upcase, operator.upcase
|
277
|
-
if value.
|
278
|
-
@value = value.map
|
291
|
+
if value.is_a? Array
|
292
|
+
@value = value.map(&:to_s)
|
279
293
|
else
|
280
294
|
@value = value.to_s
|
281
295
|
end
|
@@ -283,12 +297,11 @@ module Nexpose
|
|
283
297
|
|
284
298
|
# Convert this object into the map format expected by Nexpose.
|
285
299
|
#
|
286
|
-
def
|
300
|
+
def to_h
|
287
301
|
{ 'metadata' => { 'fieldName' => field },
|
288
302
|
'operator' => operator,
|
289
303
|
'values' => Array(value) }
|
290
304
|
end
|
291
|
-
alias_method :to_map, :to_hash
|
292
305
|
|
293
306
|
def self.parse(json)
|
294
307
|
Criterion.new(json['metadata']['fieldName'],
|
@@ -300,7 +313,6 @@ module Nexpose
|
|
300
313
|
# Join search criteria for an asset filter search or dynamic asset group.
|
301
314
|
#
|
302
315
|
class Criteria
|
303
|
-
|
304
316
|
# Whether to match any or all filters. One of 'OR' or 'AND'.
|
305
317
|
attr_accessor :match
|
306
318
|
# Array of criteria to match against.
|
@@ -311,16 +323,15 @@ module Nexpose
|
|
311
323
|
@match = match.upcase
|
312
324
|
end
|
313
325
|
|
314
|
-
def
|
326
|
+
def to_h
|
315
327
|
{ 'operator' => @match,
|
316
|
-
'criteria' => @criteria.map
|
328
|
+
'criteria' => @criteria.map(&:to_h) }
|
317
329
|
end
|
318
|
-
alias_method :to_map, :to_hash
|
319
330
|
|
320
331
|
# Convert this object into the format expected by Nexpose.
|
321
332
|
#
|
322
333
|
def to_json
|
323
|
-
JSON.generate(
|
334
|
+
JSON.generate(to_h)
|
324
335
|
end
|
325
336
|
|
326
337
|
# Generate the payload needed for a POST request for Asset Filter.
|
@@ -352,7 +363,6 @@ module Nexpose
|
|
352
363
|
# Asset data as returned by an Asset Filter search.
|
353
364
|
#
|
354
365
|
class FilteredAsset
|
355
|
-
|
356
366
|
# Unique identifier of this asset. Also known as device ID.
|
357
367
|
attr_reader :id
|
358
368
|
|
data/lib/nexpose/site.rb
CHANGED
@@ -352,7 +352,7 @@ module Nexpose
|
|
352
352
|
'tag' => @description.nil? ? '' : @description,
|
353
353
|
'riskFactor' => @risk_factor,
|
354
354
|
# 'vCenter' => @discovery_connection_id,
|
355
|
-
'searchCriteria' => @criteria.nil? ? { 'operator' => 'AND' } : @criteria.
|
355
|
+
'searchCriteria' => @criteria.nil? ? { 'operator' => 'AND' } : @criteria.to_h }
|
356
356
|
json = JSON.generate(details)
|
357
357
|
|
358
358
|
response = AJAX.post(nsc, uri, json, AJAX::CONTENT_TYPE::JSON)
|
data/lib/nexpose/tag.rb
CHANGED
@@ -8,7 +8,7 @@ module Nexpose
|
|
8
8
|
#
|
9
9
|
def tags
|
10
10
|
tag_summary = []
|
11
|
-
tags = JSON.parse(AJAX.get(self, '/api/2.0/tags', AJAX::CONTENT_TYPE::JSON, { per_page:
|
11
|
+
tags = JSON.parse(AJAX.get(self, '/api/2.0/tags', AJAX::CONTENT_TYPE::JSON, { per_page: 2_147_483_647 }))
|
12
12
|
tags['resources'].each do |json|
|
13
13
|
tag_summary << TagSummary.parse(json)
|
14
14
|
end
|
@@ -31,7 +31,7 @@ module Nexpose
|
|
31
31
|
#
|
32
32
|
def asset_tags(asset_id)
|
33
33
|
tag_summary = []
|
34
|
-
asset_tag = JSON.parse(AJAX.get(self, "/api/2.0/assets/#{asset_id}/tags", AJAX::CONTENT_TYPE::JSON, { per_page:
|
34
|
+
asset_tag = JSON.parse(AJAX.get(self, "/api/2.0/assets/#{asset_id}/tags", AJAX::CONTENT_TYPE::JSON, { per_page: 2_147_483_647 }))
|
35
35
|
asset_tag['resources'].select { |r| r['asset_ids'].find { |i| i == asset_id } }.each do |json|
|
36
36
|
tag_summary << TagSummary.parse(json)
|
37
37
|
end
|
@@ -55,7 +55,7 @@ module Nexpose
|
|
55
55
|
#
|
56
56
|
def site_tags(site_id)
|
57
57
|
tag_summary = []
|
58
|
-
site_tag = JSON.parse(AJAX.get(self, "/api/2.0/sites/#{site_id}/tags", AJAX::CONTENT_TYPE::JSON, { per_page:
|
58
|
+
site_tag = JSON.parse(AJAX.get(self, "/api/2.0/sites/#{site_id}/tags", AJAX::CONTENT_TYPE::JSON, { per_page: 2_147_483_647 }))
|
59
59
|
site_tag['resources'].each do |json|
|
60
60
|
tag_summary << TagSummary.parse(json)
|
61
61
|
end
|
@@ -79,7 +79,7 @@ module Nexpose
|
|
79
79
|
#
|
80
80
|
def asset_group_tags(asset_group_id)
|
81
81
|
tag_summary = []
|
82
|
-
asset_group_tag = JSON.parse(AJAX.get(self, "/api/2.0/asset_groups/#{asset_group_id}/tags", AJAX::CONTENT_TYPE::JSON, { per_page:
|
82
|
+
asset_group_tag = JSON.parse(AJAX.get(self, "/api/2.0/asset_groups/#{asset_group_id}/tags", AJAX::CONTENT_TYPE::JSON, { per_page: 2_147_483_647 }))
|
83
83
|
asset_group_tag['resources'].each do |json|
|
84
84
|
tag_summary << TagSummary.parse(json)
|
85
85
|
end
|
@@ -252,14 +252,12 @@ module Nexpose
|
|
252
252
|
'tag_name' => @name,
|
253
253
|
'tag_type' => @type,
|
254
254
|
'tag_id' => @id,
|
255
|
-
'attributes' => [
|
256
|
-
|
257
|
-
'tag_attribute_value' => @source }
|
258
|
-
],
|
255
|
+
'attributes' => [{ 'tag_attribute_name' => 'SOURCE',
|
256
|
+
'tag_attribute_value' => @source }],
|
259
257
|
'tag_config' => { 'site_ids' => @site_ids,
|
260
258
|
'tag_associated_asset_ids' => @associated_asset_ids,
|
261
259
|
'asset_group_ids' => @asset_group_ids,
|
262
|
-
'search_criteria' => @search_criteria ? @search_criteria.
|
260
|
+
'search_criteria' => @search_criteria ? @search_criteria.to_h : nil
|
263
261
|
}
|
264
262
|
}
|
265
263
|
if @type == Type::Generic::CUSTOM
|
@@ -306,8 +304,9 @@ module Nexpose
|
|
306
304
|
# @return [Fixnum] ID of applied tag
|
307
305
|
#
|
308
306
|
def add_to_asset(connection, asset_id)
|
309
|
-
params =
|
310
|
-
|
307
|
+
params = to_json_for_add
|
308
|
+
url = "/api/2.0/assets/#{asset_id}/tags"
|
309
|
+
uri = AJAX.post(connection, url, params, AJAX::CONTENT_TYPE::JSON)
|
311
310
|
@id = uri.split('/').last.to_i
|
312
311
|
end
|
313
312
|
|
@@ -318,8 +317,9 @@ module Nexpose
|
|
318
317
|
# @return [Fixnum] ID of applied tag
|
319
318
|
#
|
320
319
|
def add_to_site(connection, site_id)
|
321
|
-
params =
|
322
|
-
|
320
|
+
params = to_json_for_add
|
321
|
+
url = "/api/2.0/sites/#{site_id}/tags"
|
322
|
+
uri = AJAX.post(connection, url, params, AJAX::CONTENT_TYPE::JSON)
|
323
323
|
@id = uri.split('/').last.to_i
|
324
324
|
end
|
325
325
|
|
@@ -330,26 +330,24 @@ module Nexpose
|
|
330
330
|
# @return [Fixnum] ID of applied tag
|
331
331
|
#
|
332
332
|
def add_to_group(connection, group_id)
|
333
|
-
params =
|
334
|
-
|
333
|
+
params = to_json_for_add
|
334
|
+
url = "/api/2.0/asset_groups/#{group_id}/tags"
|
335
|
+
uri = AJAX.post(connection, url, params, AJAX::CONTENT_TYPE::JSON)
|
335
336
|
@id = uri.split('/').last.to_i
|
336
337
|
end
|
337
338
|
alias_method :add_to_asset_group, :add_to_group
|
338
339
|
|
339
340
|
private
|
340
341
|
|
341
|
-
def
|
342
|
+
def to_json_for_add
|
342
343
|
if @id == -1
|
343
|
-
json = {
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
{ 'tag_attribute_name' => 'SOURCE',
|
348
|
-
'tag_attribute_value' => @source }
|
349
|
-
],
|
350
|
-
}
|
344
|
+
json = { 'tag_name' => @name,
|
345
|
+
'tag_type' => @type,
|
346
|
+
'attributes' => [{ 'tag_attribute_name' => 'SOURCE',
|
347
|
+
'tag_attribute_value' => @source }] }
|
351
348
|
if @type == Tag::Type::Generic::CUSTOM
|
352
|
-
json['attributes'] << { 'tag_attribute_name' => 'COLOR',
|
349
|
+
json['attributes'] << { 'tag_attribute_name' => 'COLOR',
|
350
|
+
'tag_attribute_value' => @color }
|
353
351
|
end
|
354
352
|
params = JSON.generate(json)
|
355
353
|
else
|
data/lib/nexpose/tag/criteria.rb
CHANGED
@@ -1,45 +1,37 @@
|
|
1
1
|
module Nexpose
|
2
2
|
class Tag
|
3
|
-
|
3
|
+
# Override of filter criterion to account for proper JSON naming.
|
4
|
+
#
|
4
5
|
class Criterion < Nexpose::Criterion
|
5
|
-
|
6
|
-
def
|
7
|
-
{
|
8
|
-
|
9
|
-
|
10
|
-
}
|
6
|
+
# Convert to Hash, which can be converted to JSON for API calls.
|
7
|
+
def to_h
|
8
|
+
{ operator: operator,
|
9
|
+
values: Array(value),
|
10
|
+
field_name: field }
|
11
11
|
end
|
12
12
|
|
13
|
+
# Create a Criterion object from a JSON-derived Hash.
|
14
|
+
#
|
15
|
+
# @param [Hash] json JSON-derived Hash of a Criterion object.
|
16
|
+
# @return [Criterion] Parsed object.
|
17
|
+
#
|
13
18
|
def self.parse(json)
|
14
|
-
|
15
|
-
json['operator'],
|
16
|
-
json['values'])
|
19
|
+
new(json['field_name'], json['operator'], json['values'])
|
17
20
|
end
|
18
|
-
|
19
21
|
end
|
20
22
|
|
23
|
+
# Override of filter criteria to account for different parsing from JSON.
|
24
|
+
#
|
21
25
|
class Criteria < Nexpose::Criteria
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
def to_map
|
28
|
-
{ 'criteria' => @criteria.map { |c| c.to_map },
|
29
|
-
'operator' => @match
|
30
|
-
}
|
31
|
-
end
|
32
|
-
|
26
|
+
# Create a Criteria object from a JSON-derived Hash.
|
27
|
+
#
|
28
|
+
# @param [Hash] json JSON-derived Hash of a Criteria object.
|
29
|
+
# @return [Criteria] Parsed object.
|
30
|
+
#
|
33
31
|
def self.parse(json)
|
34
|
-
|
35
|
-
json['
|
36
|
-
ret.criteria << Criterion.parse(c)
|
37
|
-
end
|
38
|
-
ret
|
32
|
+
criteria = json['criteria'].map { |c| Criterion.parse(c) }
|
33
|
+
new(criteria, json['operator'])
|
39
34
|
end
|
40
|
-
|
41
35
|
end
|
42
36
|
end
|
43
37
|
end
|
44
|
-
|
45
|
-
|
data/lib/nexpose/version.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.9.
|
4
|
+
version: 0.9.1
|
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:
|
14
|
+
date: 2015-01-02 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: rex
|