nexpose 7.0.0 → 7.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +2 -3
- data/Gemfile.lock +1 -1
- data/lib/nexpose/ajax.rb +12 -16
- data/lib/nexpose/alert.rb +20 -21
- data/lib/nexpose/api.rb +3 -3
- data/lib/nexpose/asset.rb +23 -23
- data/lib/nexpose/blackout.rb +6 -14
- data/lib/nexpose/common.rb +87 -92
- data/lib/nexpose/connection.rb +8 -10
- data/lib/nexpose/console.rb +9 -9
- data/lib/nexpose/dag.rb +2 -2
- data/lib/nexpose/data_table.rb +8 -12
- data/lib/nexpose/device.rb +35 -34
- data/lib/nexpose/discovery.rb +69 -69
- data/lib/nexpose/discovery/filter.rb +7 -8
- data/lib/nexpose/engine.rb +22 -21
- data/lib/nexpose/error.rb +7 -5
- data/lib/nexpose/external.rb +21 -16
- data/lib/nexpose/filter.rb +51 -52
- data/lib/nexpose/global_blackout.rb +6 -7
- data/lib/nexpose/global_settings.rb +2 -3
- data/lib/nexpose/group.rb +25 -19
- data/lib/nexpose/json_serializer.rb +4 -14
- data/lib/nexpose/maint.rb +8 -9
- data/lib/nexpose/manage.rb +2 -2
- data/lib/nexpose/multi_tenant_user.rb +42 -42
- data/lib/nexpose/password_policy.rb +14 -14
- data/lib/nexpose/pool.rb +6 -5
- data/lib/nexpose/report.rb +30 -34
- data/lib/nexpose/report_template.rb +17 -18
- data/lib/nexpose/role.rb +64 -55
- data/lib/nexpose/scan.rb +77 -60
- data/lib/nexpose/scan_template.rb +17 -17
- data/lib/nexpose/scheduled_backup.rb +8 -8
- data/lib/nexpose/scheduled_maintenance.rb +9 -9
- data/lib/nexpose/shared_credential.rb +30 -33
- data/lib/nexpose/shared_secret.rb +5 -5
- data/lib/nexpose/silo.rb +68 -66
- data/lib/nexpose/silo_profile.rb +47 -50
- data/lib/nexpose/site.rb +101 -123
- data/lib/nexpose/site_credentials.rb +15 -17
- data/lib/nexpose/tag.rb +73 -80
- data/lib/nexpose/ticket.rb +45 -42
- data/lib/nexpose/user.rb +45 -45
- data/lib/nexpose/util.rb +1 -1
- data/lib/nexpose/version.rb +1 -1
- data/lib/nexpose/vuln.rb +45 -43
- data/lib/nexpose/vuln_def.rb +7 -7
- data/lib/nexpose/vuln_exception.rb +35 -36
- data/lib/nexpose/wait.rb +32 -28
- data/lib/nexpose/web_credentials.rb +34 -36
- metadata +2 -2
data/lib/nexpose/scan.rb
CHANGED
@@ -60,8 +60,8 @@ module Nexpose
|
|
60
60
|
#
|
61
61
|
def scan_devices_with_schedule(devices, schedules)
|
62
62
|
site_id = devices.map(&:site_id).uniq.first
|
63
|
-
xml
|
64
|
-
elem
|
63
|
+
xml = make_xml('SiteDevicesScanRequest', 'site-id' => site_id)
|
64
|
+
elem = REXML::Element.new('Devices')
|
65
65
|
devices.each do |device|
|
66
66
|
elem.add_element('device', 'id' => "#{device.id}")
|
67
67
|
end
|
@@ -107,7 +107,7 @@ module Nexpose
|
|
107
107
|
# @return [Scan] Scan launch information.
|
108
108
|
#
|
109
109
|
def scan_assets(site_id, assets)
|
110
|
-
xml
|
110
|
+
xml = make_xml('SiteDevicesScanRequest', 'site-id' => site_id)
|
111
111
|
hosts = REXML::Element.new('Hosts')
|
112
112
|
assets.each { |asset| _append_asset!(hosts, asset) }
|
113
113
|
xml.add_element(hosts)
|
@@ -129,7 +129,7 @@ module Nexpose
|
|
129
129
|
# @return [Status] whether the request was successful
|
130
130
|
#
|
131
131
|
def scan_assets_with_schedule(site_id, assets, schedules)
|
132
|
-
xml
|
132
|
+
xml = make_xml('SiteDevicesScanRequest', 'site-id' => site_id)
|
133
133
|
hosts = REXML::Element.new('Hosts')
|
134
134
|
assets.each { |asset| _append_asset!(hosts, asset) }
|
135
135
|
xml.add_element(hosts)
|
@@ -155,7 +155,7 @@ module Nexpose
|
|
155
155
|
# @return [Status] whether the request was successful
|
156
156
|
#
|
157
157
|
def scan_ips_with_schedule(site_id, ip_addresses, schedules)
|
158
|
-
xml
|
158
|
+
xml = make_xml('SiteDevicesScanRequest', 'site-id' => site_id)
|
159
159
|
hosts = REXML::Element.new('Hosts')
|
160
160
|
ip_addresses.each do |ip|
|
161
161
|
xml.add_element('range', 'from' => ip)
|
@@ -183,7 +183,7 @@ module Nexpose
|
|
183
183
|
# @return [Scan] Scan launch information.
|
184
184
|
#
|
185
185
|
def scan_ips(site_id, ip_addresses)
|
186
|
-
xml
|
186
|
+
xml = make_xml('SiteDevicesScanRequest', 'site-id' => site_id)
|
187
187
|
hosts = REXML::Element.new('Hosts')
|
188
188
|
ip_addresses.each do |ip|
|
189
189
|
xml.add_element('range', 'from' => ip)
|
@@ -199,7 +199,7 @@ module Nexpose
|
|
199
199
|
# @return [Scan] Scan launch information.
|
200
200
|
#
|
201
201
|
def scan_site(site_id)
|
202
|
-
xml
|
202
|
+
xml = make_xml('SiteScanRequest', 'site-id' => site_id)
|
203
203
|
response = execute(xml)
|
204
204
|
Scan.parse(response.res) if response.success
|
205
205
|
end
|
@@ -233,7 +233,7 @@ module Nexpose
|
|
233
233
|
def _append_asset!(xml, asset)
|
234
234
|
if asset.is_a? Nexpose::IPRange
|
235
235
|
xml.add_element('range', 'from' => asset.from, 'to' => asset.to)
|
236
|
-
else
|
236
|
+
else # Assume HostName
|
237
237
|
host = REXML::Element.new('host')
|
238
238
|
host.text = asset
|
239
239
|
xml.add_element(host)
|
@@ -368,8 +368,8 @@ module Nexpose
|
|
368
368
|
# recently completed first.
|
369
369
|
#
|
370
370
|
def past_scans(limit = nil)
|
371
|
-
uri
|
372
|
-
rows
|
371
|
+
uri = '/data/scan/global/scan-history'
|
372
|
+
rows = AJAX.row_pref_of(limit)
|
373
373
|
params = { 'sort' => 'endTime', 'dir' => 'DESC', 'startIndex' => 0 }
|
374
374
|
AJAX.preserving_preference(self, 'global-completed-scans') do
|
375
375
|
data = DataTable._get_json_table(self, uri, params, rows, limit)
|
@@ -386,15 +386,15 @@ module Nexpose
|
|
386
386
|
#
|
387
387
|
def paused_scans(site_id = nil, limit = nil)
|
388
388
|
if site_id
|
389
|
-
uri
|
390
|
-
rows
|
389
|
+
uri = "/data/scan/site/#{site_id}?status=active"
|
390
|
+
rows = AJAX.row_pref_of(limit)
|
391
391
|
params = { 'sort' => 'endTime', 'dir' => 'DESC', 'startIndex' => 0 }
|
392
392
|
AJAX.preserving_preference(self, 'site-active-scans') do
|
393
393
|
data = DataTable._get_json_table(self, uri, params, rows, limit).select { |scan| scan['paused'] }
|
394
394
|
data.map(&ActiveScan.method(:parse_json))
|
395
395
|
end
|
396
396
|
else
|
397
|
-
uri
|
397
|
+
uri = '/data/site/scans/dyntable.xml?printDocType=0&tableID=siteScansTable&activeOnly=true'
|
398
398
|
data = DataTable._get_dyn_table(self, uri).select { |scan| (scan['Status'].include? 'Paused') }
|
399
399
|
data.map(&ActiveScan.method(:parse_dyntable))
|
400
400
|
end
|
@@ -409,10 +409,9 @@ module Nexpose
|
|
409
409
|
# zip_file, if provided. Otherwise, returns raw ZIP binary data.
|
410
410
|
#
|
411
411
|
def export_scan(scan_id, zip_file = nil)
|
412
|
-
http
|
413
|
-
headers
|
414
|
-
|
415
|
-
resp = http.get("/data/scan/#{scan_id}/export", headers)
|
412
|
+
http = AJAX.https(self)
|
413
|
+
headers = { 'Cookie' => "nexposeCCSessionID=#{@session_id}", 'Accept-Encoding' => 'identity' }
|
414
|
+
resp = http.get("/data/scan/#{scan_id}/export", headers)
|
416
415
|
|
417
416
|
case resp
|
418
417
|
when Net::HTTPSuccess
|
@@ -502,7 +501,12 @@ module Nexpose
|
|
502
501
|
|
503
502
|
# Constructor
|
504
503
|
def initialize(scan_id, site_id, engine_id, status, start_time, end_time)
|
505
|
-
@scan_id
|
504
|
+
@scan_id = scan_id
|
505
|
+
@site_id = site_id
|
506
|
+
@engine_id = engine_id
|
507
|
+
@status = status
|
508
|
+
@start_time = start_time
|
509
|
+
@end_time = end_time
|
506
510
|
end
|
507
511
|
|
508
512
|
def self.parse(xml)
|
@@ -546,8 +550,16 @@ module Nexpose
|
|
546
550
|
|
547
551
|
# Constructor
|
548
552
|
def initialize(scan_id, site_id, engine_id, status, start_time, end_time, message, tasks, nodes, vulnerabilities)
|
549
|
-
@scan_id
|
550
|
-
@
|
553
|
+
@scan_id = scan_id
|
554
|
+
@site_id = site_id
|
555
|
+
@engine_id = engine_id
|
556
|
+
@status = status
|
557
|
+
@start_time = start_time
|
558
|
+
@end_time = end_time
|
559
|
+
@message = message
|
560
|
+
@tasks = tasks
|
561
|
+
@nodes = nodes
|
562
|
+
@vulnerabilities = vulnerabilities
|
551
563
|
end
|
552
564
|
|
553
565
|
# Parse a response from a Nexpose console into a valid ScanSummary object.
|
@@ -594,7 +606,9 @@ module Nexpose
|
|
594
606
|
attr_reader :pending, :active, :completed
|
595
607
|
|
596
608
|
def initialize(pending, active, completed)
|
597
|
-
@pending
|
609
|
+
@pending = pending
|
610
|
+
@active = active
|
611
|
+
@completed = completed
|
598
612
|
end
|
599
613
|
|
600
614
|
# Parse REXML to Tasks object.
|
@@ -616,7 +630,11 @@ module Nexpose
|
|
616
630
|
attr_reader :live, :dead, :filtered, :unresolved, :other
|
617
631
|
|
618
632
|
def initialize(live, dead, filtered, unresolved, other)
|
619
|
-
@live
|
633
|
+
@live = live
|
634
|
+
@dead = dead
|
635
|
+
@filtered = filtered
|
636
|
+
@unresolved = unresolved
|
637
|
+
@other = other
|
620
638
|
end
|
621
639
|
|
622
640
|
# Parse REXML to Nodes object.
|
@@ -637,19 +655,17 @@ module Nexpose
|
|
637
655
|
# Value class for tracking vulnerability counts.
|
638
656
|
#
|
639
657
|
class Vulnerabilities
|
640
|
-
attr_reader :vuln_exploit, :vuln_version, :vuln_potential,
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
@
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
not_vuln_exploit, not_vuln_version,
|
652
|
-
error, disabled, other
|
658
|
+
attr_reader :vuln_exploit, :vuln_version, :vuln_potential, :not_vuln_exploit, :not_vuln_version, :error, :disabled, :other
|
659
|
+
|
660
|
+
def initialize(vuln_exploit, vuln_version, vuln_potential, not_vuln_exploit, not_vuln_version, error, disabled, other)
|
661
|
+
@vuln_exploit = vuln_exploit
|
662
|
+
@vuln_version = vuln_version
|
663
|
+
@vuln_potential = vuln_potential
|
664
|
+
@not_vuln_exploit = not_vuln_exploit
|
665
|
+
@not_vuln_version = not_vuln_version
|
666
|
+
@error = error
|
667
|
+
@disabled = disabled
|
668
|
+
@other = other
|
653
669
|
end
|
654
670
|
|
655
671
|
# Parse REXML to Vulnerabilities object.
|
@@ -691,11 +707,11 @@ module Nexpose
|
|
691
707
|
def initialize(severity = nil, count = 0)
|
692
708
|
if severity
|
693
709
|
@severities = {}
|
694
|
-
@count
|
710
|
+
@count = 0
|
695
711
|
add_severity(severity.to_i, count)
|
696
712
|
else
|
697
713
|
@severities = nil
|
698
|
-
@count
|
714
|
+
@count = count
|
699
715
|
end
|
700
716
|
end
|
701
717
|
|
@@ -718,7 +734,8 @@ module Nexpose
|
|
718
734
|
attr_reader :engine
|
719
735
|
|
720
736
|
def initialize(scan_id, engine_id)
|
721
|
-
@id
|
737
|
+
@id = scan_id
|
738
|
+
@engine = engine_id
|
722
739
|
end
|
723
740
|
|
724
741
|
def self.parse(xml)
|
@@ -781,18 +798,18 @@ module Nexpose
|
|
781
798
|
# object.
|
782
799
|
def self.parse_json(json)
|
783
800
|
new do
|
784
|
-
@id
|
785
|
-
@site_id
|
786
|
-
@status
|
787
|
-
@start_time
|
788
|
-
@end_time
|
789
|
-
@duration
|
790
|
-
@vulns
|
791
|
-
@assets
|
792
|
-
@risk_score
|
793
|
-
@type
|
801
|
+
@id = json['scanID']
|
802
|
+
@site_id = json['siteID']
|
803
|
+
@status = CompletedScan._parse_status(json['status'])
|
804
|
+
@start_time = Time.at(json['startTime'] / 1000)
|
805
|
+
@end_time = Time.at(json['endTime'] / 1000)
|
806
|
+
@duration = json['duration']
|
807
|
+
@vulns = json['vulnerabilityCount']
|
808
|
+
@assets = json['liveHosts']
|
809
|
+
@risk_score = json['riskScore']
|
810
|
+
@type = json['startedByCD'] == 'S' ? :scheduled : :manual
|
794
811
|
@engine_name = json['scanEngineName']
|
795
|
-
@scan_name
|
812
|
+
@scan_name = json['scanName']
|
796
813
|
end
|
797
814
|
end
|
798
815
|
|
@@ -814,18 +831,18 @@ module Nexpose
|
|
814
831
|
class ActiveScan < CompletedScan
|
815
832
|
def self.parse_dyntable(json)
|
816
833
|
new do
|
817
|
-
@id
|
818
|
-
@site_id
|
819
|
-
@status
|
820
|
-
@start_time
|
821
|
-
@end_time
|
822
|
-
@duration
|
823
|
-
@vulns
|
824
|
-
@assets
|
825
|
-
@risk_score
|
826
|
-
@type
|
834
|
+
@id = json['Scan ID']
|
835
|
+
@site_id = json['Site ID']
|
836
|
+
@status = CompletedScan._parse_status(json['Status Code'])
|
837
|
+
@start_time = Time.at(json['Started'].to_i / 1000)
|
838
|
+
@end_time = Time.at(json['Progress'].to_i / 1000)
|
839
|
+
@duration = json['Elapsed'].to_i
|
840
|
+
@vulns = json['Vulnerabilities Discovered'].to_i
|
841
|
+
@assets = json['Devices Discovered'].to_i
|
842
|
+
@risk_score = json['riskScore']
|
843
|
+
@type = json['Scan Type'] == 'Manual' ? :manual : :scheduled
|
827
844
|
@engine_name = json['Scan Engine']
|
828
|
-
@scan_name
|
845
|
+
@scan_name = json['Scan Name']
|
829
846
|
end
|
830
847
|
end
|
831
848
|
|
@@ -11,7 +11,7 @@ module Nexpose
|
|
11
11
|
templates['resources'].map { |t| ScanTemplateSummary.new(t) }
|
12
12
|
end
|
13
13
|
|
14
|
-
|
14
|
+
alias scan_templates list_scan_templates
|
15
15
|
|
16
16
|
# Delete a scan template from the console.
|
17
17
|
# Cannot be used to delete a built-in template.
|
@@ -31,7 +31,7 @@ module Nexpose
|
|
31
31
|
|
32
32
|
def initialize(json)
|
33
33
|
@name = json['name']
|
34
|
-
@id
|
34
|
+
@id = json['id']
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
@@ -110,7 +110,7 @@ module Nexpose
|
|
110
110
|
# @return [Boolean] Whether control scanning in enabled.
|
111
111
|
def control_scanning?
|
112
112
|
global_controls_scan = REXML::XPath.first(@xml, 'ScanTemplate/ControlsScan/globalControlsScanEnabled')
|
113
|
-
local_controls_scan
|
113
|
+
local_controls_scan = REXML::XPath.first(@xml, 'ScanTemplate/ControlsScan/localControlsScanEnabled')
|
114
114
|
|
115
115
|
global_controls_scan.attributes['enabled'] == '1' || local_controls_scan.attributes['enabled'] == '1'
|
116
116
|
end
|
@@ -237,31 +237,31 @@ module Nexpose
|
|
237
237
|
# @param [Array] ports Ports to scan for TCP service discovery
|
238
238
|
def tcp_service_discovery_ports=(ports)
|
239
239
|
service_ports = REXML::XPath.first(@xml, 'ScanTemplate/ServiceDiscovery/TCPPortScan')
|
240
|
-
service_ports.attributes['mode'] =
|
241
|
-
service_ports.attributes['method'] =
|
242
|
-
REXML::XPath.first(service_ports, './portList').text = ports.join(
|
240
|
+
service_ports.attributes['mode'] = 'custom'
|
241
|
+
service_ports.attributes['method'] = 'syn'
|
242
|
+
REXML::XPath.first(service_ports, './portList').text = ports.join(',')
|
243
243
|
end
|
244
244
|
|
245
245
|
# Exclude TCP ports during TCP service discovery
|
246
246
|
# @param [Array] ports TCP ports to exclude from TCP service discovery
|
247
247
|
def exclude_tcp_service_discovery_ports=(ports)
|
248
248
|
service_ports = REXML::XPath.first(@xml, 'ScanTemplate/ServiceDiscovery/ExcludedTCPPortScan')
|
249
|
-
REXML::XPath.first(service_ports, './portList').text = ports.join(
|
249
|
+
REXML::XPath.first(service_ports, './portList').text = ports.join(',')
|
250
250
|
end
|
251
251
|
|
252
252
|
# Set custom UDP ports to scan for UDP service discovery
|
253
253
|
# @param [Array] ports Ports to scan during UDP service discovery
|
254
254
|
def udp_service_discovery_ports=(ports)
|
255
255
|
service_ports = REXML::XPath.first(@xml, 'ScanTemplate/ServiceDiscovery/UDPPortScan')
|
256
|
-
service_ports.attributes['mode'] =
|
257
|
-
REXML::XPath.first(service_ports, './portList').text = ports.join(
|
256
|
+
service_ports.attributes['mode'] = 'custom'
|
257
|
+
REXML::XPath.first(service_ports, './portList').text = ports.join(',')
|
258
258
|
end
|
259
259
|
|
260
260
|
# Exclude UDP ports when performing UDP service discovery
|
261
261
|
# @param [Array] ports UDP ports to exclude from UDP service discovery
|
262
262
|
def exclude_udp_service_discovery_ports=(ports)
|
263
263
|
service_ports = REXML::XPath.first(@xml, 'ScanTemplate/ServiceDiscovery/ExcludedUDPPortScan')
|
264
|
-
REXML::XPath.first(service_ports, './portList').text = ports.join(
|
264
|
+
REXML::XPath.first(service_ports, './portList').text = ports.join(',')
|
265
265
|
end
|
266
266
|
|
267
267
|
# Enable or disable UDP service discovery
|
@@ -509,7 +509,7 @@ module Nexpose
|
|
509
509
|
#
|
510
510
|
def self.copy(nsc, id)
|
511
511
|
dupe = load(nsc, id)
|
512
|
-
dupe.id
|
512
|
+
dupe.id = '#NewScanTemplate#'
|
513
513
|
dupe.name = "#{dupe.name} Copy"
|
514
514
|
dupe
|
515
515
|
end
|
@@ -532,14 +532,14 @@ module Nexpose
|
|
532
532
|
return if level.nil?
|
533
533
|
return unless ['full', 'default', 'none'].include? level.downcase
|
534
534
|
logging = REXML::XPath.first(@xml, 'ScanTemplate/Logging')
|
535
|
-
if
|
535
|
+
if logging.nil?
|
536
536
|
logging = REXML::Element.new('Logging')
|
537
537
|
@xml.add_element(logging)
|
538
538
|
end
|
539
539
|
aces = REXML::XPath.first(logging, 'aces')
|
540
|
-
if
|
541
|
-
|
542
|
-
|
540
|
+
if aces.nil?
|
541
|
+
aces = REXML::Element.new('aces')
|
542
|
+
logging.add_element(aces)
|
543
543
|
end
|
544
544
|
aces.attributes['level'] = level
|
545
545
|
end
|
@@ -551,13 +551,13 @@ module Nexpose
|
|
551
551
|
return 'default' if logging.nil?
|
552
552
|
aces = REXML::XPath.first(logging, 'aces')
|
553
553
|
return 'default' if aces.nil?
|
554
|
-
|
554
|
+
aces.attributes['level']
|
555
555
|
end
|
556
556
|
|
557
557
|
# @return [Boolean] whether asset configuration scanning is enabled for
|
558
558
|
# this template.
|
559
559
|
def aces_enabled?
|
560
|
-
|
560
|
+
aces_level == 'full'
|
561
561
|
end
|
562
562
|
|
563
563
|
# Enable or disable the debug logging.
|
@@ -22,14 +22,14 @@ module Nexpose
|
|
22
22
|
attr_accessor :cancellation_window
|
23
23
|
|
24
24
|
def initialize(start:, enabled: true, type:, interval:, platform_independent: true, description: nil, pause_local_scans: true, cancellation_window: 0)
|
25
|
-
@schedule_start
|
26
|
-
@enabled
|
27
|
-
@schedule_type
|
28
|
-
@schedule_interval
|
25
|
+
@schedule_start = start
|
26
|
+
@enabled = enabled
|
27
|
+
@schedule_type = type
|
28
|
+
@schedule_interval = interval.to_i
|
29
29
|
@platform_independent = platform_independent
|
30
|
-
@description
|
31
|
-
@pause_local_scans
|
32
|
-
@cancellation_window
|
30
|
+
@description = description
|
31
|
+
@pause_local_scans = pause_local_scans
|
32
|
+
@cancellation_window = cancellation_window.to_i
|
33
33
|
end
|
34
34
|
|
35
35
|
def to_json
|
@@ -72,7 +72,7 @@ module Nexpose
|
|
72
72
|
end
|
73
73
|
|
74
74
|
def self.load(nsc)
|
75
|
-
uri
|
75
|
+
uri = '/api/2.1/schedule_backup/'
|
76
76
|
resp = AJAX.get(nsc, uri, AJAX::CONTENT_TYPE::JSON)
|
77
77
|
hash = JSON.parse(resp, symbolize_names: true).first
|
78
78
|
Nexpose::ScheduledBackup.from_hash(hash || [])
|
@@ -24,14 +24,14 @@ module Nexpose
|
|
24
24
|
attr_accessor :cancellation_window
|
25
25
|
|
26
26
|
def initialize(start:, enabled: true, type:, interval:, reindex: false, compress: true, cleanup: true, pause_local_scans: true, cancellation_window: 0)
|
27
|
-
@schedule_start
|
28
|
-
@enabled
|
29
|
-
@schedule_type
|
30
|
-
@schedule_interval
|
31
|
-
@reindex
|
32
|
-
@compress
|
33
|
-
@cleanup
|
34
|
-
@pause_local_scans
|
27
|
+
@schedule_start = start
|
28
|
+
@enabled = enabled
|
29
|
+
@schedule_type = type
|
30
|
+
@schedule_interval = interval.to_i
|
31
|
+
@reindex = reindex
|
32
|
+
@compress = compress
|
33
|
+
@cleanup = cleanup
|
34
|
+
@pause_local_scans = pause_local_scans
|
35
35
|
@cancellation_window = cancellation_window.to_i
|
36
36
|
end
|
37
37
|
|
@@ -77,7 +77,7 @@ module Nexpose
|
|
77
77
|
end
|
78
78
|
|
79
79
|
def self.load(nsc)
|
80
|
-
uri
|
80
|
+
uri = '/api/2.1/schedule_maintenance/'
|
81
81
|
resp = AJAX.get(nsc, uri, AJAX::CONTENT_TYPE::JSON)
|
82
82
|
hash = JSON.parse(resp, symbolize_names: true).first
|
83
83
|
Nexpose::ScheduledMaintenance.from_hash(hash || [])
|
@@ -4,21 +4,21 @@ module Nexpose
|
|
4
4
|
|
5
5
|
def list_shared_credentials
|
6
6
|
creds = DataTable._get_json_table(self,
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
'/data/credential/shared/listing',
|
8
|
+
{ 'sort' => -1,
|
9
|
+
'table-id' => 'credential-listing' })
|
10
10
|
creds.map { |c| SharedCredentialSummary.from_json(c) }
|
11
11
|
end
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
alias list_shared_creds list_shared_credentials
|
14
|
+
alias shared_credentials list_shared_credentials
|
15
|
+
alias shared_creds list_shared_credentials
|
16
16
|
|
17
17
|
def delete_shared_credential(id)
|
18
18
|
AJAX.post(self, "/data/credential/shared/delete?credid=#{id}")
|
19
19
|
end
|
20
20
|
|
21
|
-
|
21
|
+
alias delete_shared_cred delete_shared_credential
|
22
22
|
end
|
23
23
|
|
24
24
|
class SharedCredentialSummary < Credential
|
@@ -29,18 +29,18 @@ module Nexpose
|
|
29
29
|
attr_accessor :name
|
30
30
|
# The credential service/type. See Nexpose::Credential::Service.
|
31
31
|
attr_accessor :service
|
32
|
-
alias
|
33
|
-
alias
|
32
|
+
alias type service
|
33
|
+
alias type= service=
|
34
34
|
# Domain or realm.
|
35
35
|
attr_accessor :domain
|
36
36
|
# User name.
|
37
37
|
attr_accessor :username
|
38
|
-
alias
|
39
|
-
alias
|
38
|
+
alias user_name username
|
39
|
+
alias user_name= username=
|
40
40
|
# User name to use when elevating permissions (e.g., sudo).
|
41
41
|
attr_accessor :privilege_username
|
42
|
-
alias
|
43
|
-
alias
|
42
|
+
alias permission_elevation_user privilege_username
|
43
|
+
alias permission_elevation_user= privilege_username=
|
44
44
|
# Boolean to indicate whether this credential applies to all sites.
|
45
45
|
attr_accessor :all_sites
|
46
46
|
# When this credential was last modified.
|
@@ -48,14 +48,14 @@ module Nexpose
|
|
48
48
|
|
49
49
|
def self.from_json(json)
|
50
50
|
cred = new
|
51
|
-
cred.id
|
52
|
-
cred.name
|
53
|
-
cred.type
|
54
|
-
cred.domain
|
55
|
-
cred.username
|
51
|
+
cred.id = json['credentialID']['ID']
|
52
|
+
cred.name = json['name']
|
53
|
+
cred.type = json['service']
|
54
|
+
cred.domain = json['domain']
|
55
|
+
cred.username = json['username']
|
56
56
|
cred.privilege_username = json['privilegeElevationUsername']
|
57
|
-
cred.all_sites
|
58
|
-
cred.last_modified
|
57
|
+
cred.all_sites = json['scope'] == 'ALL_SITES_ENABLED_DEFAULT'
|
58
|
+
cred.last_modified = Time.at(json['lastModified']['time'] / 1000)
|
59
59
|
cred
|
60
60
|
end
|
61
61
|
|
@@ -83,12 +83,12 @@ module Nexpose
|
|
83
83
|
attr_accessor :pem_key
|
84
84
|
# Password to use when elevating permissions (e.g., sudo).
|
85
85
|
attr_accessor :privilege_password
|
86
|
-
alias
|
87
|
-
alias
|
86
|
+
alias permission_elevation_password privilege_password
|
87
|
+
alias permission_elevation_password= privilege_password=
|
88
88
|
# Permission elevation type. See Nexpose::Credential::ElevationType.
|
89
89
|
attr_accessor :privilege_type
|
90
|
-
alias
|
91
|
-
alias
|
90
|
+
alias permission_elevation_type privilege_type
|
91
|
+
alias permission_elevation_type= privilege_type=
|
92
92
|
# Privacty password of SNMP v3 credential
|
93
93
|
attr_accessor :privacy_password
|
94
94
|
# Authentication type of SNMP v3 credential
|
@@ -130,17 +130,14 @@ module Nexpose
|
|
130
130
|
def as_xml
|
131
131
|
xml = REXML::Element.new('Credential')
|
132
132
|
xml.add_attribute('id', @id)
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
desc = xml.add_element('Description').add_text(@description)
|
133
|
+
xml.add_element('Name').add_text(@name)
|
134
|
+
xml.add_element('Description').add_text(@description)
|
137
135
|
|
138
136
|
services = xml.add_element('Services')
|
139
|
-
|
137
|
+
services.add_element('Service').add_attribute('type', @service)
|
140
138
|
|
141
139
|
(account = xml.add_element('Account')).add_attribute('type', 'nexpose')
|
142
140
|
account.add_element('Field', { 'name' => 'database' }).add_text(@database)
|
143
|
-
|
144
141
|
account.add_element('Field', { 'name' => 'domain' }).add_text(@domain)
|
145
142
|
account.add_element('Field', { 'name' => 'username' }).add_text(@username)
|
146
143
|
account.add_element('Field', { 'name' => 'ntlmhash' }).add_text(@ntlm_hash) if @ntlm_hash
|
@@ -188,10 +185,10 @@ module Nexpose
|
|
188
185
|
unless engine_id
|
189
186
|
engine_id = nsc.engines.detect { |e| e.name == 'Local scan engine' }.id
|
190
187
|
end
|
191
|
-
@port
|
188
|
+
@port = Credential::DEFAULT_PORTS[@service] if @port.nil?
|
192
189
|
parameters = _to_param(target, engine_id, @port, siteid)
|
193
|
-
xml
|
194
|
-
result
|
190
|
+
xml = AJAX.form_post(nsc, '/data/credential/shared/test', parameters)
|
191
|
+
result = REXML::XPath.first(REXML::Document.new(xml), 'TestAdminCredentialsResult')
|
195
192
|
result.attributes['success'].to_i == 1
|
196
193
|
end
|
197
194
|
|