nexpose 0.0.92 → 0.0.93
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|