dradis-qualys 3.8.0 → 3.9.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 +5 -0
- data/lib/dradis/plugins/qualys/gem_version.rb +1 -1
- data/lib/dradis/plugins/qualys/importer.rb +4 -3
- data/spec/qualys/importer_spec.rb +160 -170
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c9eeaee42452ed46dd6bce10064713f886d1995d
|
|
4
|
+
data.tar.gz: 53a67d320587cfe75feb81bbb38e6307bf111e93
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e1114fb74433e29cce2b83c01a2b4d1c23d4891ae7570d28947b678c0ebd367d85709d855e4b81ad3a4a0e47b6b03d7c514a20084c93d3d059f845f3ae0a98e5
|
|
7
|
+
data.tar.gz: 2d7b1b9d554914111fefc4c5e3838bd578d0519a1162b01aa27a5ea87e02395b0d2a5f23900a66900778403009debb39f55109f35b3c29dea98080ccb196e433
|
data/CHANGELOG.md
CHANGED
|
@@ -35,11 +35,12 @@ module Dradis::Plugins::Qualys
|
|
|
35
35
|
|
|
36
36
|
self.host_node = content_service.create_node(label: host_ip, type: :host)
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
host_node.set_property(:ip, host_ip)
|
|
39
|
+
host_node.set_property(:hostname, xml_host['name'])
|
|
39
40
|
if (xml_os = xml_host.xpath('OS')) && xml_os.any?
|
|
40
|
-
|
|
41
|
+
host_node.set_property(:os, xml_os.text)
|
|
41
42
|
end
|
|
42
|
-
|
|
43
|
+
host_node.save
|
|
43
44
|
|
|
44
45
|
# We treat INFOS, SERVICES, PRACTICES, and VULNS the same way
|
|
45
46
|
# All of these are imported into Dradis as Issues
|
|
@@ -1,200 +1,190 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
allow(content_service).to receive(:
|
|
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
|
+
# Init services
|
|
13
|
+
plugin = Dradis::Plugins::Qualys
|
|
14
|
+
|
|
15
|
+
@content_service = Dradis::Plugins::ContentService::Base.new(
|
|
16
|
+
logger: Logger.new(STDOUT),
|
|
17
|
+
plugin: plugin
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
@importer = Dradis::Plugins::Qualys::Importer.new(
|
|
21
|
+
content_service: @content_service
|
|
22
|
+
)
|
|
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|
|
|
29
37
|
OpenStruct.new(args)
|
|
30
38
|
end
|
|
31
39
|
end
|
|
32
|
-
end
|
|
33
40
|
|
|
34
|
-
|
|
41
|
+
let(:example_xml) { 'spec/fixtures/files/simple.xml' }
|
|
35
42
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
43
|
+
def run_import!
|
|
44
|
+
@importer.import(file: example_xml)
|
|
45
|
+
end
|
|
39
46
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
expect_to_create_node_with(label: '10.0.155.160')
|
|
47
|
+
it "creates nodes as needed" do
|
|
48
|
+
expect_to_create_node_with(label: '10.0.155.160')
|
|
43
49
|
|
|
44
|
-
|
|
45
|
-
|
|
50
|
+
run_import!
|
|
51
|
+
end
|
|
46
52
|
|
|
53
|
+
# Issues and evidences from vulns
|
|
54
|
+
# There are 7 vulns/infos/services in total:
|
|
55
|
+
# - DNS Host Name
|
|
56
|
+
# - Host Scan Time
|
|
57
|
+
# - Open TCP Services List
|
|
58
|
+
# - Web Server Version
|
|
59
|
+
# - TCP/IP: Sequence number in both hosts
|
|
60
|
+
# - Web server: Apache 1.3
|
|
61
|
+
# - Web server: ETag
|
|
62
|
+
|
|
63
|
+
it "creates issues from vulns" do
|
|
64
|
+
expect_to_create_issue_with(
|
|
65
|
+
text: "DNS Host Name"
|
|
66
|
+
)
|
|
47
67
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
68
|
+
expect_to_create_issue_with(
|
|
69
|
+
text: "Host Scan Time"
|
|
70
|
+
)
|
|
51
71
|
|
|
52
|
-
|
|
53
|
-
|
|
72
|
+
expect_to_create_issue_with(
|
|
73
|
+
text: "Open TCP Services List"
|
|
74
|
+
)
|
|
54
75
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
# - Host Scan Time
|
|
59
|
-
# - Open TCP Services List
|
|
60
|
-
# - Web Server Version
|
|
61
|
-
# - TCP/IP: Sequence number in both hosts
|
|
62
|
-
# - Web server: Apache 1.3
|
|
63
|
-
# - Web server: ETag
|
|
64
|
-
|
|
65
|
-
it "creates issues from vulns" do
|
|
66
|
-
expect_to_create_issue_with(
|
|
67
|
-
text: "DNS Host Name"
|
|
68
|
-
)
|
|
69
|
-
|
|
70
|
-
expect_to_create_issue_with(
|
|
71
|
-
text: "Host Scan Time"
|
|
72
|
-
)
|
|
73
|
-
|
|
74
|
-
expect_to_create_issue_with(
|
|
75
|
-
text: "Open TCP Services List"
|
|
76
|
-
)
|
|
77
|
-
|
|
78
|
-
expect_to_create_issue_with(
|
|
79
|
-
text: "Web Server Version"
|
|
80
|
-
)
|
|
81
|
-
|
|
82
|
-
expect_to_create_issue_with(
|
|
83
|
-
text: "TCP Sequence Number Approximation Based Denial of Service"
|
|
84
|
-
)
|
|
85
|
-
|
|
86
|
-
expect_to_create_issue_with(
|
|
87
|
-
text: "Apache 1.3 HTTP Server Expect Header Cross-Site Scripting"
|
|
88
|
-
)
|
|
89
|
-
|
|
90
|
-
expect_to_create_issue_with(
|
|
91
|
-
text: "Apache Web Server ETag Header Information Disclosure Weakness"
|
|
92
|
-
)
|
|
93
|
-
|
|
94
|
-
run_import!
|
|
95
|
-
end
|
|
76
|
+
expect_to_create_issue_with(
|
|
77
|
+
text: "Web Server Version"
|
|
78
|
+
)
|
|
96
79
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
issue: "DNS Host Name",
|
|
101
|
-
node_label: "10.0.155.160"
|
|
102
|
-
)
|
|
103
|
-
|
|
104
|
-
expect_to_create_evidence_with(
|
|
105
|
-
content: "Scan duration: 5445 seconds\n\nStart time: Fri, Dec 20 2011, 17:38:59 GMT\n\nEnd time: Fri, Dec 20 2011, 19:09:44 GMT",
|
|
106
|
-
issue: "Host Scan Time",
|
|
107
|
-
node_label: "10.0.155.160"
|
|
108
|
-
)
|
|
109
|
-
|
|
110
|
-
expect_to_create_evidence_with(
|
|
111
|
-
content: "\tDescription\tService Detected\tOS On Redirected Port\n80\twww\tWorld Wide Web HTTP\thttp",
|
|
112
|
-
issue: "Open TCP Services List",
|
|
113
|
-
node_label: "10.0.155.160"
|
|
114
|
-
)
|
|
115
|
-
|
|
116
|
-
expect_to_create_evidence_with(
|
|
117
|
-
content: "Server Version\tServer Banner\nApache 1.3\tApache",
|
|
118
|
-
issue: "Web Server Version",
|
|
119
|
-
node_label: "10.0.155.160"
|
|
120
|
-
)
|
|
121
|
-
|
|
122
|
-
expect_to_create_evidence_with(
|
|
123
|
-
content: "Tested on port 80 with an injected SYN/RST offset by 16 bytes.",
|
|
124
|
-
issue: "TCP Sequence Number Approximation Based Denial of Service",
|
|
125
|
-
node_label: "10.0.155.160"
|
|
126
|
-
)
|
|
127
|
-
expect_to_create_evidence_with(
|
|
128
|
-
content: "HTTP/1.1 417 Expectation Failed\nDate: Fri, 20 Dec 2011 19:05:57 GMT",
|
|
129
|
-
issue: "Apache 1.3 HTTP Server Expect Header Cross-Site Scripting",
|
|
130
|
-
node_label: "10.0.155.160"
|
|
131
|
-
)
|
|
132
|
-
expect_to_create_evidence_with(
|
|
133
|
-
content: "3bee-4f12-00794aef",
|
|
134
|
-
issue: "Apache Web Server ETag Header Information Disclosure Weakness",
|
|
135
|
-
node_label: "10.0.155.160"
|
|
136
|
-
)
|
|
137
|
-
|
|
138
|
-
run_import!
|
|
139
|
-
end
|
|
80
|
+
expect_to_create_issue_with(
|
|
81
|
+
text: "TCP Sequence Number Approximation Based Denial of Service"
|
|
82
|
+
)
|
|
140
83
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
84
|
+
expect_to_create_issue_with(
|
|
85
|
+
text: "Apache 1.3 HTTP Server Expect Header Cross-Site Scripting"
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
expect_to_create_issue_with(
|
|
89
|
+
text: "Apache Web Server ETag Header Information Disclosure Weakness"
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
run_import!
|
|
93
|
+
end
|
|
147
94
|
|
|
148
|
-
it "
|
|
149
|
-
|
|
150
|
-
|
|
95
|
+
it "creates evidence from vulns" do
|
|
96
|
+
expect_to_create_evidence_with(
|
|
97
|
+
content: "IP address\tHost name\n10.0.155.160\tNo registered hostname\n",
|
|
98
|
+
issue: "DNS Host Name",
|
|
99
|
+
node_label: "10.0.155.160"
|
|
100
|
+
)
|
|
151
101
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
text: "Sequence Number Approximation Based Denial of Service"
|
|
102
|
+
expect_to_create_evidence_with(
|
|
103
|
+
content: "Scan duration: 5445 seconds\n\nStart time: Fri, Dec 20 2011, 17:38:59 GMT\n\nEnd time: Fri, Dec 20 2011, 19:09:44 GMT",
|
|
104
|
+
issue: "Host Scan Time",
|
|
105
|
+
node_label: "10.0.155.160"
|
|
157
106
|
)
|
|
158
107
|
|
|
159
108
|
expect_to_create_evidence_with(
|
|
160
|
-
content: "
|
|
161
|
-
issue: "
|
|
109
|
+
content: "\tDescription\tService Detected\tOS On Redirected Port\n80\twww\tWorld Wide Web HTTP\thttp",
|
|
110
|
+
issue: "Open TCP Services List",
|
|
111
|
+
node_label: "10.0.155.160"
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
expect_to_create_evidence_with(
|
|
115
|
+
content: "Server Version\tServer Banner\nApache 1.3\tApache",
|
|
116
|
+
issue: "Web Server Version",
|
|
117
|
+
node_label: "10.0.155.160"
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
expect_to_create_evidence_with(
|
|
121
|
+
content: "Tested on port 80 with an injected SYN/RST offset by 16 bytes.",
|
|
122
|
+
issue: "TCP Sequence Number Approximation Based Denial of Service",
|
|
123
|
+
node_label: "10.0.155.160"
|
|
124
|
+
)
|
|
125
|
+
expect_to_create_evidence_with(
|
|
126
|
+
content: "HTTP/1.1 417 Expectation Failed\nDate: Fri, 20 Dec 2011 19:05:57 GMT",
|
|
127
|
+
issue: "Apache 1.3 HTTP Server Expect Header Cross-Site Scripting",
|
|
128
|
+
node_label: "10.0.155.160"
|
|
129
|
+
)
|
|
130
|
+
expect_to_create_evidence_with(
|
|
131
|
+
content: "3bee-4f12-00794aef",
|
|
132
|
+
issue: "Apache Web Server ETag Header Information Disclosure Weakness",
|
|
162
133
|
node_label: "10.0.155.160"
|
|
163
134
|
)
|
|
164
135
|
|
|
165
136
|
run_import!
|
|
166
137
|
end
|
|
167
|
-
end
|
|
168
|
-
|
|
169
138
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
139
|
+
# A VULN is not required to have a RESULT element.
|
|
140
|
+
# See:
|
|
141
|
+
# https://github.com/securityroots/dradispro-tracker/issues/8
|
|
142
|
+
# https://qualysapi.qualys.eu/qwebhelp/fo_help/reports/report_dtd.htm
|
|
143
|
+
context "when an issue has no RESULT element" do
|
|
144
|
+
#let(:example_xml) { 'spec/fixtures/files/no_result.xml' }
|
|
145
|
+
|
|
146
|
+
it "detects an issue without a RESULT element and applies (n/a)" do
|
|
147
|
+
# 1 node should be created:
|
|
148
|
+
expect_to_create_node_with(label: '10.0.155.160')
|
|
149
|
+
|
|
150
|
+
# There is 1 vuln in total:
|
|
151
|
+
# - TCP/IP: Sequence number in both hosts
|
|
152
|
+
# Each one should create 1 issue and 1 evidence
|
|
153
|
+
expect_to_create_issue_with(
|
|
154
|
+
text: "Sequence Number Approximation Based Denial of Service"
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
expect_to_create_evidence_with(
|
|
158
|
+
content: "n/a",
|
|
159
|
+
issue: "Sequence Number Approximation Based Denial of Service",
|
|
160
|
+
node_label: "10.0.155.160"
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
@importer.import(file: 'spec/fixtures/files/no_result.xml')
|
|
164
|
+
end
|
|
165
|
+
end
|
|
175
166
|
|
|
176
|
-
def expect_to_create_note_with(node_label: nil, text:)
|
|
177
|
-
expect(content_service).to receive(:create_note) do |args|
|
|
178
|
-
expect(args[:text]).to include text
|
|
179
|
-
expect(args[:node].label).to eq node_label unless node_label.nil?
|
|
180
|
-
end.once
|
|
181
|
-
end
|
|
182
167
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
end
|
|
188
|
-
end
|
|
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
|
|
189
173
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
end
|
|
196
|
-
end
|
|
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
|
|
197
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
|
|
198
188
|
|
|
189
|
+
end
|
|
199
190
|
end
|
|
200
|
-
|
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: 3.
|
|
4
|
+
version: 3.9.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: 2018-01-08 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: dradis-plugins
|
|
@@ -153,7 +153,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
153
153
|
version: '0'
|
|
154
154
|
requirements: []
|
|
155
155
|
rubyforge_project:
|
|
156
|
-
rubygems_version: 2.
|
|
156
|
+
rubygems_version: 2.4.5
|
|
157
157
|
signing_key:
|
|
158
158
|
specification_version: 4
|
|
159
159
|
summary: Qualys add-on for the Dradis Framework.
|