Class: Nexpose::Connection

Inherits:
Object
  • Object
show all
Includes:
XMLUtils
Defined in:
lib/nexpose/connection.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/filter.rb,
lib/nexpose/manage.rb,
lib/nexpose/report.rb,
lib/nexpose/ticket.rb,
lib/nexpose/discovery.rb,
lib/nexpose/shared_cred.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

Overview

Description

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')

# Login to NSC and Establish a Session ID
nsc.

# Check Session ID
if nsc.session_id
    puts 'Login Successful'
else
    puts 'Login Failure'
end

# Logout
logout_success = nsc.logout

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from XMLUtils

#make_xml, #parse_xml

Constructor Details

#initialize(ip, user, pass, port = 3780, silo_id = nil) ⇒ Connection

A constructor for Connection



54
55
56
57
58
59
60
61
62
# File 'lib/nexpose/connection.rb', line 54

def initialize(ip, user, pass, port = 3780, silo_id = nil)
  @host = ip
  @port = port
  @username = user
  @password = pass
  @silo_id = silo_id
  @session_id = nil
  @url = "https://#{@host}:#{@port}/api/API_VERSION/xml"
end

Instance Attribute Details

#hostObject (readonly)

The hostname or IP Address of the NSC



32
33
34
# File 'lib/nexpose/connection.rb', line 32

def host
  @host
end

#passwordObject (readonly)

The password used to login to the NSC



38
39
40
# File 'lib/nexpose/connection.rb', line 38

def password
  @password
end

#portObject (readonly)

The port of the NSC (default is 3780)



34
35
36
# File 'lib/nexpose/connection.rb', line 34

def port
  @port
end

#request_xmlObject (readonly)

The last XML request sent by this object, useful for debugging.



43
44
45
# File 'lib/nexpose/connection.rb', line 43

def request_xml
  @request_xml
end

#response_xmlObject (readonly)

The last XML response received by this object, useful for debugging.



45
46
47
# File 'lib/nexpose/connection.rb', line 45

def response_xml
  @response_xml
end

#session_idObject (readonly)

Session ID of this connection



30
31
32
# File 'lib/nexpose/connection.rb', line 30

def session_id
  @session_id
end

#urlObject (readonly)

The URL for communication



40
41
42
# File 'lib/nexpose/connection.rb', line 40

def url
  @url
end

#usernameObject (readonly)

The username used to login to the NSC



36
37
38
# File 'lib/nexpose/connection.rb', line 36

def username
  @username
end

Class Method Details

.from_uri(uri, user, pass, silo_id = nil) ⇒ Object

A constructor to load a Connection object from a URI



48
49
50
51
# File 'lib/nexpose/connection.rb', line 48

def self.from_uri(uri, user, pass, silo_id = nil)
  uri = URI.parse(uri)
  new(uri.host, user, pass, uri.port, silo_id)
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.

Parameters:

  • xml (REXML::Document)

    Prepared API call to execute.

  • asset (HostName|IPRange)

    Asset to append to XML.



112
113
114
115
116
117
118
119
120
# File 'lib/nexpose/scan.rb', line 112

def _append_asset!(xml, asset)
  if asset.kind_of? Nexpose::IPRange
    xml.add_element('range', { 'from' => asset.from, 'to' => asset.to })
  else  # Assume HostName
    host = REXML::Element.new('host')
    host.text = asset.host
    xml.add_element(host)
  end
end

#_maintenance_restartObject



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.

Parameters:

  • xml (REXML::Document)

    Prepared API call to execute.

Returns:

  • (Scan)

    Scan launch information.



128
129
130
131
# File 'lib/nexpose/scan.rb', line 128

def _scan_ad_hoc(xml)
  r = execute(xml, '1.1', timeout: 60)
  Scan.parse(r.res)
end

#asset_group_tags(asset_group_id) ⇒ Array[TagSummary] Also known as: group_tags, list_asset_group_tags

Lists all the tags on an asset_group

Parameters:

  • asset_group_id (Fixnum)

    id of the group on which tags are listed

Returns:

  • (Array[TagSummary])

    list of tags on asset group



80
81
82
83
84
85
86
87
# File 'lib/nexpose/tag.rb', line 80

def asset_group_tags(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: 2147483647 }))
  asset_group_tag['resources'].each do |json|
    tag_summary << TagSummary.parse(json)
  end
  tag_summary
end

