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 +5 -0
- data/.gitignore +42 -0
- data/Gemfile +13 -0
- data/LICENSE.txt +20 -0
- data/README.md +63 -0
- data/Rakefile +4 -0
- data/VERSION +1 -0
- data/examples/backup-reports.rb +23 -0
- data/examples/simple.rb +12 -0
- data/lib/nessus_rest.rb +750 -0
- data/nessus_rest.gemspec +25 -0
- data/test/helper.rb +18 -0
- data/test/test_nessus_rest.rb +6 -0
- metadata +126 -0
data/.document
ADDED
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
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
|
+
|
data/examples/simple.rb
ADDED
@@ -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
|
+
|
data/lib/nessus_rest.rb
ADDED
@@ -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
|
+
|
data/nessus_rest.gemspec
ADDED
@@ -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
|
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
|