dradis-qualys 4.1.0 → 4.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/lib/dradis/plugins/qualys/asset/importer.rb +115 -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 +107 -0
- data/lib/dradis/plugins/qualys/was/importer.rb +113 -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 +31 -29
- 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} +5 -50
- 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 +34 -6
- data/lib/dradis/plugins/qualys/importer.rb +0 -88
|
@@ -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.4.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-06-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: dradis-plugins
|
|
@@ -116,26 +116,49 @@ files:
|
|
|
116
116
|
- dradis-qualys.gemspec
|
|
117
117
|
- lib/dradis-qualys.rb
|
|
118
118
|
- lib/dradis/plugins/qualys.rb
|
|
119
|
+
- lib/dradis/plugins/qualys/asset/importer.rb
|
|
119
120
|
- lib/dradis/plugins/qualys/engine.rb
|
|
120
121
|
- lib/dradis/plugins/qualys/field_processor.rb
|
|
121
122
|
- lib/dradis/plugins/qualys/gem_version.rb
|
|
122
|
-
- lib/dradis/plugins/qualys/importer.rb
|
|
123
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
|
|
124
128
|
- lib/qualys/element.rb
|
|
129
|
+
- lib/qualys/was/qid.rb
|
|
130
|
+
- lib/qualys/was/vulnerability.rb
|
|
125
131
|
- lib/tasks/thorfile.rb
|
|
126
132
|
- spec/.keep
|
|
127
133
|
- spec/fixtures/files/no_result.xml
|
|
128
134
|
- spec/fixtures/files/simple.xml
|
|
135
|
+
- spec/fixtures/files/simple_asset.xml
|
|
136
|
+
- spec/fixtures/files/simple_was.xml
|
|
129
137
|
- spec/fixtures/files/two_hosts_common_issue.xml
|
|
138
|
+
- spec/qualys/asset/importer_spec.rb
|
|
130
139
|
- spec/qualys/element_spec.rb
|
|
131
|
-
- spec/qualys/importer_spec.rb
|
|
140
|
+
- spec/qualys/vuln/importer_spec.rb
|
|
141
|
+
- spec/qualys/was/importer_spec.rb
|
|
132
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
|
|
133
150
|
- templates/element.fields
|
|
134
151
|
- templates/element.sample
|
|
135
152
|
- templates/element.template
|
|
136
153
|
- templates/evidence.fields
|
|
137
154
|
- templates/evidence.sample
|
|
138
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
|
|
139
162
|
homepage: http://dradisframework.org
|
|
140
163
|
licenses:
|
|
141
164
|
- GPL-2
|
|
@@ -155,7 +178,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
155
178
|
- !ruby/object:Gem::Version
|
|
156
179
|
version: '0'
|
|
157
180
|
requirements: []
|
|
158
|
-
rubygems_version: 3.
|
|
181
|
+
rubygems_version: 3.2.32
|
|
159
182
|
signing_key:
|
|
160
183
|
specification_version: 4
|
|
161
184
|
summary: Qualys add-on for the Dradis Framework.
|
|
@@ -163,7 +186,12 @@ test_files:
|
|
|
163
186
|
- spec/.keep
|
|
164
187
|
- spec/fixtures/files/no_result.xml
|
|
165
188
|
- spec/fixtures/files/simple.xml
|
|
189
|
+
- spec/fixtures/files/simple_asset.xml
|
|
190
|
+
- spec/fixtures/files/simple_was.xml
|
|
166
191
|
- spec/fixtures/files/two_hosts_common_issue.xml
|
|
192
|
+
- spec/qualys/asset/importer_spec.rb
|
|
167
193
|
- spec/qualys/element_spec.rb
|
|
168
|
-
- spec/qualys/importer_spec.rb
|
|
194
|
+
- spec/qualys/vuln/importer_spec.rb
|
|
195
|
+
- spec/qualys/was/importer_spec.rb
|
|
169
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
|