nexpose 0.1.7 → 0.1.8
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.
- data/lib/nexpose.rb +1 -0
- data/lib/nexpose/group.rb +118 -0
- data/lib/nexpose/misc.rb +0 -50
- data/lib/nexpose/site.rb +40 -6
- metadata +3 -2
data/lib/nexpose.rb
CHANGED
@@ -0,0 +1,118 @@
|
|
1
|
+
module Nexpose
|
2
|
+
module NexposeAPI
|
3
|
+
include XMLUtils
|
4
|
+
|
5
|
+
# Delete an asset group and all associated data.
|
6
|
+
#
|
7
|
+
# @param [Fixnum] id Asset group ID to delete.
|
8
|
+
#
|
9
|
+
# @return [Boolean] Whether group deletion succeeded.
|
10
|
+
#
|
11
|
+
def asset_group_delete(id)
|
12
|
+
r = execute(make_xml('AssetGroupDeleteRequest', {'group-id' => id}))
|
13
|
+
r.success
|
14
|
+
end
|
15
|
+
|
16
|
+
alias_method :delete_asset_group, :asset_group_delete
|
17
|
+
|
18
|
+
# Retrieve a list of all asset groups the user is authorized to view or
|
19
|
+
# manage.
|
20
|
+
#
|
21
|
+
# @return [Array[AssetGroupSummary]] Array of AssetGroupSummary objects.
|
22
|
+
#
|
23
|
+
def asset_groups
|
24
|
+
r = execute(make_xml('AssetGroupListingRequest'))
|
25
|
+
|
26
|
+
res = []
|
27
|
+
if r.success
|
28
|
+
r.res.elements.each('//AssetGroupSummary') do |group|
|
29
|
+
res << AssetGroupSummary.new(group.attributes['id'].to_i,
|
30
|
+
group.attributes['name'].to_s,
|
31
|
+
group.attributes['description'].to_s,
|
32
|
+
group.attributes['riskscore'].to_f)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
res
|
36
|
+
end
|
37
|
+
|
38
|
+
alias_method :asset_groups_listing, :asset_groups
|
39
|
+
end
|
40
|
+
|
41
|
+
# Summary value object for asset group information.
|
42
|
+
#
|
43
|
+
class AssetGroupSummary
|
44
|
+
attr_reader :id, :name, :description, :risk_score
|
45
|
+
|
46
|
+
def initialize(id, name, desc, risk)
|
47
|
+
@id, @name, @description, @risk_score = id, name, desc, risk
|
48
|
+
end
|
49
|
+
|
50
|
+
# Delete this asset group and all associated data.
|
51
|
+
#
|
52
|
+
# @param [Connection] connection Connection to security console.
|
53
|
+
#
|
54
|
+
def delete(connection)
|
55
|
+
connection.asset_group_delete(@id)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Asset group configuration object containing Device details.
|
60
|
+
#
|
61
|
+
class AssetGroup < AssetGroupSummary
|
62
|
+
|
63
|
+
# Array[Device] of devices associated with this asset group.
|
64
|
+
attr_accessor :devices
|
65
|
+
|
66
|
+
def initialize(id, name, desc, risk)
|
67
|
+
@id, @name, @description, @risk_score = id, name, desc, risk
|
68
|
+
@devices = []
|
69
|
+
end
|
70
|
+
|
71
|
+
# Launch adhoc scans against each group of assets per site.
|
72
|
+
#
|
73
|
+
# @param [Connection] connection Connection to console where asset group is configured.
|
74
|
+
# @return [Array[Hash[Fixnum, Fixnum]]] Array of scan ID and engine ID
|
75
|
+
# pairs for each scan launched.
|
76
|
+
#
|
77
|
+
def rescan_assets(connection)
|
78
|
+
sites_ids = @devices.collect { |d| d.site_id }.uniq
|
79
|
+
scans = []
|
80
|
+
sites_ids.each do |id|
|
81
|
+
dev_ids = @devices.select { |d| d.site_id == id }.map { |d| d.id }
|
82
|
+
scans << connection.site_device_scan_start(id, dev_ids)
|
83
|
+
end
|
84
|
+
scans
|
85
|
+
end
|
86
|
+
|
87
|
+
# Load an existing configuration from a Nexpose instance.
|
88
|
+
#
|
89
|
+
# @param [Connection] connection Connection to console where asset group is configured.
|
90
|
+
# @param [Fixnum] id Asset group ID of an existing group.
|
91
|
+
# @return [AssetGroup] Asset group configuration loaded from a Nexpose console.
|
92
|
+
#
|
93
|
+
def self.load(connection, id)
|
94
|
+
r = APIRequest.execute(connection.url,
|
95
|
+
%Q(<AssetGroupConfigRequest session-id="#{connection.session_id}" group-id="#{id}"/>))
|
96
|
+
parse(r.res)
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.parse(rexml)
|
100
|
+
return nil unless rexml
|
101
|
+
|
102
|
+
rexml.elements.each('//AssetGroup') do |group|
|
103
|
+
asset_group = new(group.attributes['id'].to_i,
|
104
|
+
group.attributes['name'].to_s,
|
105
|
+
group.attributes['description'].to_s,
|
106
|
+
group.attributes['riskscore'].to_f)
|
107
|
+
rexml.elements.each('//Devices/device') do |dev|
|
108
|
+
asset_group.devices << Device.new(dev.attributes['id'].to_i,
|
109
|
+
dev.attributes['address'].to_s,
|
110
|
+
dev.attributes['site-id'].to_i,
|
111
|
+
dev.attributes['riskfactor'].to_f,
|
112
|
+
dev.attributes['riskscore'].to_f)
|
113
|
+
end
|
114
|
+
return asset_group
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
data/lib/nexpose/misc.rb
CHANGED
@@ -7,56 +7,6 @@ module Nexpose
|
|
7
7
|
r.success
|
8
8
|
end
|
9
9
|
|
10
|
-
def asset_group_delete(connection, id, debug = false)
|
11
|
-
r = execute(make_xml('AssetGroupDeleteRequest', {'group-id' => param}))
|
12
|
-
r.success
|
13
|
-
end
|
14
|
-
|
15
|
-
#-------------------------------------------------------------------------
|
16
|
-
# Returns all asset group information
|
17
|
-
#-------------------------------------------------------------------------
|
18
|
-
def asset_groups_listing()
|
19
|
-
r = execute(make_xml('AssetGroupListingRequest'))
|
20
|
-
|
21
|
-
if r.success
|
22
|
-
res = []
|
23
|
-
r.res.elements.each('//AssetGroupSummary') do |group|
|
24
|
-
res << {
|
25
|
-
:asset_group_id => group.attributes['id'].to_i,
|
26
|
-
:name => group.attributes['name'].to_s,
|
27
|
-
:description => group.attributes['description'].to_s,
|
28
|
-
:risk_score => group.attributes['riskscore'].to_f,
|
29
|
-
}
|
30
|
-
end
|
31
|
-
res
|
32
|
-
else
|
33
|
-
false
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
#-------------------------------------------------------------------------
|
38
|
-
# Returns an asset group configuration information for a specific group ID
|
39
|
-
#-------------------------------------------------------------------------
|
40
|
-
def asset_group_config(group_id)
|
41
|
-
r = execute(make_xml('AssetGroupConfigRequest', {'group-id' => group_id}))
|
42
|
-
|
43
|
-
if r.success
|
44
|
-
res = []
|
45
|
-
r.res.elements.each('//Devices/device') do |device_info|
|
46
|
-
res << {
|
47
|
-
:device_id => device_info.attributes['id'].to_i,
|
48
|
-
:site_id => device_info.attributes['site-id'].to_i,
|
49
|
-
:address => device_info.attributes['address'].to_s,
|
50
|
-
:riskfactor => device_info.attributes['riskfactor'].to_f,
|
51
|
-
}
|
52
|
-
end
|
53
|
-
res
|
54
|
-
else
|
55
|
-
false
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
#
|
60
10
|
# Lists all the users for the NSC along with the user details.
|
61
11
|
#
|
62
12
|
def list_users
|
data/lib/nexpose/site.rb
CHANGED
@@ -98,9 +98,9 @@ module Nexpose
|
|
98
98
|
# Starts device specific site scanning.
|
99
99
|
#
|
100
100
|
# devices - An Array of device IDs
|
101
|
-
# hosts - An Array of Hashes [o]=>{:range=>"to
|
101
|
+
# hosts - An Array of Hashes [o]=>{:range=>"from,to"} [1]=>{:host=>host}
|
102
102
|
#-----------------------------------------------------------------------
|
103
|
-
def site_device_scan_start(site_id, devices, hosts)
|
103
|
+
def site_device_scan_start(site_id, devices, hosts = nil)
|
104
104
|
|
105
105
|
if hosts == nil and devices == nil
|
106
106
|
raise ArgumentError.new("Both the device and host list is nil")
|
@@ -120,9 +120,12 @@ module Nexpose
|
|
120
120
|
inner_xml = REXML::Element.new 'Hosts'
|
121
121
|
hosts.each_index do |x|
|
122
122
|
if hosts[x].key? :range
|
123
|
-
to = hosts[x][:range].split(',')
|
124
|
-
|
125
|
-
|
123
|
+
from, to = hosts[x][:range].split(',')
|
124
|
+
if to
|
125
|
+
inner_xml.add_element 'range', {'to' => to, 'from' => from}
|
126
|
+
else
|
127
|
+
inner_xml.add_element 'range', {'from' => from}
|
128
|
+
end
|
126
129
|
end
|
127
130
|
if hosts[x].key? :host
|
128
131
|
host_element = REXML::Element.new 'host'
|
@@ -223,9 +226,40 @@ module Nexpose
|
|
223
226
|
is_dynamic
|
224
227
|
end
|
225
228
|
|
229
|
+
# Adds an asset to this site by host name.
|
230
|
+
#
|
231
|
+
# @param [String] hostname FQDN or DNS-resolvable host name of an asset.
|
232
|
+
def add_host(hostname)
|
233
|
+
@assets << HostName.new(hostname)
|
234
|
+
end
|
235
|
+
|
236
|
+
# Adds an asset to this site by IP address.
|
237
|
+
#
|
238
|
+
# @param [String] ip IP address of an asset.
|
239
|
+
def add_ip(ip)
|
240
|
+
@assets << IPRange.new(ip)
|
241
|
+
end
|
242
|
+
|
243
|
+
# Adds an asset to this site, resolving whether an IP or hostname is
|
244
|
+
# provided.
|
245
|
+
#
|
246
|
+
# @param [String] asset Identifier of an asset, either IP or host name.
|
247
|
+
#
|
248
|
+
def add_asset(asset)
|
249
|
+
begin
|
250
|
+
add_ip(asset)
|
251
|
+
rescue ArgumentError => e
|
252
|
+
if e.message == 'invalid address'
|
253
|
+
add_host(asset)
|
254
|
+
else
|
255
|
+
raise "Unable to parse asset: '#{asset}'"
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
226
260
|
# Load an existing configuration from a Nexpose instance.
|
227
261
|
#
|
228
|
-
# @param [Connection] connection Connection to console where
|
262
|
+
# @param [Connection] connection Connection to console where site exists.
|
229
263
|
# @param [Fixnum] id Site ID of an existing site.
|
230
264
|
# @return [Site] Site configuration loaded from a Nexpose console.
|
231
265
|
def self.load(connection, id)
|
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.1.
|
4
|
+
version: 0.1.8
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-
|
13
|
+
date: 2013-03-01 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: librex
|
@@ -58,6 +58,7 @@ files:
|
|
58
58
|
- README.markdown
|
59
59
|
- Rakefile
|
60
60
|
- lib/nexpose.rb
|
61
|
+
- lib/nexpose/group.rb
|
61
62
|
- lib/nexpose/ticket.rb
|
62
63
|
- lib/nexpose/common.rb
|
63
64
|
- lib/nexpose/scan_engine.rb
|