Updates from Zate, renamed commands to match the existing plugins
git-svn-id: file:///home/svn/framework3/trunk@10383 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
0b008d6c3c
commit
541c192f12
|
@ -1,471 +1,510 @@
|
|||
#
|
||||
# = nessus-xmlrpc.rb: communicate with Nessus(4.2+) over XML RPC interface
|
||||
#
|
||||
# Author:: Vlatko Kosturjak
|
||||
#
|
||||
# (C) Vlatko Kosturjak, Kost. Distributed under GPL and BSD license (dual).
|
||||
#
|
||||
# == What is this library?
|
||||
#
|
||||
# This library is used for communication with Nessus over XML RPC interface.
|
||||
# You can start, stop, pause and resume scan. Watch progress and status of scan,
|
||||
# download report, etc.
|
||||
#
|
||||
# == Requirements
|
||||
#
|
||||
# Required libraries are standard Ruby libraries: uri, net/https and rexml/document.
|
||||
#
|
||||
# == Usage:
|
||||
#
|
||||
# require 'nessus-xmlrpc'
|
||||
# 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")
|
||||
# puts "status: " + n.scan_status(uid)
|
||||
# while not n.scan_finished(uid)
|
||||
# sleep 10
|
||||
# end
|
||||
# content=n.report_file_download(uid)
|
||||
# File.open('report.xml', 'w') {|f| f.write(content) }
|
||||
# end
|
||||
|
||||
require 'uri'
|
||||
require 'net/https'
|
||||
require 'rexml/document'
|
||||
|
||||
# NessusXMLRPC module
|
||||
#
|
||||
# Usage:
|
||||
#
|
||||
# require 'nessus-xmlrpc'
|
||||
# n=NessusXMLRPC::NessusXMLRPC.new('https://localhost:8834','user','pass');
|
||||
# if n.logged_in
|
||||
# id,name = n.policy_get_first
|
||||
# uid=n.scan_new(id,"textxmlrpc","127.0.0.1")
|
||||
# puts "status: " + n.scan_status(uid)
|
||||
# end
|
||||
#
|
||||
# Check NessusXMLRPCrexml for description of methods implemented
|
||||
# (for both NessusXMLRPCnokogiri and NessusXMLRPCrexml).
|
||||
|
||||
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
|
||||
else
|
||||
@nurl=url + "/"
|
||||
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
|
||||
puts "[e] error in XML parsing"
|
||||
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
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
#checks to see if the user is an admin
|
||||
def is_admin
|
||||
if @admin
|
||||
return true
|
||||
end
|
||||
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['current']=scan.elements['completion_current'].text;
|
||||
entry['total']=scan.elements['completion_total'].text;
|
||||
scans.push(entry)
|
||||
}
|
||||
return scans
|
||||
end
|
||||
|
||||
# get hash of reports
|
||||
#
|
||||
# returns: array of hash of reports
|
||||
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
|
||||
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
|
||||
|
||||
# get hosts for particular report
|
||||
#
|
||||
# returns: array of hosts
|
||||
def report_hosts(report_id)
|
||||
post= { "token" => @token, "report" => report_id }
|
||||
docxml=nessus_request('report/hosts', post)
|
||||
list = Array.new
|
||||
docxml.root.elements['contents'].elements['hostList'].each_element('//host') { |host|
|
||||
list.push host.elements['hostname'].text
|
||||
}
|
||||
return list
|
||||
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
|
||||
|
||||
#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
|
||||
|
||||
# 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
|
||||
end # end of NessusXMLRPC::Class
|
||||
|
||||
end # of Module
|
||||
|
||||
#
|
||||
# = nessus-xmlrpc.rb: communicate with Nessus(4.2+) over XML RPC interface
|
||||
#
|
||||
# Author:: Vlatko Kosturjak
|
||||
#
|
||||
# (C) Vlatko Kosturjak, Kost. Distributed under GPL and BSD license (dual).
|
||||
#
|
||||
# == What is this library?
|
||||
#
|
||||
# This library is used for communication with Nessus over XML RPC interface.
|
||||
# You can start, stop, pause and resume scan. Watch progress and status of scan,
|
||||
# download report, etc.
|
||||
#
|
||||
# == Requirements
|
||||
#
|
||||
# Required libraries are standard Ruby libraries: uri, net/https and rexml/document.
|
||||
#
|
||||
# == Usage:
|
||||
#
|
||||
# require 'nessus-xmlrpc'
|
||||
# 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")
|
||||
# puts "status: " + n.scan_status(uid)
|
||||
# while not n.scan_finished(uid)
|
||||
# sleep 10
|
||||
# end
|
||||
# content=n.report_file_download(uid)
|
||||
# File.open('report.xml', 'w') {|f| f.write(content) }
|
||||
# end
|
||||
|
||||
require 'uri'
|
||||
require 'net/https'
|
||||
require 'rexml/document'
|
||||
|
||||
# NessusXMLRPC module
|
||||
#
|
||||
# Usage:
|
||||
#
|
||||
# require 'nessus-xmlrpc'
|
||||
# n=NessusXMLRPC::NessusXMLRPC.new('https://localhost:8834','user','pass');
|
||||
# if n.logged_in
|
||||
# id,name = n.policy_get_first
|
||||
# uid=n.scan_new(id,"textxmlrpc","127.0.0.1")
|
||||
# puts "status: " + n.scan_status(uid)
|
||||
# end
|
||||
#
|
||||
# Check NessusXMLRPCrexml for description of methods implemented
|
||||
# (for both NessusXMLRPCnokogiri and NessusXMLRPCrexml).
|
||||
|
||||
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
|
||||
else
|
||||
@nurl=url + "/"
|
||||
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
|
||||
puts "[e] error in XML parsing"
|
||||
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
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
#checks to see if the user is an admin
|
||||
def is_admin
|
||||
if @admin
|
||||
return true
|
||||
end
|
||||
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
|
||||
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
|
||||
|
||||
# get hosts for particular report
|
||||
#
|
||||
# returns: array of hosts
|
||||
def report_hosts(report_id)
|
||||
post= { "token" => @token, "report" => report_id }
|
||||
docxml=nessus_request('report/hosts', post)
|
||||
list = Array.new
|
||||
docxml.root.elements['contents'].elements['hostList'].each_element('//host') { |host|
|
||||
list.push host.elements['hostname'].text
|
||||
}
|
||||
return list
|
||||
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
|
||||
|
||||
#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
|
||||
|
||||
# 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
|
||||
end # end of NessusXMLRPC::Class
|
||||
|
||||
end # of Module
|
||||
|
||||
|
|
|
@ -25,18 +25,44 @@ class Plugin::Nessus < Msf::Plugin
|
|||
#
|
||||
def commands
|
||||
{
|
||||
"nconnect" => "Connect to a nessus server: nconnect username:password@hostname:port <ssl ok>",
|
||||
"nreports" => "List all Nessus reports",
|
||||
"ngetreport" => "Import a report from the nessus server in Nessus v2 format",
|
||||
"nscans" => "List all currently running Nessus scans",
|
||||
"nstatus" => "Check the status of your Nessus Server",
|
||||
"nfeed" => "Nessus Feed Type",
|
||||
"npluginlist" => "Displays each plugin family and the number of plugins",
|
||||
"nusers" => "Show Nessus Users"
|
||||
"nessus_connect" => "Connect to a nessus server: nconnect username:password@hostname:port <ssl ok>",
|
||||
"nessus_report_list" => "List all Nessus reports",
|
||||
"nessus_report_get" => "Import a report from the nessus server in Nessus v2 format",
|
||||
"nessus_scan_status" => "List all currently running Nessus scans",
|
||||
"nessus_server_status" => "Check the status of your Nessus Server",
|
||||
"nessus_server_feed" => "Nessus Feed Type",
|
||||
"nessus_plugin_list" => "Displays each plugin family and the number of plugins",
|
||||
"nessus_user_show" => "Show Nessus Users",
|
||||
"nessus_scan_new" => "Create new Nessus Scan",
|
||||
"nessus_scan_pause" => "Pause a Nessus Scan",
|
||||
#"nessus_scan_pause_all" => "Pause all Nessus Scans"
|
||||
#"nessus_scan_stop" => "Stop a Nessus Scan"
|
||||
#"nessus_scan_stop_all" => "Stop all Nessus Scans"
|
||||
"nessus_scan_resume" => "Resume a Nessus Scan"
|
||||
#"nessus_scan_resume_all" => "Resume all Nessus Scans"
|
||||
#"nessus_user_add" => "Add a new Nessus User"
|
||||
#"nessus_user_del" => "Delete a Nessus User"
|
||||
#"nessus_user_passwd" => "Change Nessus Users Password"
|
||||
#"nessus_plugin_family" => "List plugins in a family"
|
||||
#"nessus_plugin_details" => "List details of a particular plugin"
|
||||
#"nessus_server_prefs" => "Display Server Prefs"
|
||||
#"nessus_policy_list" => "List all polciies"
|
||||
#"nessus_policy_new" => "Save new policy"
|
||||
#"nessus_policy_del" => "Delete a policy"
|
||||
#"nessus_policy_dupe" => "Duplicate a policy"
|
||||
#"nessus_policy_rename" => "Rename a policy"
|
||||
#"nessus_report_del" => "Delete a report"
|
||||
#"nessus_report_hosts" => "Get list of hosts from a report"
|
||||
#"nessus_report_hosts_filter" => "Get list of hosts from a report with filter"
|
||||
#"nessus_report_host_ports" => "Get list of open ports from a host from a report"
|
||||
#"nessus_report_host_detail" => "Detail from a report item on a host"
|
||||
#"nessus_report_tags" => "Not sure what this does yet"
|
||||
#"nessus_report_upload" => "Upload nessusv2 report"
|
||||
|
||||
}
|
||||
end
|
||||
|
||||
def cmd_nfeed
|
||||
def cmd_nessus_server_feed
|
||||
|
||||
if nessus_verify_token
|
||||
@feed, @version, @web_version = @n.feed
|
||||
|
@ -83,13 +109,13 @@ class Plugin::Nessus < Msf::Plugin
|
|||
|
||||
def ncusage
|
||||
print_status("Usage: ")
|
||||
print_status(" nconnect username:password@hostname:port <ssl ok>")
|
||||
print_status(" Example:> nconnect msf:msf@192.168.1.10:8834 ok")
|
||||
print_status(" nessus_connect username:password@hostname:port <ssl ok>")
|
||||
print_status(" Example:> nessus_connect msf:msf@192.168.1.10:8834 ok")
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
def cmd_nconnect(*args)
|
||||
def cmd_nessus_connect(*args)
|
||||
|
||||
if(args.length == 0 or args[0].empty? or args[0] == "-h")
|
||||
ncusage
|
||||
|
@ -156,7 +182,7 @@ class Plugin::Nessus < Msf::Plugin
|
|||
|
||||
end
|
||||
|
||||
def cmd_nreports
|
||||
def cmd_nessus_report_list
|
||||
|
||||
if ! nessus_verify_token
|
||||
return
|
||||
|
@ -183,7 +209,7 @@ class Plugin::Nessus < Msf::Plugin
|
|||
$stdout.puts tbl.to_s + "\n"
|
||||
end
|
||||
|
||||
def cmd_ngetreport(*args)
|
||||
def cmd_nessus_report_get(*args)
|
||||
|
||||
if ! nessus_verify_token
|
||||
return
|
||||
|
@ -197,8 +223,8 @@ class Plugin::Nessus < Msf::Plugin
|
|||
|
||||
if(args.length == 0 or args[0].empty? or args[0] == "-h")
|
||||
print_status("Usage: ")
|
||||
print_status(" ngetreport <report id> ")
|
||||
print_status(" use nreports to list all available reports for importing")
|
||||
print_status(" nessus_report_get <report id> ")
|
||||
print_status(" use nessus_report_list to list all available reports for importing")
|
||||
return
|
||||
end
|
||||
|
||||
|
@ -209,8 +235,8 @@ class Plugin::Nessus < Msf::Plugin
|
|||
rid = args[0]
|
||||
else
|
||||
print_status("Usage: ")
|
||||
print_status(" ngetreport <report id> ")
|
||||
print_status(" use nreports to list all available reports for importing")
|
||||
print_status(" nessus_report_get <report id> ")
|
||||
print_status(" use nreport_list to list all available reports for importing")
|
||||
return
|
||||
end
|
||||
|
||||
|
@ -220,15 +246,15 @@ class Plugin::Nessus < Msf::Plugin
|
|||
|
||||
end
|
||||
|
||||
def cmd_nscans
|
||||
def cmd_nessus_scan_status
|
||||
|
||||
nessus_login
|
||||
list=@n.scan_list_hash
|
||||
if list.empty?
|
||||
print_status("No Scans Running.")
|
||||
print_status("You can:")
|
||||
print_status(" List Reports of completed scans: nreports")
|
||||
#print_status(" Create a scan: nstartscan <policy id> <scan name> <target(s)>")
|
||||
print_status(" List Reports of completed scans: nessus_report_list")
|
||||
print_status(" Create a scan: nessus_scan_new <policy id> <scan name> <target(s)>")
|
||||
#print_status(" Get policy ID: ngetpolicies")
|
||||
return
|
||||
end
|
||||
|
@ -236,24 +262,29 @@ class Plugin::Nessus < Msf::Plugin
|
|||
tbl = Rex::Ui::Text::Table.new(
|
||||
'Columns' =>
|
||||
[
|
||||
'ID',
|
||||
'Scan ID',
|
||||
'Name',
|
||||
'Owner',
|
||||
'Started',
|
||||
'Status',
|
||||
'Current Hosts',
|
||||
'Total Hosts'
|
||||
])
|
||||
|
||||
list.each {|scan|
|
||||
tbl << [ scan['id'], scan['name'], scan['current'], scan['total'] ]
|
||||
t = Time.at(scan['start'].to_i)
|
||||
tbl << [ scan['id'], scan['name'], scan['owner'], t.strftime("%H:%M %b %d %Y"), scan['status'], scan['current'], scan['total'] ]
|
||||
}
|
||||
print_good("Running Scans")
|
||||
$stdout.puts "\n"
|
||||
$stdout.puts tbl.to_s + "\n"
|
||||
$stdout.puts "\n"
|
||||
print_good("Import Nessus report to database : ngetreport <reportid>")
|
||||
|
||||
print_status("You can:")
|
||||
print_good(" Import Nessus report to database : nessus_report_get <reportid>")
|
||||
print_good(" Pause a nessus scan : nessus_scan_pause <scanid>")
|
||||
end
|
||||
|
||||
def cmd_nusers
|
||||
def cmd_nessus_user_show
|
||||
if ! nessus_verify_token
|
||||
return
|
||||
end
|
||||
|
@ -277,7 +308,7 @@ class Plugin::Nessus < Msf::Plugin
|
|||
$stdout.puts tbl.to_s + "\n"
|
||||
end
|
||||
|
||||
def cmd_nstatus
|
||||
def cmd_nessus_server_status
|
||||
#Auth
|
||||
if ! nessus_verify_token
|
||||
return
|
||||
|
@ -289,7 +320,7 @@ class Plugin::Nessus < Msf::Plugin
|
|||
end
|
||||
|
||||
#Versions
|
||||
cmd_nfeed
|
||||
cmd_nserver_feed
|
||||
|
||||
tbl = Rex::Ui::Text::Table.new(
|
||||
'Columns' =>
|
||||
|
@ -328,7 +359,7 @@ class Plugin::Nessus < Msf::Plugin
|
|||
$stdout.puts tbl.to_s + "\n"
|
||||
end
|
||||
|
||||
def cmd_npluginlist
|
||||
def cmd_nessus_plugin_list
|
||||
if ! nessus_verify_token
|
||||
nessus_login
|
||||
return
|
||||
|
@ -352,7 +383,77 @@ class Plugin::Nessus < Msf::Plugin
|
|||
print_good("Plugins By Family")
|
||||
$stdout.puts "\n"
|
||||
$stdout.puts tbl.to_s + "\n"
|
||||
print_status("List plugins for a family : ngetreport <family name>")
|
||||
print_status("List plugins for a family : nessus_report_get <family name>")
|
||||
end
|
||||
|
||||
def cmd_nessus_scan_new(*args)
|
||||
if ! nessus_verify_token
|
||||
nessus_login
|
||||
return
|
||||
end
|
||||
|
||||
case args.length
|
||||
when 3
|
||||
pid = args[0].to_i
|
||||
name = args[1]
|
||||
tgts = args[2]
|
||||
else
|
||||
print_status("Usage: ")
|
||||
print_status(" nessus_scan_new <policy id> <scan name> <targets>")
|
||||
print_status(" use nessus_policy_list to list all available policies")
|
||||
return
|
||||
end
|
||||
|
||||
print_status("Creating scan from policy number #{pid}, called \"#{name}\" and scanning #{tgts}")
|
||||
|
||||
scan = @n.scan_new(pid, name, tgts)
|
||||
|
||||
if scan
|
||||
print_status("Scan started. uid is #{scan}")
|
||||
end
|
||||
#need policy id, scan name and targets
|
||||
end
|
||||
|
||||
def cmd_nessus_scan_pause(*args)
|
||||
if ! nessus_verify_token
|
||||
nessus_login
|
||||
return
|
||||
end
|
||||
|
||||
case args.length
|
||||
when 1
|
||||
sid = args[0]
|
||||
else
|
||||
print_status("Usage: ")
|
||||
print_status(" nessus_scan_pause <scan id>")
|
||||
print_status(" use nessus_scan_status to list all available scans")
|
||||
return
|
||||
end
|
||||
|
||||
pause = @n.scan_pause(sid)
|
||||
|
||||
print_status("#{sid} has been paused")
|
||||
end
|
||||
|
||||
def cmd_nessus_scan_resume(*args)
|
||||
if ! nessus_verify_token
|
||||
nessus_login
|
||||
return
|
||||
end
|
||||
|
||||
case args.length
|
||||
when 1
|
||||
sid = args[0]
|
||||
else
|
||||
print_status("Usage: ")
|
||||
print_status(" nessus_scan_resume <scan id>")
|
||||
print_status(" use nessus_scan_status to list all available scans")
|
||||
return
|
||||
end
|
||||
|
||||
resume = @n.scan_resume(sid)
|
||||
|
||||
print_status("#{sid} has been resumed")
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue