class NessusREST::Client
Client
class implementation of Nessus (6+) JSON REST protocol. Class which uses standard JSON lib to parse nessus JSON REST replies.
Typical Usage:¶ ↑
require 'nessus_rest' n=NessusREST::Client.new ({:url=>'https://localhost:8834', :username=>'user', :password=> 'password'}) qs=n.scan_quick_template('basic','name-of-scan','localhost') scanid=qs['scan']['id'] n.scan_wait4finish(scanid) n.report_download_file(scanid,'csv','myscanreport.csv')
Attributes
Public Class Methods
initialize object: try to connect to Nessus Scanner using URL, user and password (or any other defaults)
Usage:
n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password')
# File lib/nessus_rest.rb, line 82 def initialize(params={}) # defaults @nessusurl = params.fetch(:url,'https://127.0.0.1:8834/') @username = params.fetch(:username,'nessus') @password = params.fetch(:password,'nessus') @ssl_verify = params.fetch(:ssl_verify,false) @ssl_use = params.fetch(:ssl_use,true) @autologin = params.fetch(:autologin, true) @defsleep = params.fetch(:defsleep, 1) @httpretry = params.fetch(:httpretry, 3) @httpsleep = params.fetch(:httpsleep, 1) init_quick_defaults() uri = URI.parse(@nessusurl) @connection = Net::HTTP.new(uri.host, uri.port) @connection.use_ssl = @ssl_use if @ssl_verify @connection.verify_mode = OpenSSL::SSL::VERIFY_PEER else @connection.verify_mode = OpenSSL::SSL::VERIFY_NONE end yield @connection if block_given? authenticate(@username, @password) if @autologin end
Public Instance Methods
Tries to authenticate to the Nessus REST JSON interface
returns: true if logged in, false if not
Usage:
n=NessusREST::Client.new (:url=>'https://localhost:8834', :autologin=>false, :username=>'nessususer', :password=>'nessuspassword') if n.authdefault puts "Logged in" else puts "Error" end
# File lib/nessus_rest.rb, line 142 def authdefault payload = { :username => @username, :password => @password, :json => 1, :authenticationmethod => true } res = http_post(:uri=>"/session", :data=>payload) if res['token'] @token = "token=#{res['token']}" @x_cookie = {'X-Cookie'=>@token} return true else false end end
Tries to authenticate to the Nessus REST JSON interface
returns: true if logged in, false if not
Usage:
n=NessusREST::Client.new (:url=>'https://localhost:8834', :autologin=>false) if n.authenticate('user','pass') puts "Logged in" else puts "Error" end
# File lib/nessus_rest.rb, line 122 def authenticate(username, password) @username = username @password = password authdefault end
checks if we're logged in correctly
returns: true if logged in, false if not
Usage:
n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password') if n.authenticated puts "Logged in" else puts "Error" end
# File lib/nessus_rest.rb, line 171 def authenticated if (@token && @token.include?('token=')) return true else return false end end
Get template by type and uuid. Type can be 'policy' or 'scan'
returns: JSON parsed object with template
Usage:
n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password') pp n.editor_templates('scan',uuid)
# File lib/nessus_rest.rb, line 465 def editor_templates (type, uuid) res = http_get(:uri=>"/editor/#{type}/templates/#{uuid}", :fields=>x_cookie) end
try to get server properties
returns: JSON parsed object with server properties
Usage:
n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password') pp n.get_server_properties
# File lib/nessus_rest.rb, line 187 def get_server_properties http_get(:uri=>"/server/properties", :fields=>x_cookie) end
Get host details from the scan
returns: JSON parsed object with host details
Usage:
n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password') pp n.host_detail(123, 1234)
# File lib/nessus_rest.rb, line 560 def host_detail(scan_id, host_id) res = http_get(:uri=>"/scans/#{scan_id}/hosts/#{host_id}", :fields=>x_cookie) end
Perform HTTP delete method with uri, data and fields
returns: HTTP result object
Usage:
n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password') res = n.http_delete(:uri=>"/session", :fields=>n.x_cookie) puts res.code
# File lib/nessus_rest.rb, line 656 def http_delete(opts={}) ret=http_delete_low(opts) if ret.is_a?(Hash) and ret.has_key?('error') and ret['error']=='Invalid Credentials' then authdefault ret=http_delete_low(opts) return ret else return ret end end
# File lib/nessus_rest.rb, line 667 def http_delete_low(opts={}) uri = opts[:uri] fields = opts[:fields] || {} res = nil tries = @httpretry req = Net::HTTP::Delete.new(uri) fields.each_pair do |name, value| req.add_field(name, value) end begin tries -= 1 res = @connection.request(req) rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e if tries>0 sleep @httpsleep retry else return res end rescue URI::InvalidURIError return res end res end
Perform HTTP get method with uri and fields
returns: JSON parsed object (if JSON parseable)
Usage:
n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password') pp n.http_get(:uri=>"/users", :fields=>n.x_cookie)
# File lib/nessus_rest.rb, line 704 def http_get(opts={}) raw_content = opts[:raw_content] || false ret=http_get_low(opts) if !raw_content then if ret.is_a?(Hash) and ret.has_key?('error') and ret['error']=='Invalid Credentials' then authdefault ret=http_get_low(opts) return ret else return ret end else return ret end end
# File lib/nessus_rest.rb, line 720 def http_get_low(opts={}) uri = opts[:uri] fields = opts[:fields] || {} raw_content = opts[:raw_content] || false json = {} tries = @httpretry req = Net::HTTP::Get.new(uri) fields.each_pair do |name, value| req.add_field(name, value) end begin tries -= 1 res = @connection.request(req) rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e if tries>0 sleep @httpsleep retry else return json end rescue URI::InvalidURIError return json end if !raw_content parse_json(res.body) else res.body end end
Perform HTTP post method with uri, data, body and fields
returns: JSON parsed object (if JSON parseable)
Usage:
n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password') pp n.http_post(:uri=>"/scans/#{scan_id}/launch", :fields=>n.x_cookie)
# File lib/nessus_rest.rb, line 760 def http_post(opts={}) if opts.has_key?(:authenticationmethod) then # i know authzmethod = opts.delete(:authorizationmethod) is short, but not readable authzmethod = opts[:authenticationmethod] opts.delete(:authenticationmethod) end ret=http_post_low(opts) if ret.is_a?(Hash) and ret.has_key?('error') and ret['error']=='Invalid Credentials' then if not authzmethod authdefault ret=http_post_low(opts) return ret end else return ret end end
# File lib/nessus_rest.rb, line 778 def http_post_low(opts={}) uri = opts[:uri] data = opts[:data] fields = opts[:fields] || {} body = opts[:body] ctype = opts[:ctype] json = {} tries = @httpretry req = Net::HTTP::Post.new(uri) req.set_form_data(data) unless (data.nil? || data.empty?) req.body = body unless (body.nil? || body.empty?) req['Content-Type'] = ctype unless (ctype.nil? || ctype.empty?) fields.each_pair do |name, value| req.add_field(name, value) end begin tries -= 1 res = @connection.request(req) rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e if tries>0 sleep @httpsleep retry else return json end rescue URI::InvalidURIError return json end parse_json(res.body) end
Perform HTTP put method with uri, data and fields
returns: HTTP result object
Usage:
n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password') payload = { :password => password, :json => 1 } res = n.http_put(:uri=>"/users/#{user_id}/chpasswd", :data=>payload, :fields=>n.x_cookie) puts res.code
# File lib/nessus_rest.rb, line 606 def http_put(opts={}) ret=http_put_low(opts) if ret.is_a?(Hash) and ret.has_key?('error') and ret['error']=='Invalid Credentials' then authdefault ret=http_put_low(opts) return ret else return ret end end
# File lib/nessus_rest.rb, line 617 def http_put_low(opts={}) uri = opts[:uri] data = opts[:data] fields = opts[:fields] || {} res = nil tries = @httpretry req = Net::HTTP::Put.new(uri) req.set_form_data(data) unless (data.nil? || data.empty?) fields.each_pair do |name, value| req.add_field(name, value) end begin tries -= 1 res = @connection.request(req) rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e if tries>0 sleep @httpsleep retry else return res end rescue URI::InvalidURIError return res end res end
initialize quick scan defaults: these will be used when not specifying defaults
Usage:
n.init_quick_defaults()
# File lib/nessus_rest.rb, line 68 def init_quick_defaults @quick_defaults=Hash.new @quick_defaults['enabled']=false @quick_defaults['launch']='ONETIME' @quick_defaults['launch_now']=true @quick_defaults['description']='Created with nessus_rest' end
check if logged in user is administrator
returns: boolean value depending if user is administrator or not
Usage:
n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password') if n.is_admin puts "Administrator" else puts "NOT administrator" end
# File lib/nessus_rest.rb, line 358 def is_admin res = http_get(:uri=>"/session", :fields=>x_cookie) if res['permissions'] == 128 return true else return false end end
Get List of Families
returns: JSON parsed object with list of families
Usage:
n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password') pp n.list_families
# File lib/nessus_rest.rb, line 314 def list_families http_get(:uri=>"/plugins/families", :fields=>x_cookie) end
Get List of Folders
returns: JSON parsed object with list of folders
Usage:
n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password') pp n.list_folders
# File lib/nessus_rest.rb, line 290 def list_folders http_get(:uri=>"/folders", :fields=>x_cookie) end
Get List of Plugins
returns: JSON parsed object with list of plugins
Usage:
n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password') pp n.list_plugins
# File lib/nessus_rest.rb, line 326 def list_plugins(family_id) http_get(:uri=>"/plugins/families/#{family_id}", :fields=>x_cookie) end
Get List of Policies
returns: JSON parsed object with list of policies
Usage:
n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password') pp n.list_policies
# File lib/nessus_rest.rb, line 266 def list_policies http_get(:uri=>"/policies", :fields=>x_cookie) end
Get List of Scanners
returns: JSON parsed object with list of scanners
Usage:
n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password') pp n.list_scanners
# File lib/nessus_rest.rb, line 302 def list_scanners http_get(:uri=>"/scanners", :fields=>x_cookie) end
Get List of Templates
returns: JSON parsed object with list of templates
Usage:
n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password') pp n.list_templates
# File lib/nessus_rest.rb, line 338 def list_templates(type) res = http_get(:uri=>"/editor/#{type}/templates", :fields=>x_cookie) end
Get List of Users
returns: JSON parsed object with list of users
Usage:
n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password') pp n.list_users
# File lib/nessus_rest.rb, line 278 def list_users http_get(:uri=>"/users", :fields=>x_cookie) end
Perform JSON parsing of body
returns: JSON parsed object (if JSON parseable)
# File lib/nessus_rest.rb, line 816 def parse_json(body) buf = {} begin buf = JSON.parse(body) rescue JSON::ParserError end buf end
# File lib/nessus_rest.rb, line 342 def plugin_details(plugin_id) http_get(:uri=>"/plugins/plugin/#{plugin_id}", :fields=>x_cookie) end
# File lib/nessus_rest.rb, line 452 def policy_delete(policy_id) res = http_delete(:uri=>"/policies/#{policy_id}", :fields=>x_cookie) return res.code end
# File lib/nessus_rest.rb, line 564 def report_download(scan_id, file_id) res = http_get(:uri=>"/scans/#{scan_id}/export/#{file_id}/download", :raw_content=> true, :fields=>x_cookie) end
# File lib/nessus_rest.rb, line 582 def report_download_file(scan_id, format, outputfn) report_content=report_download_quick(scan_id, format) File.open(outputfn, 'w') do |f| f.write(report_content) end end
# File lib/nessus_rest.rb, line 568 def report_download_quick(scan_id, format) se=scan_export(scan_id,format) # ready, loading while (status = scan_export_status(scan_id,se['file'])['status']) != "ready" do # puts status if status.nil? or status == '' then return nil end sleep @defsleep end rf=report_download(scan_id,se['file']) return rf end
# File lib/nessus_rest.rb, line 379 def scan_create(uuid, settings) payload = { :uuid => uuid, :settings => settings, :json => 1 }.to_json http_post(:uri=>"/scans", :body=>payload, :fields=>x_cookie, :ctype=>'application/json') end
delete scan with scan_id
returns: boolean (true if deleted)
Usage:
n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password') puts n.scan_delete(1)
# File lib/nessus_rest.rb, line 444 def scan_delete(scan_id) res = http_delete(:uri=>"/scans/#{scan_id}", :fields=>x_cookie) if res.code == 200 then return true end return false end
# File lib/nessus_rest.rb, line 405 def scan_details(scan_id) http_get(:uri=>"/scans/#{scan_id}", :fields=>x_cookie) end
# File lib/nessus_rest.rb, line 421 def scan_export(scan_id, format) payload = { :format => format }.to_json http_post(:uri=>"/scans/#{scan_id}/export", :body=>payload, :ctype=>'application/json', :fields=>x_cookie) end
# File lib/nessus_rest.rb, line 428 def scan_export_status(scan_id, file_id) request = Net::HTTP::Get.new("/scans/#{scan_id}/export/#{file_id}/status") request.add_field("X-Cookie", @token) res = @connection.request(request) res = JSON.parse(res.body) return res end
# File lib/nessus_rest.rb, line 537 def scan_finished?(scan_id) ss=scan_status(scan_id) if ss == 'completed' or ss == 'canceled' or ss == 'imported' then return true end return false end
# File lib/nessus_rest.rb, line 388 def scan_launch(scan_id) http_post(:uri=>"/scans/#{scan_id}/launch", :fields=>x_cookie) end
Get List of Scans
returns: JSON parsed object with list of scans
Usage:
n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password') pp n.scan_list
# File lib/nessus_rest.rb, line 400 def scan_list http_get(:uri=>"/scans", :fields=>x_cookie) end
# File lib/nessus_rest.rb, line 409 def scan_pause(scan_id) http_post(:uri=>"/scans/#{scan_id}/pause", :fields=>x_cookie) end
Performs scan with scan policy provided (uuid of policy or policy name). Name is your scan name and targets are targets for scan
returns: JSON parsed object with scan info
Usage:
require 'nessus_rest' n=NessusREST::Client.new ({:url=>'https://localhost:8834', :username=>'user', :password=> 'password'}) qs=n.scan_quick_policy('myscanpolicy','name-of-scan','localhost') scanid=qs['scan']['id'] n.scan_wait4finish(scanid) n.report_download_file(scanid,'nessus','myscanreport.nessus')
# File lib/nessus_rest.rb, line 514 def scan_quick_policy (policyname, name, targets) templates=list_policies['policies'].select do |pol| pol['template_uuid'] == policyname or pol['name'] == policyname end if templates.nil? then return nil end tuuid=templates.first['template_uuid'] et=Hash.new et.merge!(@quick_defaults) et['name']=name et['text_targets']=targets sc=scan_create(tuuid,et) end
Performs scan with templatename provided (name, title or uuid of scan). Name is your scan name and targets are targets for scan
returns: JSON parsed object with scan info
Usage:
require 'nessus_rest' n=NessusREST::Client.new ({:url=>'https://localhost:8834', :username=>'user', :password=> 'password'}) qs=n.scan_quick_template('basic','name-of-scan','localhost') scanid=qs['scan']['id'] n.scan_wait4finish(scanid) n.report_download_file(scanid,'csv','myscanreport.csv')
# File lib/nessus_rest.rb, line 484 def scan_quick_template (templatename, name, targets) templates=list_templates('scan')['templates'].select do |temp| temp['uuid'] == templatename or temp['name'] == templatename or temp['title'] == templatename end if templates.nil? then return nil end tuuid=templates.first['uuid'] et=editor_templates('scan',tuuid) et.merge!(@quick_defaults) et['name']=name et['text_targets']=targets sc=scan_create(tuuid,et) end
# File lib/nessus_rest.rb, line 413 def scan_resume(scan_id) http_post(:uri=>"/scans/#{scan_id}/resume", :fields=>x_cookie) end
# File lib/nessus_rest.rb, line 529 def scan_status(scan_id) sd=scan_details(scan_id) if not sd['error'].nil? return 'error' end return sd['info']['status'] end
# File lib/nessus_rest.rb, line 417 def scan_stop(scan_id) http_post(:uri=>"/scans/#{scan_id}/stop", :fields=>x_cookie) end
# File lib/nessus_rest.rb, line 545 def scan_wait4finish(scan_id) while not scan_finished?(scan_id) do # puts scan_status(scan_id) sleep @defsleep end end
Get server status
returns: JSON parsed object with server status
Usage:
n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password') pp n.server_status
# File lib/nessus_rest.rb, line 375 def server_status http_get(:uri=>"/server/status", :fields=>x_cookie) end
Add user to server
returns: JSON parsed object
Usage:
n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password') pp n.user_add('user','password','16','local')
Reference: localhost:8834/api#/resources/users/create
# File lib/nessus_rest.rb, line 203 def user_add(username, password, permissions, type) payload = { :username => username, :password => password, :permissions => permissions, :type => type, :json => 1 } http_post(:uri=>"/users", :fields=>x_cookie, :data=>payload) end
change password for user_id
returns: result code
Usage:
n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password') puts n.user_chpasswd(1,'newPassword')
# File lib/nessus_rest.rb, line 235 def user_chpasswd(user_id, password) payload = { :password => password, :json => 1 } res = http_put(:uri=>"/users/#{user_id}/chpasswd", :data=>payload, :fields=>x_cookie) return res.code end
delete user with user_id
returns: result code
Usage:
n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password') puts n.user_delete(1)
# File lib/nessus_rest.rb, line 222 def user_delete(user_id) res = http_delete(:uri=>"/users/#{user_id}", :fields=>x_cookie) return res.code end
logout from the server
returns: result code
Usage:
n=NessusREST::Client.new (:url=>'https://localhost:8834', :username=>'user', :password=> 'password') puts n.user_logout
# File lib/nessus_rest.rb, line 252 def user_logout res = http_delete(:uri=>"/session", :fields=>x_cookie) return res.code end