Class: Nexpose::Connection
- Inherits:
-
Object
- Object
- Nexpose::Connection
- Includes:
- XMLUtils
- Defined in:
- lib/nexpose/filter.rb,
lib/nexpose/tag.rb,
lib/nexpose/pool.rb,
lib/nexpose/role.rb,
lib/nexpose/scan.rb,
lib/nexpose/silo.rb,
lib/nexpose/site.rb,
lib/nexpose/user.rb,
lib/nexpose/vuln.rb,
lib/nexpose/group.rb,
lib/nexpose/maint.rb,
lib/nexpose/device.rb,
lib/nexpose/engine.rb,
lib/nexpose/manage.rb,
lib/nexpose/report.rb,
lib/nexpose/ticket.rb,
lib/nexpose/external.rb,
lib/nexpose/vuln_def.rb,
lib/nexpose/discovery.rb,
lib/nexpose/connection.rb,
lib/nexpose/silo_profile.rb,
lib/nexpose/scan_template.rb,
lib/nexpose/vuln_exception.rb,
lib/nexpose/report_template.rb,
lib/nexpose/multi_tenant_user.rb,
lib/nexpose/shared_credential.rb
Overview
Object that represents a connection to a Nexpose Security Console.
Examples
# Create a new Nexpose::Connection on the default port
nsc = Connection.new('10.1.40.10', 'nxadmin', 'password')
# Create a new Nexpose::Connection from a URI or "URI" String
nsc = Connection.from_uri('https://10.1.40.10:3780', 'nxadmin', 'password')
# Create a new Nexpose::Connection with a specific port
nsc = Connection.new('10.1.40.10', 'nxadmin', 'password', 443)
# Create a new Nexpose::Connection with a silo identifier
nsc = Connection.new('10.1.40.10', 'nxadmin', 'password', 3780, 'default')
# Create a new Nexpose::Connection with a two-factor authentication (2FA) token
nsc = Connection.new('10.1.40.10', 'nxadmin', 'password', 3780, nil, '123456')
# Create a new Nexpose::Connection with an excplicitly trusted web certificate
trusted_cert = ::File.read('cert.pem')
nsc = Connection.new('10.1.40.10', 'nxadmin', 'password', 3780, nil, nil, trusted_cert)
# Login to NSC and Establish a Session ID
nsc.login
# Check Session ID
if nsc.session_id
puts 'Login Successful'
else
puts 'Login Failure'
end
# Logout
logout_success = nsc.logout
Instance Attribute Summary collapse
-
#host ⇒ Object
readonly
The hostname or IP Address of the NSC.
-
#open_timeout ⇒ Object
The optional HTTP open_timeout value For more information visit the link below: ruby-doc.org/stdlib/libdoc/net/http/rdoc/Net/HTTP.html#open_timeout-attribute-method.
-
#password ⇒ Object
readonly
The password used to login to the NSC.
-
#port ⇒ Object
readonly
The port of the NSC (default is 3780).
-
#request_xml ⇒ Object
readonly
The last XML request sent by this object, useful for debugging.
-
#response_xml ⇒ Object
readonly
The last XML response received by this object, useful for debugging.
-
#session_id ⇒ Object
readonly
Session ID of this connection.
-
#timeout ⇒ Object
The main HTTP read_timeout value For more information visit the link below: ruby-doc.org/stdlib/libdoc/net/http/rdoc/Net/HTTP.html#read_timeout-attribute-method.
-
#token ⇒ Object
readonly
The token used to login to the NSC.
-
#trust_store ⇒ Object
readonly
The trust store to validate connections against if any.
-
#url ⇒ Object
readonly
The URL for communication.
-
#username ⇒ Object
readonly
The username used to login to the NSC.
Class Method Summary collapse
-
.from_uri(uri, user, pass, silo_id = nil, token = nil, trust_cert = nil) ⇒ Object
A constructor to load a Connection object from a URI.
Instance Method Summary collapse
-
#_append_asset!(xml, asset) ⇒ Object
Utility method for appending a HostName or IPRange object into an XML object, in preparation for ad hoc scanning.
- #_maintenance_restart ⇒ Object
-
#_scan_ad_hoc(xml) ⇒ Scan
Utility method for executing prepared XML and extracting Scan launch information.
-
#_scan_ad_hoc_with_schedules(xml) ⇒ Object
Utility method for executing prepared XML for adhoc with schedules.
-
#activity ⇒ Array[ScanData]
Retrieve a list of current scan activities across all Scan Engines managed by Nexpose.
-
#all_vulns ⇒ Array[VulnerabilityDefinition]
Retrieve all vulnerability definitions currently in a Nexpose console.
-
#asset_group_tags(asset_group_id) ⇒ Array[TagSummary]
(also: #group_tags, #list_asset_group_tags)
Lists all the tags on an asset_group.
-
#asset_scan_history(asset_id) ⇒ Array[AssetScan]
Retrieve the scan history for an asset.
-
#asset_tags(asset_id) ⇒ Array[TagSummary]
(also: #list_asset_tags)
Lists all the tags on an asset.
-
#backup(platform_independent = false, description = nil) ⇒ Boolean
Create a backup of this security console’s data.
-
#completed_assets(scan_id) ⇒ Array[CompletedAsset]
Retrieve a list of assets which completed in a given scan.
-
#completed_scans(site_id) ⇒ CompletedScan
Retrieve a history of the completed scans for a given site.
-
#console_command(cmd_string) ⇒ Object
Execute an arbitrary console command that is supplied as text via the supplied parameter.
-
#db_maintenance(clean_up = false, compress = false, reindex = false) ⇒ Boolean
Initiate database maintenance tasks to improve database performance and consistency.
-
#delete_asset_group(id) ⇒ Boolean
(also: #delete_group)
Delete an asset group and all associated data.
- #delete_device(device_id) ⇒ Object (also: #delete_asset)
-
#delete_discovery_connection(id) ⇒ Object
Delete an existing connection to a target used for dynamic discovery of assets.
-
#delete_engine(engine_id, scope = 'silo') ⇒ Boolean
Removes a scan engine from the list of available engines.
-
#delete_report(report_id) ⇒ Object
Delete a previously generated report.
-
#delete_report_config(report_config_id) ⇒ Object
Delete a previously generated report definition.
-
#delete_report_template(template_id) ⇒ Object
Deletes an existing, custom report template.
-
#delete_scan(scan_id) ⇒ Object
Delete a scan and all its data from a console.
-
#delete_scan_template(id) ⇒ Object
Delete a scan template from the console.
- #delete_shared_credential(id) ⇒ Object (also: #delete_shared_cred)
-
#delete_silo(silo_id) ⇒ Object
Delete the specified silo.
-
#delete_silo_profile(silo_profile_id) ⇒ Object
Delete the specified silo profile.
-
#delete_silo_user(user_id) ⇒ Object
Delete the specified silo user.
-
#delete_site(site_id) ⇒ Object
Delete the specified site and all associated scan data.
-
#delete_tag(tag_id) ⇒ Object
Deletes a tag by ID.
-
#delete_ticket(ticket) ⇒ Boolean
Deletes a Nexpose ticket.
-
#delete_tickets(tickets) ⇒ Boolean
Deletes a Nexpose ticket.
-
#delete_user(user_id) ⇒ Boolean
Delete a user from the Nexpose console.
-
#delete_vuln_exception(id) ⇒ Boolean
Delete an existing vulnerability exception.
-
#download(url, file_name = nil) ⇒ Object
Download a specific URL, typically a report.
-
#engine_activity(engine_id) ⇒ Array[ScanSummary]
Provide a list of current scan activities for a specific Scan Engine.
-
#engine_versions ⇒ Object
Obtain the version information for each scan engine.
-
#execute(xml, version = '1.1', options = {}) ⇒ Object
Execute an API request.
-
#export_scan(scan_id, zip_file = nil) ⇒ Fixnum
Export the data associated with a single scan, and optionally store it in a zip-compressed file under the provided name.
-
#filter(field, operator, value = '') ⇒ Array[FilteredAsset]
Perform an asset filter search that will locate assets matching the provided conditions.
-
#find_device_by_address(address, site_id = nil) ⇒ Device
(also: #find_asset_by_address)
Find a Device by its address.
-
#find_vuln_check(search_term, partial_words = true, all_words = true) ⇒ Array[VulnCheck]
Search for Vulnerability Checks.
-
#find_vulns_by_cve(cve) ⇒ Array[VulnerabilityDefinition]
Search for any vulnerability definitions which refer to a given CVE.
-
#find_vulns_by_date(from, to = nil) ⇒ Array[VulnSynopsis]
Find vulnerabilities by date available in Nexpose.
-
#find_vulns_by_ref(source, id) ⇒ Array[VulnerabilityDefinition]
Search for any vulnerability definitions which refer to a given reference ID.
-
#find_vulns_by_title(title, all_words = true) ⇒ Array[VulnerabilityDefinition]
Search for any vulnerability definitions which refer to a given title.
-
#generate_report(report_id, wait = false) ⇒ Object
Generate a new report using the specified report definition.
-
#get_user_id(user_name) ⇒ Object
Retrieve the User ID based upon the user’s login name.
-
#group_assets(group_id) ⇒ Array[FilteredAsset]
Get a list of all assets currently associated with a group.
-
#import_assets(site_id, assets) ⇒ Array[ImportResult]
Import external assets into a Nexpose console.
-
#import_assets_from_json(site_id, json) ⇒ Array[ImportResult]
Import external assets into a Nexpose console.
-
#import_scan(site_id, zip_file) ⇒ Fixnum
Import scan data into a site.
-
#incomplete_assets(scan_id) ⇒ Array[IncompleteAsset]
Retrieve a list of assets which are incomplete in a given scan.
-
#initialize(ip, user, pass, port = 3780, silo_id = nil, token = nil, trust_cert = nil) ⇒ Connection
constructor
A constructor for Connection.
-
#last_report(report_config_id) ⇒ Object
Get details of the last report generated with the specified report id.
-
#last_scan(site_id) ⇒ ScanSummary
Retrieve the scan summary statistics for the latest completed scan on a site.
-
#list_asset_groups ⇒ Array[AssetGroupSummary]
(also: #groups, #asset_groups)
Retrieve an array of all asset groups the user is authorized to view or manage.
-
#list_backups ⇒ Array[Backup]
Retrieve a list of all backups currently stored on the Console.
-
#list_device_vulns(dev_id) ⇒ Array[VulnFinding]
(also: #list_asset_vulns, #asset_vulns, #device_vulns)
List the vulnerability findings for a given device ID.
-
#list_discovery_connections ⇒ Object
(also: #discovery_connections)
Retrieve information about all available connections for dynamic discovery of assets, including whether or not connections are active.
-
#list_engine_pools ⇒ Array[EnginePoolSummary]
(also: #engine_pools)
Retrieve a list of all Scan Engine Pools managed by the Security Console.
-
#list_engines ⇒ Array[EngineSummary]
(also: #engines)
Retrieve a list of all Scan Engines managed by the Security Console.
-
#list_report_templates ⇒ Array[ReportTemplateSummary]
(also: #report_templates)
Provide a list of all report templates the user can access on the Security Console.
-
#list_reports ⇒ Array[ReportConfigSummary]
(also: #reports)
Provide a listing of all report definitions the user can access on the Security Console.
-
#list_scan_templates ⇒ Array[ScanTemplateSummary]
(also: #scan_templates)
List the scan templates currently configured on the console.
- #list_shared_credentials ⇒ Object (also: #list_shared_creds, #shared_credentials, #shared_creds)
-
#list_silo_profiles ⇒ Array[SiloProfileSummary]
(also: #silo_profiles)
Retrieve a list of all silos the user is authorized to view or manage.
-
#list_silo_users ⇒ Array[MultiTenantUserSummary]
(also: #silo_users)
Retrieve a list of all users the user is authorized to view or manage.
-
#list_silos ⇒ Array[SiloSummary]
(also: #silos)
Retrieve a list of all silos the user is authorized to view or manage.
-
#list_site_devices(site_id = nil) ⇒ Array[Device]
(also: #devices, #list_devices, #assets, #list_assets)
Retrieve a list of all of the assets in a site.
-
#list_sites ⇒ Array[SiteSummary]
(also: #sites)
Retrieve a list of all sites the user is authorized to view or manage.
- #list_tickets ⇒ Object (also: #tickets)
-
#list_users ⇒ Array[UserSummary]
(also: #users)
Retrieve a list of all users configured on this console.
-
#list_vuln_categories ⇒ Array[String]
(also: #vuln_categories)
Retrieve a list of the different vulnerability check categories.
-
#list_vuln_exceptions(status = nil) ⇒ Array[VulnException]
(also: #vuln_exceptions)
Retrieve all active vulnerability exceptions.
-
#list_vulns(full = false) ⇒ Array[Vulnerability|VulnerabilitySummary]
(also: #vulns)
Retrieve summary details of all vulnerabilities.
-
#login ⇒ Object
Establish a new connection and Session ID.
-
#logout ⇒ Object
Logout of the current connection.
-
#past_scans(limit = nil) ⇒ Array[CompletedScan]
Get a history of past scans for this console, sorted by most recent first.
-
#pause_scan(scan_id) ⇒ Object
Pauses a scan.
-
#paused_scans(site_id = nil, limit = nil) ⇒ Array[ActiveScan]
Get paused scans.
-
#recall_vuln_exception(id) ⇒ Boolean
Recall a vulnerability exception.
-
#remove_assets_from_site(asset_ids, site_id) ⇒ Object
Remove (or delete) one or more assets from a site.
-
#remove_tag_from_asset(asset_id, tag_id) ⇒ Object
Removes a tag from an asset.
-
#remove_tag_from_asset_group(asset_group_id, tag_id) ⇒ Object
(also: #remove_tag_from_group)
Removes a tag from an asset_group.
-
#remove_tag_from_site(site_id, tag_id) ⇒ Object
Removes a tag from a site.
-
#report_history(report_config_id) ⇒ Object
Provide a history of all reports generated with the specified report definition.
-
#restart ⇒ Object
Restart the application.
-
#resubmit_vuln_exception(id, comment, reason = nil) ⇒ Boolean
Resubmit a vulnerability exception request with a new comment and reason after an exception has been rejected.
-
#resume_scan(scan_id) ⇒ Object
Resumes a scan.
-
#reverse_engine_connection(engine_id) ⇒ Boolean
Reverses the direction of a connection to an engine If the connection is currently initiated from the console this method will have the engine initiate the connection.
- #role_delete(role, scope = Scope::SILO) ⇒ Object (also: #delete_role)
-
#role_listing ⇒ Object
(also: #roles)
Returns a summary list of all roles.
-
#scan_activity ⇒ Array[ScanSummary]
Retrieve a list of current scan activities across all Scan Engines managed by Nexpose.
-
#scan_asset(site_id, asset) ⇒ Scan
Perform an ad hoc scan of a single asset of a site.
-
#scan_asset_with_schedule(site_id, asset, schedule) ⇒ Status
Perform an ad hoc scan of a single asset of a site at a specific time.
-
#scan_assets(site_id, assets) ⇒ Scan
Perform an ad hoc scan of a subset of assets for a site.
-
#scan_assets_with_schedule(site_id, assets, schedules) ⇒ Status
Perform an ad hoc scan of a subset of assets for a site by adding a specific runtime.
-
#scan_assets_with_template_and_engine(site_id, assets, scan_template, scan_engine) ⇒ Fixnum
Initiate an ad-hoc scan on a subset of site assets with a specific scan template and scan engine, which may differ from the site’s defined scan template and scan engine.
-
#scan_device(device) ⇒ Scan
Perform an ad hoc scan of a single device.
-
#scan_device_with_schedule(device, schedule) ⇒ Status
Perform an ad hoc scan of a single device at a specific time.
-
#scan_devices(devices) ⇒ Scan
Perform an ad hoc scan of a subset of devices for a site.
-
#scan_devices_with_schedule(devices, schedules) ⇒ Status
Perform an ad hoc scan of a subset of devices for a site.
-
#scan_ips(site_id, ip_addresses) ⇒ Scan
Perform an ad hoc scan of a subset of IP addresses for a site.
-
#scan_ips_with_schedule(site_id, ip_addresses, schedules) ⇒ Status
Perform an ad hoc scan of a subset of IP addresses for a site at a specific time.
-
#scan_site(site_id) ⇒ Scan
Initiate a site scan.
-
#scan_statistics(scan_id) ⇒ ScanSummary
Get scan statistics, including node and vulnerability breakdowns.
-
#scan_status(scan_id) ⇒ String
Retrieve the status of a scan.
-
#search(criteria) ⇒ Array[FilteredAsset]
Perform a search that will match the criteria provided.
-
#selected_criticality_tag(asset_id) ⇒ String
Returns the criticality value which takes precedent for an asset.
-
#send_log(uri = 'https://support.rapid7.com') ⇒ Object
Output diagnostic information into log files, zip the files, and encrypt the archive with a PGP public key that is provided as a parameter for the API call.
-
#site_scan_history(site_id) ⇒ Array[ScanSummary]
Retrieve a list of all previous scans of the site.
-
#site_tags(site_id) ⇒ Array[TagSummary]
(also: #list_site_tags)
Lists all the tags on a site.
-
#start_update ⇒ Object
Induce the application to retrieve required updates and restart if necessary.
-
#stop_scan(scan_id, wait_sec = 0) ⇒ Object
Stop a running or paused scan.
-
#system_information ⇒ Object
Obtain system data, such as total RAM, free RAM, total disk space, free disk space, CPU speed, number of CPU cores, and other vital information.
-
#tags ⇒ Array[TagSummary]
(also: #list_tags)
Lists all tags.
-
#update_engine(engine_id) ⇒ Boolean
Kicks off an update on a single engine.
-
#vuln_details(vuln_id) ⇒ VulnerabilityDetail
Retrieve details for a vulnerability.
-
#vuln_types ⇒ Array[String]
(also: #list_vuln_types)
Retrieve a list of the different vulnerability check types.
Methods included from XMLUtils
#make_xml, #parse_xml, success?
Constructor Details
#initialize(ip, user, pass, port = 3780, silo_id = nil, token = nil, trust_cert = nil) ⇒ Connection
A constructor for Connection
84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/nexpose/connection.rb', line 84 def initialize(ip, user, pass, port = 3780, silo_id = nil, token = nil, trust_cert = nil) @host = ip @username = user @password = pass @port = port @silo_id = silo_id @token = token @trust_store = create_trust_store(trust_cert) unless trust_cert.nil? @session_id = nil @url = "https://#{@host}:#{@port}/api/API_VERSION/xml" @timeout = 120 @open_timeout = 120 end |
Instance Attribute Details
#host ⇒ Object (readonly)
The hostname or IP Address of the NSC
43 44 45 |
# File 'lib/nexpose/connection.rb', line 43 def host @host end |
#open_timeout ⇒ Object
The optional HTTP open_timeout value For more information visit the link below: ruby-doc.org/stdlib/libdoc/net/http/rdoc/Net/HTTP.html#open_timeout-attribute-method
67 68 69 |
# File 'lib/nexpose/connection.rb', line 67 def open_timeout @open_timeout end |
#password ⇒ Object (readonly)
The password used to login to the NSC
49 50 51 |
# File 'lib/nexpose/connection.rb', line 49 def password @password end |
#port ⇒ Object (readonly)
The port of the NSC (default is 3780)
45 46 47 |
# File 'lib/nexpose/connection.rb', line 45 def port @port end |
#request_xml ⇒ Object (readonly)
The last XML request sent by this object, useful for debugging.
55 56 57 |
# File 'lib/nexpose/connection.rb', line 55 def request_xml @request_xml end |
#response_xml ⇒ Object (readonly)
The last XML response received by this object, useful for debugging.
57 58 59 |
# File 'lib/nexpose/connection.rb', line 57 def response_xml @response_xml end |
#session_id ⇒ Object (readonly)
Session ID of this connection
41 42 43 |
# File 'lib/nexpose/connection.rb', line 41 def session_id @session_id end |
#timeout ⇒ Object
The main HTTP read_timeout value For more information visit the link below: ruby-doc.org/stdlib/libdoc/net/http/rdoc/Net/HTTP.html#read_timeout-attribute-method
63 64 65 |
# File 'lib/nexpose/connection.rb', line 63 def timeout @timeout end |
#token ⇒ Object (readonly)
The token used to login to the NSC
53 54 55 |
# File 'lib/nexpose/connection.rb', line 53 def token @token end |
#trust_store ⇒ Object (readonly)
The trust store to validate connections against if any
59 60 61 |
# File 'lib/nexpose/connection.rb', line 59 def trust_store @trust_store end |
#url ⇒ Object (readonly)
The URL for communication
51 52 53 |
# File 'lib/nexpose/connection.rb', line 51 def url @url end |
#username ⇒ Object (readonly)
The username used to login to the NSC
47 48 49 |
# File 'lib/nexpose/connection.rb', line 47 def username @username end |
Class Method Details
.from_uri(uri, user, pass, silo_id = nil, token = nil, trust_cert = nil) ⇒ Object
A constructor to load a Connection object from a URI
70 71 72 73 |
# File 'lib/nexpose/connection.rb', line 70 def self.from_uri(uri, user, pass, silo_id = nil, token = nil, trust_cert = nil) uri = URI.parse(uri) new(uri.host, user, pass, uri.port, silo_id, token, trust_cert) end |
Instance Method Details
#_append_asset!(xml, asset) ⇒ Object
Utility method for appending a HostName or IPRange object into an XML object, in preparation for ad hoc scanning.
233 234 235 236 237 238 239 240 241 |
# File 'lib/nexpose/scan.rb', line 233 def _append_asset!(xml, asset) if asset.is_a? Nexpose::IPRange xml.add_element('range', 'from' => asset.from, 'to' => asset.to) else # Assume HostName host = REXML::Element.new('host') host.text = asset xml.add_element(host) end end |
#_maintenance_restart ⇒ Object
60 61 62 63 64 65 66 |
# File 'lib/nexpose/maint.rb', line 60 def _maintenance_restart parameters = { 'cancelAllTasks' => false, 'cmd' => 'restartServer', 'targetTask' => 'maintModeHandler' } xml = AJAX.form_post(self, '/admin/global/maintenance/maintCmd.txml', parameters) !!(xml =~ /succeded="true"/) end |
#_scan_ad_hoc(xml) ⇒ Scan
Utility method for executing prepared XML and extracting Scan launch information.
249 250 251 252 |
# File 'lib/nexpose/scan.rb', line 249 def _scan_ad_hoc(xml) r = execute(xml, '1.1', timeout: 60) Scan.parse(r.res) end |
#_scan_ad_hoc_with_schedules(xml) ⇒ Object
Utility method for executing prepared XML for adhoc with schedules
258 259 260 261 |
# File 'lib/nexpose/scan.rb', line 258 def _scan_ad_hoc_with_schedules(xml) r = execute(xml, '1.1', timeout: 60) r.success end |
#activity ⇒ Array[ScanData]
Retrieve a list of current scan activities across all Scan Engines managed by Nexpose. This method returns lighter weight objects than scan_activity.
318 319 320 321 322 323 324 325 326 327 |
# File 'lib/nexpose/scan.rb', line 318 def activity r = execute(make_xml('ScanActivityRequest')) res = [] if r.success r.res.elements.each('//ScanSummary') do |scan| res << ScanData.parse(scan) end end res end |
#all_vulns ⇒ Array[VulnerabilityDefinition]
Retrieve all vulnerability definitions currently in a Nexpose console.
Note, this can easily take 30 seconds to complete and will load over 55,000 vulnerability definitions.
10 11 12 13 14 15 |
# File 'lib/nexpose/vuln_def.rb', line 10 def all_vulns uri = '/api/2.0/vulnerability_definitions' resp = AJAX.get(self, uri, AJAX::CONTENT_TYPE::JSON, per_page: 2_147_483_647) json = JSON.parse(resp, symbolize_names: true) json[:resources].map { |e| VulnerabilityDefinition.new.object_from_hash(self, e) } end |
#asset_group_tags(asset_group_id) ⇒ Array[TagSummary] Also known as: ,
Lists all the tags on an asset_group
80 81 82 83 84 85 86 87 |
# File 'lib/nexpose/tag.rb', line 80 def (asset_group_id) tag_summary = [] asset_group_tag = JSON.parse(AJAX.get(self, "/api/2.0/asset_groups/#{asset_group_id}/tags", AJAX::CONTENT_TYPE::JSON, { per_page: 2_147_483_647 })) asset_group_tag['resources'].each do |json| tag_summary << TagSummary.parse(json) end tag_summary end |
#asset_scan_history(asset_id) ⇒ Array[AssetScan]
Retrieve the scan history for an asset. Note: This is not optimized for querying many assets.
140 141 142 143 144 145 146 147 |
# File 'lib/nexpose/device.rb', line 140 def asset_scan_history(asset_id) uri = "/data/assets/#{asset_id}/scans" AJAX.preserving_preference(self, 'asset-scan-history') do data = DataTable._get_json_table(self, uri, {}, 500, nil, true) data.each { |a| a['assetID'] = asset_id.to_s } data.map(&AssetScan.method(:parse_json)) end end |
#asset_tags(asset_id) ⇒ Array[TagSummary] Also known as:
Lists all the tags on an asset
32 33 34 35 36 37 38 39 |
# File 'lib/nexpose/tag.rb', line 32 def (asset_id) tag_summary = [] asset_tag = JSON.parse(AJAX.get(self, "/api/2.0/assets/#{asset_id}/tags", AJAX::CONTENT_TYPE::JSON, { per_page: 2_147_483_647 })) asset_tag['resources'].select { |r| r['asset_ids'].find { |i| i == asset_id } }.each do |json| tag_summary << TagSummary.parse(json) end tag_summary end |
#backup(platform_independent = false, description = nil) ⇒ Boolean
Create a backup of this security console’s data. A restart will be initiated in order to put the product into maintenance mode while the backup is made. It will then restart automatically.
24 25 26 27 28 29 30 31 32 33 |
# File 'lib/nexpose/maint.rb', line 24 def backup(platform_independent = false, description = nil) parameters = { 'backup_desc' => description, 'cmd' => 'backup', 'platform_independent' => platform_independent, 'targetTask' => 'backupRestore' } xml = AJAX.form_post(self, '/admin/global/maintenance/maintCmd.txml', parameters) if !!(xml =~ /succeded="true"/) _maintenance_restart end end |
#completed_assets(scan_id) ⇒ Array[CompletedAsset]
Retrieve a list of assets which completed in a given scan. If called during a scan, this method returns currently completed assets. A “completed” asset can be in one of three states: completed successfully, failed due to an error, or stopped by a user.
104 105 106 107 108 109 110 |
# File 'lib/nexpose/device.rb', line 104 def completed_assets(scan_id) uri = "/data/asset/scan/#{scan_id}/complete-assets" AJAX.preserving_preference(self, 'scan-complete-assets') do data = DataTable._get_json_table(self, uri, {}, 500, nil, false) data.map(&CompletedAsset.method(:parse_json)) end end |
#completed_scans(site_id) ⇒ CompletedScan
Retrieve a history of the completed scans for a given site.
70 71 72 73 74 |
# File 'lib/nexpose/site.rb', line 70 def completed_scans(site_id) table = { 'table-id' => 'site-completed-scans' } data = DataTable._get_json_table(self, "/data/scan/site/#{site_id}", table) data.map(&CompletedScan.method(:parse_json)) end |
#console_command(cmd_string) ⇒ Object
Execute an arbitrary console command that is supplied as text via the supplied parameter. Console commands are documented in the administrator’s guide. If you use a command that is not listed in the administrator’s guide, the application will return the XMLResponse.
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/nexpose/manage.rb', line 12 def console_command(cmd_string) xml = make_xml('ConsoleCommandRequest', {}) cmd = REXML::Element.new('Command') cmd.text = cmd_string xml << cmd r = execute(xml) if r.success r.res.elements.each('//Output') do |out| return out.text.to_s end else false end end |
#db_maintenance(clean_up = false, compress = false, reindex = false) ⇒ Boolean
Initiate database maintenance tasks to improve database performance and consistency. A restart will be initiated in order to put the product into maintenance mode while the tasks are run. It will then restart automatically.
47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/nexpose/maint.rb', line 47 def db_maintenance(clean_up = false, compress = false, reindex = false) return unless compress || clean_up || reindex parameters = { 'cmd' => 'startMaintenance', 'targetTask' => 'dbMaintenance' } parameters['cleanup'] = 1 if clean_up parameters['compress'] = 1 if compress parameters['reindex'] = 1 if reindex xml = AJAX.form_post(self, '/admin/global/maintenance/maintCmd.txml', parameters) if !!(xml =~ /succeded="true"/) _maintenance_restart end end |
#delete_asset_group(id) ⇒ Boolean Also known as: delete_group
Delete an asset group and all associated data.
12 13 14 15 |
# File 'lib/nexpose/group.rb', line 12 def delete_asset_group(id) r = execute(make_xml('AssetGroupDeleteRequest', {'group-id' => id})) r.success end |
#delete_device(device_id) ⇒ Object Also known as: delete_asset
127 128 129 130 |
# File 'lib/nexpose/device.rb', line 127 def delete_device(device_id) r = execute(make_xml('DeviceDeleteRequest', { 'device-id' => device_id })) r.success end |
#delete_discovery_connection(id) ⇒ Object
Delete an existing connection to a target used for dynamic discovery of assets.
23 24 25 26 27 |
# File 'lib/nexpose/discovery.rb', line 23 def delete_discovery_connection(id) xml = make_xml('DiscoveryConnectionDeleteRequest', { 'id' => id }) response = execute(xml, '1.2') response.success end |
#delete_engine(engine_id, scope = 'silo') ⇒ Boolean
Removes a scan engine from the list of available engines.
12 13 14 15 16 17 |
# File 'lib/nexpose/engine.rb', line 12 def delete_engine(engine_id, scope = 'silo') xml = make_xml('EngineDeleteRequest', {'engine-id' => engine_id, 'scope' => scope}) response = execute(xml, '1.2') response.success end |
#delete_report(report_id) ⇒ Object
Delete a previously generated report.
65 66 67 68 |
# File 'lib/nexpose/report.rb', line 65 def delete_report(report_id) xml = make_xml('ReportDeleteRequest', { 'report-id' => report_id }) execute(xml).success end |
#delete_report_config(report_config_id) ⇒ Object
Delete a previously generated report definition. Also deletes any reports generated from that configuration.
75 76 77 78 |
# File 'lib/nexpose/report.rb', line 75 def delete_report_config(report_config_id) xml = make_xml('ReportDeleteRequest', { 'reportcfg-id' => report_config_id }) execute(xml).success end |
#delete_report_template(template_id) ⇒ Object
Deletes an existing, custom report template. Cannot delete built-in templates.
29 30 31 |
# File 'lib/nexpose/report_template.rb', line 29 def delete_report_template(template_id) AJAX.delete(self, "/data/report/templates/#{URI.escape(template_id)}") end |
#delete_scan(scan_id) ⇒ Object
Delete a scan and all its data from a console. Warning, this method is destructive and not guaranteed to leave a site in a valid state. DBCC may need to be run to correct missing or empty assets.
479 480 481 |
# File 'lib/nexpose/scan.rb', line 479 def delete_scan(scan_id) AJAX.delete(self, "/data/scan/#{scan_id}") end |
#delete_scan_template(id) ⇒ Object
Delete a scan template from the console. Cannot be used to delete a built-in template.
21 22 23 |
# File 'lib/nexpose/scan_template.rb', line 21 def delete_scan_template(id) AJAX.delete(self, "/data/scan/templates/#{URI.encode(id)}") end |
#delete_shared_credential(id) ⇒ Object Also known as:
17 18 19 |
# File 'lib/nexpose/shared_credential.rb', line 17 def delete_shared_credential(id) AJAX.post(self, "/data/credential/shared/delete?credid=#{id}") end |
#delete_silo(silo_id) ⇒ Object
Delete the specified silo
27 28 29 30 |
# File 'lib/nexpose/silo.rb', line 27 def delete_silo(silo_id) r = execute(make_xml('SiloDeleteRequest', {'silo-id' => silo_id}), '1.2') r.success end |
#delete_silo_profile(silo_profile_id) ⇒ Object
Delete the specified silo profile
27 28 29 30 |
# File 'lib/nexpose/silo_profile.rb', line 27 def delete_silo_profile(silo_profile_id) r = execute(make_xml('SiloProfileDeleteRequest', {'silo-profile-id' => silo_profile_id}), '1.2') r.success end |
#delete_silo_user(user_id) ⇒ Object
Delete the specified silo user
26 27 28 29 |
# File 'lib/nexpose/multi_tenant_user.rb', line 26 def delete_silo_user(user_id) r = execute(make_xml('MultiTenantUserDeleteRequest', {'user-id' => user_id}), '1.2') r.success end |
#delete_site(site_id) ⇒ Object
Delete the specified site and all associated scan data.
31 32 33 34 |
# File 'lib/nexpose/site.rb', line 31 def delete_site(site_id) r = execute(make_xml('SiteDeleteRequest', { 'site-id' => site_id })) r.success end |
#delete_tag(tag_id) ⇒ Object
Deletes a tag by ID
23 24 25 |
# File 'lib/nexpose/tag.rb', line 23 def delete_tag(tag_id) AJAX.delete(self, "/api/2.0/tags/#{tag_id}") end |
#delete_ticket(ticket) ⇒ Boolean
Deletes a Nexpose ticket.
26 27 28 29 |
# File 'lib/nexpose/ticket.rb', line 26 def delete_ticket(ticket) # TODO: Take Ticket object, too, and pull out IDs. delete_tickets([ticket]) end |
#delete_tickets(tickets) ⇒ Boolean
Deletes a Nexpose ticket.
36 37 38 39 40 41 42 43 44 |
# File 'lib/nexpose/ticket.rb', line 36 def delete_tickets(tickets) # TODO: Take Ticket objects, too, and pull out IDs. xml = make_xml('TicketDeleteRequest') tickets.each do |id| xml.add_element('Ticket', { 'id' => id }) end (execute xml, '1.2').success end |
#delete_user(user_id) ⇒ Boolean
Delete a user from the Nexpose console.
36 37 38 39 |
# File 'lib/nexpose/user.rb', line 36 def delete_user(user_id) response = execute(make_xml('UserDeleteRequest', { 'id' => user_id })) response.success end |
#delete_vuln_exception(id) ⇒ Boolean
Delete an existing vulnerability exception.
112 113 114 115 116 |
# File 'lib/nexpose/vuln_exception.rb', line 112 def delete_vuln_exception(id) xml = make_xml('VulnerabilityExceptionDeleteRequest', { 'exception-id' => id }) execute(xml, '1.2').success end |
#download(url, file_name = nil) ⇒ Object
Download a specific URL, typically a report. Include an optional file_name parameter to write the output to a file.
Note: XML and HTML reports have charts not downloaded by this method.
Would need to do something more sophisticated to grab
all the associated image files.
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/nexpose/connection.rb', line 137 def download(url, file_name = nil) return nil if (url.nil? || url.empty?) uri = URI.parse(url) http = Net::HTTP.new(@host, @port) http.use_ssl = true if @trust_store.nil? http.verify_mode = OpenSSL::SSL::VERIFY_NONE # XXX: security issue else http.cert_store = @trust_store end headers = { 'Cookie' => "nexposeCCSessionID=#{@session_id}" } resp = http.get(uri.to_s, headers) if file_name ::File.open(file_name, 'wb') { |file| file.write(resp.body) } else resp.body end end |
#engine_activity(engine_id) ⇒ Array[ScanSummary]
Provide a list of current scan activities for a specific Scan Engine.
56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/nexpose/engine.rb', line 56 def engine_activity(engine_id) xml = make_xml('EngineActivityRequest', {'engine-id' => engine_id}) r = execute(xml) arr = [] if r.success r.res.elements.each('//ScanSummary') do |scan_event| arr << ScanSummary.parse(scan_event) end end arr end |
#engine_versions ⇒ Object
Obtain the version information for each scan engine. Includes Product, Content, and Java versions.
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/nexpose/manage.rb', line 49 def engine_versions info = console_command('version engines') versions = [] engines = info.sub('VERSION INFORMATION\n', '').split(/\n\n/) engines.each do |eng| engdata = {} eng.split(/\n/).each do |kv| key, value = kv.split(/:\s*/) key = key.sub('Local Engine ', '').sub('Remote Engine ', '') engdata[key] = value end versions << engdata end versions end |
#execute(xml, version = '1.1', options = {}) ⇒ Object
Execute an API request
121 122 123 124 125 126 127 128 129 |
# File 'lib/nexpose/connection.rb', line 121 def execute(xml, version = '1.1', = {}) .store(:timeout, @timeout) unless .key?(:timeout) .store(:open_timeout, @open_timeout) @request_xml = xml.to_s @api_version = version response = APIRequest.execute(@url, @request_xml, @api_version, , @trust_store) @response_xml = response.raw_response_data response end |
#export_scan(scan_id, zip_file = nil) ⇒ Fixnum
Export the data associated with a single scan, and optionally store it in a zip-compressed file under the provided name.
411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 |
# File 'lib/nexpose/scan.rb', line 411 def export_scan(scan_id, zip_file = nil) http = AJAX.https(self) headers = { 'Cookie' => "nexposeCCSessionID=#{@session_id}", 'Accept-Encoding' => 'identity' } resp = http.get("/data/scan/#{scan_id}/export", headers) case resp when Net::HTTPSuccess if zip_file ::File.open(zip_file, 'wb') { |file| file.write(resp.body) } else resp.body end when Net::HTTPForbidden raise Nexpose::PermissionError.new(resp) else raise Nexpose::APIError.new(resp, "#{resp.class}: Unrecognized response.") end end |
#filter(field, operator, value = '') ⇒ Array[FilteredAsset]
15 16 17 18 19 |
# File 'lib/nexpose/filter.rb', line 15 def filter(field, operator, value = '') criterion = Criterion.new(field, operator, value) criteria = Criteria.new(criterion) search(criteria) end |
#find_device_by_address(address, site_id = nil) ⇒ Device Also known as: find_asset_by_address
Find a Device by its address.
This is a convenience method for finding a single device from a SiteDeviceListing. If no site_id is provided, the first matching device will be returned when a device occurs across multiple sites.
17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/nexpose/device.rb', line 17 def find_device_by_address(address, site_id = nil) r = execute(make_xml('SiteDeviceListingRequest', { 'site-id' => site_id })) if r.success device = REXML::XPath.first(r.res, "SiteDeviceListingResponse/SiteDevices/device[@address='#{address}']") return Device.new(device.attributes['id'].to_i, device.attributes['address'], device.parent.attributes['site-id'], device.attributes['riskfactor'].to_f, device.attributes['riskscore'].to_f) if device end nil end |
#find_vuln_check(search_term, partial_words = true, all_words = true) ⇒ Array[VulnCheck]
Search for Vulnerability Checks.
76 77 78 79 80 81 82 |
# File 'lib/nexpose/vuln.rb', line 76 def find_vuln_check(search_term, partial_words = true, all_words = true) uri = "/data/vulnerability/vulnerabilities/dyntable.xml?tableID=VulnCheckSynopsis&phrase=#{URI.encode(search_term)}&allWords=#{all_words}" data = DataTable._get_dyn_table(self, uri) data.map do |vuln| XML::VulnCheck.new(vuln) end end |
#find_vulns_by_cve(cve) ⇒ Array[VulnerabilityDefinition]
Search for any vulnerability definitions which refer to a given CVE.
22 23 24 25 26 27 |
# File 'lib/nexpose/vuln_def.rb', line 22 def find_vulns_by_cve(cve) uri = '/api/2.0/vulnerability_definitions' resp = AJAX.get(self, uri, AJAX::CONTENT_TYPE::JSON, cve: cve) json = JSON.parse(resp, symbolize_names: true) json[:resources].map { |e| VulnerabilityDefinition.new.object_from_hash(self, e) } end |
#find_vulns_by_date(from, to = nil) ⇒ Array[VulnSynopsis]
Find vulnerabilities by date available in Nexpose. This is not the date the original vulnerability was published, but the date the check was made available in Nexpose.
93 94 95 96 97 |
# File 'lib/nexpose/vuln.rb', line 93 def find_vulns_by_date(from, to = nil) uri = "/data/vulnerability/synopsis/dyntable.xml?addedMin=#{from}" uri += "&addedMax=#{to}" if to DataTable._get_dyn_table(self, uri).map { |v| VulnSynopsis.new(v) } end |
#find_vulns_by_ref(source, id) ⇒ Array[VulnerabilityDefinition]
Search for any vulnerability definitions which refer to a given reference ID.
Examples:
find_vulns_by_ref('oval', 'OVAL10476')
find_vulns_by_ref('bid', 35067)
find_vulns_by_ref('secunia', 35188)
42 43 44 45 46 47 48 49 50 |
# File 'lib/nexpose/vuln_def.rb', line 42 def find_vulns_by_ref(source, id) uri = '/api/2.0/vulnerability_definitions' resp = AJAX.get(self, uri, AJAX::CONTENT_TYPE::JSON, source: source, id: id) json = JSON.parse(resp, symbolize_names: true) json[:resources].map { |e| VulnerabilityDefinition.new.object_from_hash(self, e) } end |
#find_vulns_by_title(title, all_words = true) ⇒ Array[VulnerabilityDefinition]
Search for any vulnerability definitions which refer to a given title.
Note: This method will return a maximum of 500 results. If the search yields a high number of results, consider add more specific words to the title.
64 65 66 67 68 69 70 |
# File 'lib/nexpose/vuln_def.rb', line 64 def find_vulns_by_title(title, all_words = true) uri = '/api/2.0/vulnerability_definitions' params = { title: title, all_words: all_words } resp = AJAX.get(self, uri, AJAX::CONTENT_TYPE::JSON, params) json = JSON.parse(resp, symbolize_names: true) json[:resources].map { |e| VulnerabilityDefinition.new.object_from_hash(self, e) } end |
#generate_report(report_id, wait = false) ⇒ Object
Generate a new report using the specified report definition.
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/nexpose/report.rb', line 25 def generate_report(report_id, wait = false) xml = make_xml('ReportGenerateRequest', { 'report-id' => report_id }) response = execute(xml) if response.success response.res.elements.each('//ReportSummary') do |summary| summary = ReportSummary.parse(summary) # If not waiting or the report is finished, return now. return summary unless wait && summary.status == 'Started' end end so_far = 0 while wait summary = last_report(report_id) return summary unless summary.status == 'Started' sleep 5 so_far += 5 if so_far % 60 == 0 puts "Still waiting. Current status: #{summary.status}" end end nil end |
#get_user_id(user_name) ⇒ Object
Retrieve the User ID based upon the user’s login name.
27 28 29 |
# File 'lib/nexpose/user.rb', line 27 def get_user_id(user_name) users.find { |user| user.name.eql? user_name } end |
#group_assets(group_id) ⇒ Array[FilteredAsset]
Get a list of all assets currently associated with a group.
70 71 72 73 74 75 76 |
# File 'lib/nexpose/device.rb', line 70 def group_assets(group_id) payload = { 'sort' => 'assetName', 'table-id' => 'group-assets', 'groupID' => group_id } results = DataTable._get_json_table(self, '/data/asset/group', payload) results.map { |a| FilteredAsset.new(a) } end |
#import_assets(site_id, assets) ⇒ Array[ImportResult]
Import external assets into a Nexpose console.
This method will synchronously import a collection of assets into the console. Each call to this method will be treated as a single event.
This method should only be used against “static” sites, i.e., those not tied to a dynamic population service like vSphere, AWS, etc.
If a paused scan exists on the site at the time of import, the newly imported assets will not be included in the scan when it resumes.
18 19 20 21 |
# File 'lib/nexpose/external.rb', line 18 def import_assets(site_id, assets) json = JSON.generate(Array(assets).map(&:to_h)) import_assets_from_json(site_id, json) end |
#import_assets_from_json(site_id, json) ⇒ Array[ImportResult]
Import external assets into a Nexpose console.
29 30 31 32 33 34 35 |
# File 'lib/nexpose/external.rb', line 29 def import_assets_from_json(site_id, json) uri = "/api/2.1/sites/#{site_id}/assets" # Wait up to 5 minutes for a response. resp = AJAX.post(self, uri, json, AJAX::CONTENT_TYPE::JSON, 300) arr = JSON.parse(resp, symbolize_names: true) arr.map { |e| External::ImportResult.new.object_from_hash(self, e) } end |
#import_scan(site_id, zip_file) ⇒ Fixnum
Import scan data into a site.
This method is designed to work with export_scan to migrate scan data from one console to another. This method will import the data as if run from a local scan engine.
Scan importing is restricted to only importing scans in chronological order. It assumes that it is the latest scan for a given site, and will abort if attempting to import an older scan.
445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 |
# File 'lib/nexpose/scan.rb', line 445 def import_scan(site_id, zip_file) data = Rexlite::MIME::Message.new data.add_part(site_id.to_s, nil, nil, 'form-data; name="siteid"') data.add_part(session_id, nil, nil, 'form-data; name="nexposeCCSessionID"') ::File.open(zip_file, 'rb') do |scan| data.add_part(scan.read, 'application/zip', 'binary', "form-data; name=\"scan\"; filename=\"#{zip_file}\"") end post = Net::HTTP::Post.new('/data/scan/import') post.body = data.to_s post.set_content_type('multipart/form-data', boundary: data.bound) # Avoiding AJAX#request, because the data can cause binary dump on error. http = AJAX.https(self) AJAX.headers(self, post) response = http.request(post) case response when Net::HTTPOK response.body.empty? ? response.body : response.body.to_i when Net::HTTPUnauthorized raise Nexpose::PermissionError.new(response) else raise Nexpose::APIError.new(post, response.body) end end |
#incomplete_assets(scan_id) ⇒ Array[IncompleteAsset]
Retrieve a list of assets which are incomplete in a given scan. If called during a scan, this method returns currently incomplete assets which may be in progress.
119 120 121 122 123 124 125 |
# File 'lib/nexpose/device.rb', line 119 def incomplete_assets(scan_id) uri = "/data/asset/scan/#{scan_id}/incomplete-assets" AJAX.preserving_preference(self, 'scan-incomplete-assets') do data = DataTable._get_json_table(self, uri, {}, 500, nil, false) data.map(&IncompleteAsset.method(:parse_json)) end end |
#last_report(report_config_id) ⇒ Object
Get details of the last report generated with the specified report id.
56 57 58 59 |
# File 'lib/nexpose/report.rb', line 56 def last_report(report_config_id) history = report_history(report_config_id) history.sort { |a, b| b.generated_on <=> a.generated_on }.first end |
#last_scan(site_id) ⇒ ScanSummary
Retrieve the scan summary statistics for the latest completed scan on a site.
Method will not return data on an active scan.
61 62 63 |
# File 'lib/nexpose/site.rb', line 61 def last_scan(site_id) site_scan_history(site_id).select(&:end_time).max_by(&:end_time) end |
#list_asset_groups ⇒ Array[AssetGroupSummary] Also known as: groups, asset_groups
Retrieve an array of all asset groups the user is authorized to view or manage.
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/nexpose/group.rb', line 24 def list_asset_groups r = execute(make_xml('AssetGroupListingRequest')) groups = [] if r.success r.res.elements.each('AssetGroupListingResponse/AssetGroupSummary') do |group| groups << AssetGroupSummary.new(group.attributes['id'].to_i, group.attributes['name'], group.attributes['description'], group.attributes['riskscore'].to_f, group.attributes['dynamic'].to_i == 1) end end groups end |
#list_backups ⇒ Array[Backup]
Retrieve a list of all backups currently stored on the Console.
9 10 11 12 |
# File 'lib/nexpose/maint.rb', line 9 def list_backups data = DataTable._get_dyn_table(self, '/data/admin/backups?tableID=BackupSynopsis') data.map { |b| Backup.parse(b) } end |
#list_device_vulns(dev_id) ⇒ Array[VulnFinding] Also known as: list_asset_vulns, asset_vulns, device_vulns
List the vulnerability findings for a given device ID.
83 84 85 86 87 88 89 90 |
# File 'lib/nexpose/device.rb', line 83 def list_device_vulns(dev_id) parameters = { 'devid' => dev_id, 'table-id' => 'vulnerability-listing' } json = DataTable._get_json_table(self, '/data/vulnerability/asset-vulnerabilities', parameters) json.map { |vuln| VulnFinding.new(vuln) } end |
#list_discovery_connections ⇒ Object Also known as: discovery_connections
Retrieve information about all available connections for dynamic discovery of assets, including whether or not connections are active.
8 9 10 11 12 13 14 15 16 |
# File 'lib/nexpose/discovery.rb', line 8 def list_discovery_connections xml = make_xml('DiscoveryConnectionListingRequest') response = execute(xml, '1.2') connections = [] response.res.elements.each('DiscoveryConnectionListingResponse/DiscoveryConnectionSummary') do |conn| connections << DiscoveryConnection.parse(conn) end connections end |
#list_engine_pools ⇒ Array[EnginePoolSummary] Also known as: engine_pools
Retrieve a list of all Scan Engine Pools managed by the Security Console.
11 12 13 14 15 16 17 18 19 20 21 22 |
# File 'lib/nexpose/pool.rb', line 11 def list_engine_pools response = execute(make_xml('EnginePoolListingRequest'), '1.2') arr = [] if response.success response.res.elements.each('EnginePoolListingResponse/EnginePoolSummary') do |pool| arr << EnginePoolSummary.new(pool.attributes['id'], pool.attributes['name'], pool.attributes['scope']) end end arr end |
#list_engines ⇒ Array[EngineSummary] Also known as: engines
Retrieve a list of all Scan Engines managed by the Security Console.
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/nexpose/engine.rb', line 73 def list_engines response = execute(make_xml('EngineListingRequest')) arr = [] if response.success response.res.elements.each('//EngineSummary') do |engine| arr << EngineSummary.new(engine.attributes['id'].to_i, engine.attributes['name'], engine.attributes['address'], engine.attributes['port'].to_i, engine.attributes['status'], engine.attributes['scope']) end end arr end |
#list_report_templates ⇒ Array[ReportTemplateSummary] Also known as: report_templates
Provide a list of all report templates the user can access on the Security Console.
11 12 13 14 15 16 17 18 19 20 |
# File 'lib/nexpose/report_template.rb', line 11 def list_report_templates r = execute(make_xml('ReportTemplateListingRequest', {})) templates = [] if r.success r.res.elements.each('//ReportTemplateSummary') do |template| templates << ReportTemplateSummary.parse(template) end end templates end |
#list_reports ⇒ Array[ReportConfigSummary] Also known as: reports
Provide a listing of all report definitions the user can access on the Security Console.
11 12 13 14 15 16 17 18 19 20 |
# File 'lib/nexpose/report.rb', line 11 def list_reports r = execute(make_xml('ReportListingRequest')) reports = [] if r.success r.res.elements.each('//ReportConfigSummary') do |report| reports << ReportConfigSummary.parse(report) end end reports end |
#list_scan_templates ⇒ Array[ScanTemplateSummary] Also known as: scan_templates
List the scan templates currently configured on the console.
9 10 11 12 |
# File 'lib/nexpose/scan_template.rb', line 9 def list_scan_templates templates = JSON.parse(AJAX.get(self, '/api/2.0/scan_templates')) templates['resources'].map { |t| ScanTemplateSummary.new(t) } end |
#list_shared_credentials ⇒ Object Also known as: , ,
5 6 7 8 9 10 11 |
# File 'lib/nexpose/shared_credential.rb', line 5 def list_shared_credentials creds = DataTable._get_json_table(self, '/data/credential/shared/listing', { 'sort' => -1, 'table-id' => 'credential-listing' }) creds.map { |c| SharedCredentialSummary.from_json(c) } end |
#list_silo_profiles ⇒ Array[SiloProfileSummary] Also known as: silo_profiles
Retrieve a list of all silos the user is authorized to view or manage.
10 11 12 13 14 15 16 17 18 19 |
# File 'lib/nexpose/silo_profile.rb', line 10 def list_silo_profiles r = execute(make_xml('SiloProfileListingRequest'), '1.2') arr = [] if r.success r.res.elements.each('SiloProfileListingResponse/SiloProfileSummaries/SiloProfileSummary') do |profile| arr << SiloProfileSummary.parse(profile) end end arr end |
#list_silo_users ⇒ Array[MultiTenantUserSummary] Also known as: silo_users
Retrieve a list of all users the user is authorized to view or manage.
10 11 12 13 14 15 16 17 18 19 |
# File 'lib/nexpose/multi_tenant_user.rb', line 10 def list_silo_users r = execute(make_xml('MultiTenantUserListingRequest'), '1.2') arr = [] if r.success r.res.elements.each('MultiTenantUserListingResponse/MultiTenantUserSummaries/MultiTenantUserSummary') do |user| arr << MultiTenantUserSummary.parse(user) end end arr end |
#list_silos ⇒ Array[SiloSummary] Also known as: silos
Retrieve a list of all silos the user is authorized to view or manage.
10 11 12 13 14 15 16 17 18 19 |
# File 'lib/nexpose/silo.rb', line 10 def list_silos r = execute(make_xml('SiloListingRequest'), '1.2') arr = [] if r.success r.res.elements.each('SiloListingResponse/SiloSummaries/SiloSummary') do |silo| arr << SiloSummary.parse(silo) end end arr end |
#list_site_devices(site_id = nil) ⇒ Array[Device] Also known as: devices, list_devices, assets, list_assets
Retrieve a list of all of the assets in a site.
If no site-id is specified, then return all of the assets for the Nexpose console, grouped by site-id.
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/nexpose/device.rb', line 41 def list_site_devices(site_id = nil) r = execute(make_xml('SiteDeviceListingRequest', { 'site-id' => site_id })) devices = [] if r.success r.res.elements.each('SiteDeviceListingResponse/SiteDevices') do |site| site_id = site.attributes['site-id'].to_i site.elements.each('device') do |device| devices << Device.new(device.attributes['id'].to_i, device.attributes['address'], site_id, device.attributes['riskfactor'].to_f, device.attributes['riskscore'].to_f) end end end devices end |
#list_sites ⇒ Array[SiteSummary] Also known as: sites
Retrieve a list of all sites the user is authorized to view or manage.
10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/nexpose/site.rb', line 10 def list_sites r = execute(make_xml('SiteListingRequest')) arr = [] if r.success r.res.elements.each('SiteListingResponse/SiteSummary') do |site| arr << SiteSummary.new(site.attributes['id'].to_i, site.attributes['name'], site.attributes['description'], site.attributes['riskfactor'].to_f, site.attributes['riskscore'].to_f) end end arr end |
#list_tickets ⇒ Object Also known as: tickets
6 7 8 9 10 11 12 13 14 15 16 17 |
# File 'lib/nexpose/ticket.rb', line 6 def list_tickets # TODO: Should take in filters as arguments. xml = make_xml('TicketListingRequest') r = execute(xml, '1.2') tickets = [] if r.success r.res.elements.each('TicketListingResponse/TicketSummary') do |summary| tickets << TicketSummary.parse(summary) end end tickets end |
#list_users ⇒ Array[UserSummary] Also known as: users
Retrieve a list of all users configured on this console.
10 11 12 13 14 15 16 17 18 19 |
# File 'lib/nexpose/user.rb', line 10 def list_users r = execute(make_xml('UserListingRequest')) arr = [] if r.success r.res.elements.each('UserListingResponse/UserSummary') do |summary| arr << UserSummary.parse(summary) end end arr end |
#list_vuln_categories ⇒ Array[String] Also known as: vuln_categories
Retrieve a list of the different vulnerability check categories.
37 38 39 40 |
# File 'lib/nexpose/vuln.rb', line 37 def list_vuln_categories data = DataTable._get_dyn_table(self, '/data/vulnerability/categories/dyntable.xml?tableID=VulnCategorySynopsis') data.map { |c| c['Category'] } end |
#list_vuln_exceptions(status = nil) ⇒ Array[VulnException] Also known as: vuln_exceptions
Retrieve all active vulnerability exceptions.
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/nexpose/vuln_exception.rb', line 12 def list_vuln_exceptions(status = nil) unless is_valid_vuln_exception_status?(status) raise "Unknown Status ~> '#{status}' :: For available options refer to Nexpose::VulnException::Status" end status = Nexpose::VulnException::Status.const_get(status_string_to_constant(status)) unless status.nil? results = [] ajax_data = [] url_size = 500 url_page = 0 req = Nexpose::AJAX.get(self, "/api/experimental/vulnerability_exceptions?_size=#{url_size}&_page=#{url_page}") data = JSON.parse(req, object_class: OpenStruct) ajax_data << data._resources if data._links.count > 1 loop do url_page += 1 req = Nexpose::AJAX.get(self, "/api/experimental/vulnerability_exceptions?_size=#{url_size}&_page=#{url_page}") data = JSON.parse(req, object_class: OpenStruct) ajax_data << data._resources links = data._links.select { |ll| ['self', 'last'].include?(ll.rel) } break if links[0].href == links[1].href end end ajax_data.compact! ajax_data.flatten! ajax_data.each do |vuln_excep| ve = VulnException.new(vuln_excep.scope.vulnerabilityID, vuln_excep.scope.type, vuln_excep.submit.reason, vuln_excep.state) ve.id = vuln_excep.id ve.submitter = vuln_excep.submit.name ve.submitter_comment = vuln_excep.submit.comment ve.submit_date = Time.parse(vuln_excep.submit.date) unless vuln_excep.submit.date.nil? ve.asset_id = vuln_excep.scope.assetID ve.site_id = vuln_excep.scope.siteID ve.asset_group_id = vuln_excep.scope.assetGroupID ve.port = vuln_excep.scope.port ve.vuln_key = vuln_excep.scope.key ve.expiration = Time.parse(vuln_excep.expires) unless vuln_excep.expires.nil? unless vuln_excep.review.nil? ve.reviewer = vuln_excep.review.name ve.reviewer_comment = vuln_excep.review.comment ve.review_date = Time.parse(vuln_excep.review.date) unless vuln_excep.review.date.nil? end results << ve end results.keep_if { |v| v.status == status } unless status.nil? return results end |
#list_vulns(full = false) ⇒ Array[Vulnerability|VulnerabilitySummary] Also known as: vulns
Retrieve summary details of all vulnerabilities.
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/nexpose/vuln.rb', line 12 def list_vulns(full = false) xml = make_xml('VulnerabilityListingRequest') # TODO: Add a flag to do stream parsing of the XML to improve performance. response = execute(xml, '1.2') vulns = [] if response.success response.res.elements.each('VulnerabilityListingResponse/VulnerabilitySummary') do |vuln| if full vulns << XML::VulnerabilitySummary.parse(vuln) else vulns << XML::Vulnerability.new(vuln.attributes['id'], vuln.attributes['title'], vuln.attributes['severity'].to_i) end end end vulns end |
#login ⇒ Object
Establish a new connection and Session ID
99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/nexpose/connection.rb', line 99 def login begin login_hash = { 'sync-id' => 0, 'password' => @password, 'user-id' => @username, 'token' => @token } login_hash['silo-id'] = @silo_id if @silo_id r = execute(make_xml('LoginRequest', login_hash)) if r.success @session_id = r.sid true end rescue APIError raise AuthenticationFailed.new(r) end end |
#logout ⇒ Object
Logout of the current connection
114 115 116 117 118 |
# File 'lib/nexpose/connection.rb', line 114 def logout r = execute(make_xml('LogoutRequest', { 'sync-id' => 0 })) return true if r.success raise APIError.new(r, 'Logout failed') end |
#past_scans(limit = nil) ⇒ Array[CompletedScan]
Get a history of past scans for this console, sorted by most recent first.
Please note that for consoles with a deep history of scanning, this method could return an excessive amount of data (and take quite a bit of time to retrieve). Consider limiting the amount of data with the optional argument.
370 371 372 373 374 375 376 377 378 |
# File 'lib/nexpose/scan.rb', line 370 def past_scans(limit = nil) uri = '/data/scan/global/scan-history' rows = AJAX.row_pref_of(limit) params = { 'sort' => 'endTime', 'dir' => 'DESC', 'startIndex' => 0 } AJAX.preserving_preference(self, 'global-completed-scans') do data = DataTable._get_json_table(self, uri, params, rows, limit) data.map(&CompletedScan.method(:parse_json)) end end |
#pause_scan(scan_id) ⇒ Object
Pauses a scan.
306 307 308 309 |
# File 'lib/nexpose/scan.rb', line 306 def pause_scan(scan_id) r = execute(make_xml('ScanPauseRequest', 'scan-id' => scan_id)) r.success ? r.attributes['success'] == '1' : false end |
#paused_scans(site_id = nil, limit = nil) ⇒ Array[ActiveScan]
Get paused scans. Provide a site ID to get paused scans for a site. With no site ID, all paused scans are returned.
387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 |
# File 'lib/nexpose/scan.rb', line 387 def paused_scans(site_id = nil, limit = nil) if site_id uri = "/data/scan/site/#{site_id}?status=active" rows = AJAX.row_pref_of(limit) params = { 'sort' => 'endTime', 'dir' => 'DESC', 'startIndex' => 0 } AJAX.preserving_preference(self, 'site-active-scans') do data = DataTable._get_json_table(self, uri, params, rows, limit).select { |scan| scan['paused'] } data.map(&ActiveScan.method(:parse_json)) end else uri = '/data/site/scans/dyntable.xml?printDocType=0&tableID=siteScansTable&activeOnly=true' data = DataTable._get_dyn_table(self, uri).select { |scan| (scan['Status'].include? 'Paused') } data.map(&ActiveScan.method(:parse_dyntable)) end end |
#recall_vuln_exception(id) ⇒ Boolean
Recall a vulnerability exception. Recall is used by a submitter to undo an exception request that has not been approved yet.
You can only recall a vulnerability exception that has ‘Under Review’ status.
101 102 103 104 105 |
# File 'lib/nexpose/vuln_exception.rb', line 101 def recall_vuln_exception(id) xml = make_xml('VulnerabilityExceptionRecallRequest', { 'exception-id' => id }) execute(xml, '1.2').success end |
#remove_assets_from_site(asset_ids, site_id) ⇒ Object
Remove (or delete) one or more assets from a site. With asset linking enabled, this will remove the association of an asset from the given site. If this is the only site of which an asset is a member, the asset will be deleted. If asset linking is disabled, the assets will be deleted.
157 158 159 |
# File 'lib/nexpose/device.rb', line 157 def remove_assets_from_site(asset_ids, site_id) AJAX.post(self, "/data/assets/bulk-delete?siteid=#{site_id}", asset_ids, Nexpose::AJAX::CONTENT_TYPE::JSON) end |
#remove_tag_from_asset(asset_id, tag_id) ⇒ Object
Removes a tag from an asset
47 48 49 |
# File 'lib/nexpose/tag.rb', line 47 def remove_tag_from_asset(asset_id, tag_id) AJAX.delete(self, "/api/2.0/assets/#{asset_id}/tags/#{tag_id}") end |
#remove_tag_from_asset_group(asset_group_id, tag_id) ⇒ Object Also known as: remove_tag_from_group
Removes a tag from an asset_group
96 97 98 |
# File 'lib/nexpose/tag.rb', line 96 def remove_tag_from_asset_group(asset_group_id, tag_id) AJAX.delete(self, "/api/2.0/asset_groups/#{asset_group_id}/tags/#{tag_id}") end |
#remove_tag_from_site(site_id, tag_id) ⇒ Object
Removes a tag from a site
71 72 73 |
# File 'lib/nexpose/tag.rb', line 71 def remove_tag_from_site(site_id, tag_id) AJAX.delete(self, "/api/2.0/sites/#{site_id}/tags/#{tag_id}") end |
#report_history(report_config_id) ⇒ Object
Provide a history of all reports generated with the specified report definition.
50 51 52 53 |
# File 'lib/nexpose/report.rb', line 50 def report_history(report_config_id) xml = make_xml('ReportHistoryRequest', { 'reportcfg-id' => report_config_id }) ReportSummary.parse_all(execute(xml)) end |
#restart ⇒ Object
Restart the application.
There is no response to a RestartRequest. When the application shuts down as part of the restart process, it terminates any active connections. Therefore, the application cannot issue a response when it restarts.
79 80 81 |
# File 'lib/nexpose/manage.rb', line 79 def restart execute(make_xml('RestartRequest', {})).success end |
#resubmit_vuln_exception(id, comment, reason = nil) ⇒ Boolean
Resubmit a vulnerability exception request with a new comment and reason after an exception has been rejected.
You can only resubmit a request that has a “Rejected” status; if an exception is “Approved” or “Under Review” you will receive an error message stating that the exception request cannot be resubmitted.
82 83 84 85 86 87 88 89 90 |
# File 'lib/nexpose/vuln_exception.rb', line 82 def resubmit_vuln_exception(id, comment, reason = nil) = { 'exception-id' => id } ['reason'] = reason if reason xml = make_xml('VulnerabilityExceptionResubmitRequest', ) comment_xml = make_xml('comment', {}, comment, false) xml.add_element(comment_xml) r = execute(xml, '1.2') r.success end |
#resume_scan(scan_id) ⇒ Object
Resumes a scan.
297 298 299 300 |
# File 'lib/nexpose/scan.rb', line 297 def resume_scan(scan_id) r = execute(make_xml('ScanResumeRequest', 'scan-id' => scan_id), '1.1', timeout: 60) r.success ? r.attributes['success'] == '1' : false end |
#reverse_engine_connection(engine_id) ⇒ Boolean
Reverses the direction of a connection to an engine If the connection is currently initiated from the console this method will have the engine initiate the connection. If the connection is currently initiated by the engine this method with initiate the connection from the console instead. Requires a restart of the console for the connection to be properly established.
29 30 31 32 33 |
# File 'lib/nexpose/engine.rb', line 29 def reverse_engine_connection(engine_id) uri = "/api/2.1/engine/#{engine_id}/reverseConnection" response = AJAX.put(self, uri) response.eql?("true") end |
#role_delete(role, scope = Scope::SILO) ⇒ Object Also known as: delete_role
67 68 69 70 71 72 |
# File 'lib/nexpose/role.rb', line 67 def role_delete(role, scope = Scope::SILO) xml = make_xml('RoleDeleteRequest') xml.add_element('Role', {'name' => role, 'scope' => scope}) response = execute(xml, '1.2') response.success end |
#role_listing ⇒ Object Also known as: roles
Returns a summary list of all roles.
53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/nexpose/role.rb', line 53 def role_listing xml = make_xml('RoleListingRequest') r = execute(xml, '1.2') roles = [] if r.success r.res.elements.each('RoleListingResponse/RoleSummary') do |summary| roles << RoleSummary::parse(summary) end end roles end |
#scan_activity ⇒ Array[ScanSummary]
Retrieve a list of current scan activities across all Scan Engines managed by Nexpose.
335 336 337 338 339 340 341 342 343 344 |
# File 'lib/nexpose/scan.rb', line 335 def scan_activity r = execute(make_xml('ScanActivityRequest')) res = [] if r.success r.res.elements.each('//ScanSummary') do |scan| res << ScanSummary.parse(scan) end end res end |
#scan_asset(site_id, asset) ⇒ Scan
Perform an ad hoc scan of a single asset of a site.
82 83 84 |
# File 'lib/nexpose/scan.rb', line 82 def scan_asset(site_id, asset) scan_assets(site_id, [asset]) end |
#scan_asset_with_schedule(site_id, asset, schedule) ⇒ Status
Perform an ad hoc scan of a single asset of a site at a specific time
93 94 95 |
# File 'lib/nexpose/scan.rb', line 93 def scan_asset_with_schedule(site_id, asset, schedule) scan_assets_with_schedule(site_id, [asset], schedule) end |
#scan_assets(site_id, assets) ⇒ Scan
109 110 111 112 113 114 115 116 |
# File 'lib/nexpose/scan.rb', line 109 def scan_assets(site_id, assets) xml = make_xml('SiteDevicesScanRequest', 'site-id' => site_id) hosts = REXML::Element.new('Hosts') assets.each { |asset| _append_asset!(hosts, asset) } xml.add_element(hosts) _scan_ad_hoc(xml) end |
#scan_assets_with_schedule(site_id, assets, schedules) ⇒ Status
Perform an ad hoc scan of a subset of assets for a site by adding a specific runtime. Only assets from a single site should be submitted per request. Method is designed to take objects filtered from Site#assets.
For example:
site = Site.load(nsc, 5)
nsc.scan_assets_with_schedule(5, site.assets.take(10), schedules)
131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/nexpose/scan.rb', line 131 def scan_assets_with_schedule(site_id, assets, schedules) xml = make_xml('SiteDevicesScanRequest', 'site-id' => site_id) hosts = REXML::Element.new('Hosts') assets.each { |asset| _append_asset!(hosts, asset) } xml.add_element(hosts) scheds = REXML::Element.new('Schedules') schedules.each { |sched| scheds.add_element(sched.as_xml) } xml.add_element(scheds) _scan_ad_hoc_with_schedules(xml) end |
#scan_assets_with_template_and_engine(site_id, assets, scan_template, scan_engine) ⇒ Fixnum
Initiate an ad-hoc scan on a subset of site assets with a specific scan template and scan engine, which may differ from the site’s defined scan template and scan engine.
217 218 219 220 221 222 223 224 225 |
# File 'lib/nexpose/scan.rb', line 217 def scan_assets_with_template_and_engine(site_id, assets, scan_template, scan_engine) uri = "/data/site/#{site_id}/scan" assets.size > 1 ? addresses = assets.join(',') : addresses = assets.first params = { 'addressList' => addresses, 'template' => scan_template, 'scanEngine' => scan_engine } scan_id = AJAX.form_post(self, uri, params) scan_id.to_i end |
#scan_device(device) ⇒ Scan
Perform an ad hoc scan of a single device.
10 11 12 |
# File 'lib/nexpose/scan.rb', line 10 def scan_device(device) scan_devices([device]) end |
#scan_device_with_schedule(device, schedule) ⇒ Status
Perform an ad hoc scan of a single device at a specific time.
20 21 22 |
# File 'lib/nexpose/scan.rb', line 20 def scan_device_with_schedule(device, schedule) scan_devices_with_schedule([device], schedule) end |
#scan_devices(devices) ⇒ Scan
Perform an ad hoc scan of a subset of devices for a site. Nexpose only allows devices from a single site to be submitted per request. Method is designed to take objects from a Device listing.
For example:
devices = nsc.devices(5)
nsc.scan_devices(devices.take(10))
36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/nexpose/scan.rb', line 36 def scan_devices(devices) site_id = devices.map(&:site_id).uniq.first xml = make_xml('SiteDevicesScanRequest', 'site-id' => site_id) elem = REXML::Element.new('Devices') devices.each do |device| elem.add_element('device', 'id' => "#{device.id}") end xml.add_element(elem) _scan_ad_hoc(xml) end |
#scan_devices_with_schedule(devices, schedules) ⇒ Status
Perform an ad hoc scan of a subset of devices for a site. Nexpose only allows devices from a single site to be submitted per request. Method is designed to take objects from a Device listing.
For example:
devices = nsc.devices(5)
nsc.scan_devices(devices.take(10))
61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/nexpose/scan.rb', line 61 def scan_devices_with_schedule(devices, schedules) site_id = devices.map(&:site_id).uniq.first xml = make_xml('SiteDevicesScanRequest', 'site-id' => site_id) elem = REXML::Element.new('Devices') devices.each do |device| elem.add_element('device', 'id' => "#{device.id}") end xml.add_element(elem) scheds = REXML::Element.new('Schedules') schedules.each { |sched| scheds.add_element(sched.as_xml) } xml.add_element(scheds) _scan_ad_hoc_with_schedules(xml) end |
#scan_ips(site_id, ip_addresses) ⇒ Scan
Perform an ad hoc scan of a subset of IP addresses for a site. Only IPs from a single site can be submitted per request, and IP addresses must already be included in the site configuration. Method is designed for scanning when the targets are coming from an external source that does not have access to internal identfiers.
For example:
to_scan = ['192.168.2.1', '192.168.2.107']
nsc.scan_ips(5, to_scan)
185 186 187 188 189 190 191 192 193 194 |
# File 'lib/nexpose/scan.rb', line 185 def scan_ips(site_id, ip_addresses) xml = make_xml('SiteDevicesScanRequest', 'site-id' => site_id) hosts = REXML::Element.new('Hosts') ip_addresses.each do |ip| xml.add_element('range', 'from' => ip) end xml.add_element(hosts) _scan_ad_hoc(xml) end |
#scan_ips_with_schedule(site_id, ip_addresses, schedules) ⇒ Status
Perform an ad hoc scan of a subset of IP addresses for a site at a specific time. Only IPs from a single site can be submitted per request, and IP addresses must already be included in the site configuration. Method is designed for scanning when the targets are coming from an external source that does not have access to internal identfiers.
For example:
to_scan = ['192.168.2.1', '192.168.2.107']
nsc.scan_ips(5, to_scan)
157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/nexpose/scan.rb', line 157 def scan_ips_with_schedule(site_id, ip_addresses, schedules) xml = make_xml('SiteDevicesScanRequest', 'site-id' => site_id) hosts = REXML::Element.new('Hosts') ip_addresses.each do |ip| xml.add_element('range', 'from' => ip) end xml.add_element(hosts) scheds = REXML::Element.new('Schedules') schedules.each { |sched| scheds.add_element(sched.as_xml) } xml.add_element(scheds) _scan_ad_hoc_with_schedules(xml) end |
#scan_site(site_id) ⇒ Scan
Initiate a site scan.
201 202 203 204 205 |
# File 'lib/nexpose/scan.rb', line 201 def scan_site(site_id) xml = make_xml('SiteScanRequest', 'site-id' => site_id) response = execute(xml) Scan.parse(response.res) if response.success end |
#scan_statistics(scan_id) ⇒ ScanSummary
Get scan statistics, including node and vulnerability breakdowns.
351 352 353 354 355 356 357 358 |
# File 'lib/nexpose/scan.rb', line 351 def scan_statistics(scan_id) r = execute(make_xml('ScanStatisticsRequest', 'scan-id' => scan_id)) if r.success ScanSummary.parse(r.res.elements['//ScanSummary']) else false end end |
#scan_status(scan_id) ⇒ String
Retrieve the status of a scan.
288 289 290 291 |
# File 'lib/nexpose/scan.rb', line 288 def scan_status(scan_id) r = execute(make_xml('ScanStatusRequest', 'scan-id' => scan_id)) r.success ? r.attributes['status'] : nil end |
#search(criteria) ⇒ Array[FilteredAsset]
Perform a search that will match the criteria provided.
For example, the following call will return assets with Java and .NET:
java_criterion = Criterion.new(Search::Field::SOFTWARE,
Search::Operator::CONTAINS,
'java')
dot_net_criterion = Criterion.new(Search::Field::SOFTWARE,
Search::Operator::CONTAINS,
'.net')
criteria = Criteria.new([java_criterion, dot_net_criterion])
results = nsc.search(criteria)
36 37 38 39 40 41 |
# File 'lib/nexpose/filter.rb', line 36 def search(criteria) results = DataTable._get_json_table(self, '/data/asset/filterAssets', criteria._to_payload) results.map { |a| FilteredAsset.new(a) } end |
#selected_criticality_tag(asset_id) ⇒ String
Returns the criticality value which takes precedent for an asset
106 107 108 109 |
# File 'lib/nexpose/tag.rb', line 106 def selected_criticality_tag(asset_id) selected_criticality = AJAX.get(self, "/data/asset/#{asset_id}/selected-criticality-tag") selected_criticality.empty? ? nil : JSON.parse(selected_criticality)['name'] end |
#send_log(uri = 'https://support.rapid7.com') ⇒ Object
Output diagnostic information into log files, zip the files, and encrypt the archive with a PGP public key that is provided as a parameter for the API call. Then upload the archive using HTTPS to a URL that is specified as an API parameter.
90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/nexpose/manage.rb', line 90 def send_log(uri = 'https://support.rapid7.com') url = REXML::Element.new('URL') url.text = uri tpt = REXML::Element.new('Transport') tpt.add_attribute('protocol', 'https') tpt << url xml = make_xml('SendLogRequest') xml << tpt execute(xml).success end |
#site_scan_history(site_id) ⇒ Array[ScanSummary]
Retrieve a list of all previous scans of the site.
42 43 44 45 46 47 48 49 50 51 |
# File 'lib/nexpose/site.rb', line 42 def site_scan_history(site_id) r = execute(make_xml('SiteScanHistoryRequest', { 'site-id' => site_id })) scans = [] if r.success r.res.elements.each('SiteScanHistoryResponse/ScanSummary') do |scan_event| scans << ScanSummary.parse(scan_event) end end scans end |
#site_tags(site_id) ⇒ Array[TagSummary] Also known as:
Lists all the tags on a site
56 57 58 59 60 61 62 63 |
# File 'lib/nexpose/tag.rb', line 56 def (site_id) tag_summary = [] site_tag = JSON.parse(AJAX.get(self, "/api/2.0/sites/#{site_id}/tags", AJAX::CONTENT_TYPE::JSON, { per_page: 2_147_483_647 })) site_tag['resources'].each do |json| tag_summary << TagSummary.parse(json) end tag_summary end |
#start_update ⇒ Object
Induce the application to retrieve required updates and restart if necessary.
68 69 70 |
# File 'lib/nexpose/manage.rb', line 68 def start_update execute(make_xml('StartUpdateRequest', {})).success end |
#stop_scan(scan_id, wait_sec = 0) ⇒ Object
Stop a running or paused scan.
269 270 271 272 273 274 275 276 277 278 279 280 281 |
# File 'lib/nexpose/scan.rb', line 269 def stop_scan(scan_id, wait_sec = 0) r = execute(make_xml('ScanStopRequest', 'scan-id' => scan_id)) if r.success so_far = 0 while so_far < wait_sec status = scan_status(scan_id) return status if status == 'stopped' sleep 5 so_far += 5 end end r.success end |
#system_information ⇒ Object
Obtain system data, such as total RAM, free RAM, total disk space, free disk space, CPU speed, number of CPU cores, and other vital information.
32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/nexpose/manage.rb', line 32 def system_information r = execute(make_xml('SystemInformationRequest', {})) if r.success res = {} r.res.elements.each('//Statistic') do |stat| res[stat.attributes['name'].to_s] = stat.text.to_s end res else false end end |
#tags ⇒ Array[TagSummary] Also known as:
Lists all tags
9 10 11 12 13 14 15 16 |
# File 'lib/nexpose/tag.rb', line 9 def tag_summary = [] = JSON.parse(AJAX.get(self, '/api/2.0/tags', AJAX::CONTENT_TYPE::JSON, { per_page: 2_147_483_647 })) ['resources'].each do |json| tag_summary << TagSummary.parse(json) end tag_summary end |
#update_engine(engine_id) ⇒ Boolean
Kicks off an update on a single engine. A return result of true should be taken only to mean that the update was sent, not that it correctly applied.
Nexpose::APIError will be raised if the engine is already updating, or if the engine is offline or unresponsive.
46 47 48 49 |
# File 'lib/nexpose/engine.rb', line 46 def update_engine(engine_id) uri = "/data/engine/#{engine_id}/update" AJAX.post(self, uri) end |
#vuln_details(vuln_id) ⇒ VulnerabilityDetail
Retrieve details for a vulnerability.
59 60 61 62 63 64 65 66 67 |
# File 'lib/nexpose/vuln.rb', line 59 def vuln_details(vuln_id) xml = make_xml('VulnerabilityDetailsRequest', { 'vuln-id' => vuln_id }) response = execute(xml, '1.2') if response.success response.res.elements.each('VulnerabilityDetailsResponse/Vulnerability') do |vuln| return XML::VulnerabilityDetail.parse(vuln) end end end |
#vuln_types ⇒ Array[String] Also known as: list_vuln_types
Retrieve a list of the different vulnerability check types.
48 49 50 51 |
# File 'lib/nexpose/vuln.rb', line 48 def vuln_types data = DataTable._get_dyn_table(self, '/data/vulnerability/checktypes/dyntable.xml?tableID=VulnCheckCategorySynopsis') data.map { |c| c['Category'] } end |