2011-08-24 18:47:35 +00:00
|
|
|
#!/usr/bin/env ruby
|
|
|
|
require 'rubygems'
|
|
|
|
require 'optparse'
|
|
|
|
require 'msfrpc-client'
|
|
|
|
require 'rex/ui'
|
|
|
|
|
|
|
|
def usage(ropts)
|
2013-09-30 18:47:53 +00:00
|
|
|
$stderr.puts ropts
|
|
|
|
|
|
|
|
if @rpc and @rpc.token
|
|
|
|
wspaces = @rpc.call("pro.workspaces") rescue {}
|
|
|
|
if wspaces.keys.length > 0
|
|
|
|
$stderr.puts "Active Projects:"
|
|
|
|
wspaces.each_pair do |k,v|
|
|
|
|
$stderr.puts "\t#{k}"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
$stderr.puts ""
|
|
|
|
exit(1)
|
2011-08-24 18:47:35 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
opts = {}
|
|
|
|
|
|
|
|
# Parse script-specific options
|
|
|
|
parser = Msf::RPC::Client.option_parser(opts)
|
|
|
|
parser.separator('NeXpose Specific Options:')
|
|
|
|
|
|
|
|
parser.on("--project PROJECT") do |x|
|
2013-09-30 18:47:53 +00:00
|
|
|
opts[:project] = x
|
2011-08-24 18:47:35 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
parser.on("--targets TARGETS") do |x|
|
2013-09-30 18:47:53 +00:00
|
|
|
opts[:targets] = [x]
|
2011-08-24 18:47:35 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
parser.on("--nexpose-host HOST") do |x|
|
2013-09-30 18:47:53 +00:00
|
|
|
opts[:nexpose_host] = x
|
2011-08-24 18:47:35 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
parser.on("--nexpose-user USER") do |x|
|
2013-09-30 18:47:53 +00:00
|
|
|
opts[:nexpose_user] = x
|
2011-08-24 18:47:35 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
parser.on("--nexpose-pass PASSWORD") do |x|
|
2013-09-30 18:47:53 +00:00
|
|
|
opts[:nexpose_pass] = x
|
2011-08-24 18:47:35 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
parser.on("--nexpose-pass-file PATH") do |x|
|
2013-09-30 18:47:53 +00:00
|
|
|
opts[:nexpose_pass_file] = x
|
2011-08-24 18:47:35 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
parser.on("--scan-template TEMPLATE (optional)") do |x|
|
2013-09-30 18:47:53 +00:00
|
|
|
opts[:scan_template] = x
|
2011-08-24 18:47:35 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
parser.on("--nexpose-port PORT (optional)") do |x|
|
2013-09-30 18:47:53 +00:00
|
|
|
opts[:nexpose_port] = x
|
2011-08-24 18:47:35 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
parser.on("--blacklist BLACKLIST (optional)") do |x|
|
2013-09-30 18:47:53 +00:00
|
|
|
opts[:blacklist] = x
|
2011-08-24 18:47:35 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
parser.on("--help") do
|
2013-09-30 18:47:53 +00:00
|
|
|
$stderr.puts parser
|
|
|
|
exit(1)
|
2011-08-24 18:47:35 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
parser.separator('')
|
|
|
|
parser.parse!(ARGV)
|
|
|
|
|
|
|
|
@rpc = Msf::RPC::Client.new(opts)
|
|
|
|
|
|
|
|
if not @rpc.token
|
2013-09-30 18:47:53 +00:00
|
|
|
$stderr.puts "Error: Invalid RPC server options specified"
|
|
|
|
$stderr.puts parser
|
|
|
|
exit(1)
|
2011-08-24 18:47:35 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# Get the password from the file
|
|
|
|
if opts[:nexpose_pass_file]
|
2013-09-30 18:47:53 +00:00
|
|
|
nexpose_pass = File.open(opts[:nexpose_pass_file],"r").read.chomp!
|
2011-08-24 18:47:35 +00:00
|
|
|
else
|
2013-09-30 18:47:53 +00:00
|
|
|
nexpose_pass = opts[:nexpose_pass] || usage(parser)
|
2011-08-24 18:47:35 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# Store the user's settings
|
|
|
|
project = opts[:project] || usage(parser),
|
|
|
|
targets = opts[:targets] || usage(parser),
|
|
|
|
blacklist = opts[:blacklist],
|
|
|
|
nexpose_host = opts[:nexpose_host] || usage(parser),
|
|
|
|
nexpose_port = opts[:nexpose_port] || "3780",
|
|
|
|
nexpose_user = opts[:nexpose_user] || "nxadmin"
|
|
|
|
scan_template = opts[:scan_template] || "pentest-audit"
|
|
|
|
|
|
|
|
# Get the default user
|
|
|
|
user = @rpc.call("pro.default_admin_user")['username']
|
|
|
|
|
|
|
|
options = {
|
2013-09-30 18:47:53 +00:00
|
|
|
'workspace' => project,
|
|
|
|
'username' => user,
|
|
|
|
'DS_WHITELIST_HOSTS' => targets,
|
|
|
|
'DS_NEXPOSE_HOST' => nexpose_host,
|
|
|
|
'DS_NEXPOSE_PORT' => nexpose_port,
|
|
|
|
'DS_NEXPOSE_USER' => nexpose_user,
|
|
|
|
'nexpose_pass' => nexpose_pass,
|
|
|
|
'DS_SCAN_TEMPLATE' => scan_template
|
2011-08-24 18:47:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
puts "DEBUG: Running task with #{options}"
|
|
|
|
|
|
|
|
# Create the task object with all options
|
|
|
|
task = @rpc.call("pro.start_exploit", options)
|
|
|
|
|
|
|
|
|
|
|
|
if not task['task_id']
|
2013-09-30 18:47:53 +00:00
|
|
|
$stderr.puts "[-] Error starting the task: #{task.inspect}"
|
|
|
|
exit(0)
|
2011-08-24 18:47:35 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
puts "[*] Creating Task ID #{task['task_id']}..."
|
|
|
|
while true
|
2013-09-30 18:47:53 +00:00
|
|
|
select(nil, nil, nil, 0.50)
|
2011-08-24 18:47:35 +00:00
|
|
|
|
2013-09-30 18:47:53 +00:00
|
|
|
stat = @rpc.call("pro.task_status", task['task_id'])
|
2011-08-24 18:47:35 +00:00
|
|
|
|
2013-09-30 18:47:53 +00:00
|
|
|
if stat['status'] == 'invalid'
|
|
|
|
$stderr.puts "[-] Error checking task status"
|
|
|
|
exit(0)
|
|
|
|
end
|
2011-08-24 18:47:35 +00:00
|
|
|
|
2013-09-30 18:47:53 +00:00
|
|
|
info = stat[ task['task_id'] ]
|
2011-08-24 18:47:35 +00:00
|
|
|
|
2013-09-30 18:47:53 +00:00
|
|
|
if not info
|
|
|
|
$stderr.puts "[-] Error finding the task"
|
|
|
|
exit(0)
|
|
|
|
end
|
2011-08-24 18:47:35 +00:00
|
|
|
|
2013-09-30 18:47:53 +00:00
|
|
|
if info['status'] == "error"
|
|
|
|
$stderr.puts "[-] Error generating report: #{info['error']}"
|
|
|
|
exit(0)
|
|
|
|
end
|
2011-08-24 18:47:35 +00:00
|
|
|
|
2013-09-30 18:47:53 +00:00
|
|
|
break if info['progress'] == 100
|
2011-08-24 18:47:35 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
$stdout.puts "[+] Task Complete!"
|