#asset_tags(asset_id) ⇒ Array[TagSummary] Also known as: list_asset_tags

Lists all the tags on an asset

Parameters:

  • asset_id (Fixnum)

    of the asset to list the applied tags for

Returns:



32
33
34
35
36
37
38
39
# File 'lib/nexpose/tag.rb', line 32

def asset_tags(asset_id)
  tag_summary = []
  asset_tag = JSON.parse(AJAX.get(self, "/api/2.0/assets/#{asset_id}/tags", AJAX::CONTENT_TYPE::JSON, { per_page: 2147483647 }))
  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.

Parameters:

  • platform_independent (Boolean) (defaults to: false)

    Whether to make a platform independent backup.

  • description (String) (defaults to: nil)

    A note about this backup which will be visible through the web interface.

Returns:

  • (Boolean)

    Whether a backup is successfully initiated.



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

#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.

Parameters:

  • clean_up (Boolean) (defaults to: false)

    Removes any unnecessary data from the database.

  • compress (Boolean) (defaults to: false)

    Compresses the database tables and reclaims unused, allocated space.

  • reindex (Boolean) (defaults to: false)

    Drops and recreates the database indexes for improved performance.

Returns:

  • (Boolean)

    Whether a maintenance tasks are successfully initiated.



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.

Parameters:

  • id (Fixnum)

    Asset group ID to delete.

Returns:

  • (Boolean)

    Whether group deletion succeeded.



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



96
97
98
99
# File 'lib/nexpose/device.rb', line 96

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.

Parameters:

  • id (Fixnum)

    ID of an existing discovery connection.



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.

Parameters:

  • engine_id (Fixnum)

    Unique ID of an existing engine to remove.

  • scope (String) (defaults to: 'silo')

    Whether the engine is global or silo scoped.

Returns:

  • (Boolean)

    true if engine successfully deleted.



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.

Parameters:

  • report_id (Fixnum)

    ID of individual report to delete.



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.

Parameters:

  • report_config_id (Fixnum)

    ID of the report configuration to remove.



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.

Parameters:

  • template_id (String)

    Unique identifier of the report template to remove.



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.

Parameters:

  • scan_id (Fixnum)

    Scan ID to remove data for.



219
220
221
# File 'lib/nexpose/scan.rb', line 219

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.

Parameters:

  • id (String)

    Unique identifier of an existing scan 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: delete_shared_cred



17
18
19
# File 'lib/nexpose/shared_cred.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

Returns:

  • Whether or not the delete request succeeded.



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

Returns:

  • Whether or not the delete request succeeded.



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

Returns:

  • Whether or not the delete request succeeded.



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.

Returns:

  • Whether or not the delete request succeeded.



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

Parameters:

  • tag_id (Fixnum)

    ID of tag to delete



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.

Parameters:

  • ticket (Fixnum)

    Unique ID of the ticket to delete.

Returns:

  • (Boolean)

    Whether or not the ticket deletion succeeded.



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.

Parameters:

  • tickets (Array[Fixnum])

    Array of unique IDs of tickets to delete.

Returns:

  • (Boolean)

    Whether or not the ticket deletions succeeded.



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.

Parameters:

  • user_id (Fixnum)

    Unique ID for the user to delete.

Returns:

  • (Boolean)

    Whether or not the user deletion succeeded.



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.

Parameters:

  • id (Fixnum)

    The ID of a vuln exception.

Returns:

  • (Boolean)

    Whether or not deletion was successful.



74
75
76
77
78
# File 'lib/nexpose/vuln_exception.rb', line 74

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.


101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/nexpose/connection.rb', line 101

def download(url, file_name = nil)
  return nil if url.nil? or url.empty?
  uri = URI.parse(url)
  http = Net::HTTP.new(@host, @port)
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE # XXX: security issue
  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.

Returns:

  • (Array[ScanSummary])

    Array of ScanSummary objects associated with each active scan on the engine.



24
25
26
27
28
29
30
31
32
33
34
# File 'lib/nexpose/engine.rb', line 24

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

#execute(xml, version = '1.1', options = {}) ⇒ Object

Execute an API request



87
88
89
90
91
92
93
# File 'lib/nexpose/connection.rb', line 87

def execute(xml, version = '1.1', options = {})
  @request_xml = xml.to_s
  @api_version = version
  response = APIRequest.execute(@url, @request_xml, @api_version, options)
  @response_xml = response.raw_response_data
  response
