dradis-qualys 3.6.0 → 3.7.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 +6 -1
- data/lib/dradis/plugins/qualys/gem_version.rb +1 -1
- data/lib/dradis/plugins/qualys/importer.rb +8 -55
- data/lib/qualys/element.rb +4 -0
- data/lib/tasks/thorfile.rb +1 -6
- data/spec/qualys/importer_spec.rb +52 -42
- 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: c7659b662887c3f8025907a28e0ae265d268467d
|
4
|
+
data.tar.gz: ac58eaabf7fcf346b50c33339ebe4ed67c00e6a0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 68814114fe05a9175cabd11442ee7b263ef1337968c40a053a2f4d41f0349deab49be9902cb2827ef2f4ee8471ea859c24c06ad923ef520f43258a90f1d3f9dd
|
7
|
+
data.tar.gz: bc0d183262a9a2f5002dbbe2f21bf14df76f62cca8ac6f4c04b7a4d282b16dcfb7c326c56aa3f987761102a4cb03c483c2acf17dc0948f6672fb8faf4b0ed6ee
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
-
## Dradis Framework 3.
|
1
|
+
## Dradis Framework 3.7 (July, 2017) ##
|
2
|
+
|
3
|
+
* Better HTML entity translation (thanks @leesoh).
|
4
|
+
* Import INFOS, SERVICES, etc as Issues #7 (thanks @rachkor).
|
5
|
+
|
6
|
+
## Dradis Framework 3.6 (March, 2017) ##
|
2
7
|
|
3
8
|
* No changes.
|
@@ -41,89 +41,42 @@ module Dradis::Plugins::Qualys
|
|
41
41
|
end
|
42
42
|
content_service.create_note text: host_text, node: self.host_node
|
43
43
|
|
44
|
-
# We
|
45
|
-
|
44
|
+
# We treat INFOS, SERVICES, PRACTICES, and VULNS the same way
|
45
|
+
# All of these are imported into Dradis as Issues
|
46
|
+
['INFOS', 'SERVICES', 'PRACTICES', 'VULNS'].each do |collection|
|
46
47
|
xml_host.xpath(collection).each do |xml_collection|
|
47
48
|
process_collection(collection, xml_collection)
|
48
49
|
end
|
49
50
|
end
|
50
|
-
|
51
|
-
# Now we focus on 'VULNS' which we convert into Issue/Evidence
|
52
|
-
#
|
53
|
-
# For each <VULN> we need a reference to the parent <CAT> object for
|
54
|
-
# information such as port or protocol.
|
55
|
-
#
|
56
|
-
# Before we hand this to the template_service we need to make sure that
|
57
|
-
# a single VULN is hanging from the parent. To avoid messing the
|
58
|
-
# original document structure we just dup it.
|
59
|
-
logger.info{ "Extracting VULNS" }
|
60
|
-
|
61
|
-
xml_host.xpath('VULNS/CAT').each do |xml_cat|
|
62
|
-
|
63
|
-
empty_dup_xml_cat = xml_cat.dup
|
64
|
-
empty_dup_xml_cat.children.remove
|
65
|
-
|
66
|
-
xml_cat.xpath('VULN').each do |xml_vuln|
|
67
|
-
vuln_number = xml_vuln[:number]
|
68
|
-
|
69
|
-
# We need to clear any siblings before or after this VULN
|
70
|
-
dup_xml_cat = empty_dup_xml_cat.dup
|
71
|
-
dup_xml_cat.add_child(xml_vuln.dup)
|
72
|
-
|
73
|
-
process_vuln(vuln_number, dup_xml_cat)
|
74
|
-
end
|
75
|
-
end
|
76
51
|
end
|
77
52
|
|
78
53
|
def process_collection(collection, xml_collection)
|
79
|
-
collection_node = nil
|
80
54
|
xml_cats = xml_collection.xpath('CAT')
|
81
55
|
|
82
56
|
xml_cats.each do |xml_cat|
|
83
57
|
logger.info{ "\t#{ collection } - #{ xml_cat['value'] }" }
|
84
58
|
|
85
|
-
if xml_cats.count == 1
|
86
|
-
category_node = content_service.create_node(
|
87
|
-
label: "#{ collection.downcase } - #{ xml_cats.first['value'] }",
|
88
|
-
type: :default,
|
89
|
-
parent: self.host_node)
|
90
|
-
else
|
91
|
-
collection_node ||= content_service.create_node(
|
92
|
-
label: collection.downcase,
|
93
|
-
type: :default,
|
94
|
-
parent: self.host_node)
|
95
|
-
category_node = content_service.create_node(
|
96
|
-
label: xml_cat['value'],
|
97
|
-
type: :default,
|
98
|
-
parent: collection_node)
|
99
|
-
end
|
100
|
-
|
101
59
|
empty_dup_xml_cat = xml_cat.dup
|
102
60
|
empty_dup_xml_cat.children.remove
|
103
61
|
|
104
|
-
# For each INFOS/CAT/INFO, SERVICES/CAT/SERVICE, etc.
|
62
|
+
# For each INFOS/CAT/INFO, SERVICES/CAT/SERVICE, VULNS/CAT/VULN, etc.
|
105
63
|
xml_cat.xpath(collection.chop).each do |xml_element|
|
106
64
|
dup_xml_cat = empty_dup_xml_cat.dup
|
107
65
|
dup_xml_cat.add_child(xml_element.dup)
|
66
|
+
cat_number = xml_element[:number]
|
108
67
|
|
109
|
-
|
110
|
-
|
111
|
-
# retrieve hosts affected by this issue
|
112
|
-
note_content << "\n#[host]#\n"
|
113
|
-
note_content << self.host_node.label
|
114
|
-
note_content << "\n\n"
|
68
|
+
process_vuln(collection, cat_number, dup_xml_cat)
|
115
69
|
|
116
|
-
content_service.create_note text: note_content, node: category_node
|
117
70
|
end
|
118
71
|
end
|
119
72
|
end
|
120
73
|
|
121
74
|
# Takes a <CAT> element containing a single <VULN> element and processes an
|
122
75
|
# Issue and Evidence template out of it.
|
123
|
-
def process_vuln(vuln_number, xml_cat)
|
76
|
+
def process_vuln(collection, vuln_number, xml_cat)
|
124
77
|
logger.info{ "\t\t => Creating new issue (plugin_id: #{ vuln_number })" }
|
125
78
|
issue_text = template_service.process_template(template: 'element', data: xml_cat)
|
126
|
-
issue_text << "\n\n#[
|
79
|
+
issue_text << "\n\n#[qualys_collection]#\n#{ collection }"
|
127
80
|
issue = content_service.create_issue(text: issue_text, id: vuln_number)
|
128
81
|
|
129
82
|
logger.info{ "\t\t => Creating new evidence" }
|
data/lib/qualys/element.rb
CHANGED
data/lib/tasks/thorfile.rb
CHANGED
@@ -7,9 +7,6 @@ class QualysTasks < Thor
|
|
7
7
|
def upload(file_path)
|
8
8
|
require 'config/environment'
|
9
9
|
|
10
|
-
logger = Logger.new(STDOUT)
|
11
|
-
logger.level = Logger::DEBUG
|
12
|
-
|
13
10
|
unless File.exists?(file_path)
|
14
11
|
$stderr.puts "** the file [#{file_path}] does not exist"
|
15
12
|
exit -1
|
@@ -17,10 +14,8 @@ class QualysTasks < Thor
|
|
17
14
|
|
18
15
|
detect_and_set_project_scope
|
19
16
|
|
20
|
-
importer = Dradis::Plugins::Qualys::Importer.new(
|
17
|
+
importer = Dradis::Plugins::Qualys::Importer.new(task_options)
|
21
18
|
importer.import(file: file_path)
|
22
|
-
|
23
|
-
logger.close
|
24
19
|
end
|
25
20
|
|
26
21
|
end
|
@@ -4,7 +4,7 @@ require "ostruct"
|
|
4
4
|
describe Dradis::Plugins::Qualys::Importer do
|
5
5
|
let(:plugin) { Dradis::Plugins::Qualys }
|
6
6
|
|
7
|
-
let(:content_service) { Dradis::Plugins::ContentService.new(plugin: plugin) }
|
7
|
+
let(:content_service) { Dradis::Plugins::ContentService::Base.new(plugin: plugin) }
|
8
8
|
let(:template_service) { Dradis::Plugins::TemplateService.new(plugin: plugin) }
|
9
9
|
|
10
10
|
let(:importer) {
|
@@ -33,8 +33,6 @@ describe Dradis::Plugins::Qualys::Importer do
|
|
33
33
|
|
34
34
|
let(:example_xml) { 'spec/fixtures/files/simple.xml' }
|
35
35
|
|
36
|
-
pending "collapses INFOS|SERVICES|VULNS|PRACTICES node if only a single element is found"
|
37
|
-
|
38
36
|
def run_import!
|
39
37
|
importer.import(file: example_xml)
|
40
38
|
end
|
@@ -43,14 +41,6 @@ describe Dradis::Plugins::Qualys::Importer do
|
|
43
41
|
# Host node
|
44
42
|
expect_to_create_node_with(label: '10.0.155.160')
|
45
43
|
|
46
|
-
# Information gathering node
|
47
|
-
expect_to_create_node_with(label: 'infos - Information gathering')
|
48
|
-
|
49
|
-
# Services node with its child nodes
|
50
|
-
expect_to_create_node_with(label: 'services')
|
51
|
-
expect_to_create_node_with(label: 'TCP/IP')
|
52
|
-
expect_to_create_node_with(label: 'Web server')
|
53
|
-
|
54
44
|
run_import!
|
55
45
|
end
|
56
46
|
|
@@ -59,68 +49,88 @@ describe Dradis::Plugins::Qualys::Importer do
|
|
59
49
|
# Host node notes
|
60
50
|
expect_to_create_note_with(text: "Basic host info")
|
61
51
|
|
62
|
-
# Information gathering node and notes
|
63
|
-
expect_to_create_note_with(
|
64
|
-
text: "DNS Host Name",
|
65
|
-
node_label: "infos - Information gathering"
|
66
|
-
)
|
67
|
-
expect_to_create_note_with(
|
68
|
-
text: "Host Scan Time",
|
69
|
-
node_label: "infos - Information gathering"
|
70
|
-
)
|
71
|
-
|
72
|
-
# Child notes of Services node
|
73
|
-
expect_to_create_note_with(
|
74
|
-
text: "Open TCP Services List",
|
75
|
-
node_label: "TCP/IP"
|
76
|
-
)
|
77
|
-
|
78
|
-
expect_to_create_note_with(
|
79
|
-
text: "Web Server Version",
|
80
|
-
node_label: "Web server"
|
81
|
-
)
|
82
|
-
|
83
52
|
run_import!
|
84
53
|
end
|
85
54
|
|
86
55
|
# Issues and evidences from vulns
|
87
|
-
# There are
|
56
|
+
# There are 7 vulns/infos/services in total:
|
57
|
+
# - DNS Host Name
|
58
|
+
# - Host Scan Time
|
59
|
+
# - Open TCP Services List
|
60
|
+
# - Web Server Version
|
88
61
|
# - TCP/IP: Sequence number in both hosts
|
89
62
|
# - Web server: Apache 1.3
|
90
63
|
# - Web server: ETag
|
91
|
-
# Each one should create 1 issue and 1 evidence
|
92
64
|
|
93
65
|
it "creates issues from vulns" do
|
94
66
|
expect_to_create_issue_with(
|
95
|
-
text: "
|
67
|
+
text: "DNS Host Name"
|
96
68
|
)
|
97
69
|
|
98
70
|
expect_to_create_issue_with(
|
99
|
-
text: "
|
71
|
+
text: "Host Scan Time"
|
100
72
|
)
|
101
73
|
|
102
74
|
expect_to_create_issue_with(
|
103
|
-
text: "
|
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"
|
104
84
|
)
|
105
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
|
+
|
106
94
|
run_import!
|
107
95
|
end
|
108
96
|
|
109
97
|
it "creates evidence from vulns" do
|
110
98
|
expect_to_create_evidence_with(
|
111
|
-
content: "
|
112
|
-
issue: "
|
99
|
+
content: "IP address\tHost name\n10.0.155.160\tNo registered hostname\n",
|
100
|
+
issue: "DNS Host Name",
|
113
101
|
node_label: "10.0.155.160"
|
114
102
|
)
|
115
103
|
|
116
104
|
expect_to_create_evidence_with(
|
117
|
-
content: "
|
118
|
-
issue: "
|
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",
|
119
107
|
node_label: "10.0.155.160"
|
120
108
|
)
|
121
109
|
|
122
110
|
expect_to_create_evidence_with(
|
123
|
-
content: "
|
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",
|
124
134
|
issue: "Apache Web Server ETag Header Information Disclosure Weakness",
|
125
135
|
node_label: "10.0.155.160"
|
126
136
|
)
|
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.7.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: 2017-
|
11
|
+
date: 2017-07-27 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.6.8
|
157
157
|
signing_key:
|
158
158
|
specification_version: 4
|
159
159
|
summary: Qualys add-on for the Dradis Framework.
|