Incorporating mboman's save credentials

I don't think the use of the constant is a show stopper since it is
identical to the existing Nessus plugin scheme as well. It doesn't make
it right but it's not a reason to block. Both should be fixed some time.

Made a handful of minor edits regarding file handle management, and also
noted that the act of saving nexpose credentials will always cause the
SSL nag screen to not display.

Thanks for the implementation, mboman!

[Closes #57] [Fixes #6156]

Squashed commit of the following:

commit 8d421ab8e3004bcb67e156b45f1355a608e0320c
Author: Tod Beardsley <todb@metasploit.com>
Date:   Fri Dec 23 15:55:35 2011 -0600

    Adds a comment note about bypassing the SSL verify warning

commit fd956b380f14bbb394f36b0a3c565906f9aed869
Author: Tod Beardsley <todb@metasploit.com>
Date:   Fri Dec 23 15:53:29 2011 -0600

    Changing file write mode from w+ to wb.

commit d884c87482b033b7200d5045ba5f9b2d910f4aa8
Author: Tod Beardsley <todb@metasploit.com>
Date:   Fri Dec 23 15:15:46 2011 -0600

    ::File instead of File throughout

commit 6d72f87e8f175f088ac7beeb80742d50ab01b38a
Author: Tod Beardsley <todb@metasploit.com>
Date:   Fri Dec 23 15:14:54 2011 -0600

    Space change

commit f6f3527595379ba11b3be4341a0c620b06340fbb
Merge: a978d19 2335614
Author: Tod Beardsley <todb@metasploit.com>
Date:   Fri Dec 23 15:13:12 2011 -0600

    Merge branch 'master' of github_r7:rapid7/metasploit-framework into mboman_nexpose

commit a978d1962f756f507fdabb988380a7ecf3ce76bb
Author: Tod Beardsley <todb@metasploit.com>
Date:   Fri Dec 23 15:12:51 2011 -0600

    Minor fixups mostly around ::File handling.

commit bddd0249b9
Merge: 2ddc161 bb2ea62
Author: Michael Boman <michael@michaelboman.org>
Date:   Fri Dec 16 08:39:10 2011 +0100

    Merge branch 'master' of git://github.com/rapid7/metasploit-framework into nexpose

commit 2ddc161671
Author: Michael Boman <michael@michaelboman.org>
Date:   Wed Dec 14 11:44:29 2011 +0100

    msftidy cleanup (whitespace after EOL)

commit b202c7ff3a
Author: Michael Boman <michael@michaelboman.org>
Date:   Wed Dec 14 11:28:13 2011 +0100

    Removed a ncusage call

commit 45da9728d1
Author: Michael Boman <michael@michaelboman.org>
Date:   Wed Dec 14 09:19:58 2011 +0100

    Fixed indenting, removed ncusage function until later...

commit e9f03aafba
Merge: 41d3fae 8dc85f1
Author: Michael Boman <michael@michaelboman.org>
Date:   Wed Dec 14 07:35:17 2011 +0100

    Merge branch 'master' of git://github.com/rapid7/metasploit-framework into nexpose

commit 41d3fae61b
Merge: 63b6f38 d87d8d5
Author: Michael Boman <michael@michaelboman.org>
Date:   Tue Dec 13 20:07:34 2011 +0100

    Merge branch 'master' of git://github.com/rapid7/metasploit-framework into nexpose

commit 63b6f3873d
Merge: b3b7be4 cfa128a
Author: Michael Boman <michael@michaelboman.org>
Date:   Tue Dec 13 17:01:06 2011 +0100

    Merge branch 'master' of git://github.com/rapid7/metasploit-framework into nexpose

commit b3b7be4594
Author: Michael Boman <michael@michaelboman.org>
Date:   Tue Dec 13 16:54:54 2011 +0100

    Nexpose plugin can now save/load credentials
This commit is contained in:
Michael Boman 2011-12-23 16:12:34 -06:00 committed by Tod Beardsley
parent 23356141fb
commit 1102d56a27
1 changed files with 66 additions and 24 deletions

View File

@ -10,6 +10,8 @@
require 'rapid7/nexpose'
module Msf
Nexpose_yaml = "#{Msf::Config.get_config_root}/nexpose.yaml" #location of the nexpose.yml containing saved nexpose creds
class Plugin::Nexpose < Msf::Plugin
class NexposeCommandDispatcher
include Msf::Ui::Console::CommandDispatcher
@ -21,6 +23,7 @@ class Plugin::Nexpose < Msf::Plugin
def commands
{
'nexpose_connect' => "Connect to a running Nexpose instance ( user:pass@host[:port] )",
'nexpose_save' => "Save credentials to a Nexpose instance",
'nexpose_activity' => "Display any active scan jobs on the Nexpose instance",
'nexpose_scan' => "Launch a Nexpose scan against a specific IP range and import the results",
@ -62,9 +65,48 @@ class Plugin::Nexpose < Msf::Plugin
true
end
def cmd_nexpose_save(*args)
#if we are logged in, save session details to nexpose.yaml
if args[0] == "-h"
print_status("Usage: ")
print_status(" nexpose_save")
return
end
if args[0]
print_status("Usage: ")
print_status(" nexpose_save")
return
end
group = "default"
if ((@user and @user.length > 0) and (@host and @host.length > 0) and (@port and @port.length > 0 and @port.to_i > 0) and (@pass and @pass.length > 0))
config = {"#{group}" => {'username' => @user, 'password' => @pass, 'server' => @host, 'port' => @port}}
::File.open("#{Nexpose_yaml}", "wb") { |f| f.puts YAML.dump(config) }
print_good("#{Nexpose_yaml} created.")
else
print_error("Missing username/password/server/port - relogin and then try again.")
return
end
end
def cmd_nexpose_connect(*args)
return if not nexpose_verify_db
if ! args[0]
if ::File.readable?("#{Nexpose_yaml}")
lconfig = YAML.load_file("#{Nexpose_yaml}")
@user = lconfig['default']['username']
@pass = lconfig['default']['password']
@host = lconfig['default']['server']
@port = lconfig['default']['port']
@sslv = "ok" # TODO: Not super-thrilled about bypassing the SSL warning...
nexpose_login
return
end
end
if(args.length == 0 or args[0].empty? or args[0] == "-h")
print_status("Usage: ")
print_status(" nexpose_connect username:password@host[:port] <ssl-confirm>")
@ -73,18 +115,18 @@ class Plugin::Nexpose < Msf::Plugin
return
end
user = pass = host = port = sslv = nil
@user = @pass = @host = @port = @sslv = nil
case args.length
when 1,2
cred,targ = args[0].split('@', 2)
user,pass = cred.split(':', 2)
@user,@pass = cred.split(':', 2)
targ ||= '127.0.0.1:3780'
host,port = targ.split(':', 2)
@host,@port = targ.split(':', 2)
port ||= '3780'
sslv = args[1]
@sslv = args[1]
when 4,5
user,pass,host,port,sslv = args
@user,@pass,@host,@port,@sslv = args
else
print_status("Usage: ")
print_status(" nexpose_connect username:password@host[:port] <ssl-confirm>")
@ -92,9 +134,12 @@ class Plugin::Nexpose < Msf::Plugin
print_status(" nexpose_connect username password host port <ssl-confirm>")
return
end
nexpose_login
end
def nexpose_login
if ! ((user and user.length > 0) and (host and host.length > 0) and (port and port.length > 0 and port.to_i > 0) and (pass and pass.length > 0))
if ! ((@user and @user.length > 0) and (@host and @host.length > 0) and (@port and @port.length > 0 and @port.to_i > 0) and (@pass and @pass.length > 0))
print_status("Usage: ")
print_status(" nexpose_connect username:password@host[:port] <ssl-confirm>")
print_status(" -OR- ")
@ -102,7 +147,7 @@ class Plugin::Nexpose < Msf::Plugin
return
end
if(host != "localhost" and host != "127.0.0.1" and sslv != "ok")
if(@host != "localhost" and @host != "127.0.0.1" and @sslv != "ok")
print_error("Warning: SSL connections are not verified in this release, it is possible for an attacker")
print_error(" with the ability to man-in-the-middle the Nexpose traffic to capture the Nexpose")
print_error(" credentials. If you are running this on a trusted network, please pass in 'ok'")
@ -119,8 +164,8 @@ class Plugin::Nexpose < Msf::Plugin
end
begin
print_status("Connecting to Nexpose instance at #{host}:#{port} with username #{user}...")
nsc = ::Nexpose::Connection.new(host, user, pass, port)
print_status("Connecting to Nexpose instance at #{@host}:#{@port} with username #{@user}...")
nsc = ::Nexpose::Connection.new(@host, @user, @pass, @port)
nsc.login
rescue ::Nexpose::APIError => e
print_error("Connection failed: #{e.reason}")
@ -380,16 +425,16 @@ class Plugin::Nexpose < Msf::Plugin
possible_files = opt_ranges # don't allow DOS by circular reference
possible_files.each do |file|
if ::File.exist? file
if ::File.readable? file
print_status "Parsing ranges from #{file}"
range_list = ::File.open(file,"r").read.split("\n")
range_list.each{ |subrange| opt_ranges << subrange}
range_list = ::File.open(file,"rb") {|f| f.read f.stat.size}
range_list.each_line { |subrange| opt_ranges << subrange}
opt_ranges.delete(file)
end
end
opt_ranges = opt_ranges.join(' ')
if(opt_ranges.strip.empty?)
print_line("Usage: nexpose_scan [options] <Target IP Ranges>")
print_line(opts.usage)
@ -515,11 +560,9 @@ class Plugin::Nexpose < Msf::Plugin
if(opt_savexml)
::FileUtils.mkdir_p(opt_savexml)
path = File.join(opt_savexml, "nexpose-#{msfid}-#{count}.xml")
path = ::File.join(opt_savexml, "nexpose-#{msfid}-#{count}.xml")
print_status(" >> Saving scan data into #{path}") if opt_verbose
::File.open(path, "wb") do |fd|
fd.write(data)
end
::File.open(path, "wb") { |fd| fd.write(data) }
end
process_nexpose_data(report_format, data)
@ -555,12 +598,12 @@ class Plugin::Nexpose < Msf::Plugin
#
def nexpose_vuln_lookup(doc, vid, refs, host, serv=nil)
doc.elements.each("/NexposeReport/VulnerabilityDefinitions/vulnerability[@id = '#{vid}']]") do |vulndef|
title = vulndef.attributes['title']
pciSeverity = vulndef.attributes['pciSeverity']
cvss_score = vulndef.attributes['cvssScore']
cvss_vector = vulndef.attributes['cvssVector']
vulndef.elements['references'].elements.each('reference') do |ref|
if ref.attributes['source'] == 'BID'
refs[ 'BID-' + ref.text ] = true
@ -571,20 +614,20 @@ class Plugin::Nexpose < Msf::Plugin
refs[ 'MSB-MS-' + ref.text ] = true
end
end
refs[ 'NEXPOSE-' + vid.downcase ] = true
vuln = framework.db.find_or_create_vuln(
:host => host,
:service => serv,
:name => 'NEXPOSE-' + vid.downcase,
:data => title)
rids = []
refs.keys.each do |r|
rids << framework.db.find_or_create_ref(:name => r)
end
vuln.refs << (rids - vuln.refs)
end
end
@ -625,4 +668,3 @@ class Plugin::Nexpose < Msf::Plugin
end
end
end