module PWN::Plugins::NexposeVulnScan
def self.authors
def self.authors st.pentest@0dayinc.com>
def self.delete_site_assets_older_than(opts = {})
def self.delete_site_assets_older_than(opts = {}) c_obj] site_name] .to_i .each do |site| d if site.name == site_name emoving the Following Assets from #{site.name} (site id: #{site_id}) Older than #{days} Days:") expose::Search::Field::SCAN_DATE, Nexpose::Search::Operator::EARLIER_THAN, days).each do |asset| id == site_id o("#{asset.id}|#{asset.ip}|#{asset.last_scan}") te_asset(asset.id) Site: #{site_name} Not Found. Please check the spelling and try again.") => e
def self.download_recurring_report(opts = {})
def self.download_recurring_report(opts = {}) c_obj] s[:report_names].to_s.scrub.split(',') erating #{report_names.count} Report(s): #{report_names.inspect}...") opts[:poll_interval].nil? 60 se opts[:poll_interval].to_i d = [] s_arr.count == report_names.count each do |report| ach do |requested_report| name = requested_report.to_s.strip.chomp.delete('"') report.name == this_report_name o("Generating Recurring Report: #{report.name} @ #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}..Current Report Status: #{report.status}") atus == 'Failed' nfo("Report Generation for #{report.name} failed...re-generating now...") ate report from pre-existing config. generate_report_via_existing_config(nsc_obj: nsc_obj, config_id: report.config_id) = {} :report_name] = report.name :report_status] = report.status :report_uri] = report.uri ush(report_hash) s_arr = report_arr.uniq.select { |this_report| this_report[:report_status] == 'Generated' } eport_names are available within nsc_obj.reports (thus making it worthwhile to loop vs saying report !found). otal Reports Generated So Far: #{report_status_arr.count}...") val # Sleep and check the status again... port_arr.inspect) port_status_arr.inspect) each do |report_hash| ion = File.extname(report_hash[:report_uri]) nDownloading #{report_hash[:report_name]}#{this_file_extention} from #{report_hash[:report_uri]}...") (report_hash[:report_uri], "#{report_hash[:report_name]}#{this_file_extention}") plete.') => e
def self.generate_report_via_existing_config(opts = {})
def self.generate_report_via_existing_config(opts = {}) c_obj] config_id].to_i nfig = Nexpose::ReportConfig.load(nsc_obj, config_id) nfig.generate(nsc_obj) => e
def self.help
def self.help }.login( equired host/ip of Nexpose Console (server)', uired username', ional password (will prompt if nil)' lic_methods ite_assets_arr = #{self}.list_all_individual_site_assets( ired nsc_obj returned from login method', quired Nexpose site name to update (case-sensitive)' }.update_site_assets( ired nsc_obj returned from login method', quired Nexpose site name to update (case-sensitive), red array of hashes containing called :ip => values being IP address (All IPs not included in the :assets parameter will be removed from Nexpose)' }.delete_site_assets_older_than( ired nsc_obj returned from login method', quired Nexpose site name to update (case-sensitive), d assets to remove older than number of days in this parameter' }.scan_site_by_name( ired nsc_obj returned from login method', quired Nexpose site name to scan (case-sensitive), 'optional poll interval to check the completion status of the scan (defaults to 60 seconds) _recurring_report( ired nsc_obj returned from login method', 'required array of report name/types to generate e.g. ['report.html', 'report.pdf', 'report.xml']', 'optional poll interval to check the completion status of report generation (defaults to 60 seconds) sc_obj: 'required nsc_obj returned from login method')
def self.list_all_individual_site_assets(opts = {})
def self.list_all_individual_site_assets(opts = {}) c_obj] site_name] .each do |site| d if site.name == site_name e_assets_arr = [] isting All Assets from #{site_name} (site id: #{site_id}):") expose::Search::Field::SITE_ID, Nexpose::Search::Operator::IN, site_id).each do |asset| "#{asset.id}|#{asset.ip}|#{asset.last_scan}") _site_assets_arr.push(asset.ip) Site: #{site_name} Not Found. Please check the spelling and try again.") e_assets_arr => e
def self.login(opts = {})
def self.login(opts = {}) :console_ip] sername].to_s [:password].nil? Plugins::AuthenticationHelper.mask_password :password].to_s :Connection.new(console_ip, username, password) Console.load(nsc_obj) eout = 21_600 obj) # This will change the global sesion timeout config in the console => e
def self.logout(opts = {})
def self.logout(opts = {}) c_obj] ::Console.load(nsc_obj) imeout = 600 # This is the default session timeout in the console obj) # This will change the global sesion timeout config in the console => e
def self.scan_site_by_name(opts = {})
def self.scan_site_by_name(opts = {}) c_obj] site_name].to_s opts[:poll_interval].nil? 60 se opts[:poll_interval].to_i d d kick off the scan .each do |site| .name == site_name e(site.id) can Started for #{site_name} @ #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}") d ck the status of the scan r("Site name: #{site_name} does not exist as a site in Nexpose. Please check your spelling and try again.") if site_id == '' o: Checking status for an interval of #{poll_interval} seconds until completion.") l ivity.each { |scan| scan_status = scan.status if scan.site_id == site_id } = 'running' eing progress is good :) erval # Sleep and check the status again... "Scan Completed for #{site_name} @ #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}") => e
def self.update_site_assets(opts = {})
def self.update_site_assets(opts = {}) c_obj] site_name] ets] .each do |site| .name == site_name d expose::Site.load(nsc_obj, site_id) List of Assets for Given Site & Remove Old List of Assets from Given Site (if applicable) emoving the Following Assets:') ets = nsc_obj.filter(Nexpose::Search::Field::SITE_ID, Nexpose::Search::Operator::IN, site_id) = [] p_host_hash| new_site_assets.push(ip_host_hash[:ip].to_s.scrub.strip.chomp) } ets.each do |current_site_asset| te_assets.include?(current_site_asset.ip) "Removing #{current_site_asset.ip}") .remove_included_asset(current_asset) # This should work and be less invasive but no worky :( _asset(current_site_asset.id) # So we completely remove the asset from Nexpose altogether :/ omplete.') f Assets to Given Site dding the Following Assets to #{site.name} (site id: #{site_id}):") ip_host_hash| PAddr.new(ip_host_hash[:ip].to_s.scrub.strip.chomp) _ip.to_s.match?('255') # || current_ip =~ /^[224-239]/ # Multicast? to reverse DNS word to see if an IP s available as well o("Adding #{current_ip}") .include_asset(current_ip) rror e(nsc_obj) omplete.') => e