end

#filter(field, operator, value = '') ⇒ Array[Asset]

Perform an asset filter search that will locate assets matching the provided conditions.

For example, the following call will return assets with Java installed:

nsc.filter(Search::Field::SOFTWARE, Search::Operator::CONTAINS, 'java')

Parameters:

  • field (String)

    Constant from Search::Field

  • operator (String)

    Constant from Search::Operator

  • value (String) (defaults to: '')

    Search term or constant from Search::Value

Returns:

  • (Array[Asset])

    List of matching assets.



16
17
18
19
20
# File 'lib/nexpose/filter.rb', line 16

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.

Parameters:

  • address (String)

    Address of the device to find. Usually the IP address.

  • site_id (FixNum) (defaults to: nil)

    Site ID to restrict search to.

Returns:

  • (Device)

    The first matching Device with the provided address, if found.



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.

Parameters:

  • search_term (String)

    Search terms to search for.

  • partial_words (Boolean) (defaults to: true)

    Allow partial word matches.

  • all_words (Boolean) (defaults to: true)

    All words must be present.

Returns:

  • (Array[VulnCheck])

    List of matching Vulnerability Checks.



78
79
80
81
82
83
84
# File 'lib/nexpose/vuln.rb', line 78

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|
    VulnCheck.new(vuln)
  end
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.

Parameters:

  • from (String)

    Vulnerability publish date in format YYYY-MM-DD.

  • to (String) (defaults to: nil)

    Vulnerability publish date in format YYYY-MM-DD.

Returns:

  • (Array[VulnSynopsis])

    List of vulnerabilities published in Nexpose between the provided dates.



95
96
97
98
99
# File 'lib/nexpose/vuln.rb', line 95

def find_vulns_by_date(from, to = nil)
  uri = "/ajax/vuln_synopsis.txml?addedMin=#{from}"
  uri += "&addedMax=#{to}" if to
  DataTable._get_dyn_table(self, uri).map { |v| VulnSynopsis.new(v) }
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.

Parameters:

  • user_name (String)

    User name to search for.



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[Asset]

Get a list of all assets currently associated with a group.

Parameters:

  • dev_id (Fixnum)

    Unique identifier of a device (asset).

Returns:

  • (Array[Asset])

    List of group assets.



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| Asset.new(a) }
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.

Parameters:

  • site_id (FixNum)

    Site ID to find latest scan for.

Returns:

  • (ScanSummary)

    details of the last completed scan for a site.



61
62
63
# File 'lib/nexpose/site.rb', line 61

def last_scan(site_id)
  site_scan_history(site_id).select { |scan| scan.end_time }.max_by { |scan| scan.end_time }
end

#list_asset_groupsArray[AssetGroupSummary] Also known as: groups, asset_groups

Retrieve an array of all asset groups the user is authorized to view or manage.

Returns:



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_backupsArray[Backup]

Retrieve a list of all backups currently stored on the Console.

Returns:

  • (Array[Backup])

    List of backups.



9
10
11
12
# File 'lib/nexpose/maint.rb', line 9

def list_backups
  data = DataTable._get_dyn_table(self, '/admin/global/ajax/backup_listing.txml')
  data.map { |b| Backup.parse(b) }
end

#list_device_vulns(dev_id) ⇒ Array[Vulnerability] Also known as: list_asset_vulns, asset_vulns, device_vulns

List the vulnerability findings for a given device ID.

Parameters:

  • dev_id (Fixnum)

    Unique identifier of a device (asset).

Returns:



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_connectionsObject 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_poolsArray[EnginePoolSummary] Also known as: engine_pools

Retrieve a list of all Scan Engine Pools managed by the Security Console.

Returns:

  • (Array[EnginePoolSummary])

    Array of EnginePoolSummary objects associated with each engine associated with this 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_enginesArray[EngineSummary] Also known as: engines

Retrieve a list of all Scan Engines managed by the Security Console.

Returns:

  • (Array[EngineSummary])

    Array of EngineSummary objects associated with each engine associated with this security console.



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/nexpose/engine.rb', line 41

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_templatesArray[ReportTemplateSummary] Also known as: report_templates

Provide a list of all report templates the user can access on the Security Console.

Returns:



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_reportsArray[ReportConfigSummary] Also known as: reports

Provide a listing of all report definitions the user can access on the Security Console.

Returns:



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_templatesArray[String] Also known as: scan_templates

