nexpose 0.0.92 → 0.0.93
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/scan_engine.rb +264 -140
- data/nexpose.gemspec +1 -1
- metadata +6 -6
data/lib/nexpose/scan_engine.rb
CHANGED
@@ -1,124 +1,134 @@
|
|
1
1
|
module Nexpose
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
3
|
+
# ==== Description
|
4
|
+
# Object that represents a listing of all of the scan engines available on to an NSC.
|
5
|
+
#
|
6
|
+
class EngineListing
|
7
|
+
# true if an error condition exists; false otherwise
|
8
|
+
attr_reader :error
|
9
|
+
# Error message string
|
10
|
+
attr_reader :error_msg
|
11
|
+
# The last XML request sent by this object
|
12
|
+
attr_reader :request_xml
|
13
|
+
# The last XML response received by this object
|
14
|
+
attr_reader :response_xml
|
15
|
+
# The NSC Connection associated with this object
|
16
|
+
attr_reader :connection
|
17
|
+
# Array containing (EngineSummary*)
|
18
|
+
attr_reader :engines
|
19
|
+
# The number of scan engines
|
20
|
+
attr_reader :engine_count
|
21
|
+
|
22
|
+
# Constructor
|
23
|
+
# EngineListing (connection)
|
24
|
+
def initialize(connection)
|
25
|
+
@connection = connection
|
26
|
+
@engines = []
|
27
|
+
@engine_count = 0
|
28
|
+
@error = false
|
29
|
+
r = @connection.execute('<EngineListingRequest session-id="' + @connection.session_id + '"/>', '1.2')
|
30
|
+
|
31
|
+
if (r.success)
|
32
|
+
r.res.elements.each('EngineListingResponse/EngineSummary') do |v|
|
33
|
+
@engines.push(EngineSummary.new(v.attributes['id'], v.attributes['name'], v.attributes['address'],
|
34
|
+
v.attributes['port'], v.attributes['status']))
|
35
|
+
end
|
36
|
+
else
|
37
|
+
@error = true
|
38
|
+
@error_msg = 'EngineListingRequest Parse Error'
|
39
|
+
end
|
40
|
+
@engine_count = @engines.length
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# TODO
|
45
|
+
class EngineActivity
|
46
|
+
# true if an error condition exists; false otherwise
|
47
|
+
attr_reader :error
|
48
|
+
# Error message string
|
49
|
+
attr_reader :error_msg
|
50
|
+
# The last XML request sent by this object
|
51
|
+
attr_reader :request_xml
|
52
|
+
# The last XML response received by this object
|
53
|
+
attr_reader :response_xml
|
54
|
+
# The NSC Connection associated with this object
|
55
|
+
attr_reader :connection
|
56
|
+
# The Engine ID
|
57
|
+
attr_reader :engine_id
|
58
|
+
# Array containing (ScanSummary*)
|
59
|
+
attr_reader :scan_summaries
|
60
|
+
end
|
61
|
+
|
62
|
+
# ==== Description
|
63
|
+
# Object that represents the summary of a scan engine.
|
64
|
+
#
|
65
|
+
# ==== Examples
|
66
|
+
#
|
67
|
+
# # Create a new Nexpose Connection on the default port and Login
|
68
|
+
# nsc = Connection.new("10.1.40.10","nxadmin","password")
|
69
|
+
# nsc.login()
|
70
|
+
#
|
71
|
+
# # Get the engine listing for the connection
|
72
|
+
# enginelisting = EngineListing.new(nsc)
|
73
|
+
#
|
74
|
+
# # Print out the status of the first scan engine
|
75
|
+
# puts enginelisting.engines[0].status
|
76
|
+
#
|
77
|
+
class EngineSummary
|
78
|
+
# A unique ID that identifies this scan engine
|
79
|
+
attr_reader :id
|
80
|
+
# The name of this scan engine
|
81
|
+
attr_reader :name
|
82
|
+
# The hostname or IP address of the engine
|
83
|
+
attr_reader :address
|
84
|
+
# The port there the engine is listening
|
85
|
+
attr_reader :port
|
86
|
+
# The engine status (active|pending-auth| incompatible|not-responding|unknown)
|
87
|
+
attr_reader :status
|
88
|
+
# A parameter that specifies whether the engine has a global
|
89
|
+
# or silo-specific scope.
|
90
|
+
attr_reader :scope
|
91
|
+
|
92
|
+
# Constructor
|
93
|
+
# EngineSummary(id, name, address, port, status, scope)
|
94
|
+
def initialize(id, name, address, port, status, scope = 'silo')
|
95
|
+
@id = id
|
96
|
+
@name = name
|
97
|
+
@address = address
|
98
|
+
@port = port
|
99
|
+
@status = status
|
100
|
+
@scope = scope
|
101
|
+
end
|
102
|
+
|
103
|
+
def to_s
|
104
|
+
"Engine: #{@name} [ID: #{@id}] #{@address}:#{@port}, Status: #{@status}, Scope: #{@scope}"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
#-------------------------------------------------------------------------------------------------------------------
|
109
|
+
#
|
110
|
+
#-------------------------------------------------------------------------------------------------------------------
|
111
|
+
class EngineConfig
|
112
|
+
attr_accessor :id
|
113
|
+
attr_accessor :address
|
114
|
+
attr_accessor :name
|
115
|
+
attr_accessor :port
|
116
|
+
attr_accessor :scope
|
117
|
+
attr_accessor :priority
|
118
|
+
|
119
|
+
# An array of site IDs. Currently do not support 'name' value,
|
120
|
+
# which is optional in the API.
|
121
|
+
attr_accessor :sites
|
122
|
+
|
123
|
+
def initialize(connection, id = -1)
|
124
|
+
@connection = connection
|
125
|
+
@id = id
|
126
|
+
@address = nil
|
127
|
+
@name = nil
|
128
|
+
@port = 40814
|
129
|
+
@scope = 'silo'
|
130
|
+
@priority = 'normal'
|
131
|
+
@sites = []
|
122
132
|
|
123
133
|
# If valid ID provided, retrieve data from server.
|
124
134
|
if (id > 0)
|
@@ -145,6 +155,10 @@ module Nexpose
|
|
145
155
|
end
|
146
156
|
end
|
147
157
|
|
158
|
+
def add_site(siteID)
|
159
|
+
sites << siteID
|
160
|
+
end
|
161
|
+
|
148
162
|
def to_xml
|
149
163
|
xml = '<EngineConfig'
|
150
164
|
xml << %Q{ id="#{id}"}
|
@@ -153,8 +167,11 @@ module Nexpose
|
|
153
167
|
xml << %Q{ port="#{port}"}
|
154
168
|
xml << %Q{ scope="#{scope}"}
|
155
169
|
xml << %Q{ priority="#{priority}"} if (priority)
|
156
|
-
|
157
|
-
|
170
|
+
xml << '>'
|
171
|
+
#sites.each do |site|
|
172
|
+
#xml << %Q{<Site id="#{site}" />}
|
173
|
+
#end
|
174
|
+
xml << '</EngineConfig>'
|
158
175
|
xml
|
159
176
|
end
|
160
177
|
|
@@ -170,44 +187,49 @@ module Nexpose
|
|
170
187
|
xml << '</EngineSaveRequest>'
|
171
188
|
|
172
189
|
r = @connection.execute(xml, '1.2')
|
173
|
-
|
190
|
+
if (r.success)
|
191
|
+
r.res.elements.each('EngineSaveResponse/EngineConfig') do |v|
|
192
|
+
@id = v.attributes['id']
|
193
|
+
end
|
194
|
+
else (r.success)
|
174
195
|
@error = true
|
175
196
|
@error_msg = 'EngineSaveRequest Parse Error'
|
176
197
|
end
|
177
198
|
end
|
178
199
|
end
|
179
200
|
|
180
|
-
#-------------------------------------------------------------------------------------------------------------------
|
181
201
|
# Core objects for creating an engine pool
|
182
202
|
# Example usage:
|
183
203
|
# pool = EnginePool.new('East Coast Pool')
|
184
204
|
# pool.add('New York Engine')
|
185
205
|
# pool.add('Georgia Engine')
|
186
|
-
#
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
206
|
+
# pool.create(@nsc)
|
207
|
+
class EnginePool
|
208
|
+
attr_accessor :id
|
209
|
+
attr_accessor :name
|
210
|
+
attr_accessor :scope
|
211
|
+
# Array containing (EngineSummary*)
|
212
|
+
attr_accessor :engines
|
213
|
+
|
214
|
+
def initialize(name, id = -1, scope = 'silo')
|
215
|
+
@name = name
|
216
|
+
@id = id
|
217
|
+
@scope = scope
|
196
218
|
@engines = []
|
197
219
|
end
|
198
220
|
|
199
221
|
# Add an engine to the pool by name (not ID).
|
222
|
+
# Only use this for creating pools.
|
200
223
|
def add(engine)
|
201
|
-
engines << engine
|
224
|
+
@engines << EngineSummary.new(-1, engine, 'nowhere', 40814, 'unknown')
|
202
225
|
end
|
203
226
|
|
204
|
-
#
|
205
|
-
# Returns the engine ID assigned to the pool, if successful.
|
227
|
+
# Creates a new engine pool, and adds scan engines to the pool.
|
206
228
|
def create(connection)
|
207
229
|
xml = '<EnginePoolCreateRequest session-id="' + connection.session_id + '">'
|
208
|
-
xml << %Q{<EnginePool name="#{name}" scope="#{scope}">}
|
209
|
-
engines.each do |engine|
|
210
|
-
xml << %Q{<Engine name="#{engine}" />}
|
230
|
+
xml << %Q{<EnginePool name="#{@name}" scope="#{@scope}">}
|
231
|
+
@engines.each do |engine|
|
232
|
+
xml << %Q{<Engine name="#{engine.name}" />}
|
211
233
|
end
|
212
234
|
xml << '</EnginePool>'
|
213
235
|
xml << '</EnginePoolCreateRequest>'
|
@@ -215,12 +237,114 @@ module Nexpose
|
|
215
237
|
r = connection.execute(xml, '1.2')
|
216
238
|
if (r.success)
|
217
239
|
r.res.elements.each('EnginePoolCreateResponse') do |v|
|
218
|
-
|
240
|
+
@id = v.attributes['id']
|
219
241
|
end
|
220
242
|
else
|
221
243
|
@error = true
|
222
244
|
@error_msg = 'EnginePoolCreateResponse Parse Error'
|
223
245
|
end
|
224
246
|
end
|
247
|
+
|
248
|
+
# Deletes an engine pool
|
249
|
+
def delete(connection)
|
250
|
+
xml = '<EnginePoolDeleteRequest session-id="' + connection.session_id + '">'
|
251
|
+
xml << %Q{<EnginePool name="#{@name}" scope="#{@scope}" />}
|
252
|
+
xml << '</EnginePoolDeleteRequest>'
|
253
|
+
|
254
|
+
r = connection.execute(xml, '1.2')
|
255
|
+
unless (r.success)
|
256
|
+
@error = true
|
257
|
+
@error_msg = 'EnginePoolDeleteResponse Parse Error'
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
# Updates a specific role with new information. An EnginePoolUpdate is
|
262
|
+
# similar to an EnginePoolCreate, except that an EnginePoolUpdate replaces
|
263
|
+
# any previously existing information with the new information specified in
|
264
|
+
# the EnginePoolUpdateRequest.
|
265
|
+
def update(connection)
|
266
|
+
xml = '<EnginePoolUpdateRequest session-id="' + connection.session_id + '">'
|
267
|
+
xml << %Q{<EnginePool id="#{@id}" name="#{@name}" scope="#{@scope}">}
|
268
|
+
@engines.each do |engine|
|
269
|
+
xml << %Q{<Engine name="#{engine.name}" />}
|
270
|
+
end
|
271
|
+
xml << '</EnginePool>'
|
272
|
+
xml << '</EnginePoolUpdateRequest>'
|
273
|
+
|
274
|
+
r = connection.execute(xml, '1.2')
|
275
|
+
if (r.success)
|
276
|
+
r.res.elements.each('EnginePoolUpdateResponse') do |v|
|
277
|
+
@id = v.attributes['id']
|
278
|
+
end
|
279
|
+
else
|
280
|
+
@error = true
|
281
|
+
@error_msg = 'EnginePoolCreateResponse Parse Error'
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
# Returns detailed information about a single engine pool.
|
286
|
+
def load_details(connection)
|
287
|
+
xml = '<EnginePoolDetailsRequest session-id="' + connection.session_id + '">'
|
288
|
+
xml << %Q{<EnginePool name="#{@name}" scope="#{@scope}" />}
|
289
|
+
xml << '</EnginePoolDetailsRequest>'
|
290
|
+
|
291
|
+
r = connection.execute(xml, '1.2')
|
292
|
+
if (r.success)
|
293
|
+
r.res.elements.each('EnginePoolDetailsResponse/EnginePool') do |pool|
|
294
|
+
@id = pool.attributes['id']
|
295
|
+
@name = pool.attributes['name']
|
296
|
+
@scope = pool.attributes['scope']
|
297
|
+
@engines = []
|
298
|
+
r.res.elements.each('EnginePoolDetailsResponse/EnginePool/EngineSummary') do |summary|
|
299
|
+
@engines.push(EngineSummary.new(summary.attributes['id'],
|
300
|
+
summary.attributes['name'],
|
301
|
+
summary.attributes['address'],
|
302
|
+
summary.attributes['port'],
|
303
|
+
summary.attributes['status'],
|
304
|
+
summary.attributes['scope']))
|
305
|
+
end
|
306
|
+
end
|
307
|
+
else
|
308
|
+
@error = true
|
309
|
+
@error_msg = 'EnginePoolListingResponse Parse Error'
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
def to_s
|
314
|
+
"Engine Pool: #{@name} [ID: #{@id}], Scope: #{@scope}\n" + @engines.map { |engine| " #{engine}" }.join("\n")
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
# A summary of an engine pool.
|
319
|
+
class EnginePoolSummary
|
320
|
+
attr_reader :id
|
321
|
+
attr_reader :name
|
322
|
+
attr_reader :scope
|
323
|
+
|
324
|
+
def initialize(id, name, scope = 'silo')
|
325
|
+
@id = id
|
326
|
+
@name = name
|
327
|
+
@scope = scope
|
328
|
+
end
|
329
|
+
|
330
|
+
def to_s
|
331
|
+
"Engine Pool: #{@name} [ID: #{@id}], scope: #{@scope}"
|
332
|
+
end
|
333
|
+
|
334
|
+
# Returns a summary list of all engine pools.
|
335
|
+
def self.listing(connection)
|
336
|
+
xml = '<EnginePoolListingRequest session-id="' + connection.session_id + '" />'
|
337
|
+
r = connection.execute(xml, '1.2')
|
338
|
+
if (r.success)
|
339
|
+
list = []
|
340
|
+
r.res.elements.each('EnginePoolListingResponse/EnginePoolSummary') do |eps|
|
341
|
+
list << EnginePoolSummary.new(eps.attributes['id'], eps.attributes['name'], eps.attributes['scope'])
|
342
|
+
end
|
343
|
+
list
|
344
|
+
else
|
345
|
+
@error = true
|
346
|
+
@error_msg = 'EnginePoolListingResponse Parse Error'
|
347
|
+
end
|
348
|
+
end
|
225
349
|
end
|
226
350
|
end
|
data/nexpose.gemspec
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.0.
|
4
|
+
version: 0.0.93
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,11 +10,11 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-05-
|
13
|
+
date: 2012-05-03 00:00:00.000000000Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: librex
|
17
|
-
requirement: &
|
17
|
+
requirement: &28535568 !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - ! '>='
|
@@ -22,10 +22,10 @@ dependencies:
|
|
22
22
|
version: 0.0.32
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
|
-
version_requirements: *
|
25
|
+
version_requirements: *28535568
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: rex
|
28
|
-
requirement: &
|
28
|
+
requirement: &28535292 !ruby/object:Gem::Requirement
|
29
29
|
none: false
|
30
30
|
requirements:
|
31
31
|
- - ! '>='
|
@@ -33,7 +33,7 @@ dependencies:
|
|
33
33
|
version: 1.0.2
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
|
-
version_requirements: *
|
36
|
+
version_requirements: *28535292
|
37
37
|
description: This gem provides a Ruby API to the NeXpose vulnerability management
|
38
38
|
product by Rapid7. This version is based on Metasploit SVN revision 12878
|
39
39
|
email:
|