dradis-qualys 4.0.0 → 4.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +47 -53
- data/CHANGELOG.template +12 -0
- data/dradis-qualys.gemspec +1 -1
- data/lib/dradis/plugins/qualys/asset/importer.rb +112 -0
- data/lib/dradis/plugins/qualys/engine.rb +13 -0
- data/lib/dradis/plugins/qualys/field_processor.rb +23 -3
- data/lib/dradis/plugins/qualys/gem_version.rb +1 -1
- data/lib/dradis/plugins/qualys/vuln/importer.rb +103 -0
- data/lib/dradis/plugins/qualys/was/importer.rb +109 -0
- data/lib/dradis/plugins/qualys.rb +4 -1
- data/lib/dradis-qualys.rb +4 -0
- data/lib/qualys/asset/evidence.rb +74 -0
- data/lib/qualys/asset/vulnerability.rb +87 -0
- data/lib/qualys/element.rb +32 -25
- data/lib/qualys/was/qid.rb +85 -0
- data/lib/qualys/was/vulnerability.rb +68 -0
- data/lib/tasks/thorfile.rb +15 -1
- data/spec/fixtures/files/simple_asset.xml +126 -0
- data/spec/fixtures/files/simple_was.xml +134 -0
- data/spec/qualys/asset/importer_spec.rb +41 -0
- data/spec/qualys/{importer_spec.rb → vuln/importer_spec.rb} +10 -53
- data/spec/qualys/was/importer_spec.rb +41 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/support/spec_macros.rb +46 -0
- data/templates/asset-evidence.fields +9 -0
- data/templates/asset-evidence.sample +14 -0
- data/templates/asset-evidence.template +11 -0
- data/templates/asset-issue.fields +14 -0
- data/templates/asset-issue.sample +21 -0
- data/templates/asset-issue.template +22 -0
- data/templates/element.fields +1 -0
- data/templates/element.template +4 -0
- data/templates/was-evidence.fields +6 -0
- data/templates/was-evidence.sample +44 -0
- data/templates/was-evidence.template +11 -0
- data/templates/was-issue.fields +16 -0
- data/templates/was-issue.sample +24 -0
- data/templates/was-issue.template +28 -0
- metadata +36 -7
- data/lib/dradis/plugins/qualys/importer.rb +0 -88
@@ -0,0 +1,87 @@
|
|
1
|
+
module Qualys::Asset
|
2
|
+
# This class represents each of the ASSET_DATA_REPORT/GLOSSARY/VULN_DETAILS_LIST/
|
3
|
+
# VULN_DETAILS elements in the Qualys Asset XML document.
|
4
|
+
#
|
5
|
+
# It provides a convenient way to access the information scattered all over
|
6
|
+
# the XML in attributes and nested tags.
|
7
|
+
#
|
8
|
+
# Instead of providing separate methods for each supported property we rely
|
9
|
+
# on Ruby's #method_missing to do most of the work.
|
10
|
+
class Vulnerability
|
11
|
+
# Accepts an XML node from Nokogiri::XML.
|
12
|
+
def initialize(xml_node)
|
13
|
+
@xml = xml_node
|
14
|
+
end
|
15
|
+
|
16
|
+
# List of supported tags. They can be attributes, simple descendans or
|
17
|
+
# collections (e.g. <references/>, <tags/>)
|
18
|
+
def supported_tags
|
19
|
+
[
|
20
|
+
# simple tags
|
21
|
+
:category, :impact, :last_update, :pci_flag, :qid, :result,
|
22
|
+
:severity, :solution, :threat, :title,
|
23
|
+
|
24
|
+
:cvss3_base, :cvss3_temporal, :cvss_base, :cvss_temporal
|
25
|
+
]
|
26
|
+
end
|
27
|
+
|
28
|
+
# This allows external callers (and specs) to check for implemented
|
29
|
+
# properties
|
30
|
+
def respond_to?(method, include_private=false)
|
31
|
+
return true if supported_tags.include?(method.to_sym)
|
32
|
+
super
|
33
|
+
end
|
34
|
+
|
35
|
+
# This method is invoked by Ruby when a method that is not defined in this
|
36
|
+
# instance is called.
|
37
|
+
#
|
38
|
+
# In our case we inspect the @method@ parameter and try to find the
|
39
|
+
# attribute, simple descendent or collection that it maps to in the XML
|
40
|
+
# tree.
|
41
|
+
def method_missing(method, *args)
|
42
|
+
# We could remove this check and return nil for any non-recognized tag.
|
43
|
+
# The problem would be that it would make tricky to debug problems with
|
44
|
+
# typos. For instance: <>.potr would return nil instead of raising an
|
45
|
+
# exception
|
46
|
+
unless supported_tags.include?(method)
|
47
|
+
super
|
48
|
+
return
|
49
|
+
end
|
50
|
+
|
51
|
+
process_field_value(method.to_s)
|
52
|
+
end
|
53
|
+
|
54
|
+
def process_field_value(method)
|
55
|
+
tag = @xml.at_xpath("./#{method.upcase}")
|
56
|
+
|
57
|
+
if method.starts_with?('cvss')
|
58
|
+
process_cvss_field(method)
|
59
|
+
elsif tag && !tag.text.blank?
|
60
|
+
if tags_with_html_content.include?(method)
|
61
|
+
Qualys.cleanup_html(tag.text)
|
62
|
+
else
|
63
|
+
tag.text
|
64
|
+
end
|
65
|
+
else
|
66
|
+
'n/a'
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def process_cvss_field(method)
|
71
|
+
translations_table = {
|
72
|
+
cvss_base: 'CVSS_SCORE/CVSS_BASE',
|
73
|
+
cvss_temporal: 'CVSS_SCORE/CVSS_TEMPORAL',
|
74
|
+
cvss3_base: 'CVSS3_SCORE/CVSS3_BASE',
|
75
|
+
cvss3_temporal: 'CVSS3_SCORE/CVSS3_TEMPORAL'
|
76
|
+
}
|
77
|
+
|
78
|
+
@xml.xpath("./#{translations_table[method.to_sym]}").text
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def tags_with_html_content
|
84
|
+
%w[threat impact solution]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
data/lib/qualys/element.rb
CHANGED
@@ -1,4 +1,27 @@
|
|
1
1
|
module Qualys
|
2
|
+
|
3
|
+
def self.cleanup_html(source)
|
4
|
+
result = source.dup
|
5
|
+
result.gsub!(/"/, '"')
|
6
|
+
result.gsub!(/</, '<')
|
7
|
+
result.gsub!(/>/, '>')
|
8
|
+
|
9
|
+
result.gsub!(/<p>/i, "\n\n")
|
10
|
+
result.gsub!(/<br>/i, "\n")
|
11
|
+
result.gsub!(/ /, "")
|
12
|
+
result.gsub!(/<a href=\"(.*?)\"\s?target=\"_blank\">(.*?)<\/a>/i) { "\"#{$2.strip}\":#{$1.strip}" }
|
13
|
+
result.gsub!(/<pre>(.*?)<\/pre>/im) { |m| "\n\nbc.. #{$1.strip}\n\np. \n" }
|
14
|
+
result.gsub!(/<b>(.*?)<\/b>/i) { "*#{$1.strip}*" }
|
15
|
+
result.gsub!(/<b>|<\/b>/i, "")
|
16
|
+
result.gsub!(/<i>(.*?)<\/i>/i) { "_#{$1.strip}_" }
|
17
|
+
|
18
|
+
result.gsub!(/<dl>|<\/dl>/i, "\n")
|
19
|
+
result.gsub!(/<dt>(.*?)<\/dt>/i) { "* #{$1.strip}" }
|
20
|
+
result.gsub!(/<dd>(.*?)<\/dd>/i) { "** #{$1.strip}" }
|
21
|
+
result
|
22
|
+
end
|
23
|
+
|
24
|
+
|
2
25
|
# This class represents each of the /SCAN/IP/[INFOS|SERVICES|VULNS|PRACTICES]/CAT/[INFO|SERVICE|VULN|PRACTICE]
|
3
26
|
# elements in the Qualys XML document.
|
4
27
|
#
|
@@ -25,7 +48,10 @@ module Qualys
|
|
25
48
|
:consequence, :solution, :compliance, :result,
|
26
49
|
|
27
50
|
# multiple tags
|
28
|
-
:vendor_reference_list, :cve_id_list, :bugtraq_id_list
|
51
|
+
:vendor_reference_list, :cve_id_list, :bugtraq_id_list,
|
52
|
+
|
53
|
+
# category
|
54
|
+
:qualys_collection
|
29
55
|
]
|
30
56
|
end
|
31
57
|
|
@@ -66,10 +92,10 @@ module Qualys
|
|
66
92
|
return @xml.attributes[method_name].value if @xml.attributes.key?(method_name)
|
67
93
|
|
68
94
|
# Then we try simple children tags: TITLE, LAST_UPDATE, CVSS_BASE...
|
69
|
-
tag = @xml.
|
95
|
+
tag = @xml.at_xpath("./#{method_name.upcase}")
|
70
96
|
if tag && !tag.text.blank?
|
71
97
|
if tags_with_html_content.include?(method)
|
72
|
-
return cleanup_html(tag.text)
|
98
|
+
return Qualys::cleanup_html(tag.text)
|
73
99
|
else
|
74
100
|
return tag.text
|
75
101
|
end
|
@@ -77,11 +103,8 @@ module Qualys
|
|
77
103
|
'n/a'
|
78
104
|
end
|
79
105
|
|
80
|
-
|
81
|
-
|
82
|
-
# @xml.xpath("./references/reference").collect{|entry| {:source => entry['source'], :text => entry.text} }
|
83
|
-
elsif method == 'tags'
|
84
|
-
# @xml.xpath("./tags/tag").collect(&:text)
|
106
|
+
if method_name == 'qualys_collection'
|
107
|
+
@xml.name
|
85
108
|
else
|
86
109
|
# nothing found, the tag is valid but not present in this ReportItem
|
87
110
|
return nil
|
@@ -90,24 +113,8 @@ module Qualys
|
|
90
113
|
|
91
114
|
private
|
92
115
|
|
93
|
-
def cleanup_html(source)
|
94
|
-
result = source.dup
|
95
|
-
result.gsub!(/"/, '"')
|
96
|
-
result.gsub!(/</, '<')
|
97
|
-
result.gsub!(/>/, '>')
|
98
|
-
|
99
|
-
result.gsub!(/<p>/i, "\n\n")
|
100
|
-
result.gsub!(/<br>/i, "\n")
|
101
|
-
result.gsub!(/ /, "")
|
102
|
-
result.gsub!(/<a href=\"(.*?)\" target=\"_blank\">(.*?)<\/a>/i) { "\"#{$2.strip}\":#{$1.strip}" }
|
103
|
-
result.gsub!(/<pre>(.*?)<\/pre>/im) { |m| "\n\nbc.. #{$1.strip}\n\np. \n" }
|
104
|
-
result.gsub!(/<b>(.*?)<\/b>/i) { "*#{$1.strip}*" }
|
105
|
-
result.gsub!(/<i>(.*?)<\/i>/i) { "_#{$1.strip}_" }
|
106
|
-
result
|
107
|
-
end
|
108
|
-
|
109
116
|
def tags_with_html_content
|
110
|
-
[:diagnosis, :solution]
|
117
|
+
[:consequence, :diagnosis, :solution]
|
111
118
|
end
|
112
119
|
|
113
120
|
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Qualys::WAS
|
2
|
+
# This class represents each of the WAS_SCAN_REPORT/GLOSSARY/QID_LIST/QID
|
3
|
+
# elements in the Qualys WAS XML document.
|
4
|
+
#
|
5
|
+
# It provides a convenient way to access the information scattered all over
|
6
|
+
# the XML in attributes and nested tags.
|
7
|
+
#
|
8
|
+
# Instead of providing separate methods for each supported property we rely
|
9
|
+
# on Ruby's #method_missing to do most of the work.
|
10
|
+
class QID
|
11
|
+
# Accepts an XML node from Nokogiri::XML.
|
12
|
+
def initialize(xml_node)
|
13
|
+
@xml = xml_node
|
14
|
+
end
|
15
|
+
|
16
|
+
# List of supported tags. They can be attributes, simple descendans or
|
17
|
+
# collections (e.g. <references/>, <tags/>)
|
18
|
+
def supported_tags
|
19
|
+
[
|
20
|
+
# simple tags
|
21
|
+
:category, :cwe, :description, :group, :impact, :owasp, :qid,
|
22
|
+
:severity, :solution, :title, :wasc,
|
23
|
+
|
24
|
+
:cvss_base, :cvss_temporal, :cvss3_base, :cvss3_temporal, :cvss3_vector
|
25
|
+
]
|
26
|
+
end
|
27
|
+
|
28
|
+
# This allows external callers (and specs) to check for implemented
|
29
|
+
# properties
|
30
|
+
def respond_to?(method, include_private=false)
|
31
|
+
return true if supported_tags.include?(method.to_sym)
|
32
|
+
super
|
33
|
+
end
|
34
|
+
|
35
|
+
# This method is invoked by Ruby when a method that is not defined in this
|
36
|
+
# instance is called.
|
37
|
+
#
|
38
|
+
# In our case we inspect the @method@ parameter and try to find the
|
39
|
+
# attribute, simple descendent or collection that it maps to in the XML
|
40
|
+
# tree.
|
41
|
+
def method_missing(method, *args)
|
42
|
+
# We could remove this check and return nil for any non-recognized tag.
|
43
|
+
# The problem would be that it would make tricky to debug problems with
|
44
|
+
# typos. For instance: <>.potr would return nil instead of raising an
|
45
|
+
# exception
|
46
|
+
unless supported_tags.include?(method)
|
47
|
+
super
|
48
|
+
return
|
49
|
+
end
|
50
|
+
|
51
|
+
process_field_value(method.to_s)
|
52
|
+
end
|
53
|
+
|
54
|
+
def process_field_value(method)
|
55
|
+
tag = @xml.at_xpath("./#{method.upcase}")
|
56
|
+
|
57
|
+
if method.starts_with?('cvss3')
|
58
|
+
process_cvss3_field(method)
|
59
|
+
elsif tag && !tag.text.blank?
|
60
|
+
if tags_with_html_content.include?(method)
|
61
|
+
Qualys.cleanup_html(tag.text)
|
62
|
+
else
|
63
|
+
tag.text
|
64
|
+
end
|
65
|
+
else
|
66
|
+
'n/a'
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def process_cvss3_field(method)
|
71
|
+
translations_table = {
|
72
|
+
cvss3_vector: 'CVSS_V3/ATTACK_VECTOR',
|
73
|
+
cvss3_base: 'CVSS_V3/BASE',
|
74
|
+
cvss3_temporal: 'CVSS_V3/TEMPORAL'
|
75
|
+
}
|
76
|
+
|
77
|
+
@xml.xpath("./#{translations_table[method.to_sym]}").text
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
def tags_with_html_content
|
82
|
+
[:description, :impact, :solution]
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Qualys::WAS
|
2
|
+
# This class represents each of the WAS_SCAN_REPORT/RESULTS/VULNERABILITY_LIST/
|
3
|
+
# VULNERABILITY elements in the Qualys WAS XML document.
|
4
|
+
#
|
5
|
+
# It provides a convenient way to access the information scattered all over
|
6
|
+
# the XML in attributes and nested tags.
|
7
|
+
#
|
8
|
+
# Instead of providing separate methods for each supported property we rely
|
9
|
+
# on Ruby's #method_missing to do most of the work.
|
10
|
+
class Vulnerability
|
11
|
+
# Accepts an XML node from Nokogiri::XML.
|
12
|
+
def initialize(xml_node)
|
13
|
+
@xml = xml_node
|
14
|
+
end
|
15
|
+
|
16
|
+
# List of supported tags. They can be attributes, simple descendans or
|
17
|
+
# collections (e.g. <references/>, <tags/>)
|
18
|
+
def supported_tags
|
19
|
+
[
|
20
|
+
# simple tags
|
21
|
+
:access_paths, :ajax, :authentication, :ignored, :potential, :url
|
22
|
+
]
|
23
|
+
end
|
24
|
+
|
25
|
+
# This allows external callers (and specs) to check for implemented
|
26
|
+
# properties
|
27
|
+
def respond_to?(method, include_private=false)
|
28
|
+
return true if supported_tags.include?(method.to_sym)
|
29
|
+
super
|
30
|
+
end
|
31
|
+
|
32
|
+
# This method is invoked by Ruby when a method that is not defined in this
|
33
|
+
# instance is called.
|
34
|
+
#
|
35
|
+
# In our case we inspect the @method@ parameter and try to find the
|
36
|
+
# attribute, simple descendent or collection that it maps to in the XML
|
37
|
+
# tree.
|
38
|
+
def method_missing(method, *args)
|
39
|
+
# We could remove this check and return nil for any non-recognized tag.
|
40
|
+
# The problem would be that it would make tricky to debug problems with
|
41
|
+
# typos. For instance: <>.potr would return nil instead of raising an
|
42
|
+
# exception
|
43
|
+
unless supported_tags.include?(method)
|
44
|
+
super
|
45
|
+
return
|
46
|
+
end
|
47
|
+
|
48
|
+
method_name = method.to_s
|
49
|
+
|
50
|
+
# Then we try simple children tags: TITLE, LAST_UPDATE, CVSS_BASE...
|
51
|
+
tag = @xml.at_xpath("./#{method_name.upcase}")
|
52
|
+
if tag && !tag.text.blank?
|
53
|
+
if tags_with_html_content.include?(method)
|
54
|
+
return Qualys::cleanup_html(tag.text)
|
55
|
+
else
|
56
|
+
return tag.text
|
57
|
+
end
|
58
|
+
else
|
59
|
+
'n/a'
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
def tags_with_html_content
|
65
|
+
[]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/tasks/thorfile.rb
CHANGED
@@ -14,8 +14,22 @@ class QualysTasks < Thor
|
|
14
14
|
|
15
15
|
detect_and_set_project_scope
|
16
16
|
|
17
|
-
importer = Dradis::Plugins::Qualys::Importer.new(task_options)
|
17
|
+
importer = Dradis::Plugins::Qualys::Vuln::Importer.new(task_options)
|
18
18
|
importer.import(file: file_path)
|
19
19
|
end
|
20
20
|
|
21
|
+
desc "upload_was FILE", "upload Qualys WAS XML results"
|
22
|
+
def upload_was(file_path)
|
23
|
+
require 'config/environment'
|
24
|
+
|
25
|
+
unless File.exists?(file_path)
|
26
|
+
$stderr.puts "** the file [#{file_path}] does not exist"
|
27
|
+
exit -1
|
28
|
+
end
|
29
|
+
|
30
|
+
detect_and_set_project_scope
|
31
|
+
|
32
|
+
importer = Dradis::Plugins::Qualys::WAS::Importer.new(task_options)
|
33
|
+
importer.import(file: file_path)
|
34
|
+
end
|
21
35
|
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" ?>
|
2
|
+
|
3
|
+
<!DOCTYPE ASSET_DATA_REPORT SYSTEM "https://qualysguard.qg3.apps.qualys.com/asset_data_report.dtd">
|
4
|
+
<ASSET_DATA_REPORT>
|
5
|
+
<HEADER>
|
6
|
+
<COMPANY><![CDATA[Security Roots Ltd.]]></COMPANY>
|
7
|
+
<USERNAME>dradispro</USERNAME>
|
8
|
+
<GENERATION_DATETIME>2021-03-19T18:16:17Z</GENERATION_DATETIME>
|
9
|
+
<TEMPLATE><![CDATA[Technical Report]]></TEMPLATE>
|
10
|
+
<TARGET>
|
11
|
+
<USER_ASSET_GROUPS>
|
12
|
+
<ASSET_GROUP_TITLE><![CDATA[ProdManagement]]></ASSET_GROUP_TITLE>
|
13
|
+
</USER_ASSET_GROUPS>
|
14
|
+
<COMBINED_IP_LIST>
|
15
|
+
<RANGE network_id="-100">
|
16
|
+
<START>10.0.0.0</START>
|
17
|
+
<END>10.0.255.255</END>
|
18
|
+
</RANGE>
|
19
|
+
<RANGE network_id="-100">
|
20
|
+
<START>192.168.0.0</START>
|
21
|
+
<END>192.168.255.255</END>
|
22
|
+
</RANGE>
|
23
|
+
</COMBINED_IP_LIST>
|
24
|
+
<ASSET_TAG_LIST>
|
25
|
+
<INCLUDED_TAGS scope="any">
|
26
|
+
<ASSET_TAG><![CDATA[asset-tag]]></ASSET_TAG>
|
27
|
+
</INCLUDED_TAGS>
|
28
|
+
</ASSET_TAG_LIST>
|
29
|
+
</TARGET>
|
30
|
+
<RISK_SCORE_SUMMARY>
|
31
|
+
<TOTAL_VULNERABILITIES>479</TOTAL_VULNERABILITIES>
|
32
|
+
<AVG_SECURITY_RISK>2.5</AVG_SECURITY_RISK>
|
33
|
+
<BUSINESS_RISK>48/100</BUSINESS_RISK>
|
34
|
+
</RISK_SCORE_SUMMARY>
|
35
|
+
</HEADER>
|
36
|
+
<HOST_LIST>
|
37
|
+
<HOST>
|
38
|
+
<IP network_id="0">10.0.0.1</IP>
|
39
|
+
<TRACKING_METHOD>QAGENT</TRACKING_METHOD>
|
40
|
+
<ASSET_TAGS>
|
41
|
+
<ASSET_TAG><![CDATA[Cloud Agent]]></ASSET_TAG>
|
42
|
+
</ASSET_TAGS>
|
43
|
+
<HOST_ID>112859328</HOST_ID>
|
44
|
+
<DNS><![CDATA[ontlpmutil01]]></DNS>
|
45
|
+
<QG_HOSTID><![CDATA[8d7fb998-0512-48c3-bb94-e40ac09ce9d4]]></QG_HOSTID>
|
46
|
+
<OPERATING_SYSTEM><![CDATA[Red Hat Enterprise Linux Server 7.9]]></OPERATING_SYSTEM>
|
47
|
+
<VULN_INFO_LIST>
|
48
|
+
<VULN_INFO>
|
49
|
+
<QID id="qid_11">11</QID>
|
50
|
+
<TYPE>Vuln</TYPE>
|
51
|
+
<SSL>false</SSL>
|
52
|
+
<RESULT format="table"><![CDATA[Package Installed Version Required Version
|
53
|
+
kernel-debug 3.10.0-957.27.2.el7.x86_64 3.10.0-1160.11.1.el7
|
54
|
+
kernel-debug 3.10.0-1160.6.1.el7.x86_64 3.10.0-1160.11.1.el7]]></RESULT>
|
55
|
+
<FIRST_FOUND>2020-12-18T13:11:56Z</FIRST_FOUND>
|
56
|
+
<LAST_FOUND>2021-03-19T13:05:42Z</LAST_FOUND>
|
57
|
+
<TIMES_FOUND>447</TIMES_FOUND>
|
58
|
+
<VULN_STATUS>Active</VULN_STATUS>
|
59
|
+
<CVSS_FINAL>5.5</CVSS_FINAL>
|
60
|
+
<CVSS3_FINAL>6.3</CVSS3_FINAL>
|
61
|
+
</VULN_INFO>
|
62
|
+
</VULN_INFO_LIST>
|
63
|
+
</HOST>
|
64
|
+
</HOST_LIST>
|
65
|
+
<GLOSSARY>
|
66
|
+
<VULN_DETAILS_LIST>
|
67
|
+
<VULN_DETAILS id="qid_11">
|
68
|
+
<QID id="qid_11">11</QID>
|
69
|
+
<TITLE><![CDATA[Hidden RPC Services]]></TITLE>
|
70
|
+
<SEVERITY>2</SEVERITY>
|
71
|
+
<CATEGORY>RPC</CATEGORY>
|
72
|
+
<THREAT><![CDATA[The Portmapper/Rpcbind listens on port 111 and stores an updated list of registered RPC services running on the server (RPC name, version and port number). It acts as a "gateway" for clients wanting to connect to any RPC daemon.
|
73
|
+
<P>
|
74
|
+
When the portmapper/rpcbind is removed or firewalled, standard RPC client programs fail to obtain the portmapper list. However, by sending carefully crafted packets, it's possible to determine which RPC programs are listening on which port. This technique is known as direct RPC scanning. It's used to bypass portmapper/rpcbind in order to find RPC programs running on a port (TCP or UDP ports). On Linux servers, RPC services are typically listening on privileged ports (below 1024), whereas on Solaris, RPC services are on temporary ports (starting with port 32700).]]></THREAT>
|
75
|
+
<IMPACT><![CDATA[Unauthorized users can build a list of RPC services running on the host. If they discover vulnerable RPC services on the host, they then can exploit them.]]></IMPACT>
|
76
|
+
<SOLUTION><![CDATA[Firewalling the portmapper port or removing the portmapper service is not sufficient to prevent unauthorized users from accessing the RPC daemons. You should remove all RPC services that are not strictly required on this host.]]></SOLUTION>
|
77
|
+
<PCI_FLAG>1</PCI_FLAG>
|
78
|
+
<LAST_UPDATE>1999-01-01T08:00:00Z</LAST_UPDATE>
|
79
|
+
<CVSS_SCORE>
|
80
|
+
<CVSS_BASE source="service">5</CVSS_BASE>
|
81
|
+
<CVSS_TEMPORAL>3.6</CVSS_TEMPORAL>
|
82
|
+
</CVSS_SCORE>
|
83
|
+
<CVSS3_SCORE>
|
84
|
+
<CVSS3_BASE>-</CVSS3_BASE>
|
85
|
+
<CVSS3_TEMPORAL>-</CVSS3_TEMPORAL>
|
86
|
+
</CVSS3_SCORE>
|
87
|
+
</VULN_DETAILS>
|
88
|
+
</VULN_DETAILS_LIST>
|
89
|
+
</GLOSSARY>
|
90
|
+
<APPENDICES>
|
91
|
+
<NO_RESULTS>
|
92
|
+
<IP_LIST>
|
93
|
+
<RANGE network_id="-100">
|
94
|
+
<START>10.0.0.0</START>
|
95
|
+
<END>10.0.0.4</END>
|
96
|
+
</RANGE>
|
97
|
+
<RANGE network_id="-100">
|
98
|
+
<START>192.168.0.0</START>
|
99
|
+
<END>192.168.2.4</END>
|
100
|
+
</RANGE>
|
101
|
+
<RANGE network_id="-100">
|
102
|
+
<START>192.168.2.6</START>
|
103
|
+
<END>192.168.255.255</END>
|
104
|
+
</RANGE>
|
105
|
+
</IP_LIST>
|
106
|
+
</NO_RESULTS>
|
107
|
+
<TEMPLATE_DETAILS>
|
108
|
+
<FILTER_SUMMARY>
|
109
|
+
Status:New, Active, Re-Opened, Fixed
|
110
|
+
Display non-running kernels:
|
111
|
+
Off
|
112
|
+
Exclude non-running kernels:
|
113
|
+
Off
|
114
|
+
Exclude non-running services:
|
115
|
+
Off
|
116
|
+
Exclude QIDs not exploitable due to configuration:
|
117
|
+
Off
|
118
|
+
Vulnerabilities:
|
119
|
+
State:Active
|
120
|
+
Included Operating Systems:
|
121
|
+
All Operating Systems
|
122
|
+
</FILTER_SUMMARY>
|
123
|
+
</TEMPLATE_DETAILS>
|
124
|
+
</APPENDICES>
|
125
|
+
</ASSET_DATA_REPORT>
|
126
|
+
<!-- CONFIDENTIAL AND PROPRIETARY INFORMATION. Qualys provides the QualysGuard Service "As Is," without any warranty of any kind. Qualys makes no warranty that the information contained in this report is complete or error-free. Copyright 2021, Qualys, Inc. //-->
|
@@ -0,0 +1,134 @@
|
|
1
|
+
<?xml version='1.0' encoding='UTF-8'?>
|
2
|
+
<WAS_SCAN_REPORT>
|
3
|
+
<HEADER>
|
4
|
+
<NAME>Scan Report</NAME>
|
5
|
+
<DESCRIPTION>Vulnerabilities of all selected scans are consolidated into one report so that you can view their evolution.</DESCRIPTION>
|
6
|
+
<GENERATION_DATETIME>10 Nov 2021 10:00AM GMT-0500</GENERATION_DATETIME>
|
7
|
+
<COMPANY_INFO>
|
8
|
+
<NAME>Sample Company</NAME>
|
9
|
+
<ADDRESS>Sample Address</ADDRESS>
|
10
|
+
<CITY>Sample City</CITY>
|
11
|
+
<STATE>Sample State</STATE>
|
12
|
+
<COUNTRY>Sample Country</COUNTRY>
|
13
|
+
<ZIP_CODE>00000</ZIP_CODE>
|
14
|
+
</COMPANY_INFO>
|
15
|
+
<USER_INFO>
|
16
|
+
<NAME>Test User</NAME>
|
17
|
+
<USERNAME>test_user</USERNAME>
|
18
|
+
<ROLE>PC User,VM User</ROLE>
|
19
|
+
</USER_INFO>
|
20
|
+
</HEADER>
|
21
|
+
<FILTERS>
|
22
|
+
<FILTER>
|
23
|
+
<NAME>REMEDIATION</NAME>
|
24
|
+
<VALUE>Include patched findings</VALUE>
|
25
|
+
</FILTER>
|
26
|
+
<FILTER>
|
27
|
+
<NAME>REMEDIATION</NAME>
|
28
|
+
<VALUE>Show ignored findings </VALUE>
|
29
|
+
</FILTER>
|
30
|
+
</FILTERS>
|
31
|
+
<TARGET>
|
32
|
+
<SCAN>Test Scan</SCAN>
|
33
|
+
</TARGET>
|
34
|
+
<SUMMARY>
|
35
|
+
<GLOBAL_SUMMARY>
|
36
|
+
<SECURITY_RISK>High</SECURITY_RISK>
|
37
|
+
<VULNERABILITY>31</VULNERABILITY>
|
38
|
+
<SENSITIVE_CONTENT>0</SENSITIVE_CONTENT>
|
39
|
+
<INFORMATION_GATHERED>30</INFORMATION_GATHERED>
|
40
|
+
</GLOBAL_SUMMARY>
|
41
|
+
<SUMMARY_STATS>
|
42
|
+
<SUMMARY_STAT>
|
43
|
+
<SCAN>test Scan</SCAN>
|
44
|
+
<DATE>12 Oct 2021</DATE>
|
45
|
+
<LEVEL5>5</LEVEL5>
|
46
|
+
<LEVEL4>2</LEVEL4>
|
47
|
+
<LEVEL3>9</LEVEL3>
|
48
|
+
<LEVEL2>2</LEVEL2>
|
49
|
+
<LEVEL1>13</LEVEL1>
|
50
|
+
<SENSITIVE_CONTENT>0</SENSITIVE_CONTENT>
|
51
|
+
<INFORMATION_GATHERED>30</INFORMATION_GATHERED>
|
52
|
+
</SUMMARY_STAT>
|
53
|
+
</SUMMARY_STATS>
|
54
|
+
</SUMMARY>
|
55
|
+
<RESULTS>
|
56
|
+
<VULNERABILITY_LIST>
|
57
|
+
<VULNERABILITY>
|
58
|
+
<UNIQUE_ID>test-id</UNIQUE_ID>
|
59
|
+
<ID>1</ID>
|
60
|
+
<DETECTION_ID>1</DETECTION_ID>
|
61
|
+
<QID>6</QID>
|
62
|
+
<URL>http://example.com</URL>
|
63
|
+
<ACCESS_PATH>
|
64
|
+
<URL>http://example.com</URL>
|
65
|
+
</ACCESS_PATH>
|
66
|
+
<AJAX>false</AJAX>
|
67
|
+
<AUTHENTICATION>Not Required</AUTHENTICATION>
|
68
|
+
<DETECTION_DATE>21 Aug 2021 10:00PM GMT-0500</DETECTION_DATE>
|
69
|
+
<POTENTIAL>false</POTENTIAL>
|
70
|
+
<PAYLOADS>
|
71
|
+
<PAYLOAD>
|
72
|
+
<NUM>1</NUM>
|
73
|
+
<PAYLOAD>N/A</PAYLOAD>
|
74
|
+
<REQUEST>
|
75
|
+
<METHOD>GET</METHOD>
|
76
|
+
<URL>http://example.com</URL>
|
77
|
+
<HEADERS>
|
78
|
+
<HEADER>
|
79
|
+
<key>Host</key>
|
80
|
+
<value><![CDATA[ example.com ]]></value>
|
81
|
+
</HEADER>
|
82
|
+
<HEADER>
|
83
|
+
<key>User-Agent</key>
|
84
|
+
<value>user-agent</value>
|
85
|
+
</HEADER>
|
86
|
+
<HEADER>
|
87
|
+
<key>Accept</key>
|
88
|
+
<value><![CDATA[ */*
|
89
|
+
</HEADER>
|
90
|
+
</HEADERS>
|
91
|
+
<BODY></BODY>
|
92
|
+
</REQUEST>
|
93
|
+
<RESPONSE>
|
94
|
+
<CONTENTS base64="true"></CONTENTS>
|
95
|
+
</RESPONSE>
|
96
|
+
</PAYLOAD>
|
97
|
+
</PAYLOADS>
|
98
|
+
<IGNORED>false</IGNORED>
|
99
|
+
</VULNERABILITY>
|
100
|
+
</VULNERABILITY_LIST>
|
101
|
+
</RESULTS>
|
102
|
+
<GLOSSARY>
|
103
|
+
<QID_LIST>
|
104
|
+
<QID>
|
105
|
+
<QID>6</QID>
|
106
|
+
<CATEGORY>Information Gathered</CATEGORY>
|
107
|
+
<SEVERITY>1</SEVERITY>
|
108
|
+
<TITLE>DNS Host Name</TITLE>
|
109
|
+
<GROUP>DIAG</GROUP>
|
110
|
+
<DESCRIPTION>The fully qualified domain name of this host, if it was obtained from a DNS server, is displayed in the RESULT section.</DESCRIPTION>
|
111
|
+
<IMPACT>N/A</IMPACT>
|
112
|
+
<SOLUTION>N/A</SOLUTION>
|
113
|
+
<CVSS_BASE>4.3</CVSS_BASE>
|
114
|
+
<CVSS_TEMPORAL>3.9</CVSS_TEMPORAL>
|
115
|
+
<CVSS_V3>
|
116
|
+
<BASE>6.1</BASE>
|
117
|
+
<TEMPORAL>5.8</TEMPORAL>
|
118
|
+
<ATTACK_VECTOR>Network</ATTACK_VECTOR>
|
119
|
+
</CVSS_V3>
|
120
|
+
</QID>
|
121
|
+
</QID_LIST>
|
122
|
+
</GLOSSARY>
|
123
|
+
<APPENDIX>
|
124
|
+
<WEBAPP>
|
125
|
+
<ID>1</ID>
|
126
|
+
<NAME>Test</NAME>
|
127
|
+
<URL>http://example.com</URL>
|
128
|
+
<OWNER>Test User</OWNER>
|
129
|
+
<SCOPE>Limit to URL hostname</SCOPE>
|
130
|
+
<CUSTOM_ATTRIBUTES/>
|
131
|
+
<TAGS/>
|
132
|
+
</WEBAPP>
|
133
|
+
</APPENDIX>
|
134
|
+
</WAS_SCAN_REPORT>
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
module Dradis::Plugins
|
5
|
+
describe 'Qualys upload plugin' do
|
6
|
+
before(:each) do
|
7
|
+
# Stub template service
|
8
|
+
templates_dir = File.expand_path('../../../../templates', __FILE__)
|
9
|
+
expect_any_instance_of(Dradis::Plugins::TemplateService)
|
10
|
+
.to receive(:default_templates_dir).and_return(templates_dir)
|
11
|
+
|
12
|
+
stub_content_service
|
13
|
+
|
14
|
+
@importer = Dradis::Plugins::Qualys::Asset::Importer.new(
|
15
|
+
content_service: @content_service
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
let(:example_xml) { 'spec/fixtures/files/simple_asset.xml' }
|
20
|
+
let(:run_import!) { @importer.import(file: example_xml) }
|
21
|
+
|
22
|
+
it 'creates nodes as needed' do
|
23
|
+
expect_to_create_node_with(label: '10.0.2.8')
|
24
|
+
run_import!
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'creates issues as needed' do
|
28
|
+
expect_to_create_issue_with(text: 'Hidden RPC Services')
|
29
|
+
run_import!
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'creates evidence as needed' do
|
33
|
+
expect_to_create_evidence_with(
|
34
|
+
content: 'http://example.com',
|
35
|
+
issue: 'Hidden RPC Services',
|
36
|
+
node_label: '10.0.2.8'
|
37
|
+
)
|
38
|
+
run_import!
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|