List the scan templates currently configured on the console.

Returns:

  • (Array[String])

    list of scan templates IDs.



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_credentialsObject Also known as: list_shared_creds, shared_credentials, shared_creds



5
6
7
8
9
10
11
# File 'lib/nexpose/shared_cred.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_profilesArray[SiloProfileSummary] Also known as: silo_profiles

Retrieve a list of all silos the user is authorized to view or manage.

Returns:



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_usersArray[MultiTenantUserSummary] Also known as: silo_users

Retrieve a list of all users the user is authorized to view or manage.

Returns:



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_silosArray[SiloSummary] Also known as: silos

Retrieve a list of all silos the user is authorized to view or manage.

Returns:

  • (Array[SiloSummary])

    Array of SiloSummary objects.



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.

Parameters:

  • site_id (FixNum) (defaults to: nil)

    Site ID to request device listing for. Optional.

Returns:

  • (Array[Device])

    Array of devices associated with the site, or all devices on the console if no site is provided.



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_sitesArray[SiteSummary] Also known as: sites

Retrieve a list of all sites the user is authorized to view or manage.

Returns:

  • (Array[SiteSummary])

    Array of SiteSummary objects.



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_ticketsObject 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_usersArray[UserSummary] Also known as: users

Retrieve a list of all users configured on this console.

Returns:



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_categoriesArray[String] Also known as: vuln_categories

Retrieve a list of the different vulnerability check categories.

Returns:

  • (Array[String])

    Array of currently valid check categories.



38
39
40
41
# File 'lib/nexpose/vuln.rb', line 38

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, duration = nil) ⇒ Array[VulnException] Also known as: vuln_exceptions

Retrieve vulnerability exceptions.

Parameters:

  • status (String) (defaults to: nil)

    Filter exceptions by the current status. @see Nexpose::VulnException::Status

  • duration (String) (defaults to: nil)

    A time interval in the format “PnYnMnDTnHnMnS”.

Returns:

  • (Array[VulnException])

    List of matching vulnerability exceptions.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/nexpose/vuln_exception.rb', line 13

def list_vuln_exceptions(status = nil, duration = nil)
  option = {}
  option['status'] = status if status
  option['time-duration'] = duration if duration
  xml = make_xml('VulnerabilityExceptionListingRequest', option)
  response = execute(xml, '1.2')

  xs = []
  if response.success
    response.res.elements.each('//VulnerabilityException') do |ve|
      xs << VulnException.parse(ve)
    end
  end
  xs
end

#list_vuln_typesArray[String] Also known as: vuln_types

Retrieve a list of the different vulnerability check types.

Returns:

  • (Array[String])

    Array of currently valid check types.



49
50
51
52
# File 'lib/nexpose/vuln.rb', line 49

def list_vuln_types
  data = DataTable._get_dyn_table(self, '/ajax/vulnck_cat_synopsis.txml')
  data.map { |c| c['Category'] }
end

#list_vulns(full = false) ⇒ Array[Vulnerability|VulnerabilitySummary] Also known as: vulns

Retrieve summary details of all vulnerabilities.

Parameters:

  • full (Boolean) (defaults to: false)

    Whether or not to gather the full summary. Without the flag, only id, title, and severity are returned. It can take twice a long to retrieve full summary information.

Returns:



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/nexpose/vuln.rb', line 13

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 << VulnerabilitySummary.parse(vuln)
      else
        vulns << Vulnerability.new(vuln.attributes['id'],
                                   vuln.attributes['title'],
                                   vuln.attributes['severity'].to_i)
      end
    end
  end
  vulns
end

#loginObject

Establish a new connection and Session ID



65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/nexpose/connection.rb', line 65

def 
  begin
     = {'sync-id' => 0, 'password' => @password, 'user-id' => @username}
    ['silo-id'] = @silo_id if @silo_id
    r = execute(make_xml('LoginRequest', ))
    if r.success
      @session_id = r.sid
      true
    end
  rescue APIError
    raise AuthenticationFailed.new(r)
  end
end

#logoutObject

Logout of the current connection

Raises:



80
81
82
83
84
# File 'lib/nexpose/connection.rb', line 80

def logout
  r = execute(make_xml('LogoutRequest', {'sync-id' => 0}))
  return true if r.success
  raise APIError.new(r, 'Logout failed')
end

#pause_scan(scan_id) ⇒ Object

