nessus_rest 0.1.0

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/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.gitignore ADDED
@@ -0,0 +1,42 @@
1
+ # rcov generated
2
+ coverage
3
+
4
+ # rdoc generated
5
+ rdoc
6
+
7
+ # yard generated
8
+ doc
9
+ .yardoc
10
+
11
+ # bundler
12
+ .bundle
13
+
14
+ # jeweler generated
15
+ pkg
16
+
17
+ # Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
18
+ #
19
+ # * Create a file at ~/.gitignore
20
+ # * Include files you want ignored
21
+ # * Run: git config --global core.excludesfile ~/.gitignore
22
+ #
23
+ # After doing this, these files will be ignored in all your git projects,
24
+ # saving you from having to 'pollute' every project you touch with them
25
+ #
26
+ # Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
27
+ #
28
+ # For MacOS:
29
+ #
30
+ #.DS_Store
31
+ #
32
+ # For TextMate
33
+ #*.tmproj
34
+ #tmtags
35
+ #
36
+ # For emacs:
37
+ *~
38
+ #\#*
39
+ #.\#*
40
+ #
41
+ # For vim:
42
+ *.swp
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source "https://rubygems.org"
2
+ gemspec
3
+ # Add dependencies required to use your gem here.
4
+ # Example:
5
+ # gem "activesupport", ">= 2.3.5"
6
+
7
+ # Add dependencies to develop your gem here.
8
+ # Include everything needed to run rake, tests, features, etc.
9
+ group :development do
10
+ gem "shoulda", ">= 0"
11
+ gem "bundler", "~> 1.0.0"
12
+ gem "rcov", ">= 0"
13
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Vlatko Kosturjak
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # nessus_rest
2
+
3
+ Communicate with Nessus Scanner (version 6+) over REST/JSON interface
4
+
5
+ ## Usage
6
+
7
+ ```ruby
8
+ require 'nessus_rest'
9
+
10
+ n=NessusREST::Client.new ({
11
+ :url=>'https://localhost:8834',
12
+ :username=>'user',
13
+ :password=> 'password' })
14
+ qs=n.scan_quick_template('basic','name-of-scan','localhost')
15
+ scanid=qs['scan']['id']
16
+ n.scan_wait4finish(scanid)
17
+ n.report_download_file(scanid,'csv','myscanreport.csv')
18
+ ```
19
+
20
+ ## Installation
21
+
22
+ Add this line to your application's Gemfile:
23
+
24
+ gem 'nessus_rest'
25
+
26
+ And then execute:
27
+
28
+ $ bundle
29
+
30
+ Or install it yourself as:
31
+
32
+ $ gem install nessus_rest
33
+
34
+ ## Requirements
35
+
36
+ Requirements are quite standard Ruby libraries for HTTPS and JSON
37
+ parsing:
38
+ ```ruby
39
+ require 'uri'
40
+ require 'net/https'
41
+ require 'json'
42
+ ```
43
+
44
+ ## Contributing
45
+
46
+ 1. Fork it
47
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
48
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
49
+ 4. Push to the branch (`git push origin my-new-feature`)
50
+ 5. Create new Pull Request
51
+
52
+ ### Todo
53
+ - [ ] Provide more examples
54
+
55
+ ## Copyright
56
+ Copyright (c) 2016 Vlatko Kosturjak. See LICENSE.txt for
57
+ further details.
58
+
59
+ ## Credits
60
+
61
+ Vlatko Kosturjak made initial Nessus XMLRPC library. Averagesecurityguy made
62
+ initial JSON REST patches. Vlatko did bugfixes, gemification and few features.
63
+
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ task :default => :install
4
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'nessus_rest'
4
+
5
+ n=NessusREST::Client.new ({:url=>'https://localhost:8834', :username=>'user', :password=> 'password'})
6
+
7
+ formats=["nessus","csv","html"]
8
+ folders_id=Hash.new
9
+
10
+ sl["folders"].each do |f|
11
+ folders_id[f['id']]=f['name']
12
+ end
13
+
14
+ sl["scans"].each do |s|
15
+ puts "backing up: "+s["name"]+":"+s["uuid"].to_s
16
+ formats.each do |format|
17
+ # fn = folder__name__scanid.format
18
+ outputfn=folders_id[s['folder_id']]+'__'+s['name']+'__'+s['id'].to_s+'.'+format
19
+ puts "-> Format: #{format"} Filename: #{outputfn}"
20
+ n.report_download_file(s['id'],format,outputfn)
21
+ end
22
+ end
23
+
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'nessus_rest'
4
+
5
+ n=NessusREST::Client.new ({:url=>'https://localhost:8834', :username=>'user', :password=> 'password'})
6
+ qs=n.scan_quick_template('basic','name-of-scan','localhost')
7
+ scanid=qs['scan']['id']
8
+ n.scan_wait4finish(scanid)
9
+ n.report_download_file(scanid,"csv","myscanreport.csv")
10
+
11
+
12
+
@@ -0,0 +1,750 @@
1
+ #!/usr/bin/env ruby
2
+ # coding: utf-8
3
+ # = nessus_rest.rb: communicate with Nessus(6+) over JSON REST interface
4
+ #
5
+ # Author:: Vlatko Kosturjak
6
+ #
7
+ # (C) Vlatko Kosturjak, Kost. Distributed under MIT license.
8
+ #
9
+ # == What is this library?
10
+ #
11
+ # This library is used for communication with Nessus over JSON REST interface.
12
+ # You can start, stop, pause and resume scan. Watch progress and status of scan,
13
+ # download report, etc.
14
+ #
15
+ # == Requirements
16
+ #
17
+ # Required libraries are standard Ruby libraries: uri, net/https and json.
18
+ #
19
+ # == Usage:
20
+ #
21
+ # require 'nessus_rest'
22
+ #
23
+ # n=NessusREST::Client.new ({:url=>'https://localhost:8834', :username=>'user', :password=> 'password'})
24
+ # qs=n.scan_quick_template('basic','name-of-scan','localhost')
25
+ # scanid=qs['scan']['id']
26
+ # n.scan_wait4finish(scanid)
27
+ # n.report_download_file(scanid,'csv','myscanreport.csv')
28
+ #
29
+
30
+ require 'uri'
31
+ require 'net/http'
32
+ require 'json'
33
+
34
+ # NessusREST module - for all stuff regarding Nessus REST JSON
35
+ #
36
+
37
+ module NessusREST
38
+ # Client class implementation of Nessus (6+) JSON REST protocol.
39
+ # Class which uses standard JSON lib to parse nessus JSON REST replies.
40
+ #
41
+ # == Typical Usage:
42
+ #
43
+ # require 'nessus_rest'
44
+ #
45
+ # n=NessusREST::Client.new ({:url=>'https://localhost:8834', :username=>'user', :password=> 'password'})
46
+ # qs=n.scan_quick_template('basic','name-of-scan','localhost')
47
+ # scanid=qs['scan']['id']
48
+ # n.scan_wait4finish(scanid)
49
+ # n.report_download_file(scanid,'csv','myscanreport.csv')
50
+ #
51
+ class Client
52
+ attr_accessor :quick_defaults
53
+ attr_accessor :defsleep, :httpsleep, :httpretry, :ssl_use, :ssl_verify, :autologin
54
+ attr_reader :x_cookie
55
+
56
+ class << self
57
+ @connection
58
+ @token
59
+ end
60
+
61
+ # initialize quick scan defaults: these will be used when not specifying defaults
62
+ #
63
+ # Usage:
64
+ #
65
+ # n.init_quick_defaults()
66
+ def init_quick_defaults
67
+ @quick_defaults=Hash.new
68
+ @quick_defaults['enabled']=false
69
+ @quick_defaults['launch']='ONETIME'
70
+ @quick_defaults['launch_now']=true
71
+ @quick_defaults['description']='Created with nessus_rest'
72
+ end
73
+
74
+ # initialize object: try to connect to Nessus Scanner using URL, user and password
75
+ # (or any other defaults)
76
+ #
77
+ # Usage:
78
+ #
79
+ # n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password')
80
+ def initialize(params={})
81
+ # defaults
82
+ @nessusurl = params.fetch(:url,'https://127.0.0.1:8834/')
83
+ @username = params.fetch(:username,'nessus')
84
+ @password = params.fetch(:password,'nessus')
85
+ @ssl_verify = params.fetch(:ssl_verify,false)
86
+ @ssl_use = params.fetch(:ssl_use,true)
87
+ @autologin = params.fetch(:autologin, true)
88
+ @defsleep = params.fetch(:defsleep, 1)
89
+ @httpretry = params.fetch(:httpretry, 3)
90
+ @httpsleep = params.fetch(:httpsleep, 1)
91
+
92
+ init_quick_defaults()
93
+
94
+ uri = URI.parse(@nessusurl)
95
+ @connection = Net::HTTP.new(uri.host, uri.port)
96
+ @connection.use_ssl = @ssl_use
97
+
98
+ if @ssl_verify
99
+ @connection.verify_mode = OpenSSL::SSL::VERIFY_PEER
100
+ else
101
+ @connection.verify_mode = OpenSSL::SSL::VERIFY_NONE
102
+ end
103
+
104
+ yield @connection if block_given?
105
+ authenticate(@username, @password) if @autologin
106
+ end
107
+
108
+ # Tries to authenticate to the Nessus REST JSON interface
109
+ #
110
+ # returns: true if logged in, false if not
111
+ #
112
+ # Usage:
113
+ #
114
+ # n=NessusREST::Client.new (:url=>'https://localhost:8834', :autologin=>false)
115
+ # if n.authenticate('user','pass')
116
+ # puts "Logged in"
117
+ # else
118
+ # puts "Error"
119
+ # end
120
+ def authenticate(username, password)
121
+ @username = username
122
+ @password = password
123
+ payload = {
124
+ :username => @username,
125
+ :password => @password,
126
+ :json => 1
127
+ }
128
+ res = http_post(:uri=>"/session", :data=>payload)
129
+ if res['token']
130
+ @token = "token=#{res['token']}"
131
+ @x_cookie = {'X-Cookie'=>@token}
132
+ return true
133
+ else
134
+ false
135
+ end
136
+ end
137
+ alias_method :login, :authenticate
138
+
139
+ # checks if we're logged in correctly
140
+ #
141
+ # returns: true if logged in, false if not
142
+ #
143
+ # Usage:
144
+ #
145
+ # n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password')
146
+ # if n.authenticated
147
+ # puts "Logged in"
148
+ # else
149
+ # puts "Error"
150
+ # end
151
+ def authenticated
152
+ if (@token && @token.include?('token='))
153
+ return true
154
+ else
155
+ return false
156
+ end
157
+ end
158
+
159
+ # try to get server properties
160
+ #
161
+ # returns: JSON parsed object with server properties
162
+ #
163
+ # Usage:
164
+ #
165
+ # n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password')
166
+ # pp n.get_server_properties
167
+ def get_server_properties
168
+ http_get(:uri=>"/server/properties", :fields=>x_cookie)
169
+ end
170
+ alias_method :server_properties, :get_server_properties
171
+
172
+ # Add user to server
173
+ #
174
+ # returns: JSON parsed object
175
+ #
176
+ # Usage:
177
+ #
178
+ # n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password')
179
+ # pp n.user_add('user','password','16','local')
180
+ #
181
+ # Reference:
182
+ # https://localhost:8834/api#/resources/users/create
183
+ def user_add(username, password, permissions, type)
184
+ payload = {
185
+ :username => username,
186
+ :password => password,
187
+ :permissions => permissions,
188
+ :type => type,
189
+ :json => 1
190
+ }
191
+ http_post(:uri=>"/users", :fields=>x_cookie, :data=>payload)
192
+ end
193
+
194
+ # delete user with user_id
195
+ #
196
+ # returns: result code
197
+ #
198
+ # Usage:
199
+ #
200
+ # n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password')
201
+ # puts n.user_delete(1)
202
+ def user_delete(user_id)
203
+ res = http_delete(:uri=>"/users/#{user_id}", :fields=>x_cookie)
204
+ return res.code
205
+ end
206
+
207
+ # change password for user_id
208
+ #
209
+ # returns: result code
210
+ #
211
+ # Usage:
212
+ #
213
+ # n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password')
214
+ # puts n.user_chpasswd(1,'newPassword')
215
+ def user_chpasswd(user_id, password)
216
+ payload = {
217
+ :password => password,
218
+ :json => 1
219
+ }
220
+ res = http_put(:uri=>"/users/#{user_id}/chpasswd", :data=>payload, :fields=>x_cookie)
221
+ return res.code
222
+ end
223
+
224
+ # logout from the server
225
+ #
226
+ # returns: result code
227
+ #
228
+ # Usage:
229
+ #
230
+ # n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password')
231
+ # puts n.user_logout
232
+ def user_logout
233
+ res = http_delete(:uri=>"/session", :fields=>x_cookie)
234
+ return res.code
235
+ end
236
+ alias_method :logout, :user_logout
237
+
238
+ # Get List of Policies
239
+ #
240
+ # returns: JSON parsed object with list of policies
241
+ #
242
+ # Usage:
243
+ #
244
+ # n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password')
245
+ # pp n.list_policies
246
+ def list_policies
247
+ http_get(:uri=>"/policies", :fields=>x_cookie)
248
+ end
249
+
250
+ # Get List of Users
251
+ #
252
+ # returns: JSON parsed object with list of users
253
+ #
254
+ # Usage:
255
+ #
256
+ # n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password')
257
+ # pp n.list_users
258
+ def list_users
259
+ http_get(:uri=>"/users", :fields=>x_cookie)
260
+ end
261
+
262
+ # Get List of Folders
263
+ #
264
+ # returns: JSON parsed object with list of folders
265
+ #
266
+ # Usage:
267
+ #
268
+ # n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password')
269
+ # pp n.list_folders
270
+ def list_folders
271
+ http_get(:uri=>"/folders", :fields=>x_cookie)
272
+ end
273
+
274
+ # Get List of Scanners
275
+ #
276
+ # returns: JSON parsed object with list of scanners
277
+ #
278
+ # Usage:
279
+ #
280
+ # n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password')
281
+ # pp n.list_scanners
282
+ def list_scanners
283
+ http_get(:uri=>"/scanners", :fields=>x_cookie)
284
+ end
285
+
286
+ # Get List of Families
287
+ #
288
+ # returns: JSON parsed object with list of families
289
+ #
290
+ # Usage:
291
+ #
292
+ # n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password')
293
+ # pp n.list_families
294
+ def list_families
295
+ http_get(:uri=>"/plugins/families", :fields=>x_cookie)
296
+ end
297
+
298
+ # Get List of Plugins
299
+ #
300
+ # returns: JSON parsed object with list of plugins
301
+ #
302
+ # Usage:
303
+ #
304
+ # n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password')
305
+ # pp n.list_plugins
306
+ def list_plugins(family_id)
307
+ http_get(:uri=>"/plugins/families/#{family_id}", :fields=>x_cookie)
308
+ end
309
+
310
+ # Get List of Templates
311
+ #
312
+ # returns: JSON parsed object with list of templates
313
+ #
314
+ # Usage:
315
+ #
316
+ # n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password')
317
+ # pp n.list_templates
318
+ def list_templates(type)
319
+ res = http_get(:uri=>"/editor/#{type}/templates", :fields=>x_cookie)
320
+ end
321
+
322
+ def plugin_details(plugin_id)
323
+ http_get(:uri=>"/plugins/plugin/#{plugin_id}", :fields=>x_cookie)
324
+ end
325
+
326
+ # check if logged in user is administrator
327
+ #
328
+ # returns: boolean value depending if user is administrator or not
329
+ #
330
+ # Usage:
331
+ #
332
+ # n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password')
333
+ # if n.is_admin
334
+ # puts "Administrator"
335
+ # else
336
+ # puts "NOT administrator"
337
+ # end
338
+ def is_admin
339
+ res = http_get(:uri=>"/session", :fields=>x_cookie)
340
+ if res['permissions'] == 128
341
+ return true
342
+ else
343
+ return false
344
+ end
345
+ end
346
+
347
+ # Get server status
348
+ #
349
+ # returns: JSON parsed object with server status
350
+ #
351
+ # Usage:
352
+ #
353
+ # n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password')
354
+ # pp n.server_status
355
+ def server_status
356
+ http_get(:uri=>"/server/status", :fields=>x_cookie)
357
+ end
358
+
359
+ def scan_create(uuid, settings)
360
+ payload = {
361
+ :uuid => uuid,
362
+ :settings => settings,
363
+ :json => 1
364
+ }.to_json
365
+ http_post(:uri=>"/scans", :body=>payload, :fields=>x_cookie, :ctype=>'application/json')
366
+ end
367
+
368
+ def scan_launch(scan_id)
369
+ http_post(:uri=>"/scans/#{scan_id}/launch", :fields=>x_cookie)
370
+ end
371
+
372
+ # Get List of Scans
373
+ #
374
+ # returns: JSON parsed object with list of scans
375
+ #
376
+ # Usage:
377
+ #
378
+ # n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password')
379
+ # pp n.scan_list
380
+ def scan_list
381
+ http_get(:uri=>"/scans", :fields=>x_cookie)
382
+ end
383
+ alias_method :list_scans, :scan_list
384
+
385
+ def scan_details(scan_id)
386
+ http_get(:uri=>"/scans/#{scan_id}", :fields=>x_cookie)
387
+ end
388
+
389
+ def scan_pause(scan_id)
390
+ http_post(:uri=>"/scans/#{scan_id}/pause", :fields=>x_cookie)
391
+ end
392
+
393
+ def scan_resume(scan_id)
394
+ http_post(:uri=>"/scans/#{scan_id}/resume", :fields=>x_cookie)
395
+ end
396
+
397
+ def scan_stop(scan_id)
398
+ http_post(:uri=>"/scans/#{scan_id}/stop", :fields=>x_cookie)
399
+ end
400
+
401
+ def scan_export(scan_id, format)
402
+ payload = {
403
+ :format => format
404
+ }.to_json
405
+ http_post(:uri=>"/scans/#{scan_id}/export", :body=>payload, :ctype=>'application/json', :fields=>x_cookie)
406
+ end
407
+
408
+ def scan_export_status(scan_id, file_id)
409
+ request = Net::HTTP::Get.new("/scans/#{scan_id}/export/#{file_id}/status")
410
+ request.add_field("X-Cookie", @token)
411
+ res = @connection.request(request)
412
+ res = JSON.parse(res.body)
413
+ return res
414
+ end
415
+
416
+ # delete scan with scan_id
417
+ #
418
+ # returns: boolean (true if deleted)
419
+ #
420
+ # Usage:
421
+ #
422
+ # n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password')
423
+ # puts n.scan_delete(1)
424
+ def scan_delete(scan_id)
425
+ res = http_delete(:uri=>"/scans/#{scan_id}", :fields=>x_cookie)
426
+ if res.code == 200 then
427
+ return true
428
+ end
429
+ return false
430
+ end
431
+
432
+ def policy_delete(policy_id)
433
+ res = http_delete(:uri=>"/policies/#{policy_id}", :fields=>x_cookie)
434
+ return res.code
435
+ end
436
+
437
+ # Get template by type and uuid. Type can be 'policy' or 'scan'
438
+ #
439
+ # returns: JSON parsed object with template
440
+ #
441
+ # Usage:
442
+ #
443
+ # n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password')
444
+ # pp n.editor_templates('scan',uuid)
445
+ def editor_templates (type, uuid)
446
+ res = http_get(:uri=>"/editor/#{type}/templates/#{uuid}", :fields=>x_cookie)
447
+ end
448
+
449
+ # Performs scan with templatename provided (name, title or uuid of scan).
450
+ # Name is your scan name and targets are targets for scan
451
+ #
452
+ # returns: JSON parsed object with scan info
453
+ #
454
+ # Usage:
455
+ #
456
+ # require 'nessus_rest'
457
+ #
458
+ # n=NessusREST::Client.new ({:url=>'https://localhost:8834', :username=>'user', :password=> 'password'})
459
+ # qs=n.scan_quick_template('basic','name-of-scan','localhost')
460
+ # scanid=qs['scan']['id']
461
+ # n.scan_wait4finish(scanid)
462
+ # n.report_download_file(scanid,'csv','myscanreport.csv')
463
+ #
464
+ def scan_quick_template (templatename, name, targets)
465
+ templates=list_templates('scan')['templates'].select do |temp|
466
+ temp['uuid'] == templatename or temp['name'] == templatename or temp['title'] == templatename
467
+ end
468
+ if templates.nil? then
469
+ return nil
470
+ end
471
+ tuuid=templates.first['uuid']
472
+ et=editor_templates('scan',tuuid)
473
+ et.merge!(@quick_defaults)
474
+ et['name']=name
475
+ et['text_targets']=targets
476
+ sc=scan_create(tuuid,et)
477
+ end
478
+
479
+ # Performs scan with scan policy provided (uuid of policy or policy name).
480
+ # Name is your scan name and targets are targets for scan
481
+ #
482
+ # returns: JSON parsed object with scan info
483
+ #
484
+ # Usage:
485
+ #
486
+ # require 'nessus_rest'
487
+ #
488
+ # n=NessusREST::Client.new ({:url=>'https://localhost:8834', :username=>'user', :password=> 'password'})
489
+ # qs=n.scan_quick_policy('myscanpolicy','name-of-scan','localhost')
490
+ # scanid=qs['scan']['id']
491
+ # n.scan_wait4finish(scanid)
492
+ # n.report_download_file(scanid,'nessus','myscanreport.nessus')
493
+ #
494
+ def scan_quick_policy (policyname, name, targets)
495
+ templates=list_policies['policies'].select do |pol|
496
+ pol['template_uuid'] == policyname or pol['name'] == policyname
497
+ end
498
+ if templates.nil? then
499
+ return nil
500
+ end
501
+ tuuid=templates.first['template_uuid']
502
+ et=Hash.new
503
+ et.merge!(@quick_defaults)
504
+ et['name']=name
505
+ et['text_targets']=targets
506
+ sc=scan_create(tuuid,et)
507
+ end
508
+
509
+ def scan_status(scan_id)
510
+ sd=scan_details(scan_id)
511
+ return sd['info']['status']
512
+ end
513
+
514
+ def scan_finished?(scan_id)
515
+ ss=scan_status(scan_id)
516
+ if ss == 'completed' then
517
+ return true
518
+ end
519
+ return false
520
+ end
521
+
522
+ def scan_wait4finish(scan_id)
523
+ while not scan_finished?(scan_id) do
524
+ # puts scan_status(scan_id)
525
+ sleep @defsleep
526
+ end
527
+ end
528
+
529
+ # Get host details from the scan
530
+ #
531
+ # returns: JSON parsed object with host details
532
+ #
533
+ # Usage:
534
+ #
535
+ # n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password')
536
+ # pp n.host_detail(123, 1234)
537
+ def host_detail(scan_id, host_id)
538
+ res = http_get(:uri=>"/scans/#{scan_id}/hosts/#{host_id}", :fields=>x_cookie)
539
+ end
540
+
541
+ def report_download(scan_id, file_id)
542
+ res = http_get(:uri=>"/scans/#{scan_id}/export/#{file_id}/download", :raw_content=> true, :fields=>x_cookie)
543
+ end
544
+
545
+ def report_download_quick(scan_id, format)
546
+ se=scan_export(scan_id,format)
547
+ # ready, loading
548
+ while (status = scan_export_status(scan_id,se['file'])['status']) != "ready" do
549
+ # puts status
550
+ if status.nil? or status == '' then
551
+ return nil
552
+ end
553
+ sleep @defsleep
554
+ end
555
+ rf=report_download(scan_id,se['file'])
556
+ return rf
557
+ end
558
+
559
+ def report_download_file(scan_id, format, outputfn)
560
+ report_content=report_download_quick(scan_id, format)
561
+ File.open(outputfn, 'w') do |f|
562
+ f.write(report_content)
563
+ end
564
+ end
565
+
566
+ #
567
+ # private?
568
+ #
569
+
570
+ # Perform HTTP put method with uri, data and fields
571
+ #
572
+ # returns: HTTP result object
573
+ #
574
+ # Usage:
575
+ #
576
+ # n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password')
577
+ # payload = {
578
+ # :password => password,
579
+ # :json => 1
580
+ # }
581
+ # res = n.http_put(:uri=>"/users/#{user_id}/chpasswd", :data=>payload, :fields=>n.x_cookie)
582
+ # puts res.code
583
+ def http_put(opts={})
584
+ uri = opts[:uri]
585
+ data = opts[:data]
586
+ fields = opts[:fields] || {}
587
+ res = nil
588
+ tries = @httpretry
589
+
590
+ req = Net::HTTP::Put.new(uri)
591
+ req.set_form_data(data) unless (data.nil? || data.empty?)
592
+ fields.each_pair do |name, value|
593
+ req.add_field(name, value)
594
+ end
595
+
596
+ begin
597
+ tries -= 1
598
+ res = @connection.request(req)
599
+ rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
600
+ if tries>0
601
+ sleep @httpsleep
602
+ retry
603
+ else
604
+ return res
605
+ end
606
+ rescue URI::InvalidURIError
607
+ return res
608
+ end
609
+
610
+ res
611
+ end
612
+
613
+ # Perform HTTP delete method with uri, data and fields
614
+ #
615
+ # returns: HTTP result object
616
+ #
617
+ # Usage:
618
+ #
619
+ # n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password')
620
+ # res = n.http_delete(:uri=>"/session", :fields=>n.x_cookie)
621
+ # puts res.code
622
+ def http_delete(opts={})
623
+ uri = opts[:uri]
624
+ fields = opts[:fields] || {}
625
+ res = nil
626
+ tries = @httpretry
627
+
628
+ req = Net::HTTP::Delete.new(uri)
629
+
630
+ fields.each_pair do |name, value|
631
+ req.add_field(name, value)
632
+ end
633
+
634
+ begin
635
+ tries -= 1
636
+ res = @connection.request(req)
637
+ rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
638
+ if tries>0
639
+ sleep @httpsleep
640
+ retry
641
+ else
642
+ return res
643
+ end
644
+ rescue URI::InvalidURIError
645
+ return res
646
+ end
647
+
648
+ res
649
+ end
650
+
651
+ # Perform HTTP get method with uri and fields
652
+ #
653
+ # returns: JSON parsed object (if JSON parseable)
654
+ #
655
+ # Usage:
656
+ #
657
+ # n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password')
658
+ # pp n.http_get(:uri=>"/users", :fields=>n.x_cookie)
659
+ def http_get(opts={})
660
+ uri = opts[:uri]
661
+ fields = opts[:fields] || {}
662
+ raw_content = opts[:raw_content] || false
663
+ json = {}
664
+ tries = @httpretry
665
+
666
+ req = Net::HTTP::Get.new(uri)
667
+ fields.each_pair do |name, value|
668
+ req.add_field(name, value)
669
+ end
670
+
671
+ begin
672
+ tries -= 1
673
+ res = @connection.request(req)
674
+ rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
675
+ if tries>0
676
+ sleep @httpsleep
677
+ retry
678
+ else
679
+ return json
680
+ end
681
+ rescue URI::InvalidURIError
682
+ return json
683
+ end
684
+ if !raw_content
685
+ parse_json(res.body)
686
+ else
687
+ res.body
688
+ end
689
+ end
690
+
691
+ # Perform HTTP post method with uri, data, body and fields
692
+ #
693
+ # returns: JSON parsed object (if JSON parseable)
694
+ #
695
+ # Usage:
696
+ #
697
+ # n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password')
698
+ # pp n.http_post(:uri=>"/scans/#{scan_id}/launch", :fields=>n.x_cookie)
699
+ def http_post(opts={})
700
+ uri = opts[:uri]
701
+ data = opts[:data]
702
+ fields = opts[:fields] || {}
703
+ body = opts[:body]
704
+ ctype = opts[:ctype]
705
+ json = {}
706
+ tries = @httpretry
707
+
708
+ req = Net::HTTP::Post.new(uri)
709
+ req.set_form_data(data) unless (data.nil? || data.empty?)
710
+ req.body = body unless (body.nil? || body.empty?)
711
+ req['Content-Type'] = ctype unless (ctype.nil? || ctype.empty?)
712
+ fields.each_pair do |name, value|
713
+ req.add_field(name, value)
714
+ end
715
+
716
+ begin
717
+ tries -= 1
718
+ res = @connection.request(req)
719
+ rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
720
+ if tries>0
721
+ sleep @httpsleep
722
+ retry
723
+ else
724
+ return json
725
+ end
726
+ rescue URI::InvalidURIError
727
+ return json
728
+ end
729
+
730
+ parse_json(res.body)
731
+ end
732
+
733
+ # Perform JSON parsing of body
734
+ #
735
+ # returns: JSON parsed object (if JSON parseable)
736
+ #
737
+ def parse_json(body)
738
+ buf = {}
739
+
740
+ begin
741
+ buf = JSON.parse(body)
742
+ rescue JSON::ParserError
743
+ end
744
+
745
+ buf
746
+ end
747
+
748
+ end # of Client class
749
+ end # of NessusREST module
750
+
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'nessus_rest'
7
+ spec.homepage = 'https://github.com/kost/nessus_rest-ruby'
8
+ spec.license = 'MIT'
9
+ spec.summary = %Q{Communicate with Nessus Scanner (version 6+) over REST/JSON interface}
10
+ spec.description = %Q{Ruby library for Nessus JSON/REST interface. This library is used for communication with Nessus over REST interface. You can start, stop, pause and resume scan. Watch progress and status of scan, download report, etc. }
11
+ spec.email = 'vlatko.kosturjak@gmail.com'
12
+ spec.authors = ['Vlatko Kosturjak']
13
+ # spec.version = '0.1.5'
14
+ spec.version = File.exist?('VERSION') ? File.read('VERSION') : ""
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_development_dependency 'bundler', '~> 1.3'
22
+ spec.add_development_dependency 'pry'
23
+ spec.add_development_dependency 'rake'
24
+ spec.add_development_dependency 'yard'
25
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+ require 'shoulda'
12
+
13
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
15
+ require 'nessus-xmlrpc'
16
+
17
+ class Test::Unit::TestCase
18
+ end
@@ -0,0 +1,6 @@
1
+ require 'helper'
2
+
3
+ class TestNessusRest < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ end
6
+ end
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nessus_rest
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Vlatko Kosturjak
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2016-08-14 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.3'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.3'
30
+ - !ruby/object:Gem::Dependency
31
+ name: pry
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rake
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: yard
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ description: ! 'Ruby library for Nessus JSON/REST interface. This library is used
79
+ for communication with Nessus over REST interface. You can start, stop, pause and
80
+ resume scan. Watch progress and status of scan, download report, etc. '
81
+ email: vlatko.kosturjak@gmail.com
82
+ executables: []
83
+ extensions: []
84
+ extra_rdoc_files: []
85
+ files:
86
+ - .document
87
+ - .gitignore
88
+ - Gemfile
89
+ - LICENSE.txt
90
+ - README.md
91
+ - Rakefile
92
+ - VERSION
93
+ - examples/backup-reports.rb
94
+ - examples/simple.rb
95
+ - lib/nessus_rest.rb
96
+ - nessus_rest.gemspec
97
+ - test/helper.rb
98
+ - test/test_nessus_rest.rb
99
+ homepage: https://github.com/kost/nessus_rest-ruby
100
+ licenses:
101
+ - MIT
102
+ post_install_message:
103
+ rdoc_options: []
104
+ require_paths:
105
+ - lib
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ! '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ requirements: []
119
+ rubyforge_project:
120
+ rubygems_version: 1.8.23
121
+ signing_key:
122
+ specification_version: 3
123
+ summary: Communicate with Nessus Scanner (version 6+) over REST/JSON interface
124
+ test_files:
125
+ - test/helper.rb
126
+ - test/test_nessus_rest.rb