diff --git a/lib/nessus/nessus-xmlrpc.rb b/lib/nessus/nessus-xmlrpc.rb index fe4ce84bee..257c5c22b4 100644 --- a/lib/nessus/nessus-xmlrpc.rb +++ b/lib/nessus/nessus-xmlrpc.rb @@ -52,575 +52,634 @@ require 'rexml/document' module NessusXMLRPC -# Class which uses standard REXML to parse nessus XML RPC replies. -class NessusXMLRPC - # initialize object: try to connect to Nessus Scanner using URL, user and password - # - # Usage: - # - # n=NessusXMLRPC::NessusXMLRPC.new('https://localhost:8834','user','pass'); - def initialize(url,user,password) - if url == '' - @nurl="https://localhost:8834/" - else - if url =~ /\/$/ - @nurl=url + # Class which uses standard REXML to parse nessus XML RPC replies. + class NessusXMLRPC + # initialize object: try to connect to Nessus Scanner using URL, user and password + # + # Usage: + # + # n=NessusXMLRPC::NessusXMLRPC.new('https://localhost:8834','user','pass'); + def initialize(url,user,password) + if url == '' + @nurl="https://localhost:8834/" else - @nurl=url + "/" + if url =~ /\/$/ + @nurl=url + else + @nurl=url + "/" + end end - end - @token='' - #login(user,password) - end - - # checks if we're logged in correctly - # - # returns: true if logged in, false if not - # - # Usage: - # - # n=NessusXMLRPC::NessusXMLRPC.new('https://localhost:8834','user','pass'); - # if n.logged_in - # puts "Logged in" - # else - # puts "Error" - # end - - def logged_in - if @token == '' - return false - else - return true - end - end - - # send standard Nessus XML request and check - # - # returns: rexml/document root - def nessus_request(uri, post_data) - body=nessus_http_request(uri, post_data) - # puts response.body - docxml = REXML::Document.new(body) - begin - status = docxml.root.elements['status'].text - rescue - print("Error connecting/logging to the server!") - end - if status == "OK" - return docxml - else - return '' - end - end - - # send standard Nessus HTTP request and check - # - # returns: body of response - def nessus_http_request(uri, post_data) - url = URI.parse(@nurl + uri) - request = Net::HTTP::Post.new( url.path ) - request.set_form_data( post_data ) - if not defined? @https - @https = Net::HTTP.new( url.host, url.port ) - @https.use_ssl = true - @https.verify_mode = OpenSSL::SSL::VERIFY_NONE - end - # puts request - begin - response = @https.request( request ) - rescue - #"[e] error connecting to server: "+ @nurl + " with URI: " + uri - @error = "stuff" - exit - end - # puts response.body - return response.body - end - - # login with user & password and sets object-wide @token, @name and @admin - def login(user, password) - post = { "login" => user, "password" => password } - docxml=nessus_request('login', post) - if docxml == '' @token='' - else - @token = docxml.root.elements['contents'].elements['token'].text - @name = docxml.root.elements['contents'].elements['user'].elements['name'].text - @admin = docxml.root.elements['contents'].elements['user'].elements['admin'].text - # puts "Got token:" + @token - return @token + #login(user,password) end + + # checks if we're logged in correctly + # + # returns: true if logged in, false if not + # + # Usage: + # + # n=NessusXMLRPC::NessusXMLRPC.new('https://localhost:8834','user','pass'); + # if n.logged_in + # puts "Logged in" + # else + # puts "Error" + # end + + def logged_in + if @token == '' + return false + else + return true + end + end + + # send standard Nessus XML request and check + # + # returns: rexml/document root + def nessus_request(uri, post_data) + body=nessus_http_request(uri, post_data) + # puts response.body + docxml = REXML::Document.new(body) + begin + status = docxml.root.elements['status'].text + rescue + print_error("Error connecting/logging to the server!") + end + if status == "OK" + return docxml + else + return '' + end + end + + # send standard Nessus HTTP request and check + # + # returns: body of response + def nessus_http_request(uri, post_data) + url = URI.parse(@nurl + uri) + request = Net::HTTP::Post.new( url.path ) + request.set_form_data( post_data ) + if not defined? @https + @https = Net::HTTP.new( url.host, url.port ) + @https.use_ssl = true + @https.verify_mode = OpenSSL::SSL::VERIFY_NONE + end + # puts request + begin + response = @https.request( request ) + rescue + print_error("error connecting to server: #{@nurl} with URI: #{uri}") + exit + end + # puts response.body + return response.body + end + + # login with user & password and sets object-wide @token, @name and @admin + def login(user, password) + post = { "login" => user, "password" => password } + docxml=nessus_request('login', post) + if docxml == '' + @token='' + else + @token = docxml.root.elements['contents'].elements['token'].text + @name = docxml.root.elements['contents'].elements['user'].elements['name'].text + @admin = docxml.root.elements['contents'].elements['user'].elements['admin'].text + # puts "Got token:" + @token + return @token + end - end - - #checks to see if the user is an admin - def is_admin - if @admin == "TRUE" - return true end - return false - end - # initiate new scan with policy id, descriptive name and list of targets - # - # returns: uuid of scan - # - # Usage: - # - # n=NessusXMLRPC::NessusXMLRPC.new('https://localhost:8834','user','pass'); - # if n.logged_in - # id,name = n.policy_get_first - # puts "using policy ID: " + id + " with name: " + name - # uid=n.scan_new(id,"textxmlrpc","127.0.0.1") - # end - def scan_new(policy_id,scan_name,target) - post= { "token" => @token, "policy_id" => policy_id, "scan_name" => scan_name, "target" => target } - docxml=nessus_request('scan/new', post) - if docxml == '' - return '' - else - uuid=docxml.root.elements['contents'].elements['scan'].elements['uuid'].text - return uuid - end - end - - # get uids of scans - # - # returns: array of uids of active scans - def scan_list_uids - post= { "token" => @token } - docxml=nessus_request('scan/list', post) - uuids=Array.new - docxml.root.elements['contents'].elements['scans'].elements['scanList'].each_element('//scan') {|scan| uuids.push(scan.elements['uuid'].text) } - return uuids - end - - # get hash of active scan data - # - # returns: array of hash of active scans - def scan_list_hash - post= { "token" => @token } - docxml=nessus_request('scan/list', post) - scans=Array.new - docxml.root.elements['contents'].elements['scans'].elements['scanList'].each_element('//scan') {|scan| - entry=Hash.new - entry['id']=scan.elements['uuid'].text - entry['name']=scan.elements['readableName'].text - entry['owner']=scan.elements['owner'].text - entry['start']=scan.elements['start_time'].text - entry['status']=scan.elements['status'].text - entry['current']=scan.elements['completion_current'].text; - entry['total']=scan.elements['completion_total'].text; - scans.push(entry) - } - return scans - end - - # get hash of policies - # - # returns: array of hash of policies - def policy_list_hash - post= { "token" => @token } - docxml=nessus_request('scan/list', post) - scans=Array.new - docxml.root.elements['policies'].elements['policies'].each_element('//policy') {|scan| - entry=Hash.new - entry['id']=scan.elements['uuid'].text - entry['name']=scan.elements['readableName'].text - entry['current']=scan.elements['completion_current'].text; - entry['total']=scan.elements['completion_total'].text; - scans.push(entry) - } - return scans - end - - # get hash of templates - # - # returns: array of hash of templates - def template_list_hash - post= { "token" => @token } - docxml=nessus_request('scan/list', post) - scans=Array.new - docxml.root.elements['contents'].elements['scans'].elements['scanList'].each_element('//scan') {|scan| - entry=Hash.new - entry['id']=scan.elements['uuid'].text - entry['name']=scan.elements['readableName'].text - entry['current']=scan.elements['completion_current'].text; - entry['total']=scan.elements['completion_total'].text; - scans.push(entry) - } - return scans - end - - # get hash of templates - # - # returns: array of hash of templates - def report_list_hash - post= { "token" => @token } - docxml=nessus_request('report/list', post) - #puts docxml - reports=Array.new - docxml.root.elements['contents'].elements['reports'].each_element('//report') {|report| - entry=Hash.new - entry['id']=report.elements['name'].text - entry['name']=report.elements['readableName'].text - entry['status']=report.elements['status'].text; - entry['timestamp']=report.elements['timestamp'].text; - reports.push(entry) - } - return reports - end - - # get policy by textname and return policyID - # - # returns: policyID - def policy_get_id(textname) - post= { "token" => @token } - docxml=nessus_request('policy/list', post) - docxml.root.elements['contents'].elements['policies'].each_element('//policy') {|policy| - if policy.elements['policyName'].text == textname - return policy.elements['policyID'].text + #checks to see if the user is an admin + def is_admin + if @admin == "TRUE" + return true end - } - return '' - end - - # get first policy from server and returns: policyID, policyName - # - # returns: policyID, policyName - def policy_get_first - post= { "token" => @token } - docxml=nessus_request('policy/list', post) - docxml.root.elements['contents'].elements['policies'].each_element('//policy') {|policy| - return policy.elements['policyID'].text, policy.elements['policyName'].text - } - end - - # get list of policy IDs - # - # returns: array of all policy uids - def policy_list_uids - post= { "token" => @token } - docxml=nessus_request('policy/list', post) - pids=Array.new - docxml.root.elements['contents'].elements['policies'].each_element('//policy') { |policy| - pids.push(policy.elements['policyID'].text) } - return pids - end - - # stop scan identified by scan_uuid - def scan_stop(uuid) - post= { "token" => @token, "scan_uuid" => uuid } - docxml=nessus_request('scan/stop', post) - return docxml - end - - # stop all active scans - # - # Usage: - # - # n=NessusXMLRPC::NessusXMLRPC.new('https://localhost:8834','user','pass'); - # if n.logged_in - # n.scan_stop_all - # end - def scan_stop_all - b=scan_list_uids - b.each {|uuid| - scan_stop(uuid) - } - return b - end - - # pause scan identified by scan_uuid - def scan_pause(uuid) - post= { "token" => @token, "scan_uuid" => uuid } - docxml=nessus_request('scan/pause', post) - return docxml - end - - # pause all active scans - # - # Usage: - # - # n=NessusXMLRPC::NessusXMLRPC.new('https://localhost:8834','user','pass'); - # if n.logged_in - # n.scan_pause_all - # end - def scan_pause_all - b=scan_list_uids - b.each {|uuid| - scan_pause(uuid) - } - return b - end - - # remove scan identified by uuid - def scan_resume(uuid) - post= { "token" => @token, "scan_uuid" => uuid } - docxml=nessus_request('scan/resume', post) - return docxml - end - # resume all active scans - # - # Usage: - # - # n=NessusXMLRPC::NessusXMLRPC.new('https://localhost:8834','user','pass'); - # if n.logged_in - # n.scan_resume_all - # end - def scan_resume_all - b=scan_list_uids - b.each {|uuid| - scan_resume(uuid) - } - return b - end - - # check status of scan identified by uuid - def scan_status(uuid) - post= { "token" => @token, "report" => uuid } - docxml=nessus_request('report/list', post) - docxml.root.elements['contents'].elements['reports'].each_element('//report') { |report| - if report.elements['name'].text == uuid - return (report.elements['status'].text) - end - } - return '' - end - - # check if scan is finished (completed to be exact) identified by uuid - def scan_finished(uuid) - status=scan_status(uuid) - if status == "completed" - return true - else return false end - end - # get report by reportID and return XML file - # - # returns: XML file of report (nessus v2 format) - def report_file_download(report) - post= { "token" => @token, "report" => report } - file=nessus_http_request('file/report/download', post) - return file - end + # initiate new scan with policy id, descriptive name and list of targets + # + # returns: uuid of scan + # + # Usage: + # + # n=NessusXMLRPC::NessusXMLRPC.new('https://localhost:8834','user','pass'); + # if n.logged_in + # id,name = n.policy_get_first + # puts "using policy ID: " + id + " with name: " + name + # uid=n.scan_new(id,"textxmlrpc","127.0.0.1") + # end + def scan_new(policy_id,scan_name,target) + post= { "token" => @token, "policy_id" => policy_id, "scan_name" => scan_name, "target" => target } + docxml=nessus_request('scan/new', post) + if docxml == '' + return '' + else + uuid=docxml.root.elements['contents'].elements['scan'].elements['uuid'].text + return uuid + end + end - # get report by reportID and return XML file (version 1) - # - # returns: XML file of report (nessus v1 format) - def report_file1_download(report) - post= { "token" => @token, "report" => report, "v1" => "true" } - file=nessus_http_request('file/report/download', post) - return file - end + # get uids of scans + # + # returns: array of uids of active scans + def scan_list_uids + post= { "token" => @token } + docxml=nessus_request('scan/list', post) + uuids=Array.new + docxml.root.elements['contents'].elements['scans'].elements['scanList'].each_element('//scan') {|scan| uuids.push(scan.elements['uuid'].text) } + return uuids + end + + # get hash of active scan data + # + # returns: array of hash of active scans + def scan_list_hash + post= { "token" => @token } + docxml=nessus_request('scan/list', post) + scans=Array.new + docxml.root.elements['contents'].elements['scans'].elements['scanList'].each_element('//scan') {|scan| + entry=Hash.new + entry['id']=scan.elements['uuid'].text if scan.elements['uuid'] + entry['name']=scan.elements['readableName'].text if scan.elements['readableName'] + entry['owner']=scan.elements['owner'].text if scan.elements['owner'] + entry['start']=scan.elements['start_time'].text if scan.elements['start_time'] + entry['status']=scan.elements['status'].text if scan.elements['status'] + entry['current']=scan.elements['completion_current'].text if scan.elements['completion_current'] + entry['total']=scan.elements['completion_total'].text if scan.elements['completion_total'] + scans.push(entry) + } + return scans + end - # delete report by report ID - def report_delete(id) - post= { "token" => @token, "report" => id } - docxml=nessus_request('report/delete', post) - return docxml - end + # get hash of policies + # + # returns: array of hash of policies + def policy_list_hash + post= { "token" => @token } + docxml=nessus_request('policy/list', post) + policies=Array.new + docxml.elements.each('/reply/contents/policies/policy') { |policy| + entry=Hash.new + entry['id']=policy.elements['policyID'].text + entry['name']=policy.elements['policyName'].text + entry['owner']=policy.elements['policyOwner'].text + entry['vis']=policy.elements['visibility'].text + policies.push(entry) + } + return policies + end + + # get hash of templates + # + # returns: array of hash of templates + def template_list_hash + post= { "token" => @token } + docxml=nessus_request('scan/list', post) + scans=Array.new + docxml.root.elements['contents'].elements['scans'].elements['scanList'].each_element('//scan') {|scan| + entry=Hash.new + entry['id']=scan.elements['uuid'].text if scan.elements['uuid'] + entry['name']=scan.elements['readableName'].text if scan.elements['readableName'] + entry['current']=scan.elements['completion_current'].text if scan.elements['completion_current'] + entry['total']=scan.elements['completion_total'].text if scan.elements['completion_total'] + scans.push(entry) + } + return scans + end + + # get hash of templates + # + # returns: array of hash of templates + def report_list_hash + post= { "token" => @token } + docxml=nessus_request('report/list', post) + #puts docxml + reports=Array.new + docxml.root.elements['contents'].elements['reports'].each_element('//report') {|report| + entry=Hash.new + entry['id']=report.elements['name'].text if report.elements['name'] + entry['name']=report.elements['readableName'].text if report.elements['readableName'] + entry['status']=report.elements['status'].text if report.elements['status'] + entry['timestamp']=report.elements['timestamp'].text if report.elements['timestamp'] + reports.push(entry) + } + return reports + end - # get list of names of policies - # - # returns: array of names - def policy_list_names - post= { "token" => @token } - docxml=nessus_request('policy/list', post) - list = Array.new - docxml.root.elements['contents'].elements['policies'].each_element('//policy') {|policy| + # get policy by textname and return policyID + # + # returns: policyID + def policy_get_id(textname) + post= { "token" => @token } + docxml=nessus_request('policy/list', post) + docxml.root.elements['contents'].elements['policies'].each_element('//policy') {|policy| + if policy.elements['policyName'].text == textname + return policy.elements['policyID'].text + end + } + return '' + end + + # get first policy from server and returns: policyID, policyName + # + # returns: policyID, policyName + def policy_get_first + post= { "token" => @token } + docxml=nessus_request('policy/list', post) + docxml.root.elements['contents'].elements['policies'].each_element('//policy') {|policy| + return policy.elements['policyID'].text, policy.elements['policyName'].text + } + end + + # get list of policy IDs + # + # returns: array of all policy uids + def policy_list_uids + post= { "token" => @token } + docxml=nessus_request('policy/list', post) + pids=Array.new + docxml.root.elements['contents'].elements['policies'].each_element('//policy') { |policy| + pids.push(policy.elements['policyID'].text) } + return pids + end + + # stop scan identified by scan_uuid + def scan_stop(uuid) + post= { "token" => @token, "scan_uuid" => uuid } + docxml=nessus_request('scan/stop', post) + return docxml + end + + # stop all active scans + # + # Usage: + # + # n=NessusXMLRPC::NessusXMLRPC.new('https://localhost:8834','user','pass'); + # if n.logged_in + # n.scan_stop_all + # end + def scan_stop_all + b=scan_list_uids + b.each {|uuid| + scan_stop(uuid) + } + return b + end + + # pause scan identified by scan_uuid + def scan_pause(uuid) + post= { "token" => @token, "scan_uuid" => uuid } + docxml=nessus_request('scan/pause', post) + return docxml + end + + # pause all active scans + # + # Usage: + # + # n=NessusXMLRPC::NessusXMLRPC.new('https://localhost:8834','user','pass'); + # if n.logged_in + # n.scan_pause_all + # end + def scan_pause_all + b=scan_list_uids + b.each {|uuid| + scan_pause(uuid) + } + return b + end + + # remove scan identified by uuid + def scan_resume(uuid) + post= { "token" => @token, "scan_uuid" => uuid } + docxml=nessus_request('scan/resume', post) + return docxml + end + # resume all active scans + # + # Usage: + # + # n=NessusXMLRPC::NessusXMLRPC.new('https://localhost:8834','user','pass'); + # if n.logged_in + # n.scan_resume_all + # end + def scan_resume_all + b=scan_list_uids + b.each {|uuid| + scan_resume(uuid) + } + return b + end + + # check status of scan identified by uuid + def scan_status(uuid) + post= { "token" => @token, "report" => uuid } + docxml=nessus_request('report/list', post) + docxml.root.elements['contents'].elements['reports'].each_element('//report') { |report| + if report.elements['name'].text == uuid + return (report.elements['status'].text) + end + } + return '' + end + + # check if scan is finished (completed to be exact) identified by uuid + def scan_finished(uuid) + status=scan_status(uuid) + if status == "completed" + return true + else + return false + end + end + + # get report by reportID and return XML file + # + # returns: XML file of report (nessus v2 format) + def report_file_download(report) + post= { "token" => @token, "report" => report } + file=nessus_http_request('file/report/download', post) + return file + end + + # get report by reportID and return XML file (version 1) + # + # returns: XML file of report (nessus v1 format) + def report_file1_download(report) + post= { "token" => @token, "report" => report, "v1" => "true" } + file=nessus_http_request('file/report/download', post) + return file + end + + # delete report by report ID + def report_delete(id) + post= { "token" => @token, "report" => id } + docxml=nessus_request('report/delete', post) + return docxml + end + + # get list of names of policies + # + # returns: array of names + def policy_list_names + post= { "token" => @token } + docxml=nessus_request('policy/list', post) + list = Array.new + docxml.root.elements['contents'].elements['policies'].each_element('//policy') {|policy| list.push policy.elements['policyName'].text - } - return list - end + } + return list + end - # get data for each host for a particular report - # - # - # returns: array of hashes: - # hostname - # severity - # severityCount0 - # severityCount1 - # severityCount2 - # severityCount3 - # scanProgressCurrent - # scanprogressTotal - def report_hosts(report_id) - post= { "token" => @token, "report" => report_id } - docxml=nessus_request('report/hosts', post) - hosts=Array.new - docxml.elements.each('/reply/contents/hostList/host') do |host| - entry=Hash.new - entry['hostname'] = host.elements['hostname'].text - entry['severity'] = host.elements['severity'].text - sevs=Array.new - host.elements.each('severityCount/item') do |item| - sevs.push item.elements['count'].text + # get data for each host for a particular report + # + # + # returns: array of hashes: + # hostname + # severity + # severityCount0 + # severityCount1 + # severityCount2 + # severityCount3 + # scanProgressCurrent + # scanprogressTotal + def report_hosts(report_id) + post= { "token" => @token, "report" => report_id } + docxml=nessus_request('report/hosts', post) + hosts=Array.new + docxml.elements.each('/reply/contents/hostList/host') do |host| + entry=Hash.new + entry['hostname'] = host.elements['hostname'].text if host.elements['hostname'] + entry['severity'] = host.elements['severity'].text if host.elements['severity'] + sevs=Array.new + host.elements.each('severityCount/item') do |item| + sevs.push item.elements['count'].text if item.elements['count'] + end + entry['sev0'] = sevs[0] if sevs[0] + entry['sev1'] = sevs[1] if sevs[1] + entry['sev2'] = sevs[2] if sevs[2] + entry['sev3'] = sevs[3] if sevs[3] + entry['current'] = host.elements['scanProgressCurrent'].text if host.elements['scanProgressCurrent'] + entry['total'] = host.elements['scanProgressTotal'].text if host.elements['scanProgressTotal'] + hosts.push(entry) end - entry['sev0'] = sevs[0] - entry['sev1'] = sevs[1] - entry['sev2'] = sevs[2] - entry['sev3'] = sevs[3] - entry['current'] = host.elements['scanProgressCurrent'].text - entry['total'] = host.elements['scanProgressTotal'].text - hosts.push(entry) + return hosts end - return hosts - end - def report_host_ports(report_id,host) - post= { "token" => @token, "report" => report_id, "hostname" => host } - docxml=nessus_request('report/ports', post) - ports=Array.new - docxml.elements.each('/reply/contents/portList/port') do |port| - entry=Hash.new - entry['portnum'] = port.elements['portNum'].text - entry['protocol'] = port.elements['protocol'].text - entry['severity'] = port.elements['severity'].text - entry['svcname'] = port.elements['svcName'].text - sevs=Array.new - port.elements.each('severityCount/item') do |item| - sevs.push item.elements['count'].text + def report_host_ports(report_id,host) + post= { "token" => @token, "report" => report_id, "hostname" => host } + docxml=nessus_request('report/ports', post) + ports=Array.new + docxml.elements.each('/reply/contents/portList/port') do |port| + entry=Hash.new + entry['portnum'] = port.elements['portNum'].text if port.elements['portNum'] + entry['protocol'] = port.elements['protocol'].text if port.elements['protocol'] + entry['severity'] = port.elements['severity'].text if port.elements['severity'] + entry['svcname'] = port.elements['svcName'].text if port.elements['svcName'] + sevs=Array.new + port.elements.each('severityCount/item') do |item| + sevs.push item.elements['count'].text if item.elements['count'] + end + entry['sev0'] = sevs[0] if sevs[0] + entry['sev1'] = sevs[1] if sevs[1] + entry['sev2'] = sevs[2] if sevs[2] + entry['sev3'] = sevs[3] if sevs[3] + ports.push(entry) end - entry['sev0'] = sevs[0] - entry['sev1'] = sevs[1] - entry['sev2'] = sevs[2] - entry['sev3'] = sevs[3] - ports.push(entry) + return ports end - return ports - end - def report_host_port_details(report_id,host,port,protocol) - post= { "token" => @token, "report" => report_id, "hostname" => host, "port" => port, "protocol" => protocol } - docxml=nessus_request('report/details', post) - reportitems=Array.new - docxml.elements.each('/reply/contents/portDetails/ReportItem') do |rpt| - entry=Hash.new - entry['port'] = rpt.elements['port'].text - entry['severity'] = rpt.elements['severity'].text - entry['pluginID'] = rpt.elements['pluginID'].text - entry['pluginName'] = rpt.elements['pluginName'].text - if rpt.elements['data'].elements['cvss_base_score'] - entry['cvss_base_score'] = rpt.elements['data'].elements['cvss_base_score'].text + def report_host_port_details(report_id,host,port,protocol) + post= { "token" => @token, "report" => report_id, "hostname" => host, "port" => port, "protocol" => protocol } + docxml=nessus_request('report/details', post) + reportitems=Array.new + docxml.elements.each('/reply/contents/portDetails/ReportItem') do |rpt| + entry=Hash.new + entry['port'] = rpt.elements['port'].text if rpt.elements['port'] + entry['severity'] = rpt.elements['severity'].text if rpt.elements['severity'] + entry['pluginID'] = rpt.elements['pluginID'].text if rpt.elements['pluginID'] + entry['pluginName'] = rpt.elements['pluginName'].text if rpt.elements['pluginName'] + entry['cvss_base_score'] = rpt.elements['data'].elements['cvss_base_score'].text if rpt.elements['data'].elements['cvss_base_score'] + entry['exploit_available'] = rpt.elements['data'].elements['exploit_available'].text if rpt.elements['data'].elements['exploit_available'] + entry['cve'] = rpt.elements['data'].elements['cve'].text if rpt.elements['data'].elements['cve'] + entry['risk_factor'] = rpt.elements['data'].elements['risk_factor'].text if rpt.elements['data'].elements['risk_factor'] + entry['cvss_vector'] = rpt.elements['data'].elements['cvss_vector'].text if rpt.elements['data'].elements['cvss_vector'] + #entry['solution'] = rpt.elements['data/solution'].text #not important right now + #entry['description'] = rpt.elements['data/description'].text #not important right now + #entry['synopsis'] = rpt.elements['data/synopsis'].text #not important right now + #entry['see_also'] = rpt.elements['data/see_also'].text # multiple of these + #entry['bid'] = rpt.elements['data/bid'].text multiple of these + #entry['xref'] = rpt.elements['data/xref'].text # multiple of these + #entry['plugin_output'] = rpt.elements['data/plugin_output'].text #not important right now + reportitems.push(entry) end - if rpt.elements['data'].elements['exploit_available'] - entry['exploit_available'] = rpt.elements['data'].elements['exploit_available'].text - end - if rpt.elements['data'].elements['cve'] - entry['cve'] = rpt.elements['data'].elements['cve'].text - end - if rpt.elements['data'].elements['risk_factor'] - entry['risk_factor'] = rpt.elements['data'].elements['risk_factor'].text - end - if rpt.elements['data'].elements['cvss_vector'] - entry['cvss_vector'] = rpt.elements['data'].elements['cvss_vector'].text - end - - #entry['solution'] = rpt.elements['data/solution'].text #not important right now - #entry['description'] = rpt.elements['data/description'].text #not important right now - #entry['synopsis'] = rpt.elements['data/synopsis'].text #not important right now - #entry['see_also'] = rpt.elements['data/see_also'].text # multiple of these - #entry['bid'] = rpt.elements['data/bid'].text multiple of these - #entry['xref'] = rpt.elements['data/xref'].text # multiple of these - #entry['plugin_output'] = rpt.elements['data/plugin_output'].text #not important right now - reportitems.push(entry) + return reportitems end - return reportitems - end - # get host details for particular host identified by report id - # - # returns: severity, current, total - def report_get_host(report_id,host) - post= { "token" => @token, "report" => report_id } - docxml=nessus_request('report/hosts', post) - docxml.root.elements['contents'].elements['hostList'].each_element('//host') { |host| - if host.elements['hostname'].text == host - severity = host.elements['severity'].text - current = host.elements['scanProgressCurrent'].text - total = host.elements['scanProgressTotal'].text - return severity, current, total - end - } - end + # get host details for particular host identified by report id + # + # returns: severity, current, total + def report_get_host(report_id,host) + post= { "token" => @token, "report" => report_id } + docxml=nessus_request('report/hosts', post) + docxml.root.elements['contents'].elements['hostList'].each_element('//host') { |host| + if host.elements['hostname'].text == host + severity = host.elements['severity'].text + current = host.elements['scanProgressCurrent'].text + total = host.elements['scanProgressTotal'].text + return severity, current, total + end + } + end - # gets a list of each plugin family and the number of plugins for that family. - def plugins_list - post= { "token" => @token } - docxml=nessus_request('plugins/list', post) - plugins=Array.new - docxml.root.elements['contents'].elements['pluginFamilyList'].each_element('//family') { |plugin| - entry=Hash.new - entry['name']=plugin.elements['familyName'].text - entry['num']=plugin.elements['numFamilyMembers'].text; - plugins.push(entry) - } - return plugins - end + # gets a list of each plugin family and the number of plugins for that family. + def plugins_list + post= { "token" => @token } + docxml=nessus_request('plugins/list', post) + plugins=Array.new + docxml.root.elements['contents'].elements['pluginFamilyList'].each_element('//family') { |plugin| + entry=Hash.new + entry['name']=plugin.elements['familyName'].text + entry['num']=plugin.elements['numFamilyMembers'].text + plugins.push(entry) + } + return plugins + end - #returns a list of users, if they are an admin and their last login time. - def users_list - post= { "token" => @token } - docxml=nessus_request('users/list', post) - users=Array.new - docxml.root.elements['contents'].elements['users'].each_element('//user') { |user| - entry=Hash.new - entry['name']=user.elements['name'].text - entry['admin']=user.elements['admin'].text; - entry['lastlogin']=user.elements['lastlogin'].text; - users.push(entry) - } - return users + #returns a list of users, if they are an admin and their last login time. + def users_list + post= { "token" => @token } + docxml=nessus_request('users/list', post) + users=Array.new + docxml.root.elements['contents'].elements['users'].each_element('//user') { |user| + entry=Hash.new + entry['name']=user.elements['name'].text + entry['admin']=user.elements['admin'].text + entry['lastlogin']=user.elements['lastlogin'].text + users.push(entry) + } + return users - end + end - # returns basic data about the feed type and versions. - def feed - post = { "token" => @token } - docxml = nessus_request('feed', post) - feed = docxml.root.elements['contents'].elements['feed'].text - version = docxml.root.elements['contents'].elements['server_version'].text - web_version = docxml.root.elements['contents'].elements['web_server_version'].text - return feed, version, web_version - end + # returns basic data about the feed type and versions. + def feed + post = { "token" => @token } + docxml = nessus_request('feed', post) + feed = docxml.root.elements['contents'].elements['feed'].text + version = docxml.root.elements['contents'].elements['server_version'].text + web_version = docxml.root.elements['contents'].elements['web_server_version'].text + return feed, version, web_version + end - def user_add(user,pass) - post= { "token" => @token, "login" => user, "password" => pass } - docxml = nessus_request('users/add', post) - return docxml - end + def user_add(user,pass) + post= { "token" => @token, "login" => user, "password" => pass } + docxml = nessus_request('users/add', post) + return docxml + end - def user_del(user) - post= { "token" => @token, "login" => user } - docxml = nessus_request('users/delete', post) - return docxml - end + def user_del(user) + post= { "token" => @token, "login" => user } + docxml = nessus_request('users/delete', post) + return docxml + end - def user_pass(user,pass) - post= { "token" => @token, "login" => user, "password" => pass } - docxml = nessus_request('users/chpasswd', post) - return docxml - end + def user_pass(user,pass) + post= { "token" => @token, "login" => user, "password" => pass } + docxml = nessus_request('users/chpasswd', post) + return docxml + end - def plugin_family(fam) - post = { "token" => @token, "family" => fam } - docxml = nessus_request('plugins/list/family', post) - family=Array.new - docxml.elements.each('/reply/contents/pluginList/plugin') { |plugin| + def plugin_family(fam) + post = { "token" => @token, "family" => fam } + docxml = nessus_request('plugins/list/family', post) + family=Array.new + docxml.elements.each('/reply/contents/pluginList/plugin') { |plugin| + entry=Hash.new + entry['filename'] = plugin.elements['pluginFileName'].text if plugin.elements['pluginFileName'] + entry['id'] = plugin.elements['pluginID'].text if plugin.elements['pluginID'] + entry['name'] = plugin.elements['pluginName'].text if plugin.elements['pluginName'] + family.push(entry) + } + return family + end + + def policy_del(pid) + post= { "token" => @token, "policy_id" => pid } + docxml = nessus_request('policy/delete', post) + return docxml + end + + def report_del(rid) + post= { "token" => @token, "report" => rid } + docxml = nessus_request('report/delete', post) + return docxml + end + + def plugin_detail(pname) + post = { "token" => @token, "fname" => pname } + docxml = nessus_request('plugins/description', post) + #return docxml + #details=Array.new entry=Hash.new - entry['filename'] = plugin.elements['pluginFileName'].text - entry['id'] = plugin.elements['pluginID'].text - entry['name'] = plugin.elements['pluginName'].text - family.push(entry) - } - return family - end -end # end of NessusXMLRPC::Class + docxml.elements.each('reply/contents/pluginDescription') { |desc| + entry['name'] = desc.elements['pluginName'].text + entry['id'] = desc.elements['pluginID'].text + entry['family'] = desc.elements['pluginFamily'].text + desc.elements.each('pluginAttributes') { |attr| + entry['exploit_ease'] = attr.elements['exploitability_ease'].text if attr.elements['exploitability_ease'] + entry['cvss_temporal_vector'] = attr.elements['cvss_temporal_vector'].text if attr.elements['cvss_temporal_vector'] + entry['solution'] = attr.elements['solution'].text if attr.elements['solution'] + entry['cvss_temporal_score'] = attr.elements['cvss_temporal_score'].text if attr.elements['cvss_temporal_score'] + entry['risk_factor'] = attr.elements['risk_factor'].text if attr.elements['risk_factor'] + entry['description'] = attr.elements['description'].text if attr.elements['description'] + entry['plugin_publication_date'] = attr.elements['plugin_publication_date'].text if attr.elements['plugin_publication_date'] + entry['cvss_vector'] = attr.elements['cvss_vector'].text if attr.elements['cvss_vector'] + entry['synopsis'] = attr.elements['synopsis'].text if attr.elements['synopsis'] + entry['exploit_available'] = attr.elements['exploit_available'].text if attr.elements['exploit_available'] + entry['plugin_modification_date'] = attr.elements['plugin_modification_date'].text if attr.elements['plugin_modification_date'] + entry['cvss_base_score'] = attr.elements['cvss_base_score'].text if attr.elements['cvss_base_score'] + } + } + + + return entry + end + + def server_prefs + post= { "token" => @token } + docxml = nessus_request('preferences/list', post) + prefs = Array.new + docxml.elements.each('/reply/contents/ServerPreferences/preference') { |pref| + entry=Hash.new + entry['name'] = pref.elements['name'].text if pref.elements['name'] + entry['value']= pref.elements['value'].text if pref.elements['value'] + prefs.push(entry) + } + return prefs + end + + def plugin_prefs + post= { "token" => @token } + docxml = nessus_request('plugins/preferences', post) + prefs = Array.new + docxml.elements.each('/reply/contents/PluginsPreferences/item') { |pref| + entry=Hash.new + entry['fullname'] = pref.elements['fullName'].text if pref.elements['fullName'] + entry['pluginname'] = pref.elements['pluginName'].text if pref.elements['pluginName'] + entry['prefname'] = pref.elements['preferenceName'].text if pref.elements['preferenceName'] + entry['preftype'] = pref.elements['preferenceType'].text if pref.elements['preferenceType'] + entry['prefvalues'] = pref.elements['preferenceValues'].text if pref.elements['preferenceValues'] + prefs.push(entry) + } + return prefs + end + end # end of NessusXMLRPC::Class end # of Module