Pauses a scan.

Parameters:

  • scan_id (Fixnum)

    The scan ID.



176
177
178
179
# File 'lib/nexpose/scan.rb', line 176

def pause_scan(scan_id)
  r = execute(make_xml('ScanPauseRequest', { 'scan-id' => scan_id }))
  r.success ? r.attributes['success'] : nil
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.

Parameters:

  • id (Fixnum)

    Unique identifier of the exception to resubmit.

Returns:

  • (Boolean)

    Whether or not the recall was accepted by the console.



63
64
65
66
67
# File 'lib/nexpose/vuln_exception.rb', line 63

def recall_vuln_exception(id)
  xml = make_xml('VulnerabilityExceptionRecallRequest',
                 { 'exception-id' => id })
  execute(xml, '1.2').success
end

#remove_tag_from_asset(asset_id, tag_id) ⇒ Object

Removes a tag from an asset

Parameters:

  • asset_id (Fixnum)

    on which to remove tag

  • tag_id (Fixnum)

    to remove from 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

Parameters:

  • asset_group_id (Fixnum)

    id of group on which to remove tag

  • tag_id (Fixnum)

    of the tag to remove from 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

Parameters:

  • site_id (Fixnum)

    id of the site on which to remove the tag

  • tag_id (Fixnum)

    id of the tag to remove



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

#restartObject

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.



60
61
62
# File 'lib/nexpose/manage.rb', line 60

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.

Parameters:

  • id (Fixnum)

    Unique identifier of the exception to resubmit.

  • comment (String)

    Comment to justify the exception resubmission.

  • reason (String) (defaults to: nil)

    The reason for the exception status, if changing. @see Nexpose::VulnException::Reason

Returns:

  • (Boolean)

    Whether or not the resubmission was valid.



44
45
46
47
48
49
50
51
52
# File 'lib/nexpose/vuln_exception.rb', line 44

def resubmit_vuln_exception(id, comment, reason = nil)
  options = { 'exception-id' => id }
  options['reason'] = reason if reason
  xml = make_xml('VulnerabilityExceptionResubmitRequest', options)
  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.

Parameters:

  • scan_id (Fixnum)

    The scan ID.



167
168
169
170
# File 'lib/nexpose/scan.rb', line 167

def resume_scan(scan_id)
  r = execute(make_xml('ScanResumeRequest', { 'scan-id' => scan_id }), '1.1', timeout: 60)
  r.success ? r.attributes['success'] : nil
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_listingObject 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_activityArray[ScanSummary]

Retrieve a list of current scan activities across all Scan Engines managed by Nexpose.

Returns:

  • (Array[ScanSummary])

    Array of ScanSummary objects associated with each active scan on the engines.



187
188
189
190
191
192
193
194
195
196
# File 'lib/nexpose/scan.rb', line 187

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.

Parameters:

  • site_id (Fixnum)

    Site ID that the assets belong to.

  • asset (HostName|IPRange)

    Asset to scan.

Returns:

  • (Scan)

    Scan launch information.



45
46
47
# File 'lib/nexpose/scan.rb', line 45

def scan_asset(site_id, asset)
  scan_assets(site_id, [asset])
end

#scan_assets(site_id, assets) ⇒ Scan

Perform an ad hoc scan of a subset of assets for a site. 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(5, site.assets.take(10))

Parameters:

  • site_id (Fixnum)

    Site ID that the assets belong to.

  • assets (Array[HostName|IPRange])

    List of assets to scan.

Returns:

  • (Scan)

    Scan launch information.



61
62
63
64
65
66
67
68
# File 'lib/nexpose/scan.rb', line 61

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_device(device) ⇒ Scan

Perform an ad hoc scan of a single device.

Parameters:

  • device (Device)

    Device to scan.

Returns:

  • (Scan)

    Scan launch information.



11
12
13
# File 'lib/nexpose/scan.rb', line 11

def scan_device(device)
  scan_devices([device])
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))

Parameters:

  • devices (Array[Device])

    List of devices to scan.

Returns:

  • (Scan)

    Scan launch information.



27
28
29
30
31
32
33
34
35
36
37
# File 'lib/nexpose/scan.rb', line 27

def scan_devices(devices)
  site_id = devices.map { |d| d.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_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)

Parameters:

  • site_id (Fixnum)

    Site ID that the assets belong to.

  • ip_addresses (Array[String])

    Array of IP addresses to scan.

