Start using gem instead of obsolete library/tool
Rationale is following: nessus-cli is obsolete nessus is using json rest api instead of xmlrpc xmlrpc name is therefore obsolete Solution: with minimal changes start using nessus_rest gem.bug/bundler_fix
parent
d34579f1f0
commit
46e4ee4c5b
|
@ -1,66 +0,0 @@
|
||||||
Nessus XML RPC library and Nessus Command Line interface to XML RPC
|
|
||||||
|
|
||||||
(C) Vlatko Kosturjak, Kost. Distributed under GPL and BSD (dual licensed).
|
|
||||||
|
|
||||||
Requirements
|
|
||||||
============
|
|
||||||
Requirements are quite standard Ruby libraries for HTTPS and XML
|
|
||||||
parsing:
|
|
||||||
require 'uri'
|
|
||||||
require 'net/https'
|
|
||||||
require 'rexml/document'
|
|
||||||
|
|
||||||
nessus-cli.rb
|
|
||||||
=============
|
|
||||||
Nessus command line interface for XML-RPC.
|
|
||||||
|
|
||||||
Type ./nessus-cli.rb --help for command line options.
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
---------
|
|
||||||
|
|
||||||
./nessus-cli.rb --user john --password doe --scan scan-localhost --wait --output report.xml --target localhost
|
|
||||||
|
|
||||||
./nessus-cli.rb --user user --password pass --scan localhost-scan --wait 5 -D --output report-localhost.xml --target localhost --verbose
|
|
||||||
|
|
||||||
./nessus-cli.rb --user user --password pass --scan localhost-scan --wait 5 -D --output report-localhost.xml --target 127.0.0.1 --verbose --policy mypolicy --url https://localhost:8834
|
|
||||||
|
|
||||||
Or if you want to have detached scans:
|
|
||||||
--------------------------------------
|
|
||||||
|
|
||||||
./nessus-cli.rb --user user --password pass --scan localhost-scan --target 127.0.0.1 --policy mypolicy
|
|
||||||
|
|
||||||
./nessus-cli.rb --user user --password pass --list-scans
|
|
||||||
|
|
||||||
./nessus-cli.rb --user user --password pass --pause 5329fae9-fb1d-0c67-a401-a0db12637c0d5bcd67900d34e00e
|
|
||||||
|
|
||||||
./nessus-cli.rb --user user --password pass --resume 5329fae9-fb1d-0c67-a401-a0db12637c0d5bcd67900d34e00e
|
|
||||||
|
|
||||||
./nessus-cli.rb --user user --password pass --stop 5329fae9-fb1d-0c67-a401-a0db12637c0d5bcd67900d34e00e
|
|
||||||
|
|
||||||
./nessus-cli.rb --user user --password pass --stop-all
|
|
||||||
|
|
||||||
./nessus-cli.rb --user user --password pass --report 5329fae9-fb1d-0c67-a401-a0db12637c0d5bcd67900d34e00e --output report.xml
|
|
||||||
|
|
||||||
nessus-xmlrpc.rb
|
|
||||||
================
|
|
||||||
communicate with Nessus(4.2+) over XML RPC interface
|
|
||||||
|
|
||||||
Simple example:
|
|
||||||
|
|
||||||
require 'nessus-xmlrpc'
|
|
||||||
n=NessusXMLRPC::NessusXMLRPC.new('https://localhost:8834','user','pass');
|
|
||||||
# n=NessusXMLRPC::NessusXMLRPC.new('','user','pass'); # it's same
|
|
||||||
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
|
|
||||||
|
|
||||||
Take a look at nessus-cli.rb for more advanced examples.
|
|
|
@ -1 +0,0 @@
|
||||||
- Error handling, no puts
|
|
|
@ -1,382 +0,0 @@
|
||||||
#!/usr/bin/env ruby
|
|
||||||
# = nessus-cli.rb: Nessus command line interface for XML-RPC
|
|
||||||
# Author:: Vlatko Kosturjak
|
|
||||||
#
|
|
||||||
# (C) Vlatko Kosturjak, Kost. Distributed under GPL and BSD (dual licensed).
|
|
||||||
|
|
||||||
require 'nessus-xmlrpc'
|
|
||||||
require 'getoptlong'
|
|
||||||
|
|
||||||
verbose = 0
|
|
||||||
debug = 0
|
|
||||||
operation = ''
|
|
||||||
targets = ''
|
|
||||||
deletereport = false
|
|
||||||
user = ''
|
|
||||||
password = ''
|
|
||||||
scanname = ''
|
|
||||||
output = ''
|
|
||||||
output1 = ''
|
|
||||||
wait = ''
|
|
||||||
policy = ''
|
|
||||||
url = ''
|
|
||||||
|
|
||||||
def intro
|
|
||||||
$stderr.print $0 + ": Nessus command line interface for XML-RPC\n"
|
|
||||||
$stderr.print "(C) Vlatko Kosturjak, Kost. Distributed under GPL.\n"
|
|
||||||
$stderr.print "\n"
|
|
||||||
end
|
|
||||||
|
|
||||||
intro
|
|
||||||
|
|
||||||
def give_help
|
|
||||||
puts <<-EOF
|
|
||||||
--user <user> user for login to Nessus server
|
|
||||||
--password <p> password for login to Nessus server
|
|
||||||
--scan <name> start scan with name
|
|
||||||
--target <ip> specify list of targets, separated by comma
|
|
||||||
--policy <pol> specify policy to use (name of policy)
|
|
||||||
--url <url> url of Nessus server (default: localhost:8834)
|
|
||||||
--wait [t] wait scan to finish (ask in regular periods of <t> for status)
|
|
||||||
--output <f> output report XML to file <f>
|
|
||||||
--output1 <f> output report XML v1 to file <f>
|
|
||||||
--reportdelete delete report after finish or delete report by id (if alone)
|
|
||||||
--stop <id> stop scan identified by <id>
|
|
||||||
--stop-all stop all scans
|
|
||||||
--pause <id> pause scan identified by <id>
|
|
||||||
--pause-all pause all scans
|
|
||||||
--resume <id> resume scan identified by <id>
|
|
||||||
--resume-all resume all scans
|
|
||||||
--report <id> download report identified by <id>
|
|
||||||
--list-scans list scans
|
|
||||||
--list-policy list policies
|
|
||||||
--status <id> get status of scan by <id>
|
|
||||||
--verbose be verbose
|
|
||||||
--debug be even more verbose
|
|
||||||
--help this help
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
#{$0} --user john --password doe --scan scan-localhost --wait --output report.xml --target localhost
|
|
||||||
EOF
|
|
||||||
exit 0
|
|
||||||
end
|
|
||||||
|
|
||||||
if ARGV.length < 1
|
|
||||||
give_help
|
|
||||||
end
|
|
||||||
|
|
||||||
opt = GetoptLong.new(
|
|
||||||
["--help", "-h", GetoptLong::NO_ARGUMENT],
|
|
||||||
["--verbose", "-v", GetoptLong::OPTIONAL_ARGUMENT],
|
|
||||||
["--target", "-t", GetoptLong::REQUIRED_ARGUMENT],
|
|
||||||
["--user", "-u", GetoptLong::REQUIRED_ARGUMENT],
|
|
||||||
["--password", "-p", GetoptLong::REQUIRED_ARGUMENT],
|
|
||||||
["--policy", "-P", GetoptLong::REQUIRED_ARGUMENT],
|
|
||||||
["--url", "-U", GetoptLong::REQUIRED_ARGUMENT],
|
|
||||||
["--deletereport", "-D", GetoptLong::OPTIONAL_ARGUMENT],
|
|
||||||
["--wait", "-w", GetoptLong::OPTIONAL_ARGUMENT],
|
|
||||||
["--scan", "-s", GetoptLong::REQUIRED_ARGUMENT],
|
|
||||||
["--list-scans", "-l", GetoptLong::NO_ARGUMENT],
|
|
||||||
["--list-policy", "-L", GetoptLong::NO_ARGUMENT],
|
|
||||||
["--status", "-W", GetoptLong::REQUIRED_ARGUMENT],
|
|
||||||
["--stop", "-S", GetoptLong::REQUIRED_ARGUMENT],
|
|
||||||
["--stop-all", "-a", GetoptLong::NO_ARGUMENT],
|
|
||||||
["--pause", "-q", GetoptLong::REQUIRED_ARGUMENT],
|
|
||||||
["--pause-all", "-Q", GetoptLong::NO_ARGUMENT],
|
|
||||||
["--resume", "-e", GetoptLong::REQUIRED_ARGUMENT],
|
|
||||||
["--resume-all", "-E", GetoptLong::NO_ARGUMENT],
|
|
||||||
["--report", "-r", GetoptLong::REQUIRED_ARGUMENT],
|
|
||||||
["--output", "-o", GetoptLong::REQUIRED_ARGUMENT],
|
|
||||||
["--output1", "-1", GetoptLong::REQUIRED_ARGUMENT]
|
|
||||||
)
|
|
||||||
|
|
||||||
def give_error
|
|
||||||
$stderr.print "You used incompatible options, probably you mixed --scan with --stop"
|
|
||||||
$stderr.print "or something similar."
|
|
||||||
exit 0
|
|
||||||
end
|
|
||||||
|
|
||||||
opt.each do |opt,arg|
|
|
||||||
case opt
|
|
||||||
when '--help'
|
|
||||||
give_help
|
|
||||||
when '--user'
|
|
||||||
user = arg
|
|
||||||
when '--password'
|
|
||||||
password = arg
|
|
||||||
when '--stop'
|
|
||||||
if operation == ''
|
|
||||||
operation = "stop"
|
|
||||||
scanname = arg
|
|
||||||
else
|
|
||||||
give_error
|
|
||||||
end
|
|
||||||
when '--pause'
|
|
||||||
if operation == ''
|
|
||||||
operation = "pause"
|
|
||||||
scanname = arg
|
|
||||||
else
|
|
||||||
give_error
|
|
||||||
end
|
|
||||||
when '--resume'
|
|
||||||
if operation == ''
|
|
||||||
operation = "resume"
|
|
||||||
scanname = arg
|
|
||||||
else
|
|
||||||
give_error
|
|
||||||
end
|
|
||||||
when '--stop-all'
|
|
||||||
if operation == ''
|
|
||||||
operation = "stop-all"
|
|
||||||
else
|
|
||||||
give_error
|
|
||||||
end
|
|
||||||
when '--pause-all'
|
|
||||||
if operation == ''
|
|
||||||
operation = "pause-all"
|
|
||||||
else
|
|
||||||
give_error
|
|
||||||
end
|
|
||||||
when '--resume-all'
|
|
||||||
if operation == ''
|
|
||||||
operation = "resume-all"
|
|
||||||
else
|
|
||||||
give_error
|
|
||||||
end
|
|
||||||
when '--report'
|
|
||||||
if operation == ''
|
|
||||||
operation = "report"
|
|
||||||
scanname = arg
|
|
||||||
else
|
|
||||||
give_error
|
|
||||||
end
|
|
||||||
when '--scan'
|
|
||||||
if operation == ''
|
|
||||||
operation = "scan"
|
|
||||||
scanname = arg
|
|
||||||
else
|
|
||||||
give_error
|
|
||||||
end
|
|
||||||
when '--target'
|
|
||||||
if arg[0..6] == 'file://'
|
|
||||||
f = File.open(arg[7..-1], "r")
|
|
||||||
f.each_line do |line|
|
|
||||||
line=line.chomp
|
|
||||||
line=line.strip
|
|
||||||
unless line == '' or line == nil
|
|
||||||
if targets == ''
|
|
||||||
targets = line
|
|
||||||
else
|
|
||||||
targets = targets + "," + line
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
f.close
|
|
||||||
else
|
|
||||||
# if there's multiple target options, add comma
|
|
||||||
if targets == ''
|
|
||||||
targets = arg
|
|
||||||
|
|
||||||
else
|
|
||||||
targets = targets + "," + arg
|
|
||||||
end
|
|
||||||
end
|
|
||||||
when '--wait'
|
|
||||||
if arg == ''
|
|
||||||
wait = 15
|
|
||||||
else
|
|
||||||
wait = arg.to_i
|
|
||||||
end
|
|
||||||
when '--reportdelete'
|
|
||||||
if arg == ''
|
|
||||||
deletereport=true
|
|
||||||
else
|
|
||||||
operation = "reportdelete"
|
|
||||||
scanname = arg
|
|
||||||
end
|
|
||||||
|
|
||||||
when '--output'
|
|
||||||
output = arg
|
|
||||||
when '--output1'
|
|
||||||
output1 = arg
|
|
||||||
when '--policy'
|
|
||||||
policy = arg
|
|
||||||
when '--status'
|
|
||||||
if operation == ''
|
|
||||||
operation = "status"
|
|
||||||
scanname = arg
|
|
||||||
else
|
|
||||||
give_error
|
|
||||||
end
|
|
||||||
when '--url'
|
|
||||||
url = arg
|
|
||||||
when '--verbose'
|
|
||||||
if arg == ''
|
|
||||||
verbose += 1
|
|
||||||
else
|
|
||||||
verbose = arg.to_i
|
|
||||||
end
|
|
||||||
when '--debug'
|
|
||||||
if arg == ''
|
|
||||||
debug += 1
|
|
||||||
else
|
|
||||||
debug = arg.to_i
|
|
||||||
end
|
|
||||||
when '--list-scans'
|
|
||||||
if operation == ''
|
|
||||||
operation = "list-scans"
|
|
||||||
scanname = arg
|
|
||||||
else
|
|
||||||
give_error
|
|
||||||
end
|
|
||||||
when '--list-policy'
|
|
||||||
if operation == ''
|
|
||||||
operation = "list-policy"
|
|
||||||
scanname = arg
|
|
||||||
else
|
|
||||||
give_error
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if (user == '') or (password == '')
|
|
||||||
$stderr.print "User and password is required to login to Nessus server"
|
|
||||||
$stderr.print "Try --help!"
|
|
||||||
exit 1
|
|
||||||
end
|
|
||||||
|
|
||||||
$stderr.print "[i] Targets: " + targets +"\n" if verbose > 0
|
|
||||||
$stderr.print "[i] Connecting to nessus server: " if verbose > 0
|
|
||||||
n=NessusXMLRPC::NessusXMLRPC.new(url,user,password)
|
|
||||||
if n.logged_in
|
|
||||||
$stderr.print "OK!\n" if verbose > 0
|
|
||||||
else
|
|
||||||
$stderr.print "[e] Error connecting/logging to the server!\n"
|
|
||||||
exit 2
|
|
||||||
end
|
|
||||||
|
|
||||||
case operation
|
|
||||||
when "scan"
|
|
||||||
if policy == ''
|
|
||||||
$stderr.print "[w] Policy not defined, using first served from the server\n"
|
|
||||||
pid,name = n.policy_get_first
|
|
||||||
$stderr.print "[w] using policy id " + pid + " with name " + name + "\n"
|
|
||||||
else
|
|
||||||
pid=n.policy_get_id(policy)
|
|
||||||
if pid == ''
|
|
||||||
$stderr.print "[e] policy doesn't exit: " + policy + "\n"
|
|
||||||
exit 3
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if targets == ''
|
|
||||||
$stderr.print "[w] Targets not defined, using localhost as target\n"
|
|
||||||
targets = '127.0.0.1'
|
|
||||||
end
|
|
||||||
$stderr.print "[i] Initiating scan with targets: "+targets+': ' if verbose > 0
|
|
||||||
uid=n.scan_new(pid,scanname,targets)
|
|
||||||
$stderr.print "done\n" if verbose > 0
|
|
||||||
unless wait == ''
|
|
||||||
while not n.scan_finished(uid)
|
|
||||||
$stderr.print "[v] Sleeping for " + wait.to_s() + ": " if verbose > 1
|
|
||||||
sleep wait
|
|
||||||
$stderr.print "done\n" if verbose > 1
|
|
||||||
stat = n.scan_status(uid)
|
|
||||||
print "\r" + stat if verbose > 0
|
|
||||||
end
|
|
||||||
else
|
|
||||||
puts uid
|
|
||||||
exit 0
|
|
||||||
end
|
|
||||||
unless output == ''
|
|
||||||
$stderr.print "[i] Output XML report to file: "+output if verbose > 0
|
|
||||||
content=n.report_file_download(uid)
|
|
||||||
File.open(output, 'w') {|f| f.write(content) }
|
|
||||||
$stderr.print ": done\n" if verbose > 0
|
|
||||||
end
|
|
||||||
unless output1 == ''
|
|
||||||
$stderr.print "[i] Output XML1 report to file: "+output1 if verbose > 0
|
|
||||||
content=n.report_file1_download(uid)
|
|
||||||
File.open(output, 'w') {|f| f.write(content) }
|
|
||||||
$stderr.print ": done\n" if verbose > 0
|
|
||||||
end
|
|
||||||
if deletereport
|
|
||||||
$stderr.print "[i] Deleting report: " if verbose > 0
|
|
||||||
n.report_delete(uid)
|
|
||||||
$stderr.print "done\n" if verbose > 0
|
|
||||||
end
|
|
||||||
when "report"
|
|
||||||
uid=scanname
|
|
||||||
if (output == '') and (output1 == '')
|
|
||||||
$stderr.print "[e] You want report, but specify filename with --output or output1\n"
|
|
||||||
end
|
|
||||||
unless output == ''
|
|
||||||
$stderr.print "[i] Output XML report to file: "+output if verbose > 0
|
|
||||||
content=n.report_file_download(uid)
|
|
||||||
File.open(output, 'w') {|f| f.write(content) }
|
|
||||||
$stderr.print ": done\n" if verbose > 0
|
|
||||||
end
|
|
||||||
unless output1 == ''
|
|
||||||
$stderr.print "[i] Output XML1 report to file: "+output1 if verbose > 0
|
|
||||||
content=n.report1_file_download(uid)
|
|
||||||
File.open(output, 'w') {|f| f.write(content) }
|
|
||||||
$stderr.print ": done\n" if verbose > 0
|
|
||||||
end
|
|
||||||
if deletereport
|
|
||||||
$stderr.print "[i] Deleting report: " if verbose > 0
|
|
||||||
n.report_delete(uid)
|
|
||||||
$stderr.print "done\n" if verbose > 0
|
|
||||||
end
|
|
||||||
when "stop"
|
|
||||||
$stderr.print "[i] Stopping scan: " + scanname if verbose > 0
|
|
||||||
n.scan_stop(scanname)
|
|
||||||
$stderr.print "done\n" if verbose > 0
|
|
||||||
when "stop-all"
|
|
||||||
$stderr.print "[i] Stopping all scans: " if verbose > 0
|
|
||||||
list=n.scan_stop_all
|
|
||||||
$stderr.print "done\n" if verbose > 0
|
|
||||||
if verbose > 1
|
|
||||||
list.each {|uuid| puts "[v] Stop all: " + uuid }
|
|
||||||
end
|
|
||||||
when "pause"
|
|
||||||
$stderr.print "[i] Pausing scan: " + scanname if verbose > 0
|
|
||||||
n.scan_pause(scanname)
|
|
||||||
$stderr.print "done\n" if verbose > 0
|
|
||||||
when "pause-all"
|
|
||||||
$stderr.print "[i] Pausing all scans: " if verbose > 0
|
|
||||||
list=n.scan_pause_all
|
|
||||||
$stderr.print "done\n" if verbose > 0
|
|
||||||
if verbose > 1
|
|
||||||
list.each {|uuid| puts "[v] Pause all: " + uuid }
|
|
||||||
end
|
|
||||||
when "resume"
|
|
||||||
$stderr.print "[i] Resuming scan: " + scanname if verbose > 0
|
|
||||||
n.scan_resume(scanname)
|
|
||||||
$stderr.print "done\n" if verbose > 0
|
|
||||||
when "resume-all"
|
|
||||||
$stderr.print "[i] Resuming all scans: " if verbose > 0
|
|
||||||
list=n.scan_resume_all
|
|
||||||
$stderr.print "done\n" if verbose > 0
|
|
||||||
if verbose > 1
|
|
||||||
list.each {|uuid| puts "[v] Resume all: " + uuid }
|
|
||||||
end
|
|
||||||
when "reportdelete"
|
|
||||||
$stderr.print "[i] Deleting report: " + scanname if verbose > 0
|
|
||||||
n.report_delete(scanname)
|
|
||||||
$stderr.print "done\n" if verbose > 0
|
|
||||||
when "status"
|
|
||||||
puts "status: " + n.scan_status(scanname)
|
|
||||||
when "list-scans"
|
|
||||||
list=n.scan_list_hash
|
|
||||||
list.each {|scan|
|
|
||||||
puts scan['id']+":"+scan['name']+":"+ \
|
|
||||||
scan['current']+"/"+scan['total']
|
|
||||||
}
|
|
||||||
when "list-policy"
|
|
||||||
list=n.policy_list_names
|
|
||||||
list.each {|policy|
|
|
||||||
puts policy
|
|
||||||
}
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
$stderr.print "[v] End reached.\n" if verbose > 1
|
|
|
@ -1,308 +0,0 @@
|
||||||
require 'net/http'
|
|
||||||
|
|
||||||
module Nessus
|
|
||||||
class Client
|
|
||||||
class << self
|
|
||||||
@connection
|
|
||||||
@token
|
|
||||||
end
|
|
||||||
|
|
||||||
def initialize(host, username = nil, password = nil, ssl_option = nil)
|
|
||||||
uri = URI.parse(host)
|
|
||||||
@connection = Net::HTTP.new(uri.host, uri.port)
|
|
||||||
@connection.use_ssl = true
|
|
||||||
if ssl_option == "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 username && password
|
|
||||||
end
|
|
||||||
|
|
||||||
def authenticate(username, password)
|
|
||||||
payload = {
|
|
||||||
:username => username,
|
|
||||||
:password => password,
|
|
||||||
:json => 1
|
|
||||||
}
|
|
||||||
res = http_post(:uri=>"/session", :data=>payload)
|
|
||||||
if res['token']
|
|
||||||
@token = "token=#{res['token']}"
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def x_cookie
|
|
||||||
{'X-Cookie'=>@token}
|
|
||||||
end
|
|
||||||
|
|
||||||
alias_method :login, :authenticate
|
|
||||||
|
|
||||||
def authenticated
|
|
||||||
if (@token && @token.include?('token='))
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_server_properties
|
|
||||||
http_get(:uri=>"/server/properties", :fields=>x_cookie)
|
|
||||||
end
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
def user_delete(user_id)
|
|
||||||
res = http_delete(:uri=>"/users/#{user_id}", :fields=>x_cookie)
|
|
||||||
return res.code
|
|
||||||
end
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
def user_logout
|
|
||||||
res = http_delete(:uri=>"/session", :fields=>x_cookie)
|
|
||||||
return res.code
|
|
||||||
end
|
|
||||||
|
|
||||||
def list_policies
|
|
||||||
http_get(:uri=>"/policies", :fields=>x_cookie)
|
|
||||||
end
|
|
||||||
|
|
||||||
def list_users
|
|
||||||
http_get(:uri=>"/users", :fields=>x_cookie)
|
|
||||||
end
|
|
||||||
|
|
||||||
def list_folders
|
|
||||||
http_get(:uri=>"/folders", :fields=>x_cookie)
|
|
||||||
end
|
|
||||||
|
|
||||||
def list_scanners
|
|
||||||
http_get(:uri=>"/scanners", :fields=>x_cookie)
|
|
||||||
end
|
|
||||||
|
|
||||||
def list_families
|
|
||||||
http_get(:uri=>"/plugins/families", :fields=>x_cookie)
|
|
||||||
end
|
|
||||||
|
|
||||||
def list_plugins(family_id)
|
|
||||||
http_get(:uri=>"/plugins/families/#{family_id}", :fields=>x_cookie)
|
|
||||||
end
|
|
||||||
|
|
||||||
def list_template(type)
|
|
||||||
res = http_get(:uri=>"/editor/#{type}/templates", :fields=>x_cookie)
|
|
||||||
end
|
|
||||||
|
|
||||||
def plugin_details(plugin_id)
|
|
||||||
http_get(:uri=>"/plugins/plugin/#{plugin_id}", :fields=>x_cookie)
|
|
||||||
end
|
|
||||||
|
|
||||||
def is_admin
|
|
||||||
res = http_get(:uri=>"/session", :fields=>x_cookie)
|
|
||||||
if res['permissions'] == 128
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def server_properties
|
|
||||||
http_get(:uri=>"/server/properties", :fields=>x_cookie)
|
|
||||||
end
|
|
||||||
|
|
||||||
def scan_create(uuid, name, description, targets)
|
|
||||||
payload = {
|
|
||||||
:uuid => uuid,
|
|
||||||
:settings => {
|
|
||||||
:name => name,
|
|
||||||
:description => description,
|
|
||||||
:text_targets => targets
|
|
||||||
},
|
|
||||||
:json => 1
|
|
||||||
}.to_json
|
|
||||||
http_post(:uri=>"/scans", :body=>payload, :fields=>x_cookie, :ctype=>'application/json')
|
|
||||||
end
|
|
||||||
|
|
||||||
def scan_launch(scan_id)
|
|
||||||
http_post(:uri=>"/scans/#{scan_id}/launch", :fields=>x_cookie)
|
|
||||||
end
|
|
||||||
|
|
||||||
def server_status
|
|
||||||
http_get(:uri=>"/server/status", :fields=>x_cookie)
|
|
||||||
end
|
|
||||||
|
|
||||||
def scan_list
|
|
||||||
http_get(:uri=>"/scans", :fields=>x_cookie)
|
|
||||||
end
|
|
||||||
|
|
||||||
def scan_details(scan_id)
|
|
||||||
http_get(:uri=>"/scans/#{scan_id}", :fields=>x_cookie)
|
|
||||||
end
|
|
||||||
|
|
||||||
def scan_pause(scan_id)
|
|
||||||
http_post(:uri=>"/scans/#{scan_id}/pause", :fields=>x_cookie)
|
|
||||||
end
|
|
||||||
|
|
||||||
def scan_resume(scan_id)
|
|
||||||
http_post(:uri=>"/scans/#{scan_id}/resume", :fields=>x_cookie)
|
|
||||||
end
|
|
||||||
|
|
||||||
def scan_stop(scan_id)
|
|
||||||
http_post(:uri=>"/scans/#{scan_id}/stop", :fields=>x_cookie)
|
|
||||||
end
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
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)
|
|
||||||
if res.code == "200"
|
|
||||||
return "ready"
|
|
||||||
else
|
|
||||||
res = JSON.parse(res.body)
|
|
||||||
return res
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def policy_delete(policy_id)
|
|
||||||
res = http_delete(:uri=>"/policies/#{policy_id}", :fields=>x_cookie)
|
|
||||||
return res.code
|
|
||||||
end
|
|
||||||
|
|
||||||
def host_detail(scan_id, host_id)
|
|
||||||
res = http_get(:uri=>"/scans/#{scan_id}/hosts/#{host_id}", :fields=>x_cookie)
|
|
||||||
end
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def http_put(opts={})
|
|
||||||
uri = opts[:uri]
|
|
||||||
data = opts[:data]
|
|
||||||
fields = opts[:fields] || {}
|
|
||||||
res = nil
|
|
||||||
|
|
||||||
req = Net::HTTP::Put.new(uri)
|
|
||||||
req.set_form_data(data) unless data.blank?
|
|
||||||
fields.each_pair do |name, value|
|
|
||||||
req.add_field(name, value)
|
|
||||||
end
|
|
||||||
|
|
||||||
begin
|
|
||||||
res = @connection.request(req)
|
|
||||||
rescue URI::InvalidURIError
|
|
||||||
return res
|
|
||||||
end
|
|
||||||
|
|
||||||
res
|
|
||||||
end
|
|
||||||
|
|
||||||
def http_delete(opts={})
|
|
||||||
uri = opts[:uri]
|
|
||||||
fields = opts[:fields] || {}
|
|
||||||
res = nil
|
|
||||||
|
|
||||||
req = Net::HTTP::Delete.new(uri)
|
|
||||||
|
|
||||||
fields.each_pair do |name, value|
|
|
||||||
req.add_field(name, value)
|
|
||||||
end
|
|
||||||
|
|
||||||
begin
|
|
||||||
res = @connection.request(req)
|
|
||||||
rescue URI::InvalidURIError
|
|
||||||
return res
|
|
||||||
end
|
|
||||||
|
|
||||||
res
|
|
||||||
end
|
|
||||||
|
|
||||||
def http_get(opts={})
|
|
||||||
uri = opts[:uri]
|
|
||||||
fields = opts[:fields] || {}
|
|
||||||
raw_content = opts[:raw_content] || false
|
|
||||||
json = {}
|
|
||||||
|
|
||||||
req = Net::HTTP::Get.new(uri)
|
|
||||||
fields.each_pair do |name, value|
|
|
||||||
req.add_field(name, value)
|
|
||||||
end
|
|
||||||
|
|
||||||
begin
|
|
||||||
res = @connection.request(req)
|
|
||||||
rescue URI::InvalidURIError
|
|
||||||
return json
|
|
||||||
end
|
|
||||||
if !raw_content
|
|
||||||
parse_json(res.body)
|
|
||||||
else
|
|
||||||
res.body
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def http_post(opts={})
|
|
||||||
uri = opts[:uri]
|
|
||||||
data = opts[:data]
|
|
||||||
fields = opts[:fields] || {}
|
|
||||||
body = opts[:body]
|
|
||||||
ctype = opts[:ctype]
|
|
||||||
json = {}
|
|
||||||
|
|
||||||
req = Net::HTTP::Post.new(uri)
|
|
||||||
req.set_form_data(data) unless data.blank?
|
|
||||||
req.body = body unless body.blank?
|
|
||||||
req['Content-Type'] = ctype unless ctype.blank?
|
|
||||||
fields.each_pair do |name, value|
|
|
||||||
req.add_field(name, value)
|
|
||||||
end
|
|
||||||
|
|
||||||
begin
|
|
||||||
res = @connection.request(req)
|
|
||||||
rescue URI::InvalidURIError
|
|
||||||
return json
|
|
||||||
end
|
|
||||||
|
|
||||||
parse_json(res.body)
|
|
||||||
end
|
|
||||||
|
|
||||||
def parse_json(body)
|
|
||||||
buf = {}
|
|
||||||
|
|
||||||
begin
|
|
||||||
buf = JSON.parse(body)
|
|
||||||
rescue JSON::ParserError
|
|
||||||
end
|
|
||||||
|
|
||||||
buf
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -151,4 +151,6 @@ Gem::Specification.new do |spec|
|
||||||
spec.add_runtime_dependency 'tzinfo'
|
spec.add_runtime_dependency 'tzinfo'
|
||||||
# Needed so that disk size output isn't horrible
|
# Needed so that disk size output isn't horrible
|
||||||
spec.add_runtime_dependency 'filesize'
|
spec.add_runtime_dependency 'filesize'
|
||||||
|
# Needed by metasploit nessus bridge
|
||||||
|
spec.add_runtime_dependency 'nessus_rest'
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# $Id$ $Revision$
|
# $Id$ $Revision$
|
||||||
require 'nessus/nessus-xmlrpc'
|
require 'nessus_rest'
|
||||||
require 'rex/parser/nessus_xml'
|
require 'rex/parser/nessus_xml'
|
||||||
|
|
||||||
module Msf
|
module Msf
|
||||||
|
@ -44,7 +44,6 @@ module Msf
|
||||||
"nessus_logout" => "Terminate the session",
|
"nessus_logout" => "Terminate the session",
|
||||||
"nessus_server_status" => "Check the status of your Nessus server",
|
"nessus_server_status" => "Check the status of your Nessus server",
|
||||||
"nessus_server_properties" => "Nessus server properties such as feed type, version, plugin set and server UUID",
|
"nessus_server_properties" => "Nessus server properties such as feed type, version, plugin set and server UUID",
|
||||||
"nessus_scanner_list" => "List all the scanners configured on the Nessus server",
|
|
||||||
"nessus_report_download" => "Download a report from the nessus server in either Nessus, HTML, PDF, CSV, or DB format",
|
"nessus_report_download" => "Download a report from the nessus server in either Nessus, HTML, PDF, CSV, or DB format",
|
||||||
"nessus_report_vulns" => "Get list of vulns from a report",
|
"nessus_report_vulns" => "Get list of vulns from a report",
|
||||||
"nessus_report_hosts" => "Get list of hosts from a report",
|
"nessus_report_hosts" => "Get list of hosts from a report",
|
||||||
|
@ -158,7 +157,11 @@ module Msf
|
||||||
end
|
end
|
||||||
@url = "https://#{@host}:#{@port}/"
|
@url = "https://#{@host}:#{@port}/"
|
||||||
print_status("Connecting to #{@url} as #{@user}")
|
print_status("Connecting to #{@url} as #{@user}")
|
||||||
@n = Nessus::Client.new(@url, @user, @pass,@sslv)
|
verify_ssl=false
|
||||||
|
if @sslv == "verify_ssl" then
|
||||||
|
verify_ssl=true
|
||||||
|
end
|
||||||
|
@n = NessusREST::Client.new(:url=>@url,:username=>@user,:password=>@pass,:ssl_verify=>verify_ssl)
|
||||||
if @n.authenticated
|
if @n.authenticated
|
||||||
print_status("User #{@user} authenticated successfully.")
|
print_status("User #{@user} authenticated successfully.")
|
||||||
@token = 1
|
@token = 1
|
||||||
|
@ -791,7 +794,7 @@ module Msf
|
||||||
print_status("Report downloaded to #{msf_local} directory")
|
print_status("Report downloaded to #{msf_local} directory")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
print_error("Only completed scans ca be downloaded")
|
print_error("Only completed scans can be downloaded")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
print_status("Usage: ")
|
print_status("Usage: ")
|
||||||
|
@ -963,7 +966,14 @@ module Msf
|
||||||
end
|
end
|
||||||
if valid_policy(uuid)
|
if valid_policy(uuid)
|
||||||
print_status("Creating scan from policy number #{uuid}, called #{scan_name} - #{description} and scanning #{targets}")
|
print_status("Creating scan from policy number #{uuid}, called #{scan_name} - #{description} and scanning #{targets}")
|
||||||
scan = @n.scan_create(uuid, scan_name, description, targets)
|
et=Hash.new
|
||||||
|
et['enabled']=false
|
||||||
|
et['launch']='ONETIME'
|
||||||
|
et['name']=scan_name
|
||||||
|
et['text_targets']=targets
|
||||||
|
et['description']=description
|
||||||
|
et['launch_now']=false
|
||||||
|
scan = @n.scan_create(uuid, et)
|
||||||
tbl = Rex::Text::Table.new(
|
tbl = Rex::Text::Table.new(
|
||||||
'Columns' => [
|
'Columns' => [
|
||||||
"Scan ID",
|
"Scan ID",
|
||||||
|
@ -1065,11 +1075,17 @@ module Msf
|
||||||
end
|
end
|
||||||
targets.chop!
|
targets.chop!
|
||||||
print_status("Creating scan from policy #{policy_id}, called \"#{name}\" and scanning all hosts in all the workspaces")
|
print_status("Creating scan from policy #{policy_id}, called \"#{name}\" and scanning all hosts in all the workspaces")
|
||||||
scan = @n.scan_create(policy_id, name, desc, targets)
|
et=Hash.new
|
||||||
|
et['enabled']=false
|
||||||
|
et['launch']='ONETIME'
|
||||||
|
et['name']=name
|
||||||
|
et['text_targets']=targets
|
||||||
|
et['description']=desc
|
||||||
|
et['launch_now']=true
|
||||||
|
scan = @n.scan_create(policy_id, et)
|
||||||
if !scan["error"]
|
if !scan["error"]
|
||||||
scan = scan["scan"]
|
scan = scan["scan"]
|
||||||
print_status("Scan ID #{scan['id']} successfully created")
|
print_status("Scan ID #{scan['id']} successfully created and launched")
|
||||||
print_status("Run nessus_scan_launch #{scan['id']} to launch the scan")
|
|
||||||
else
|
else
|
||||||
print_error(JSON.pretty_generate(scan))
|
print_error(JSON.pretty_generate(scan))
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue