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
@@ -5,37 +5,15 @@ module Dradis::Plugins
|
|
5
5
|
describe 'Qualys upload plugin' do
|
6
6
|
before(:each) do
|
7
7
|
# Stub template service
|
8
|
-
templates_dir = File.expand_path('
|
8
|
+
templates_dir = File.expand_path('../../../../templates', __FILE__)
|
9
9
|
expect_any_instance_of(Dradis::Plugins::TemplateService)
|
10
10
|
.to receive(:default_templates_dir).and_return(templates_dir)
|
11
11
|
|
12
|
-
|
13
|
-
plugin = Dradis::Plugins::Qualys
|
12
|
+
stub_content_service
|
14
13
|
|
15
|
-
@
|
16
|
-
logger: Logger.new(STDOUT),
|
17
|
-
plugin: plugin
|
18
|
-
)
|
19
|
-
|
20
|
-
@importer = Dradis::Plugins::Qualys::Importer.new(
|
14
|
+
@importer = Dradis::Plugins::Qualys::Vuln::Importer.new(
|
21
15
|
content_service: @content_service
|
22
16
|
)
|
23
|
-
|
24
|
-
# Stub dradis-plugins methods
|
25
|
-
#
|
26
|
-
# They return their argument hashes as objects mimicking
|
27
|
-
# Nodes, Issues, etc
|
28
|
-
allow(@content_service).to receive(:create_node) do |args|
|
29
|
-
obj = OpenStruct.new(args)
|
30
|
-
obj.define_singleton_method(:set_property) { |_, __| }
|
31
|
-
obj
|
32
|
-
end
|
33
|
-
allow(@content_service).to receive(:create_issue) do |args|
|
34
|
-
OpenStruct.new(args)
|
35
|
-
end
|
36
|
-
allow(@content_service).to receive(:create_evidence) do |args|
|
37
|
-
OpenStruct.new(args)
|
38
|
-
end
|
39
17
|
end
|
40
18
|
|
41
19
|
let(:example_xml) { 'spec/fixtures/files/simple.xml' }
|
@@ -84,11 +62,12 @@ module Dradis::Plugins
|
|
84
62
|
expect_to_create_issue_with(
|
85
63
|
text: "Apache 1.3 HTTP Server Expect Header Cross-Site Scripting"
|
86
64
|
)
|
87
|
-
|
65
|
+
|
88
66
|
expect_to_create_issue_with(
|
89
|
-
|
67
|
+
text: "Apache Web Server ETag Header Information Disclosure Weakness",
|
68
|
+
text: "OpenBSD has released a \"patch\":ftp://ftp.openbsd.org/pub/OpenBSD/patches/3.2/common/008_httpd.patch that fixes this vulnerability. After installing the patch, inode numbers returned from the server are encoded using a private hash to avoid the release of sensitive information.\n\n\n\nCustomers"
|
90
69
|
)
|
91
|
-
|
70
|
+
|
92
71
|
run_import!
|
93
72
|
end
|
94
73
|
|
@@ -143,7 +122,7 @@ module Dradis::Plugins
|
|
143
122
|
context "when an issue has no RESULT element" do
|
144
123
|
#let(:example_xml) { 'spec/fixtures/files/no_result.xml' }
|
145
124
|
|
146
|
-
it "detects an issue without a RESULT element and applies (n/a)" do
|
125
|
+
it "detects an issue without a RESULT element and applies (n/a) and strips/replaces formatting tags" do
|
147
126
|
# 1 node should be created:
|
148
127
|
expect_to_create_node_with(label: '10.0.155.160')
|
149
128
|
|
@@ -151,7 +130,8 @@ module Dradis::Plugins
|
|
151
130
|
# - TCP/IP: Sequence number in both hosts
|
152
131
|
# Each one should create 1 issue and 1 evidence
|
153
132
|
expect_to_create_issue_with(
|
154
|
-
text: "Sequence Number Approximation Based Denial of Service"
|
133
|
+
text: "Sequence Number Approximation Based Denial of Service",
|
134
|
+
text: "Please first check the results section below for the port number on which this vulnerability was detected. If that port number is known to be used for port-forwarding, then it is the backend host that is really vulnerable.\n\n\n\nVarious implementations and products including Check Point, Cisco, Cray Inc, Hitachi, Internet Initiative Japan, Inc (IIJ), Juniper Networks, NEC, Polycom, and Yamaha are currently undergoing review. Contact the vendors to obtain more information about affected products and fixes. \"NISCC Advisory 236929 - Vulnerability Issues in TCP\":http://packetstormsecurity.org/0404-advisories/246929.html details the vendor patch status as of the time of the advisory, and identifies resolutions and workarounds."
|
155
135
|
)
|
156
136
|
|
157
137
|
expect_to_create_evidence_with(
|
@@ -163,28 +143,5 @@ module Dradis::Plugins
|
|
163
143
|
@importer.import(file: 'spec/fixtures/files/no_result.xml')
|
164
144
|
end
|
165
145
|
end
|
166
|
-
|
167
|
-
|
168
|
-
def expect_to_create_node_with(label:)
|
169
|
-
expect(@content_service).to receive(:create_node).with(
|
170
|
-
hash_including label: label
|
171
|
-
).once
|
172
|
-
end
|
173
|
-
|
174
|
-
def expect_to_create_issue_with(text:)
|
175
|
-
expect(@content_service).to receive(:create_issue) do |args|
|
176
|
-
expect(args[:text]).to include text
|
177
|
-
OpenStruct.new(args)
|
178
|
-
end.once
|
179
|
-
end
|
180
|
-
|
181
|
-
def expect_to_create_evidence_with(content:, issue:, node_label:)
|
182
|
-
expect(@content_service).to receive(:create_evidence) do |args|
|
183
|
-
expect(args[:content]).to include content
|
184
|
-
expect(args[:issue].text).to include issue
|
185
|
-
expect(args[:node].label).to eq node_label
|
186
|
-
end.once
|
187
|
-
end
|
188
|
-
|
189
146
|
end
|
190
147
|
end
|
@@ -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::WAS::Importer.new(
|
15
|
+
content_service: @content_service
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
let(:example_xml) { 'spec/fixtures/files/simple_was.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: 'example.com')
|
24
|
+
run_import!
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'creates issues as needed' do
|
28
|
+
expect_to_create_issue_with(text: 'DNS Host Name')
|
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: 'DNS Host Name',
|
36
|
+
node_label: 'example.com'
|
37
|
+
)
|
38
|
+
run_import!
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -0,0 +1,46 @@
|
|
1
|
+
module SpecMacros
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
def stub_content_service
|
5
|
+
# Init services
|
6
|
+
plugin = Dradis::Plugins::Qualys
|
7
|
+
|
8
|
+
@content_service = Dradis::Plugins::ContentService::Base.new(
|
9
|
+
logger: Logger.new(STDOUT),
|
10
|
+
plugin: plugin
|
11
|
+
)
|
12
|
+
|
13
|
+
# Stub dradis-plugins methods
|
14
|
+
#
|
15
|
+
# They return their argument hashes as objects mimicking
|
16
|
+
# Nodes, Issues, etc
|
17
|
+
allow(@content_service).to receive(:create_node) do |args|
|
18
|
+
obj = OpenStruct.new(args)
|
19
|
+
obj.define_singleton_method(:set_property) { |_, __| }
|
20
|
+
obj
|
21
|
+
end
|
22
|
+
allow(@content_service).to receive(:create_issue) do |args|
|
23
|
+
OpenStruct.new(args)
|
24
|
+
end
|
25
|
+
allow(@content_service).to receive(:create_evidence) do |args|
|
26
|
+
OpenStruct.new(args)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def expect_to_create_node_with(label:)
|
31
|
+
expect(@content_service).to receive(:create_node).with(
|
32
|
+
hash_including label: label
|
33
|
+
).once
|
34
|
+
end
|
35
|
+
|
36
|
+
def expect_to_create_issue_with(text:)
|
37
|
+
expect(@content_service).to receive(:create_issue) do |args|
|
38
|
+
expect(args[:text]).to include text
|
39
|
+
OpenStruct.new(args)
|
40
|
+
end.once
|
41
|
+
end
|
42
|
+
|
43
|
+
def expect_to_create_evidence_with(content:, issue:, node_label:)
|
44
|
+
expect(@content_service).to receive(:create_evidence)
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<VULN_INFO>
|
2
|
+
<QID id="qid_238938">238938</QID>
|
3
|
+
<TYPE>Vuln</TYPE>
|
4
|
+
<SSL>false</SSL>
|
5
|
+
<RESULT format="table"><![CDATA[Package Installed Version Required Version
|
6
|
+
kernel-debug 3.10.0-957.27.2.el7.x86_64 3.10.0-1160.11.1.el7
|
7
|
+
kernel-debug 3.10.0-1160.6.1.el7.x86_64 3.10.0-1160.11.1.el7]]></RESULT>
|
8
|
+
<FIRST_FOUND>2020-12-18T13:11:56Z</FIRST_FOUND>
|
9
|
+
<LAST_FOUND>2021-03-19T13:05:42Z</LAST_FOUND>
|
10
|
+
<TIMES_FOUND>447</TIMES_FOUND>
|
11
|
+
<VULN_STATUS>Active</VULN_STATUS>
|
12
|
+
<CVSS_FINAL>5.5</CVSS_FINAL>
|
13
|
+
<CVSS3_FINAL>6.3</CVSS3_FINAL>
|
14
|
+
</VULN_INFO>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
asset-issue.category
|
2
|
+
asset-issue.cvss3_base
|
3
|
+
asset-issue.cvss3_temporal
|
4
|
+
asset-issue.cvss_base
|
5
|
+
asset-issue.cvss_temporal
|
6
|
+
asset-issue.impact
|
7
|
+
asset-issue.last_update
|
8
|
+
asset-issue.pci_flag
|
9
|
+
asset-issue.qid
|
10
|
+
asset-issue.result
|
11
|
+
asset-issue.severity
|
12
|
+
asset-issue.solution
|
13
|
+
asset-issue.threat
|
14
|
+
asset-issue.title
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<VULN_DETAILS id="qid_11">
|
2
|
+
<QID id="qid_11">11</QID>
|
3
|
+
<TITLE><![CDATA[Hidden RPC Services]]></TITLE>
|
4
|
+
<SEVERITY>2</SEVERITY>
|
5
|
+
<CATEGORY>RPC</CATEGORY>
|
6
|
+
<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.
|
7
|
+
<P>
|
8
|
+
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>
|
9
|
+
<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>
|
10
|
+
<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>
|
11
|
+
<PCI_FLAG>1</PCI_FLAG>
|
12
|
+
<LAST_UPDATE>1999-01-01T08:00:00Z</LAST_UPDATE>
|
13
|
+
<CVSS_SCORE>
|
14
|
+
<CVSS_BASE source="service">5</CVSS_BASE>
|
15
|
+
<CVSS_TEMPORAL>3.6</CVSS_TEMPORAL>
|
16
|
+
</CVSS_SCORE>
|
17
|
+
<CVSS3_SCORE>
|
18
|
+
<CVSS3_BASE>-</CVSS3_BASE>
|
19
|
+
<CVSS3_TEMPORAL>-</CVSS3_TEMPORAL>
|
20
|
+
</CVSS3_SCORE>
|
21
|
+
</VULN_DETAILS>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#[Title]#
|
2
|
+
%asset-issue.title%
|
3
|
+
|
4
|
+
#[Severity]#
|
5
|
+
%asset-issue.severity%
|
6
|
+
|
7
|
+
#[Categories]#
|
8
|
+
Category: %asset-issue.category%
|
9
|
+
|
10
|
+
#[CVSSv3.BaseScore]#
|
11
|
+
%asset-issue.cvss3_base%
|
12
|
+
|
13
|
+
#[CVSSv3.TemporalScore]#
|
14
|
+
%asset-issue.cvss3_temporal%
|
15
|
+
|
16
|
+
#[Threat]#
|
17
|
+
%asset-issue.threat%
|
18
|
+
|
19
|
+
%asset-issue.impact%
|
20
|
+
|
21
|
+
#[Solution]#
|
22
|
+
%asset-issue.solution%
|
data/templates/element.fields
CHANGED
data/templates/element.template
CHANGED
@@ -0,0 +1,44 @@
|
|
1
|
+
<VULNERABILITY>
|
2
|
+
<UNIQUE_ID>db9bd89e-a8d8-402d-a6ca-8f6ff8be426f</UNIQUE_ID>
|
3
|
+
<ID>827065910</ID>
|
4
|
+
<DETECTION_ID>20879664</DETECTION_ID>
|
5
|
+
<QID>150124</QID>
|
6
|
+
<URL>http://demo.hackmebank.net/index.jsp?content=personal_loans.htm</URL>
|
7
|
+
<ACCESS_PATH>
|
8
|
+
<URL>http://demo.hackmebank.net/index.jsp</URL>
|
9
|
+
</ACCESS_PATH>
|
10
|
+
<AJAX>false</AJAX>
|
11
|
+
<AUTHENTICATION>Not Required</AUTHENTICATION>
|
12
|
+
<DETECTION_DATE>11 Oct 2021 07:16PM GMT-0500</DETECTION_DATE>
|
13
|
+
<POTENTIAL>false</POTENTIAL>
|
14
|
+
<PAYLOADS>
|
15
|
+
<PAYLOAD>
|
16
|
+
<NUM>1</NUM>
|
17
|
+
<PAYLOAD>N/A</PAYLOAD>
|
18
|
+
<REQUEST>
|
19
|
+
<METHOD>GET</METHOD>
|
20
|
+
<URL>http://demo.hackmebank.net/index.jsp?content=business.htm</URL>
|
21
|
+
<HEADERS>
|
22
|
+
<HEADER>
|
23
|
+
<key>Host</key>
|
24
|
+
<value><![CDATA[ demo.hackmebank.net
|
25
|
+
</HEADER>
|
26
|
+
<HEADER>
|
27
|
+
<key>User-Agent</key>
|
28
|
+
<value><![CDATA[ Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.1 Safari/605.1.15
|
29
|
+
</HEADER>
|
30
|
+
<HEADER>
|
31
|
+
<key>Accept</key>
|
32
|
+
<value><![CDATA[ */*
|
33
|
+
</HEADER>
|
34
|
+
</HEADERS>
|
35
|
+
<BODY></BODY>
|
36
|
+
</REQUEST>
|
37
|
+
<RESPONSE>
|
38
|
+
<CONTENTS base64="true"><![CDATA[VGhlIFVSSSB3YXMgZnJhbWVkLgo=
|
39
|
+
]]></CONTENTS>
|
40
|
+
</RESPONSE>
|
41
|
+
</PAYLOAD>
|
42
|
+
</PAYLOADS>
|
43
|
+
<IGNORED>false</IGNORED>
|
44
|
+
</VULNERABILITY>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
was-issue.category
|
2
|
+
was-issue.cvss_base
|
3
|
+
was-issue.cvss_temporal
|
4
|
+
was-issue.cvss3_base
|
5
|
+
was-issue.cvss3_temporal
|
6
|
+
was-issue.cvss3_vector
|
7
|
+
was-issue.cwe
|
8
|
+
was-issue.description
|
9
|
+
was-issue.group
|
10
|
+
was-issue.impact
|
11
|
+
was-issue.owasp
|
12
|
+
was-issue.qid
|
13
|
+
was-issue.severity
|
14
|
+
was-issue.solution
|
15
|
+
was-issue.title
|
16
|
+
was-issue.wasc
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<QID>
|
2
|
+
<QID>150001</QID>
|
3
|
+
<CATEGORY>Confirmed Vulnerability</CATEGORY>
|
4
|
+
<SEVERITY>5</SEVERITY>
|
5
|
+
<TITLE>Reflected Cross-Site Scripting (XSS) Vulnerabilities</TITLE>
|
6
|
+
<GROUP>XSS</GROUP>
|
7
|
+
<OWASP>A7</OWASP>
|
8
|
+
<WASC>WASC-8</WASC>
|
9
|
+
<CWE>CWE-79</CWE>
|
10
|
+
<CVSS_BASE>4.3</CVSS_BASE>
|
11
|
+
<CVSS_TEMPORAL>3.9</CVSS_TEMPORAL>
|
12
|
+
<CVSS_V3>
|
13
|
+
<BASE>6.1</BASE>
|
14
|
+
<TEMPORAL>5.8</TEMPORAL>
|
15
|
+
<ATTACK_VECTOR>Network</ATTACK_VECTOR>
|
16
|
+
</CVSS_V3>
|
17
|
+
<DESCRIPTION><![CDATA[XSS vulnerabilities occur when the Web application echoes user-supplied data in an HTML response sent to the Web browser. For example, a Web application might include the user's name as part of a welcome message or display a home address when confirming a shipping destination. If the user-supplied data contain characters that are interpreted as part of an HTML element instead of literal text, then an attacker can modify the HTML that is received by the victim's Web browser.
|
18
|
+
<P>
|
19
|
+
The XSS payload is echoed in HTML document returned by the request. An XSS payload may consist of HTML, JavaScript or other content that will be rendered by the browser. In order to exploit this vulnerability, a malicious user would need to trick a victim into visiting the URL with the XSS payload.]]></DESCRIPTION>
|
20
|
+
<IMPACT>XSS exploits pose a significant threat to a Web application, its users and user data. XSS exploits target the users of a Web application rather than the Web application itself. An exploit can lead to theft of the user's credentials and personal or financial information. Complex exploits and attack scenarios are possible via XSS because it enables an attacker to execute dynamic code. Consequently, any capability or feature available to the Web browser (for example HTML, JavaScript, Flash and Java applets) can be used to as a part of a compromise.</IMPACT>
|
21
|
+
<SOLUTION><![CDATA[Filter all data collected from the client including user-supplied content and browser content such as Referrer and User-Agent headers.
|
22
|
+
<P>
|
23
|
+
Any data collected from the client and displayed in a Web page should be HTML-encoded to ensure the content is rendered as text instead of an HTML element or JavaScript.]]></SOLUTION>
|
24
|
+
</QID>
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#[Title]#
|
2
|
+
%was-issue.title%
|
3
|
+
|
4
|
+
#[Severity]#
|
5
|
+
%was-issue.severity%
|
6
|
+
|
7
|
+
#[Categories]#
|
8
|
+
Category: %was-issue.category%
|
9
|
+
Group: %was-issue.group%
|
10
|
+
OWASP: %was-issue.owasp%
|
11
|
+
CWE: %was-issue.cwe%
|
12
|
+
|
13
|
+
#[CVSSv3.Vector]#
|
14
|
+
%was-issue.cvss3_vector%
|
15
|
+
|
16
|
+
#[CVSSv3.BaseScore]#
|
17
|
+
%was-issue.cvss3_base%
|
18
|
+
|
19
|
+
#[CVSSv3.TemporalScore]#
|
20
|
+
%was-issue.cvss3_temporal%
|
21
|
+
|
22
|
+
#[Description]#
|
23
|
+
%was-issue.description%
|
24
|
+
|
25
|
+
%was-issue.impact%
|
26
|
+
|
27
|
+
#[Solution]#
|
28
|
+
%was-issue.solution%
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dradis-qualys
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Martin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-04-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dradis-plugins
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 4.0
|
19
|
+
version: '4.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 4.0
|
26
|
+
version: '4.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: nokogiri
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -107,6 +107,7 @@ files:
|
|
107
107
|
- ".gitignore"
|
108
108
|
- ".rspec"
|
109
109
|
- CHANGELOG.md
|
110
|
+
- CHANGELOG.template
|
110
111
|
- CONTRIBUTING.md
|
111
112
|
- Gemfile
|
112
113
|
- LICENSE
|
@@ -115,26 +116,49 @@ files:
|
|
115
116
|
- dradis-qualys.gemspec
|
116
117
|
- lib/dradis-qualys.rb
|
117
118
|
- lib/dradis/plugins/qualys.rb
|
119
|
+
- lib/dradis/plugins/qualys/asset/importer.rb
|
118
120
|
- lib/dradis/plugins/qualys/engine.rb
|
119
121
|
- lib/dradis/plugins/qualys/field_processor.rb
|
120
122
|
- lib/dradis/plugins/qualys/gem_version.rb
|
121
|
-
- lib/dradis/plugins/qualys/importer.rb
|
122
123
|
- lib/dradis/plugins/qualys/version.rb
|
124
|
+
- lib/dradis/plugins/qualys/vuln/importer.rb
|
125
|
+
- lib/dradis/plugins/qualys/was/importer.rb
|
126
|
+
- lib/qualys/asset/evidence.rb
|
127
|
+
- lib/qualys/asset/vulnerability.rb
|
123
128
|
- lib/qualys/element.rb
|
129
|
+
- lib/qualys/was/qid.rb
|
130
|
+
- lib/qualys/was/vulnerability.rb
|
124
131
|
- lib/tasks/thorfile.rb
|
125
132
|
- spec/.keep
|
126
133
|
- spec/fixtures/files/no_result.xml
|
127
134
|
- spec/fixtures/files/simple.xml
|
135
|
+
- spec/fixtures/files/simple_asset.xml
|
136
|
+
- spec/fixtures/files/simple_was.xml
|
128
137
|
- spec/fixtures/files/two_hosts_common_issue.xml
|
138
|
+
- spec/qualys/asset/importer_spec.rb
|
129
139
|
- spec/qualys/element_spec.rb
|
130
|
-
- spec/qualys/importer_spec.rb
|
140
|
+
- spec/qualys/vuln/importer_spec.rb
|
141
|
+
- spec/qualys/was/importer_spec.rb
|
131
142
|
- spec/spec_helper.rb
|
143
|
+
- spec/support/spec_macros.rb
|
144
|
+
- templates/asset-evidence.fields
|
145
|
+
- templates/asset-evidence.sample
|
146
|
+
- templates/asset-evidence.template
|
147
|
+
- templates/asset-issue.fields
|
148
|
+
- templates/asset-issue.sample
|
149
|
+
- templates/asset-issue.template
|
132
150
|
- templates/element.fields
|
133
151
|
- templates/element.sample
|
134
152
|
- templates/element.template
|
135
153
|
- templates/evidence.fields
|
136
154
|
- templates/evidence.sample
|
137
155
|
- templates/evidence.template
|
156
|
+
- templates/was-evidence.fields
|
157
|
+
- templates/was-evidence.sample
|
158
|
+
- templates/was-evidence.template
|
159
|
+
- templates/was-issue.fields
|
160
|
+
- templates/was-issue.sample
|
161
|
+
- templates/was-issue.template
|
138
162
|
homepage: http://dradisframework.org
|
139
163
|
licenses:
|
140
164
|
- GPL-2
|
@@ -162,7 +186,12 @@ test_files:
|
|
162
186
|
- spec/.keep
|
163
187
|
- spec/fixtures/files/no_result.xml
|
164
188
|
- spec/fixtures/files/simple.xml
|
189
|
+
- spec/fixtures/files/simple_asset.xml
|
190
|
+
- spec/fixtures/files/simple_was.xml
|
165
191
|
- spec/fixtures/files/two_hosts_common_issue.xml
|
192
|
+
- spec/qualys/asset/importer_spec.rb
|
166
193
|
- spec/qualys/element_spec.rb
|
167
|
-
- spec/qualys/importer_spec.rb
|
194
|
+
- spec/qualys/vuln/importer_spec.rb
|
195
|
+
- spec/qualys/was/importer_spec.rb
|
168
196
|
- spec/spec_helper.rb
|
197
|
+
- spec/support/spec_macros.rb
|
@@ -1,88 +0,0 @@
|
|
1
|
-
module Dradis::Plugins::Qualys
|
2
|
-
class Importer < Dradis::Plugins::Upload::Importer
|
3
|
-
|
4
|
-
attr_accessor :host_node
|
5
|
-
|
6
|
-
# The framework will call this function if the user selects this plugin from
|
7
|
-
# the dropdown list and uploads a file.
|
8
|
-
# @returns true if the operation was successful, false otherwise
|
9
|
-
def import(params={})
|
10
|
-
file_content = File.read( params[:file] )
|
11
|
-
|
12
|
-
logger.info{'Parsing Qualys output file...'}
|
13
|
-
@doc = Nokogiri::XML( file_content )
|
14
|
-
logger.info{'Done.'}
|
15
|
-
|
16
|
-
if @doc.root.name != 'SCAN'
|
17
|
-
error = "No scan results were detected in the uploaded file. Ensure you uploaded a Qualys XML file."
|
18
|
-
logger.fatal{ error }
|
19
|
-
content_service.create_note text: error
|
20
|
-
return false
|
21
|
-
end
|
22
|
-
|
23
|
-
@doc.xpath('SCAN/IP').each do |xml_host|
|
24
|
-
process_ip(xml_host)
|
25
|
-
end
|
26
|
-
|
27
|
-
return true
|
28
|
-
end
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
|
-
def process_ip(xml_host)
|
33
|
-
host_ip = xml_host['value']
|
34
|
-
logger.info{ "Host: %s" % host_ip }
|
35
|
-
|
36
|
-
self.host_node = content_service.create_node(label: host_ip, type: :host)
|
37
|
-
|
38
|
-
host_node.set_property(:ip, host_ip)
|
39
|
-
host_node.set_property(:hostname, xml_host['name'])
|
40
|
-
if (xml_os = xml_host.xpath('OS')) && xml_os.any?
|
41
|
-
host_node.set_property(:os, xml_os.text)
|
42
|
-
end
|
43
|
-
host_node.save
|
44
|
-
|
45
|
-
# We treat INFOS, SERVICES, PRACTICES, and VULNS the same way
|
46
|
-
# All of these are imported into Dradis as Issues
|
47
|
-
['INFOS', 'SERVICES', 'PRACTICES', 'VULNS'].each do |collection|
|
48
|
-
xml_host.xpath(collection).each do |xml_collection|
|
49
|
-
process_collection(collection, xml_collection)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def process_collection(collection, xml_collection)
|
55
|
-
xml_cats = xml_collection.xpath('CAT')
|
56
|
-
|
57
|
-
xml_cats.each do |xml_cat|
|
58
|
-
logger.info{ "\t#{ collection } - #{ xml_cat['value'] }" }
|
59
|
-
|
60
|
-
empty_dup_xml_cat = xml_cat.dup
|
61
|
-
empty_dup_xml_cat.children.remove
|
62
|
-
|
63
|
-
# For each INFOS/CAT/INFO, SERVICES/CAT/SERVICE, VULNS/CAT/VULN, etc.
|
64
|
-
xml_cat.xpath(collection.chop).each do |xml_element|
|
65
|
-
dup_xml_cat = empty_dup_xml_cat.dup
|
66
|
-
dup_xml_cat.add_child(xml_element.dup)
|
67
|
-
cat_number = xml_element[:number]
|
68
|
-
|
69
|
-
process_vuln(collection, cat_number, dup_xml_cat)
|
70
|
-
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
# Takes a <CAT> element containing a single <VULN> element and processes an
|
76
|
-
# Issue and Evidence template out of it.
|
77
|
-
def process_vuln(collection, vuln_number, xml_cat)
|
78
|
-
logger.info{ "\t\t => Creating new issue (plugin_id: #{ vuln_number })" }
|
79
|
-
issue_text = template_service.process_template(template: 'element', data: xml_cat)
|
80
|
-
issue_text << "\n\n#[qualys_collection]#\n#{ collection }"
|
81
|
-
issue = content_service.create_issue(text: issue_text, id: vuln_number)
|
82
|
-
|
83
|
-
logger.info{ "\t\t => Creating new evidence" }
|
84
|
-
evidence_content = template_service.process_template(template: 'evidence', data: xml_cat)
|
85
|
-
content_service.create_evidence(issue: issue, node: self.host_node, content: evidence_content)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|