qualys 0.1.4 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -2
- data/.rubocop.yml +7 -0
- data/.rubocop_todo.yml +71 -0
- data/.travis.yml +13 -1
- data/Gemfile +3 -1
- data/Gemfile.lock +91 -0
- data/README.md +50 -10
- data/Rakefile +3 -4
- data/lib/qualys.rb +10 -11
- data/lib/qualys/api.rb +38 -47
- data/lib/qualys/auth.rb +11 -20
- data/lib/qualys/compliance.rb +3 -7
- data/lib/qualys/config.rb +3 -5
- data/lib/qualys/host.rb +17 -0
- data/lib/qualys/report.rb +90 -0
- data/lib/qualys/scans.rb +10 -22
- data/lib/qualys/version.rb +1 -1
- data/lib/qualys/vulnerability.rb +74 -0
- data/qualys.gemspec +18 -19
- data/spec/fixtures/vcr_cassettes/api_get.yml +52 -0
- data/spec/fixtures/vcr_cassettes/create_global_report.yml +68 -0
- data/spec/fixtures/vcr_cassettes/emptyscans.yml +35 -0
- data/spec/fixtures/vcr_cassettes/get.yml +107 -0
- data/spec/fixtures/vcr_cassettes/global_report.yml +17800 -0
- data/spec/fixtures/vcr_cassettes/load_global_report.yml +625 -0
- data/spec/fixtures/vcr_cassettes/login.yml +50 -0
- data/spec/fixtures/vcr_cassettes/logout.yml +50 -0
- data/spec/fixtures/vcr_cassettes/scan.yml +73 -0
- data/spec/fixtures/vcr_cassettes/scans.yml +89 -0
- data/spec/fixtures/vcr_cassettes/templates.yml +121 -0
- data/spec/fixtures/vcr_cassettes/try_load_not_existing_report.yml +63 -0
- data/spec/fixtures/vcr_cassettes/unlogged.yml +45 -0
- data/spec/fixtures/vcr_cassettes/wrong.yml +101 -0
- data/spec/qualys/api_spec.rb +27 -0
- data/spec/qualys/report_spec.rb +65 -0
- data/spec/qualys/scans_spec.rb +75 -0
- data/spec/qualys/version_spec.rb +11 -0
- data/spec/qualys/vulnerability_spec.rb +53 -0
- data/spec/qualys_spec.rb +20 -0
- data/spec/spec_helper.rb +37 -0
- metadata +61 -15
- data/.rock.yml +0 -17
- data/lib/qualys/reports.rb +0 -47
data/lib/qualys/auth.rb
CHANGED
@@ -6,37 +6,28 @@ module Qualys
|
|
6
6
|
|
7
7
|
# Do Login
|
8
8
|
def self.login
|
9
|
-
|
10
9
|
# Request a login
|
11
|
-
response =
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
})
|
18
|
-
|
10
|
+
response = api_post('/session/', body: {
|
11
|
+
action: 'login',
|
12
|
+
username: Qualys::Config.username,
|
13
|
+
password: Qualys::Config.password
|
14
|
+
})
|
15
|
+
|
19
16
|
# set the session key
|
20
17
|
Qualys::Config.session_key = response.header['Set-Cookie']
|
21
18
|
true
|
22
|
-
|
23
19
|
end
|
24
20
|
|
25
21
|
# Set Logout
|
26
22
|
def self.logout
|
27
|
-
|
28
23
|
# Request a login
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
})
|
34
|
-
|
24
|
+
api_post('/session/', body: {
|
25
|
+
action: 'logout'
|
26
|
+
})
|
27
|
+
|
35
28
|
# set the session key
|
36
29
|
Qualys::Config.session_key = nil
|
37
30
|
true
|
38
|
-
|
39
31
|
end
|
40
|
-
|
41
32
|
end
|
42
|
-
end
|
33
|
+
end
|
data/lib/qualys/compliance.rb
CHANGED
@@ -1,21 +1,17 @@
|
|
1
1
|
module Qualys
|
2
2
|
class Compliance < Api
|
3
|
-
|
4
3
|
def self.all
|
5
|
-
response = api_get(
|
4
|
+
response = api_get('/compliance/control/', query: { action: 'list' })
|
6
5
|
|
7
|
-
unless response.parsed_response['<COMPLIANCE_SCAN_RESULT_OUTPUT']['RESPONSE'].
|
6
|
+
unless response.parsed_response['<COMPLIANCE_SCAN_RESULT_OUTPUT']['RESPONSE'].key? 'COMPLIANCE_SCAN'
|
8
7
|
return []
|
9
8
|
end
|
10
9
|
|
11
10
|
response.parsed_response['COMPLIANCE_SCAN_RESULT_OUTPUT']['RESPONSE']['COMPLIANCE_SCAN']
|
12
|
-
|
13
11
|
end
|
14
12
|
|
15
13
|
def self.each
|
16
|
-
|
14
|
+
all
|
17
15
|
end
|
18
|
-
|
19
16
|
end
|
20
|
-
|
21
17
|
end
|
data/lib/qualys/config.rb
CHANGED
@@ -26,10 +26,8 @@ module Qualys
|
|
26
26
|
#
|
27
27
|
# @param [ String ] path The path to the file.
|
28
28
|
def load!(path)
|
29
|
-
settings = YAML.
|
30
|
-
if settings.is_a? Hash
|
31
|
-
from_hash(settings)
|
32
|
-
end
|
29
|
+
settings = YAML.safe_load(ERB.new(File.new(path).read).result)['api']
|
30
|
+
from_hash(settings) if settings.is_a? Hash
|
33
31
|
end
|
34
32
|
end
|
35
|
-
end
|
33
|
+
end
|
data/lib/qualys/host.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Qualys
|
4
|
+
# a scanned target
|
5
|
+
class Host
|
6
|
+
attr_accessor :ip, :tracking_method, :dns, :operating_system, :vuln_info_list, :vulnerabilities
|
7
|
+
|
8
|
+
def initialize(host, vulnerabilities = nil)
|
9
|
+
@ip = host['IP']
|
10
|
+
@tracking_method = host['TRACKING_METHOD']
|
11
|
+
@dns = host['DNS']
|
12
|
+
@operating_system = host['OPERATING_SYSTEM']
|
13
|
+
@vuln_info_list = host['VULN_INFO_LIST']
|
14
|
+
@vulnerabilities = vulnerabilities
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Qualys
|
4
|
+
# Qualys reports
|
5
|
+
class Report < Api
|
6
|
+
attr_accessor :header, :host_list, :glossary, :appendices
|
7
|
+
|
8
|
+
# accepted timeout in seconds
|
9
|
+
TIMEOUT = 60.0
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def find_by_id(id)
|
13
|
+
response = api_get('/report/', query: {
|
14
|
+
action: 'fetch',
|
15
|
+
id: id
|
16
|
+
})
|
17
|
+
|
18
|
+
# check if report exist
|
19
|
+
return unless response.parsed_response.keys.include?('ASSET_DATA_REPORT')
|
20
|
+
|
21
|
+
Report.new(response.parsed_response)
|
22
|
+
end
|
23
|
+
|
24
|
+
# returns the list of the templates
|
25
|
+
def templates
|
26
|
+
auth = { username: Qualys::Config.username, password: Qualys::Config.password }
|
27
|
+
response = HTTParty.get('https://qualysapi.qualys.eu/msp/report_template_list.php',
|
28
|
+
basic_auth: auth)
|
29
|
+
response.parsed_response['REPORT_TEMPLATE_LIST']['REPORT_TEMPLATE']
|
30
|
+
end
|
31
|
+
|
32
|
+
def delete(id)
|
33
|
+
api_post('/report/', query: {
|
34
|
+
action: 'delete',
|
35
|
+
id: id
|
36
|
+
})
|
37
|
+
end
|
38
|
+
|
39
|
+
# returns the id of the report
|
40
|
+
def create_global_report
|
41
|
+
scan_template = templates.detect { |template| template['TITLE'] == 'Technical Report' }
|
42
|
+
response = api_post('/report/', query: {
|
43
|
+
action: 'launch',
|
44
|
+
report_title: 'Generated_by_Ruby_Qualys_gem',
|
45
|
+
report_type: 'Scan',
|
46
|
+
output_format: 'xml',
|
47
|
+
template_id: scan_template['ID']
|
48
|
+
})
|
49
|
+
|
50
|
+
response.parsed_response['SIMPLE_RETURN']['RESPONSE']['ITEM_LIST']['ITEM']['VALUE']
|
51
|
+
end
|
52
|
+
|
53
|
+
# returns a report global report object.
|
54
|
+
# This method can be time consuming and times out after 64 s
|
55
|
+
def global_report
|
56
|
+
report_id = create_global_report
|
57
|
+
report = find_by_id(report_id)
|
58
|
+
|
59
|
+
10.times do
|
60
|
+
sleep(TIMEOUT / 10)
|
61
|
+
report = find_by_id(report_id)
|
62
|
+
break unless report.nil?
|
63
|
+
end
|
64
|
+
|
65
|
+
raise Qualys::Report::Exception, 'Report generation timed out' if report.nil?
|
66
|
+
|
67
|
+
delete(report_id)
|
68
|
+
report
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def initialize(report)
|
73
|
+
@header = report['ASSET_DATA_REPORT']['HEADER']
|
74
|
+
@host_list = report['ASSET_DATA_REPORT']['HOST_LIST']['HOST']
|
75
|
+
@glossary = report['ASSET_DATA_REPORT']['GLOSSARY']['VULN_DETAILS_LIST']['VULN_DETAILS']
|
76
|
+
@appendices = report['ASSET_DATA_REPORT']['APPENDICES']
|
77
|
+
end
|
78
|
+
|
79
|
+
def hosts
|
80
|
+
hosts ||= host_list.map do |xml_host|
|
81
|
+
vulnerabilities = xml_host['VULN_INFO_LIST']['VULN_INFO'].map do |vuln|
|
82
|
+
Qualys::Vulnerability.new(vuln, @glossary)
|
83
|
+
end
|
84
|
+
Qualys::Host.new(xml_host, vulnerabilities)
|
85
|
+
end
|
86
|
+
|
87
|
+
hosts
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/lib/qualys/scans.rb
CHANGED
@@ -1,37 +1,28 @@
|
|
1
1
|
module Qualys
|
2
2
|
class Scans < Api
|
3
|
-
|
4
3
|
def self.all
|
5
|
-
response = api_get(
|
6
|
-
unless response.parsed_response['SCAN_LIST_OUTPUT']['RESPONSE'].
|
4
|
+
response = api_get('/scan/', query: { action: 'list' })
|
5
|
+
unless response.parsed_response['SCAN_LIST_OUTPUT']['RESPONSE'].key? 'SCAN_LIST'
|
7
6
|
return []
|
8
7
|
end
|
9
8
|
|
10
9
|
scanlist = response.parsed_response['SCAN_LIST_OUTPUT']['RESPONSE']['SCAN_LIST']['SCAN']
|
11
|
-
scanlist.map!{|scan| Scan.new(scan)}
|
12
|
-
|
13
|
-
end
|
14
|
-
|
15
|
-
def self.each
|
16
|
-
self.all
|
10
|
+
scanlist.map! { |scan| Scan.new(scan) }
|
17
11
|
end
|
18
12
|
|
19
13
|
def self.get(ref)
|
20
|
-
response = api_get(
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
}} )
|
14
|
+
response = api_get('/scan/', query: {
|
15
|
+
action: 'fetch',
|
16
|
+
scan_ref: ref,
|
17
|
+
mode: 'extended',
|
18
|
+
output_format: 'json'
|
19
|
+
})
|
27
20
|
|
28
21
|
JSON.parse(response.parsed_response)
|
29
22
|
end
|
30
|
-
|
31
23
|
end
|
32
24
|
|
33
25
|
class Scan
|
34
|
-
|
35
26
|
attr_accessor :ref, :title, :type, :date, :duration, :status, :target, :user
|
36
27
|
|
37
28
|
def initialize(scan)
|
@@ -50,15 +41,12 @@ module Qualys
|
|
50
41
|
end
|
51
42
|
|
52
43
|
def finished?
|
53
|
-
if @status.eql? 'Finished'
|
54
|
-
return true
|
55
|
-
end
|
44
|
+
return true if @status.eql? 'Finished'
|
56
45
|
|
57
46
|
false
|
58
47
|
end
|
59
48
|
end
|
60
49
|
|
61
50
|
class Details
|
62
|
-
|
63
51
|
end
|
64
52
|
end
|
data/lib/qualys/version.rb
CHANGED
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Qualys
|
4
|
+
# Qualys vulnerabilities from a report xml
|
5
|
+
class Vulnerability
|
6
|
+
attr_accessor :qid, :type, :port, :service, :protocol, :ssl, :result,
|
7
|
+
:first_found, :last_found, :times_found, :status, :details,
|
8
|
+
:cve_code_list, :title, :severity, :category, :threat, :impact,
|
9
|
+
:solution, :pci_flag, :correlation, :vendor_reference_list, :last_update,
|
10
|
+
:url
|
11
|
+
|
12
|
+
def initialize(vuln, glossary)
|
13
|
+
parse_vuln vuln
|
14
|
+
|
15
|
+
match_details glossary
|
16
|
+
|
17
|
+
parse_cve if @details['CVE_ID_LIST']
|
18
|
+
parse_details
|
19
|
+
# gives the url to the qualys knowledge base for this vulnerabitlty
|
20
|
+
parse_url
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_s
|
24
|
+
"#{qid}, #{title}, severity : #{severity}, cves: #{cve_code_list&.join(', ') || 'no cve'}"
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def parse_cve
|
30
|
+
cve_xlm_array = if @details['CVE_ID_LIST']['CVE_ID'].is_a?(Array)
|
31
|
+
@details['CVE_ID_LIST']['CVE_ID']
|
32
|
+
else
|
33
|
+
[@details['CVE_ID_LIST']['CVE_ID']]
|
34
|
+
end
|
35
|
+
@cve_code_list = cve_xlm_array.map { |cve| cve['ID'] }
|
36
|
+
end
|
37
|
+
|
38
|
+
# this methods finds the details for this qid in the report's glossary
|
39
|
+
def match_details(glossary)
|
40
|
+
@details = glossary.select { |detail| detail['id'] == @qid }[0]
|
41
|
+
end
|
42
|
+
|
43
|
+
def parse_details
|
44
|
+
@title = @details['TITLE']
|
45
|
+
@severity = @details['SEVERITY']
|
46
|
+
@category = @details['CATEGORY']
|
47
|
+
@threat = @details['THREAT']
|
48
|
+
@impact = @details['IMPACT']
|
49
|
+
@solution = @details['SOLUTION']
|
50
|
+
@pci_flag = @details['PCI_FLAG']
|
51
|
+
@correlation = @details['CORRELATION']
|
52
|
+
@vendor_reference_list = @details['VENDOR_REFERENCE_LIST']
|
53
|
+
@last_update = @details['BUGTRAQ_ID_LIST']
|
54
|
+
end
|
55
|
+
|
56
|
+
def parse_url
|
57
|
+
@url = 'https://qualysguard.qualys.eu/fo/common/vuln_info.php?id=' + @qid[4..-1]
|
58
|
+
end
|
59
|
+
|
60
|
+
def parse_vuln(vuln)
|
61
|
+
@qid = vuln['QID']['id']
|
62
|
+
@type = vuln['TYPE']
|
63
|
+
@port = vuln['PORT']
|
64
|
+
@service = vuln['SERVICE']
|
65
|
+
@protocol = vuln['PROTOCOL']
|
66
|
+
@ssl = vuln['SSL']
|
67
|
+
@result = vuln['RESULT']
|
68
|
+
@first_found = vuln['FIRST_FOUND']
|
69
|
+
@last_found = vuln['LAST_FOUND']
|
70
|
+
@times_found = vuln['TIMES_FOUND']
|
71
|
+
@status = vuln['VULN_STATUS']
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/qualys.gemspec
CHANGED
@@ -1,37 +1,36 @@
|
|
1
1
|
# Created by hand, like a real man
|
2
2
|
# coding: utf-8
|
3
|
+
|
3
4
|
lib = File.expand_path('../lib', __FILE__)
|
4
5
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
6
|
require 'qualys/version'
|
6
7
|
|
7
8
|
Gem::Specification.new do |s|
|
8
|
-
|
9
9
|
s.name = 'qualys'
|
10
10
|
s.version = Qualys::VERSION
|
11
|
-
s.date = '
|
12
|
-
s.summary =
|
13
|
-
s.description =
|
14
|
-
s.authors = [
|
11
|
+
s.date = '2017-12-17'
|
12
|
+
s.summary = 'qualys API Client'
|
13
|
+
s.description = 'Easily interface with the qualys for consuming events'
|
14
|
+
s.authors = ['Mike Mackintosh']
|
15
15
|
s.email = 'm@zyp.io'
|
16
16
|
s.homepage =
|
17
17
|
'http://github.com/mikemackintosh/ruby-qualys'
|
18
18
|
|
19
19
|
s.license = 'MIT'
|
20
|
-
|
21
|
-
s.require_paths = [
|
20
|
+
|
21
|
+
s.require_paths = ['lib']
|
22
22
|
s.files = `git ls-files -z`.split("\x0")
|
23
|
-
#s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
24
|
-
|
23
|
+
# s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
24
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
25
25
|
|
26
|
-
s.add_dependency 'json'
|
27
26
|
s.add_dependency 'erubis'
|
28
|
-
s.add_dependency 'httparty'
|
29
|
-
|
30
|
-
s.add_development_dependency "bundler"
|
31
|
-
s.add_development_dependency "rake"
|
32
|
-
s.add_development_dependency "rspec"
|
33
|
-
s.add_development_dependency "vcr"
|
34
|
-
s.add_development_dependency "webmock"
|
35
|
-
s.add_development_dependency "rubocop"
|
27
|
+
s.add_dependency 'httparty', '~> 0.15'
|
28
|
+
s.add_dependency 'json'
|
36
29
|
|
37
|
-
|
30
|
+
s.add_development_dependency 'bundler'
|
31
|
+
s.add_development_dependency 'rake'
|
32
|
+
s.add_development_dependency 'rspec'
|
33
|
+
s.add_development_dependency 'rubocop'
|
34
|
+
s.add_development_dependency 'vcr'
|
35
|
+
s.add_development_dependency 'webmock'
|
36
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: https://qualysapi.qualys.eu/api/2.0/fo/scan/?action=list
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
response:
|
10
|
+
status:
|
11
|
+
code: 200
|
12
|
+
message: OK
|
13
|
+
body:
|
14
|
+
encoding: UTF-8
|
15
|
+
string: "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<!DOCTYPE SCAN_LIST_OUTPUT
|
16
|
+
SYSTEM \"https://qualysapi.qualys.eu/api/2.0/fo/scan/scan_list_output.dtd\">\n<!--
|
17
|
+
This report was generated with an evaluation version of Qualys //--> \n<SCAN_LIST_OUTPUT>\n
|
18
|
+
\ <RESPONSE>\n <DATETIME>2017-12-11T12:49:00Z</DATETIME>\n <SCAN_LIST>\n
|
19
|
+
\ <SCAN>\n <REF>scan/XXXX633905.79357</REF>\n <TYPE>On-Demand</TYPE>\n
|
20
|
+
\ <TITLE><![CDATA[shellshock 20171207]]></TITLE>\n <USER_LOGIN>Thomas</USER_LOGIN>\n
|
21
|
+
\ <LAUNCH_DATETIME>2017-12-07T08:05:05Z</LAUNCH_DATETIME>\n <DURATION>00:01:43</DURATION>\n
|
22
|
+
\ <PROCESSING_PRIORITY>0 - No Priority</PROCESSING_PRIORITY>\n <PROCESSED>1</PROCESSED>\n
|
23
|
+
\ <STATUS>\n <STATE>Error</STATE>\n </STATUS>\n <TARGET><![CDATA[47.69.112.62]]></TARGET>\n
|
24
|
+
\ </SCAN>\n <SCAN>\n <REF>scan/1512633883.79354</REF>\n <TYPE>On-Demand</TYPE>\n
|
25
|
+
\ <TITLE><![CDATA[shellshock 20171207]]></TITLE>\n <USER_LOGIN>Thomas</USER_LOGIN>\n
|
26
|
+
\ <LAUNCH_DATETIME>2017-12-07T08:04:43Z</LAUNCH_DATETIME>\n <DURATION>00:07:02</DURATION>\n
|
27
|
+
\ <PROCESSING_PRIORITY>0 - No Priority</PROCESSING_PRIORITY>\n <PROCESSED>1</PROCESSED>\n
|
28
|
+
\ <STATUS>\n <STATE>Finished</STATE>\n </STATUS>\n <TARGET><![CDATA[47.69.112.62]]></TARGET>\n
|
29
|
+
\ </SCAN>\n <SCAN>\n <REF>scan/1512633720.79248</REF>\n <TYPE>On-Demand</TYPE>\n
|
30
|
+
\ <TITLE><![CDATA[shellshock]]></TITLE>\n <USER_LOGIN>Thomas</USER_LOGIN>\n
|
31
|
+
\ <LAUNCH_DATETIME>2017-12-07T08:01:59Z</LAUNCH_DATETIME>\n <DURATION>00:00:06</DURATION>\n
|
32
|
+
\ <PROCESSING_PRIORITY>0 - No Priority</PROCESSING_PRIORITY>\n <PROCESSED>1</PROCESSED>\n
|
33
|
+
\ <STATUS>\n <STATE>Error</STATE>\n </STATUS>\n <TARGET><![CDATA[47.69.112.62]]></TARGET>\n
|
34
|
+
\ </SCAN>\n <SCAN>\n <REF>scan/1512469561.67379</REF>\n <TYPE>On-Demand</TYPE>\n
|
35
|
+
\ <TITLE><![CDATA[test_vuln]]></TITLE>\n <USER_LOGIN>Thomas</USER_LOGIN>\n
|
36
|
+
\ <LAUNCH_DATETIME>2017-12-05T10:26:01Z</LAUNCH_DATETIME>\n <DURATION>00:04:48</DURATION>\n
|
37
|
+
\ <PROCESSING_PRIORITY>1 - Emergency</PROCESSING_PRIORITY>\n <PROCESSED>1</PROCESSED>\n
|
38
|
+
\ <STATUS>\n <STATE>Finished</STATE>\n </STATUS>\n <TARGET><![CDATA[192.168.1.100]]></TARGET>\n
|
39
|
+
\ </SCAN>\n <SCAN>\n <REF>scan/1512466786.67046</REF>\n <TYPE>On-Demand</TYPE>\n
|
40
|
+
\ <TITLE><![CDATA[test]]></TITLE>\n <USER_LOGIN>Thomas</USER_LOGIN>\n
|
41
|
+
\ <LAUNCH_DATETIME>2017-12-05T09:39:46Z</LAUNCH_DATETIME>\n <DURATION>00:07:56</DURATION>\n
|
42
|
+
\ <PROCESSING_PRIORITY>0 - No Priority</PROCESSING_PRIORITY>\n <PROCESSED>1</PROCESSED>\n
|
43
|
+
\ <STATUS>\n <STATE>Finished</STATE>\n </STATUS>\n <TARGET><![CDATA[88.78.187.177]]></TARGET>\n
|
44
|
+
\ </SCAN>\n </SCAN_LIST>\n </RESPONSE>\n</SCAN_LIST_OUTPUT>\n<!--
|
45
|
+
This report was generated with an evaluation version of Qualys //--> \n<!--
|
46
|
+
CONFIDENTIAL AND PROPRIETARY INFORMATION. Qualys provides the QualysGuard
|
47
|
+
Service \"As Is,\" without any warranty of any kind. Qualys makes no warranty
|
48
|
+
that the information contained in this report is complete or error-free. Copyright
|
49
|
+
2017, Qualys, Inc. //--> \n"
|
50
|
+
http_version:
|
51
|
+
recorded_at: Mon, 11 Dec 2017 12:49:00 GMT
|
52
|
+
recorded_with: VCR 4.0.0
|