nessus_rest 0.1.0

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