Returns:

  • (Scan)

    Scan launch information.



84
85
86
87
88
89
90
91
92
93
# File 'lib/nexpose/scan.rb', line 84

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_site(site_id) ⇒ Scan

Initiate a site scan.

Parameters:

  • site_id (Fixnum)

    Site ID to scan.

Returns:

  • (Scan)

    Scan launch information.



100
101
102
103
104
# File 'lib/nexpose/scan.rb', line 100

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.

Parameters:

  • scan_id (Fixnum)

    Scan ID to retrieve statistics for.

Returns:

  • (ScanSummary)

    ScanSummary object providing statistics for the scan.



203
204
205
206
207
208
209
210
# File 'lib/nexpose/scan.rb', line 203

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.

Parameters:

  • scan_id (Fixnum)

    The scan ID.

Returns:

  • (String)

    Current status of the scan. See Nexpose::Scan::Status.



158
159
160
161
# File 'lib/nexpose/scan.rb', line 158

def scan_status(scan_id)
  r = execute(make_xml('ScanStatusRequest', { 'scan-id' => scan_id }))
  r.success ? r.attributes['status'] : nil
end

#search(criteria) ⇒ Array[Asset]

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)

Parameters:

  • criteria (Criteria)

    Criteria search object.

Returns:

  • (Array[Asset])

    List of matching assets.



37
38
39
40
41
42
# File 'lib/nexpose/filter.rb', line 37

def search(criteria)
  results = DataTable._get_json_table(self,
                                      '/data/asset/filterAssets',
                                      criteria._to_payload)
  results.map { |a| Asset.new(a) }
end

#selected_criticality_tag(asset_id) ⇒ String

Returns the criticality value which takes precedent for an asset

Parameters:

  • asset_id (Fixnum)

    id of asset on which criticality tag is selected

Returns:

  • (String)

    selected_criticality string of the relevant criticality; nil if not tagged



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.

Parameters:

  • url

    Upload server to send the support log package to.



71
72
73
74
75
76
77
78
79
80
81
# File 'lib/nexpose/manage.rb', line 71

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.

Parameters:

  • site_id (FixNum)

    Site ID to request scan history for.

Returns:

  • (Array[ScanSummary])

    Array of ScanSummary objects representing each scan run to date on the site provided.



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: list_site_tags

Lists all the tags on a site

Parameters:

  • site_id (Fixnum)

    id of the site to get the applied tags

Returns:



56
57
58
59
60
61
62
63
# File 'lib/nexpose/tag.rb', line 56

def site_tags(site_id)
  tag_summary = []
  site_tag = JSON.parse(AJAX.get(self, "/api/2.0/sites/#{site_id}/tags", AJAX::CONTENT_TYPE::JSON, { per_page: 2147483647 }))
  site_tag['resources'].each do |json|
    tag_summary << TagSummary.parse(json)
  end
  tag_summary
end

#start_updateObject

Induce the application to retrieve required updates and restart if necessary.



49
50
51
# File 'lib/nexpose/manage.rb', line 49

def start_update
  execute(make_xml('StartUpdateRequest', {})).success
end

#stop_scan(scan_id, wait_sec = 0) ⇒ Object

Stop a running or paused scan.

Parameters:

  • scan_id (Fixnum)

    ID of the scan to stop.

  • wait_sec (Fixnum) (defaults to: 0)

    Number of seconds to wait for status to be updated.



139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/nexpose/scan.rb', line 139

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_informationObject

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

#tagsArray[TagSummary] Also known as: list_tags

Lists all tags

Returns:



9
10
11
12
13
14
15
16
# File 'lib/nexpose/tag.rb', line 9

def tags
  tag_summary = []
  tags = JSON.parse(AJAX.get(self, '/api/2.0/tags', AJAX::CONTENT_TYPE::JSON, { per_page: 2147483647 }))
  tags['resources'].each do |json|
    tag_summary << TagSummary.parse(json)
  end
  tag_summary
end

#vuln_details(vuln_id) ⇒ VulnerabilityDetail

Retrieve details for a vulnerability.

Parameters:

  • vuln_id (String)

    Nexpose vulnerability ID, such as ‘windows-duqu-cve-2011-3402’.

Returns:



61
62
63
64
65
66
67
68
69
# File 'lib/nexpose/vuln.rb', line 61

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 VulnerabilityDetail.parse(vuln)
    end
  end
end