Permalink
Browse files

Merge branch 'redesign'

  • Loading branch information...
2 parents ce1dc95 + 82ef7fc commit 66cdf9ceae48e31265d78b4901b78de1fd568f94 @mdaines-r7 mdaines-r7 committed Aug 31, 2012
Showing with 1,487 additions and 1,113 deletions.
  1. +2 −0 README.markdown
  2. +78 −44 examples/nexpose_report.rb
  3. +1 −0 lib/nexpose.rb
  4. +138 −0 lib/nexpose/common.rb
  5. +108 −97 lib/nexpose/connection.rb
  6. +16 −3 lib/nexpose/creds.rb
  7. +585 −394 lib/nexpose/report.rb
  8. +0 −15 lib/nexpose/scan.rb
  9. +18 −37 lib/nexpose/scan_engine.rb
  10. +30 −2 lib/nexpose/site.rb
  11. +508 −518 lib/nexpose/vuln.rb
  12. +3 −3 nexpose.gemspec
View
@@ -3,5 +3,7 @@
This is the official gem package for the Ruby Nexpose API included in the Metasploit Framework. This version is based on SVN revision 12430.
The upstream for this gem can be found at https://metasploit.com/svn/framework3/trunk/lib/rapid7
+For assistance with using the gem, to share your scripts, or to discuss different approaches, please visit the Rapid7 forums for Nexpose: https://community.rapid7.com/community/nexpose
+
# Credits
Rapid7 LLC
View
@@ -1,57 +1,91 @@
#!/usr/bin/env ruby
-
-require 'rubygems'
require 'nexpose'
+include Nexpose
+
+nsc = Connection.new('127.0.0.1', 'user', 'pass')
+nsc.login
+
+# Get details of last report run.
+last = nsc.last_report(15)
+puts "Report ID 15 last run on #{last.generated_on} with a status of #{last.status}."
+
+# Get the configuration of an existing template
+template = nsc.get_report_template('audit-report')
+ # or ...
+template = ReportTemplate.get(nsc, 'audit-report')
+
+# Create a new template based upon an existing one.
+template.name = "#{template.name} Copy"
+template.id = -1
+template.built_in = false
+template.show_device_names = true
+id = template.save(nsc)
+puts "New template saved with ID: #{id}"
+
+# Load existing report configuration.
+config = nsc.get_report_config(15)
+ # or ...
+config = ReportConfig.get(nsc, 15)
+
+# Try to generate a new report from the existing configuration.
+summary = config.generate(nsc)
+ # or ...
+summary = nsc.generate_report(15)
+unless summary.status == 'Started'
+ puts "Report ID 15 finished on #{summary.generated_on} with a status of #{summary.status}."
+else
+ puts 'Report ID 15 started.'
+end
+# Generate a new report and wait for it to finish.
+summary = config.generate(nsc, true)
+puts "Report ID 15 finished on #{summary.generated_on} with a status of #{summary.status}."
-host = '127.0.0.1'
-port = 3780
-user = "user"
-pass = "pass"
-
-@nsc = Nexpose::Connection.new(host, user, pass, port)
-
-@nsc.login
+# Copy that configuration for a new report.
+config.id = -1
+config.name = "#{config.name} Copy"
-sites = @nsc.site_listing
+# Save but do not generate a new report.
+id = config.save(nsc, false)
+puts "Saved report with report ID #{id}."
-sites.each do |site|
- p site[:site_id].to_s + ". " + site[:name]
+# Delete failed reports from the report history.
+bad_reports = nsc.report_history(15).select do |summary|
+ summary.status == 'Failed'
+ || summary.status == 'Aborted'
+ || summary.status == 'Unknown'
end
-
-#must be the ID of the site, the int printed from above.
-site = gets
-
-templates = @nsc.report_template_listing
-
-templates.each do |template|
- p template[:template_id]
+bad_reports.each do |report|
+ report.delete(nsc)
end
-p "Creating report config"
-report = Nexpose::ReportConfig.new(@nsc)
-report.set_name("Test" + Time.now.to_i.to_s)
-report.set_template_id("audit-report")
-report.addFilter("site", site.to_i)
-report.set_format("raw-xml")
-
-#report = Nexpose::ReportAdHoc.new(@nsc, 'audit-report', 'raw-xml')
-#report.addFilter('site', site.to_i)
-#p report.generate.to_s
-
-#gets
+# Get a listing of all PCI-related report templates
+pci_templates = nsc.report_template_listing.select { |tmp| tmp.name =~ /PCI/ }
+pci_templates.each { |tmp| puts tmp.id }
-p "Saving report"
-report.saveReport()
-
-url = nil
-while not url
- url = @nsc.report_last(report.config_id)
- select(nil, nil, nil, 10)
+# Get a listing of all reports IDs successfully generated since 13 Aug 2012.
+reports = nsc.report_listing.select do |report|
+ report.status == 'Generated' && report.generated_on > '20120813T000000000'
+end
+reports.each { |report| puts report.config_id }
+
+# Create a new report from scratch and download
+report = ReportConfig.new('CSV Export', 'basic-vulnerability-check-results', 'csv')
+report.filters << Filter.new('site', 31)
+id = report.save(nsc, true)
+puts "Report saved with ID #{id}"
+until nsc.last_report(id)
+ puts 'waiting . . .'
end
-p url
-#gets
-data = @nsc.download(url)
+last = nsc.last_report(id)
+data = nsc.download(last.uri)
+puts data.inspect
+
+# Generate an Adhoc report.
+adhoc = AdhocReportConfig.new('audit-report', 'pdf', 31)
+data = adhoc.generate(nsc)
+File.open('site-31-audit.pdf', 'w') { |file| file.write(data) }
-p data.inspect
+# Logout your Nexpose connection.
+nsc.logout
View
@@ -69,6 +69,7 @@
require 'nexpose/creds'
require 'nexpose/connection'
require 'nexpose/role'
+require 'nexpose/common'
module Nexpose
View
@@ -0,0 +1,138 @@
+module Nexpose
+
+ # Configuration structure for e-mail notification.
+ #
+ # The send_as and send_to_acl_as attributes are optional, but one of them is
+ # required for sending reports via e-mail. The send_as attribute is required
+ # for sending e-mails to users who are not on the report access list.
+ # The send_to_acl attribute is required for sending e-mails to report access
+ # list members.
+ #
+ # E-mails and attachments are sent via the Internet in clear text and are not
+ # encrypted. If you do not set a valid value for either attribute,
+ # the application will save the report but not send it via e-mail.
+ # If you set a valid value for the send_as attribute but not for the
+ # send_to_acl_as attribute, the application will send the report via e-mail to
+ # non-access-list members only. If you set a valid value for the
+ # send_to_acl_as attribute, the application will send the report via e-mail to
+ # access-list members only. If you set a valid value for both attributes,
+ # the application will send reports via e-mail to access-list members and
+ # non-members.
+ class Email
+ # Send as file attachment or zipped file to individuals who are not members
+ # of the report access list. One of: file|zip
+ attr_accessor :send_as
+ # Send to all the authorized users of sites, groups, and devices.
+ attr_accessor :to_all_authorized
+ # Send to users on the report access list.
+ attr_accessor :send_to_acl_as
+ # Format to send to users on the report access list. One of: file|zip|url
+ attr_accessor :send_to_owner_as
+
+ # Sender that e-mail will be attributed to.
+ attr_accessor :sender
+ # SMTP relay server.
+ attr_accessor :smtp_relay_server
+ # Array of report recipients (i.e., not already on the report access list).
+ attr_accessor :recipients
+
+ def initialize(to_all_authorized, send_to_owner_as, send_to_acl_as, send_as)
+ @to_all_authorized = to_all_authorized
+ @send_to_owner_as = send_to_owner_as
+ @send_to_acl_as = send_to_acl_as
+ @send_as = send_as
+
+ @recipients = []
+ end
+
+ def to_xml
+ xml = '<Email'
+ xml << %Q{ toAllAuthorized='#{@toAllAuthorized ? 1 : 0}'}
+ xml << %Q{ sendToOwnerAs='#{@send_to_owner_as}'} if @send_to_owner_as
+ xml << %Q{ sendToAclAs='#{@send_to_acl_as}'} if @send_to_acl_as
+ xml << %Q{ sendAs='#{@send_as}'} if @send_as
+ xml << '>'
+ xml << %Q{<Sender>#{@sender}</Sender>} if @sender
+ xml << %Q{<SmtpRelayServer>#{@smtp_relay_server}</SmtpRelayServer>} if @smtp_relay_server
+ if @recipients
+ xml << '<Recipients>'
+ @recipients.each do |recipient|
+ xml << %Q{<Recipient>#{recipient}</Recipient>}
+ end
+ xml << '</Recipients>'
+ end
+ xml << '</Email>'
+ end
+
+ def self.parse(xml)
+ xml.elements.each('//Email') do |email|
+ config = Email.new(email.attributes['toAllAuthorized'] == '1',
+ email.attributes['sendToOwnerAs'],
+ email.attributes['sendToAclAs'],
+ email.attributes['sendAs'])
+
+ xml.elements.each('//Sender') do |sender|
+ config.sender = sender.text
+ end
+ xml.elements.each('//SmtpRelayServer') do |server|
+ config.smtp_relay_server = server.text
+ end
+ xml.elements.each('//Recipient') do |recipient|
+ config.recipients << recipient.text
+ end
+ return config
+ end
+ nil
+ end
+ end
+
+ # Configuration structure for schedules.
+ class Schedule
+ # Whether or not this schedule is enabled.
+ attr_accessor :enabled
+ # Valid schedule types: daily, hourly, monthly-date, monthly-day, weekly.
+ attr_accessor :type
+ # The repeat interval based upon type.
+ attr_accessor :interval
+ # The earliest date to generate the report on (in ISO 8601 format).
+ attr_accessor :start
+
+ # The amount of time, in minutes, to allow execution before stopping.
+ attr_accessor :max_duration
+ # The date after which the schedule is disabled, in ISO 8601 format.
+ attr_accessor :not_valid_after
+
+ # --
+ # TODO These are not captured or put to XML.
+ # ++
+ attr_accessor :incremental
+ attr_accessor :repeater_type
+
+ def initialize(type, interval, start, enabled = true)
+ @type = type
+ @interval = interval
+ @start = start
+ @enabled = enabled
+ end
+
+ def to_xml
+ xml = %Q{<Schedule enabled='#{@enabled ? 1 : 0}' type='#{@type}' interval='#{@interval}' start='#{@start}'}
+ xml << %Q{ maxDuration='#@max_duration'} if @max_duration
+ xml << %Q{ notValidAfter='#@not_valid_after'} if @not_valid_after
+ xml << '/>'
+ end
+
+ def self.parse(xml)
+ xml.elements.each('//Schedule') do |sched|
+ schedule = Schedule.new(sched.attributes['type'],
+ sched.attributes['interval'].to_i,
+ sched.attributes['start'],
+ sched.attributes['enabled'] || true)
+ # Optional parameters.
+ schedule.max_duration = sched.attributes['maxDuration'].to_i if sched.attributes['maxDuration']
+ schedule.not_valid_after = sched.attributes['notValidAfter'] if sched.attributes['notValidAfter']
+ return schedule
+ end
+ end
+ end
+end
Oops, something went wrong.

0 comments on commit 66cdf9c

Please sign in to comment.