dradis-nexpose 4.10.0 → 4.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/pull_request_template.md +12 -3
- data/CHANGELOG.md +6 -0
- data/README.md +2 -2
- data/lib/dradis/plugins/nexpose/formats/full.rb +39 -38
- data/lib/dradis/plugins/nexpose/gem_version.rb +2 -2
- data/lib/nexpose/endpoint.rb +5 -7
- data/lib/nexpose/node.rb +6 -12
- data/lib/nexpose/service.rb +18 -11
- data/lib/nexpose/test.rb +3 -1
- data/lib/nexpose/vulnerability.rb +3 -2
- data/spec/fixtures/files/full.xml +1 -1
- data/spec/fixtures/files/full_with_duplicate_node.xml +136 -0
- data/spec/nexpose_upload_spec.rb +177 -146
- data/templates/full_evidence.fields +2 -0
- data/templates/full_evidence.sample +1 -1
- data/templates/full_service.fields +1 -1
- data/templates/full_service.sample +1 -1
- data/templates/full_vulnerability.fields +1 -0
- data/templates/full_vulnerability.sample +1 -0
- metadata +9 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fefa5d899cb4a34cead8f685c4bd13efdea29d034ddb7a505ce0e00f23b9b17d
|
4
|
+
data.tar.gz: 713ae33f6884e7c75393055f4cf68932a4ec9ef310e722d333b34c83df8b65ba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7a07af401d0dbe92e6d488244502eae76d2404482429190b8e7a68117c97e79e850905b0ab71954024137e9144125de3169866ef2749343c9b0d909c7e3027e1
|
7
|
+
data.tar.gz: 69b31e47e60b9ee6bbd6771222ea1a8f5940bf9d40c6700e789bee6a546a2b296d087b9a75fc850c32f827c9ac917bd22cbc16ebffed2ed6449f5ac8ca77023b
|
@@ -1,3 +1,5 @@
|
|
1
|
+
Please review [CONTRIBUTING.md](https://github.com/dradis/dradis-ce/blob/develop/CONTRIBUTING.md) and remove this line.
|
2
|
+
|
1
3
|
### Summary
|
2
4
|
|
3
5
|
Provide a general description of the code changes in your pull
|
@@ -6,6 +8,11 @@ these bugs have open GitHub issues, be sure to tag them here as well,
|
|
6
8
|
to keep the conversation linked together.
|
7
9
|
|
8
10
|
|
11
|
+
### Testing Steps
|
12
|
+
|
13
|
+
Provide steps to test functionality, described in detail for someone not familiar with this part of the application / code base
|
14
|
+
|
15
|
+
|
9
16
|
### Other Information
|
10
17
|
|
11
18
|
If there's anything else that's important and relevant to your pull
|
@@ -26,11 +33,13 @@ products, we must have the copyright associated with the entire
|
|
26
33
|
codebase. Any code you create which is merged must be owned by us.
|
27
34
|
That's not us trying to be a jerks, that's just the way it works.
|
28
35
|
|
29
|
-
Please review the [CONTRIBUTING.md](https://github.com/dradis/dradis-ce/blob/master/CONTRIBUTING.md)
|
30
|
-
file for the details.
|
31
|
-
|
32
36
|
You can delete this section, but the following sentence needs to
|
33
37
|
remain in the PR's description:
|
34
38
|
|
35
39
|
> I assign all rights, including copyright, to any future Dradis
|
36
40
|
> work by myself to Security Roots.
|
41
|
+
|
42
|
+
### Check List
|
43
|
+
|
44
|
+
- [ ] Added a CHANGELOG entry
|
45
|
+
- [ ] Added specs
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
v4.11.0 (January 2024)
|
2
|
+
- Add port/protocol to evidences
|
3
|
+
- Use the details in <os> as the OS node property
|
4
|
+
- Import `vulnerability.risk_score` as a new Issue field
|
5
|
+
- Allow multiple evidence with the same test id & node address
|
6
|
+
|
1
7
|
v4.10.0 (September 2023)
|
2
8
|
- Update gemspec links
|
3
9
|
|
data/README.md
CHANGED
@@ -11,12 +11,12 @@ The add-on requires [Dradis CE](https://dradisframework.org/) > 3.0, or [Dradis
|
|
11
11
|
|
12
12
|
## More information
|
13
13
|
|
14
|
-
See the Dradis Framework's [README.md](https://github.com/dradis/
|
14
|
+
See the Dradis Framework's [README.md](https://github.com/dradis/dradis-ce/blob/develop/README.md)
|
15
15
|
|
16
16
|
|
17
17
|
## Contributing
|
18
18
|
|
19
|
-
See the Dradis Framework's [CONTRIBUTING.md](https://github.com/dradis/
|
19
|
+
See the Dradis Framework's [CONTRIBUTING.md](https://github.com/dradis/dradis-ce/blob/develop/CONTRIBUTING.md)
|
20
20
|
|
21
21
|
|
22
22
|
## License
|
@@ -1,5 +1,4 @@
|
|
1
1
|
module Dradis::Plugins::Nexpose::Formats
|
2
|
-
|
3
2
|
# This module knows how to parse Nexpose Ful XML format.
|
4
3
|
module Full
|
5
4
|
private
|
@@ -12,30 +11,29 @@ module Dradis::Plugins::Nexpose::Formats
|
|
12
11
|
|
13
12
|
# First, extract scans
|
14
13
|
scan_node = content_service.create_node(label: 'Nexpose Scan Summary')
|
15
|
-
logger.info{ "\tProcessing scan summary" }
|
14
|
+
logger.info { "\tProcessing scan summary" }
|
16
15
|
|
17
16
|
doc.xpath('//scans/scan').each do |xml_scan|
|
18
17
|
note_text = template_service.process_template(template: 'full_scan', data: xml_scan)
|
19
18
|
content_service.create_note(node: scan_node, text: note_text)
|
20
19
|
end
|
21
20
|
|
22
|
-
|
23
21
|
# Second, we parse the nodes
|
24
22
|
doc.xpath('//nodes/node').each do |xml_node|
|
25
23
|
nexpose_node = Nexpose::Node.new(xml_node)
|
26
24
|
|
27
25
|
host_node = content_service.create_node(label: nexpose_node.address, type: :host)
|
28
|
-
logger.info{ "\tProcessing host: #{nexpose_node.address}" }
|
26
|
+
logger.info { "\tProcessing host: #{nexpose_node.address}" }
|
29
27
|
|
30
28
|
# add the summary note for this host
|
31
29
|
note_text = template_service.process_template(template: 'full_node', data: nexpose_node)
|
32
30
|
content_service.create_note(node: host_node, text: note_text)
|
33
31
|
|
34
32
|
if host_node.respond_to?(:properties)
|
35
|
-
logger.info{ "\tAdding host properties to #{nexpose_node.address}"}
|
33
|
+
logger.info { "\tAdding host properties to #{nexpose_node.address}" }
|
36
34
|
host_node.set_property(:ip, nexpose_node.address)
|
37
35
|
host_node.set_property(:hostname, nexpose_node.names)
|
38
|
-
host_node.set_property(:os, nexpose_node.
|
36
|
+
host_node.set_property(:os, nexpose_node.fingerprints)
|
39
37
|
host_node.set_property(:risk_score, nexpose_node.risk_score)
|
40
38
|
host_node.save
|
41
39
|
end
|
@@ -54,21 +52,22 @@ module Dradis::Plugins::Nexpose::Formats
|
|
54
52
|
# See:
|
55
53
|
# http://stackoverflow.com/questions/1625446/problem-with-upper-case-and-lower-case-xpath-functions-in-selenium-ide/1625859#1625859
|
56
54
|
xml_vuln = doc.xpath("//VulnerabilityDefinitions/vulnerability[translate(@id,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='#{test_id}']").first
|
57
|
-
xml_vuln.add_child(
|
55
|
+
xml_vuln.add_child('<hosts/>') unless xml_vuln.last_element_child.name == 'hosts'
|
58
56
|
|
59
57
|
if xml_vuln.xpath("./hosts/host[text()='#{nexpose_node.address}']").empty?
|
60
58
|
xml_vuln.last_element_child.add_child("<host>#{nexpose_node.address}</host>")
|
61
59
|
end
|
62
60
|
|
63
|
-
evidence[test_id][nexpose_node.address]
|
61
|
+
evidence[test_id][nexpose_node.address] ||= []
|
62
|
+
evidence[test_id][nexpose_node.address] << node_test
|
64
63
|
end
|
65
64
|
|
66
65
|
nexpose_node.endpoints.each do |endpoint|
|
67
66
|
# endpoint_node = content_service.create_node(label: endpoint.label, parent: host_node)
|
68
|
-
logger.info{ "\t\tEndpoint: #{endpoint.label}" }
|
67
|
+
logger.info { "\t\tEndpoint: #{endpoint.label}" }
|
69
68
|
|
70
69
|
if host_node.respond_to?(:properties)
|
71
|
-
logger.info{ "\t\tAdding to Services table" }
|
70
|
+
logger.info { "\t\tAdding to Services table" }
|
72
71
|
host_node.set_service(
|
73
72
|
port: endpoint.port.to_i,
|
74
73
|
protocol: endpoint.protocol,
|
@@ -102,13 +101,14 @@ module Dradis::Plugins::Nexpose::Formats
|
|
102
101
|
# http://stackoverflow.com/questions/1625446/problem-with-upper-case-and-lower-case-xpath-functions-in-selenium-ide/1625859#1625859
|
103
102
|
#
|
104
103
|
xml_vuln = doc.xpath("//VulnerabilityDefinitions/vulnerability[translate(@id,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='#{test_id}']").first
|
105
|
-
xml_vuln.add_child(
|
104
|
+
xml_vuln.add_child('<hosts/>') unless xml_vuln.last_element_child.name == 'hosts'
|
106
105
|
|
107
106
|
if xml_vuln.xpath("./hosts/host[text()='#{nexpose_node.address}']").empty?
|
108
107
|
xml_vuln.last_element_child.add_child("<host>#{nexpose_node.address}</host>")
|
109
108
|
end
|
110
109
|
|
111
|
-
evidence[test_id][nexpose_node.address]
|
110
|
+
evidence[test_id][nexpose_node.address] ||= []
|
111
|
+
evidence[test_id][nexpose_node.address] << service_test
|
112
112
|
end
|
113
113
|
end
|
114
114
|
end
|
@@ -118,42 +118,43 @@ module Dradis::Plugins::Nexpose::Formats
|
|
118
118
|
end
|
119
119
|
|
120
120
|
# Third, parse vulnerability definitions
|
121
|
-
logger.info{ "\tProcessing issue definitions:" }
|
121
|
+
logger.info { "\tProcessing issue definitions:" }
|
122
122
|
|
123
123
|
doc.xpath('//VulnerabilityDefinitions/vulnerability').each do |xml_vulnerability|
|
124
124
|
id = xml_vulnerability['id'].downcase
|
125
125
|
# if @vuln_list.include?(id)
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
# 3.2 associate with the nodes via Evidence.
|
146
|
-
# TODO: there is room for improvement here by providing proper Evidence content
|
147
|
-
xml_vulnerability.xpath('./hosts/host').collect(&:text).each do |host_name|
|
148
|
-
# if the node exists, this just returns it
|
149
|
-
host_node = content_service.create_node(label: host_name, type: :host)
|
126
|
+
issue_text = template_service.process_template(
|
127
|
+
template: 'full_vulnerability',
|
128
|
+
data: xml_vulnerability
|
129
|
+
)
|
130
|
+
|
131
|
+
# retrieve hosts affected by this issue (injected in step 2)
|
132
|
+
#
|
133
|
+
# There is no need for the below as Issues are linked to hosts via the
|
134
|
+
# corresponding Evidence instance
|
135
|
+
#
|
136
|
+
# note_text << "\n\n#[host]#\n"
|
137
|
+
# note_text << xml_vulnerability.xpath('./hosts/host').collect(&:text).join("\n")
|
138
|
+
# note_text << "\n\n"
|
139
|
+
|
140
|
+
# 3.1 create the Issue
|
141
|
+
issue = content_service.create_issue(text: issue_text, id: id)
|
142
|
+
logger.info { "\tIssue: #{issue.fields ? issue.fields['Title'] : id}" }
|
150
143
|
|
144
|
+
# 3.2 associate with the nodes via Evidence.
|
145
|
+
# TODO: there is room for improvement here by providing proper Evidence content
|
146
|
+
xml_vulnerability.xpath('./hosts/host').map(&:text).each do |host_name|
|
147
|
+
# if the node exists, this just returns it
|
148
|
+
host_node = content_service.create_node(label: host_name, type: :host)
|
149
|
+
|
150
|
+
evidence[id][host_name].each do |evidence|
|
151
151
|
evidence_content = template_service.process_template(
|
152
152
|
template: 'full_evidence',
|
153
|
-
data: evidence
|
153
|
+
data: evidence
|
154
154
|
)
|
155
155
|
content_service.create_evidence(content: evidence_content, issue: issue, node: host_node)
|
156
156
|
end
|
157
|
+
end
|
157
158
|
|
158
159
|
# end
|
159
160
|
end
|
data/lib/nexpose/endpoint.rb
CHANGED
@@ -8,7 +8,6 @@ module Nexpose
|
|
8
8
|
# Instead of providing separate methods for each supported property we rely
|
9
9
|
# on Ruby's #method_missing to do most of the work.
|
10
10
|
class Endpoint
|
11
|
-
|
12
11
|
# Accepts an XML node from Nokogiri::XML.
|
13
12
|
def initialize(xml_node)
|
14
13
|
@xml = xml_node
|
@@ -39,13 +38,14 @@ module Nexpose
|
|
39
38
|
# Each of the services associated with this endpoint. Returns an array of
|
40
39
|
# Nexpose::Service objects
|
41
40
|
def services
|
42
|
-
@xml.xpath('./services/service').
|
41
|
+
@xml.xpath('./services/service').map do |xml_service|
|
42
|
+
Service.new(xml_service, endpoint: { port: port, protocol: protocol })
|
43
|
+
end
|
43
44
|
end
|
44
45
|
|
45
|
-
|
46
46
|
# This allows external callers (and specs) to check for implemented
|
47
47
|
# properties
|
48
|
-
def respond_to?(method, include_private=false)
|
48
|
+
def respond_to?(method, include_private = false)
|
49
49
|
return true if supported_tags.include?(method.to_sym)
|
50
50
|
super
|
51
51
|
end
|
@@ -57,7 +57,6 @@ module Nexpose
|
|
57
57
|
# attribute, simple descendent or collection that it maps to in the XML
|
58
58
|
# tree.
|
59
59
|
def method_missing(method, *args)
|
60
|
-
|
61
60
|
# We could remove this check and return nil for any non-recognized tag.
|
62
61
|
# The problem would be that it would make tricky to debug problems with
|
63
62
|
# typos. For instance: <>.potr would return nil instead of raising an
|
@@ -69,8 +68,7 @@ module Nexpose
|
|
69
68
|
|
70
69
|
# First we try the attributes. In Ruby we use snake_case, but in XML
|
71
70
|
# CamelCase is used for some attributes
|
72
|
-
translations_table = {
|
73
|
-
}
|
71
|
+
translations_table = {}
|
74
72
|
|
75
73
|
method_name = translations_table.fetch(method, method.to_s)
|
76
74
|
return @xml.attributes[method_name].value if @xml.attributes.key?(method_name)
|
data/lib/nexpose/node.rb
CHANGED
@@ -43,10 +43,9 @@ module Nexpose
|
|
43
43
|
@xml.xpath('./endpoints/endpoint').collect { |xml_endpoint| Endpoint.new(xml_endpoint) }
|
44
44
|
end
|
45
45
|
|
46
|
-
|
47
46
|
# This allows external callers (and specs) to check for implemented
|
48
47
|
# properties
|
49
|
-
def respond_to?(method, include_private=false)
|
48
|
+
def respond_to?(method, include_private = false)
|
50
49
|
return true if supported_tags.include?(method.to_sym)
|
51
50
|
super
|
52
51
|
end
|
@@ -58,7 +57,6 @@ module Nexpose
|
|
58
57
|
# attribute, simple descendent or collection that it maps to in the XML
|
59
58
|
# tree.
|
60
59
|
def method_missing(method, *args)
|
61
|
-
|
62
60
|
# We could remove this check and return nil for any non-recognized tag.
|
63
61
|
# The problem would be that it would make tricky to debug problems with
|
64
62
|
# typos. For instance: <>.potr would return nil instead of raising an
|
@@ -84,7 +82,7 @@ module Nexpose
|
|
84
82
|
|
85
83
|
# Finally the enumerations: names
|
86
84
|
if method_name == 'names'
|
87
|
-
@xml.xpath(
|
85
|
+
@xml.xpath('./names/name').collect(&:text)
|
88
86
|
|
89
87
|
elsif ['fingerprints', 'software'].include?(method_name)
|
90
88
|
|
@@ -93,14 +91,10 @@ module Nexpose
|
|
93
91
|
'software' => './software/fingerprint'
|
94
92
|
}[method_name]
|
95
93
|
|
96
|
-
@xml.
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
[name.sub(/-/,'_').to_sym, xml_attribute.value]
|
101
|
-
end
|
102
|
-
]
|
103
|
-
end
|
94
|
+
xml_os = @xml.at_xpath(xpath_selector)
|
95
|
+
return '' if xml_os.nil?
|
96
|
+
|
97
|
+
xml_os.attributes['product'].value
|
104
98
|
else
|
105
99
|
# nothing found, the tag is valid but not present in this ReportItem
|
106
100
|
return nil
|
data/lib/nexpose/service.rb
CHANGED
@@ -8,9 +8,15 @@ module Nexpose
|
|
8
8
|
# Instead of providing separate methods for each supported property we rely
|
9
9
|
# on Ruby's #method_missing to do most of the work.
|
10
10
|
class Service
|
11
|
+
attr_accessor :endpoint, :xml
|
12
|
+
|
11
13
|
# Accepts an XML node from Nokogiri::XML.
|
12
|
-
|
14
|
+
#
|
15
|
+
# endpoint - If the Service is instantiated from the Endpoint class (e.g.
|
16
|
+
# from <endpoint><services>...) , it will have access to the parent data.
|
17
|
+
def initialize(xml_node, endpoint: nil)
|
13
18
|
@xml = xml_node
|
19
|
+
@endpoint = endpoint
|
14
20
|
end
|
15
21
|
|
16
22
|
# List of supported tags. They can be attributes, simple descendans or
|
@@ -29,15 +35,18 @@ module Nexpose
|
|
29
35
|
|
30
36
|
# Convert each ./test/test entry into a simple hash
|
31
37
|
def tests(*args)
|
32
|
-
|
38
|
+
xml.xpath('./tests/test').map do |xml_test|
|
39
|
+
# Inject evidence with data from the node
|
40
|
+
xml_test['port'] = endpoint[:port]
|
41
|
+
xml_test['protocol'] = endpoint[:protocol]
|
42
|
+
|
33
43
|
Nexpose::Test.new(xml_test)
|
34
44
|
end
|
35
45
|
end
|
36
46
|
|
37
|
-
|
38
47
|
# This allows external callers (and specs) to check for implemented
|
39
48
|
# properties
|
40
|
-
def respond_to?(method, include_private=false)
|
49
|
+
def respond_to?(method, include_private = false)
|
41
50
|
return true if supported_tags.include?(method.to_sym)
|
42
51
|
super
|
43
52
|
end
|
@@ -49,7 +58,6 @@ module Nexpose
|
|
49
58
|
# attribute, simple descendent or collection that it maps to in the XML
|
50
59
|
# tree.
|
51
60
|
def method_missing(method, *args)
|
52
|
-
|
53
61
|
# We could remove this check and return nil for any non-recognized tag.
|
54
62
|
# The problem would be that it would make tricky to debug problems with
|
55
63
|
# typos. For instance: <>.potr would return nil instead of raising an
|
@@ -61,11 +69,10 @@ module Nexpose
|
|
61
69
|
|
62
70
|
# First we try the attributes. In Ruby we use snake_case, but in XML
|
63
71
|
# CamelCase is used for some attributes
|
64
|
-
translations_table = {
|
65
|
-
}
|
72
|
+
translations_table = {}
|
66
73
|
|
67
74
|
method_name = translations_table.fetch(method, method.to_s)
|
68
|
-
return
|
75
|
+
return xml.attributes[method_name].value if xml.attributes.key?(method_name)
|
69
76
|
|
70
77
|
# Finally the enumerations: references, tags
|
71
78
|
if ['fingerprints', 'configurations'].include?(method_name)
|
@@ -74,11 +81,11 @@ module Nexpose
|
|
74
81
|
'configurations' => './configuration/config'
|
75
82
|
}[method_name]
|
76
83
|
|
77
|
-
|
78
|
-
{:
|
84
|
+
xml.xpath(xpath_selector).collect do |xml_item|
|
85
|
+
{ text: xml_item.text }.merge(
|
79
86
|
Hash[
|
80
87
|
xml_item.attributes.collect do |name, xml_attribute|
|
81
|
-
[name.sub(/-/,'_').to_sym, xml_attribute.value]
|
88
|
+
[name.sub(/-/, '_').to_sym, xml_attribute.value]
|
82
89
|
end
|
83
90
|
]
|
84
91
|
)
|
data/lib/nexpose/test.rb
CHANGED
@@ -20,8 +20,8 @@ module Nexpose
|
|
20
20
|
def supported_tags
|
21
21
|
[
|
22
22
|
# attributes
|
23
|
-
:
|
24
|
-
:published, :
|
23
|
+
:added, :cvss_score, :cvss_vector, :modified, :nexpose_id, :pci_severity,
|
24
|
+
:published, :risk_score, :severity, :title,
|
25
25
|
|
26
26
|
# simple tags
|
27
27
|
:description, :solution,
|
@@ -64,6 +64,7 @@ module Nexpose
|
|
64
64
|
translations_table = {
|
65
65
|
:nexpose_id => 'id',
|
66
66
|
:pci_severity => 'pciSeverity',
|
67
|
+
:risk_score => 'riskScore',
|
67
68
|
:cvss_score => 'cvssScore',
|
68
69
|
:cvss_vector =>'cvssVector'
|
69
70
|
}
|
@@ -0,0 +1,136 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<NexposeReport version="2.0">
|
3
|
+
<scans>
|
4
|
+
<scan endTime="20141110T175832478" id="4" name="USDA_Internal" startTime="20141110T094538362" status="finished"/>
|
5
|
+
</scans>
|
6
|
+
<nodes>
|
7
|
+
<node address="1.1.1.1" device-id="75" risk-score="0.0" scan-template="Edge Standard" site-importance="Normal" site-name="USDA_Internal" status="alive">
|
8
|
+
<names>
|
9
|
+
<name>localhost:5000</name>
|
10
|
+
</names>
|
11
|
+
<fingerprints>
|
12
|
+
<os certainty="0.80" family="IOS" product="IOS" vendor="Cisco" arch="x86_64"/>
|
13
|
+
</fingerprints>
|
14
|
+
<tests/>
|
15
|
+
<endpoints>
|
16
|
+
<endpoint port="123" protocol="udp" status="open">
|
17
|
+
<services>
|
18
|
+
<service name="NTP">
|
19
|
+
<fingerprints>
|
20
|
+
<fingerprint certainty="0.90" family="NTP" product="NTP" vendor="Cisco"/>
|
21
|
+
</fingerprints>
|
22
|
+
<configuration>
|
23
|
+
<config name="ntp.variables">system="cisco", leap=0, stratum=5, rootdelay=88.21,
|
24
|
+
|
25
|
+
rootdispersion=108.54, peer=24960, refid=135.89.100.96,
|
26
|
+
|
27
|
+
reftime=0xD80BB6B5.715ACDD8, poll=10, clock=0xD80BB78F.8931F3F6,
|
28
|
+
|
29
|
+
phase=8.259, freq=-141.24, error=11.32</config>
|
30
|
+
</configuration>
|
31
|
+
<tests>
|
32
|
+
<test id="ntp-clock-variables-disclosure" pci-compliance-status="pass" scan-id="4" status="vulnerable-exploited" vulnerable-since="20141110T161846666">
|
33
|
+
<Paragraph>
|
34
|
+
<Paragraph>The following NTP variables were found from a readvar request: system="cisco", leap=0, stratum=5, rootdelay=88.21,
|
35
|
+
rootdispersion=108.54, peer=24960, refid=135.89.100.96,
|
36
|
+
reftime=0xD80BB6B5.715ACDD8, poll=10, clock=0xD80BB78F.8931F3F6,
|
37
|
+
phase=8.259, freq=-141.24, error=11.32</Paragraph>
|
38
|
+
</Paragraph>
|
39
|
+
</test>
|
40
|
+
</tests>
|
41
|
+
</service>
|
42
|
+
</services>
|
43
|
+
</endpoint>
|
44
|
+
<endpoint port="161" protocol="udp" status="open">
|
45
|
+
<services>
|
46
|
+
<service name="SNMP">
|
47
|
+
<tests/>
|
48
|
+
</service>
|
49
|
+
</services>
|
50
|
+
</endpoint>
|
51
|
+
</endpoints>
|
52
|
+
</node>
|
53
|
+
<node address="1.1.1.1" device-id="75" risk-score="0.0" scan-template="Edge Standard" site-importance="Normal" site-name="USDA_Internal" status="alive">
|
54
|
+
<names>
|
55
|
+
<name>localhost:6000</name>
|
56
|
+
</names>
|
57
|
+
<fingerprints>
|
58
|
+
<os certainty="0.80" family="IOS" product="IOS" vendor="Cisco" arch="x86_64"/>
|
59
|
+
</fingerprints>
|
60
|
+
<tests/>
|
61
|
+
<endpoints>
|
62
|
+
<endpoint port="123" protocol="udp" status="open">
|
63
|
+
<services>
|
64
|
+
<service name="NTP">
|
65
|
+
<fingerprints>
|
66
|
+
<fingerprint certainty="0.90" family="NTP" product="NTP" vendor="Cisco"/>
|
67
|
+
</fingerprints>
|
68
|
+
<configuration>
|
69
|
+
<config name="ntp.variables">system="cisco", leap=0, stratum=5, rootdelay=88.21,
|
70
|
+
|
71
|
+
rootdispersion=108.54, peer=24960, refid=135.89.100.96,
|
72
|
+
|
73
|
+
reftime=0xD80BB6B5.715ACDD8, poll=10, clock=0xD80BB78F.8931F3F6,
|
74
|
+
|
75
|
+
phase=8.259, freq=-141.24, error=11.32</config>
|
76
|
+
</configuration>
|
77
|
+
<tests>
|
78
|
+
<test id="ntp-clock-variables-disclosure" pci-compliance-status="pass" scan-id="4" status="vulnerable-exploited" vulnerable-since="20141110T161846666">
|
79
|
+
<Paragraph>
|
80
|
+
<Paragraph>The following NTP variables were found from a readvar request: system="cisco", leap=0, stratum=5, rootdelay=88.21,
|
81
|
+
rootdispersion=108.54, peer=24960, refid=135.89.100.96,
|
82
|
+
reftime=0xD80BB6B5.715ACDD8, poll=10, clock=0xD80BB78F.8931F3F6,
|
83
|
+
phase=8.259, freq=-141.24, error=11.32</Paragraph>
|
84
|
+
</Paragraph>
|
85
|
+
</test>
|
86
|
+
</tests>
|
87
|
+
</service>
|
88
|
+
</services>
|
89
|
+
</endpoint>
|
90
|
+
<endpoint port="161" protocol="udp" status="open">
|
91
|
+
<services>
|
92
|
+
<service name="SNMP">
|
93
|
+
<tests/>
|
94
|
+
</service>
|
95
|
+
</services>
|
96
|
+
</endpoint>
|
97
|
+
</endpoints>
|
98
|
+
</node>
|
99
|
+
</nodes>
|
100
|
+
<VulnerabilityDefinitions>
|
101
|
+
<vulnerability added="20120412T000000000" cvssScore="4.3" cvssVector="(AV:N/AC:M/Au:N/C:P/I:N/A:N)" id="ntp-clock-variables-disclosure" modified="20131205T000000000" pciSeverity="3" published="20120127T000000000" riskScore="378.27377" severity="4" title="Apache HTTPD: error responses can expose cookies (CVE-2012-0053)">
|
102
|
+
<malware/>
|
103
|
+
<exploits>
|
104
|
+
<exploit id="3479" link="http://www.exploit-db.com/exploits/18442" skillLevel="Expert" title="Apache httpOnly Cookie Disclosure" type="exploitdb"/>
|
105
|
+
</exploits>
|
106
|
+
<description>
|
107
|
+
<ContainerBlockElement>
|
108
|
+
<Paragraph>A flaw was found in the default error response for status code 400. This flaw could be used by an attacker to expose "httpOnly" cookies when no custom ErrorDocument is specified.</Paragraph>
|
109
|
+
</ContainerBlockElement>
|
110
|
+
</description>
|
111
|
+
<references>
|
112
|
+
<reference source="APPLE">APPLE-SA-2012-09-19-2</reference>
|
113
|
+
<reference source="BID">51706</reference>
|
114
|
+
<reference source="CVE">CVE-2012-0053</reference>
|
115
|
+
<reference source="REDHAT">RHSA-2012:0128</reference>
|
116
|
+
<reference source="SECUNIA">48551</reference>
|
117
|
+
<reference source="URL">http://httpd.apache.org/security/vulnerabilities_20.html</reference>
|
118
|
+
<reference source="URL">http://httpd.apache.org/security/vulnerabilities_22.html</reference>
|
119
|
+
</references>
|
120
|
+
<tags>
|
121
|
+
<tag>Apache</tag>
|
122
|
+
<tag>Apache HTTP Server</tag>
|
123
|
+
<tag>Web</tag>
|
124
|
+
</tags>
|
125
|
+
<solution>
|
126
|
+
<ContainerBlockElement>
|
127
|
+
<Paragraph>Apache HTTPD >= 2.0 and < 2.0.65</Paragraph>
|
128
|
+
<Paragraph>Download and apply the upgrade from:
|
129
|
+
|
130
|
+
<URLLink LinkTitle="http://archive.apache.org/dist/httpd/httpd-2.0.65.tar.gz" LinkURL="http://archive.apache.org/dist/httpd/httpd-2.0.65.tar.gz"/></Paragraph>
|
131
|
+
<Paragraph>Many platforms and distributions provide pre-built binary packages for Apache HTTP server. These pre-built packages are usually customized and optimized for a particular distribution, therefore we recommend that you use the packages if they are available for your operating system.</Paragraph>
|
132
|
+
</ContainerBlockElement>
|
133
|
+
</solution>
|
134
|
+
</vulnerability>
|
135
|
+
</VulnerabilityDefinitions>
|
136
|
+
</NexposeReport>
|
data/spec/nexpose_upload_spec.rb
CHANGED
@@ -1,170 +1,201 @@
|
|
1
|
-
require '
|
1
|
+
require 'rails_helper'
|
2
2
|
require 'ostruct'
|
3
3
|
|
4
4
|
describe 'Nexpose upload plugin' do
|
5
|
-
before
|
6
|
-
|
7
|
-
templates_dir = File.expand_path('../../templates', __FILE__)
|
8
|
-
expect_any_instance_of(Dradis::Plugins::TemplateService)
|
9
|
-
.to receive(:default_templates_dir).and_return(templates_dir)
|
10
|
-
|
11
|
-
# Init services
|
12
|
-
plugin = Dradis::Plugins::Nexpose
|
13
|
-
|
14
|
-
@content_service = Dradis::Plugins::ContentService::Base.new(
|
15
|
-
logger: Logger.new(STDOUT),
|
16
|
-
plugin: plugin
|
17
|
-
)
|
18
|
-
|
19
|
-
@importer = plugin::Importer.new(
|
20
|
-
content_service: @content_service,
|
21
|
-
)
|
22
|
-
|
23
|
-
# Stub dradis-plugins methods
|
24
|
-
#
|
25
|
-
# They return their argument hashes as objects mimicking
|
26
|
-
# Nodes, Issues, etc
|
27
|
-
allow(@content_service).to receive(:create_node) do |args|
|
28
|
-
OpenStruct.new(args)
|
29
|
-
end
|
30
|
-
allow(@content_service).to receive(:create_note) do |args|
|
31
|
-
OpenStruct.new(args)
|
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
|
5
|
+
before do
|
6
|
+
@fixtures_dir = File.expand_path('../fixtures/files/', __FILE__)
|
39
7
|
end
|
40
8
|
|
41
|
-
describe
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
9
|
+
describe 'importer' do
|
10
|
+
before(:each) do
|
11
|
+
# Stub template service
|
12
|
+
templates_dir = File.expand_path('../../templates', __FILE__)
|
13
|
+
expect_any_instance_of(Dradis::Plugins::TemplateService)
|
14
|
+
.to receive(:default_templates_dir).and_return(templates_dir)
|
15
|
+
|
16
|
+
# Init services
|
17
|
+
plugin = Dradis::Plugins::Nexpose
|
18
|
+
|
19
|
+
@content_service = Dradis::Plugins::ContentService::Base.new(
|
20
|
+
logger: Logger.new(STDOUT),
|
21
|
+
plugin: plugin
|
22
|
+
)
|
23
|
+
|
24
|
+
@importer = plugin::Importer.new(
|
25
|
+
content_service: @content_service,
|
26
|
+
)
|
27
|
+
|
28
|
+
# Stub dradis-plugins methods
|
29
|
+
#
|
30
|
+
# They return their argument hashes as objects mimicking
|
31
|
+
# Nodes, Issues, etc
|
32
|
+
allow(@content_service).to receive(:create_node) do |args|
|
55
33
|
OpenStruct.new(args)
|
56
|
-
end
|
57
|
-
|
58
|
-
expect(@content_service).to receive(:create_node) do |args|
|
59
|
-
expect(args[:label]).to eq('udp-000')
|
60
|
-
expect(args[:parent].label).to eq("1.1.1.1")
|
34
|
+
end
|
35
|
+
allow(@content_service).to receive(:create_note) do |args|
|
61
36
|
OpenStruct.new(args)
|
62
|
-
end
|
63
|
-
|
64
|
-
expect(@content_service).to receive(:create_note) do |args|
|
65
|
-
expect(args[:text]).to include("#[Id]#\nntpd-crypto")
|
66
|
-
expect(args[:text]).to include("#[host]#\n1.1.1.1")
|
67
|
-
expect(args[:node].label).to eq("udp-000")
|
68
|
-
end.once
|
69
|
-
|
70
|
-
expect(@content_service).to receive(:create_note) do |args|
|
71
|
-
expect(args[:text]).to include("#[Id]#\nntp-clock-radio")
|
72
|
-
expect(args[:text]).to include("#[host]#\n1.1.1.1")
|
73
|
-
expect(args[:node].label).to eq("udp-000")
|
74
|
-
end.once
|
75
|
-
|
76
|
-
@importer.import(file: 'spec/fixtures/files/simple.xml')
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
describe "Importer: Full" do
|
81
|
-
it "creates nodes, issues, notes and an evidences as needed" do
|
82
|
-
expect(@content_service).to receive(:create_node).with(hash_including label: "Nexpose Scan Summary").once
|
83
|
-
expect(@content_service).to receive(:create_note) do |args|
|
84
|
-
expect(args[:text]).to include("#[Title]#\nUSDA_Internal (4)")
|
85
|
-
expect(args[:node].label).to eq("Nexpose Scan Summary")
|
86
|
-
end.once
|
87
|
-
|
88
|
-
expect(@content_service).to receive(:create_node).with(
|
89
|
-
hash_including label: "1.1.1.1", type: :host
|
90
|
-
).twice
|
91
|
-
|
92
|
-
expect(@content_service).to receive(:create_note) do |args|
|
93
|
-
expect(args[:text]).to include("#[Title]#\n1.1.1.1")
|
94
|
-
expect(args[:node].label).to eq("1.1.1.1")
|
95
|
-
end.once
|
96
|
-
|
97
|
-
expect(@content_service).to receive(:create_note) do |args|
|
98
|
-
expect(args[:text]).to include("#[Title]#\nService name: NTP")
|
99
|
-
expect(args[:node].label).to eq("1.1.1.1")
|
100
|
-
end.once
|
101
|
-
|
102
|
-
expect(@content_service).to receive(:create_note) do |args|
|
103
|
-
expect(args[:text]).to include("#[Title]#\nService name: SNMP")
|
104
|
-
expect(args[:node].label).to eq("1.1.1.1")
|
105
|
-
end.once
|
106
|
-
|
107
|
-
expect(@content_service).to receive(:create_issue) do |args|
|
108
|
-
expect(args[:text]).to include("#[Title]#\nApache HTTPD: error responses can expose cookies (CVE-2012-0053)")
|
109
|
-
expect(args[:id]).to eq("ntp-clock-variables-disclosure")
|
37
|
+
end
|
38
|
+
allow(@content_service).to receive(:create_issue) do |args|
|
110
39
|
OpenStruct.new(args)
|
111
|
-
end
|
112
|
-
|
113
|
-
expect(@content_service).to receive(:create_issue) do |args|
|
114
|
-
expect(args[:text]).to include("#[Title]#\nApache HTTPD: ETag Inode Information Leakage (CVE-2003-1418)")
|
115
|
-
expect(args[:id]).to eq("ntp-clock-variables-disclosure")
|
40
|
+
end
|
41
|
+
allow(@content_service).to receive(:create_evidence) do |args|
|
116
42
|
OpenStruct.new(args)
|
117
|
-
end
|
43
|
+
end
|
44
|
+
end
|
118
45
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
expect(
|
123
|
-
|
46
|
+
describe 'Importer: Simple' do
|
47
|
+
it 'creates nodes, issues, notes and an evidences as needed' do
|
48
|
+
|
49
|
+
expect(@content_service).to receive(:create_node).with(hash_including label: '1.1.1.1', type: :host).once
|
50
|
+
|
51
|
+
expect(@content_service).to receive(:create_note) do |args|
|
52
|
+
expect(args[:text]).to include('Host Description : Linux 2.6.9-89.ELsmp')
|
53
|
+
expect(args[:text]).to include('Scanner Fingerprint certainty : 0.80')
|
54
|
+
expect(args[:node].label).to eq('1.1.1.1')
|
55
|
+
end.once
|
56
|
+
|
57
|
+
expect(@content_service).to receive(:create_node) do |args|
|
58
|
+
expect(args[:label]).to eq('Generic Findings')
|
59
|
+
expect(args[:parent].label).to eq('1.1.1.1')
|
60
|
+
OpenStruct.new(args)
|
61
|
+
end.once
|
62
|
+
|
63
|
+
expect(@content_service).to receive(:create_node) do |args|
|
64
|
+
expect(args[:label]).to eq('udp-000')
|
65
|
+
expect(args[:parent].label).to eq('1.1.1.1')
|
66
|
+
OpenStruct.new(args)
|
67
|
+
end.once
|
68
|
+
|
69
|
+
expect(@content_service).to receive(:create_note) do |args|
|
70
|
+
expect(args[:text]).to include("#[Id]#\nntpd-crypto")
|
71
|
+
expect(args[:text]).to include("#[host]#\n1.1.1.1")
|
72
|
+
expect(args[:node].label).to eq('udp-000')
|
73
|
+
end.once
|
74
|
+
|
75
|
+
expect(@content_service).to receive(:create_note) do |args|
|
76
|
+
expect(args[:text]).to include("#[Id]#\nntp-clock-radio")
|
77
|
+
expect(args[:text]).to include("#[host]#\n1.1.1.1")
|
78
|
+
expect(args[:node].label).to eq('udp-000')
|
79
|
+
end.once
|
80
|
+
|
81
|
+
@importer.import(file: @fixtures_dir + '/simple.xml')
|
82
|
+
end
|
83
|
+
end
|
124
84
|
|
125
|
-
|
126
|
-
|
85
|
+
describe 'Importer: Full' do
|
86
|
+
it 'creates nodes, issues, notes and an evidences as needed' do
|
87
|
+
expect(@content_service).to receive(:create_node).with(hash_including label: 'Nexpose Scan Summary').once
|
88
|
+
expect(@content_service).to receive(:create_note) do |args|
|
89
|
+
expect(args[:text]).to include("#[Title]#\nUSDA_Internal (4)")
|
90
|
+
expect(args[:node].label).to eq('Nexpose Scan Summary')
|
91
|
+
end.once
|
92
|
+
|
93
|
+
expect(@content_service).to receive(:create_node) do |args|
|
94
|
+
expect(args[:label]).to eq('1.1.1.1')
|
95
|
+
expect(args[:type]).to eq(:host)
|
96
|
+
create(:node, args.except(:type))
|
97
|
+
end
|
98
|
+
|
99
|
+
expect(@content_service).to receive(:create_note) do |args|
|
100
|
+
expect(args[:text]).to include("#[Title]#\n1.1.1.1")
|
101
|
+
expect(args[:node].label).to eq('1.1.1.1')
|
102
|
+
end.once
|
103
|
+
|
104
|
+
expect(@content_service).to receive(:create_note) do |args|
|
105
|
+
expect(args[:text]).to include("#[Title]#\nService name: NTP")
|
106
|
+
expect(args[:node].label).to eq('1.1.1.1')
|
107
|
+
end.once
|
108
|
+
|
109
|
+
expect(@content_service).to receive(:create_note) do |args|
|
110
|
+
expect(args[:text]).to include("#[Title]#\nService name: SNMP")
|
111
|
+
expect(args[:node].label).to eq('1.1.1.1')
|
112
|
+
end.once
|
113
|
+
|
114
|
+
expect(@content_service).to receive(:create_issue) do |args|
|
115
|
+
expect(args[:text]).to include("#[Title]#\nApache HTTPD: error responses can expose cookies (CVE-2012-0053)")
|
116
|
+
expect(args[:id]).to eq('ntp-clock-variables-disclosure')
|
117
|
+
OpenStruct.new(args)
|
118
|
+
end.once
|
119
|
+
|
120
|
+
expect(@content_service).to receive(:create_issue) do |args|
|
121
|
+
expect(args[:text]).to include("#[Title]#\nApache HTTPD: ETag Inode Information Leakage (CVE-2003-1418)")
|
122
|
+
expect(args[:id]).to eq('ntp-clock-variables-disclosure')
|
123
|
+
OpenStruct.new(args)
|
124
|
+
end.once
|
125
|
+
|
126
|
+
expect(@content_service).to receive(:create_evidence) do |args|
|
127
|
+
expect(args[:content]).to include("#[ID]#\nntp-clock-variables-disclosure\n\n")
|
128
|
+
expect(args[:issue].id).to eq('ntp-clock-variables-disclosure')
|
129
|
+
expect(args[:node].label).to eq('1.1.1.1')
|
130
|
+
end.once
|
131
|
+
|
132
|
+
@importer.import(file: @fixtures_dir + '/full.xml')
|
133
|
+
|
134
|
+
expect(Node.find_by(label: '1.1.1.1').properties[:os]).to eq('IOS')
|
135
|
+
end
|
127
136
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
137
|
+
it 'wraps ciphers inside ssl issues in code blocks' do
|
138
|
+
expect(@content_service).to receive(:create_issue) do |args|
|
139
|
+
expect(args[:text]).to include('bc. ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256')
|
140
|
+
OpenStruct.new(args)
|
141
|
+
end.once
|
132
142
|
|
133
|
-
|
134
|
-
|
143
|
+
@importer.import(file: @fixtures_dir + '/ssl.xml')
|
144
|
+
end
|
135
145
|
|
136
|
-
|
137
|
-
|
138
|
-
expect(
|
139
|
-
|
140
|
-
|
146
|
+
# Regression test for github.com/dradis/dradis-nexpose/issues/1
|
147
|
+
it 'populates solutions regardless they are wrapped in paragraphs or lists' do
|
148
|
+
expect(@content_service).to receive(:create_issue) do |args|
|
149
|
+
expect(args[:text]).to include("#[Solution]#\n\nApache HTTPD >= 2.0 and < 2.0.65")
|
150
|
+
OpenStruct.new(args)
|
151
|
+
end.once
|
141
152
|
|
142
|
-
|
143
|
-
|
153
|
+
expect(@content_service).to receive(:create_issue) do |args|
|
154
|
+
expect(args[:text]).to include("#[Solution]#\n")
|
155
|
+
expect(args[:text]).to include('You can remove inode information from the ETag header')
|
156
|
+
OpenStruct.new(args)
|
157
|
+
end.once
|
144
158
|
|
145
|
-
|
146
|
-
|
147
|
-
expect(@content_service).to receive(:create_issue) do |args|
|
148
|
-
expect(args[:text]).to include("#[Solution]#\n\nApache HTTPD >= 2.0 and < 2.0.65")
|
149
|
-
OpenStruct.new(args)
|
150
|
-
end.once
|
159
|
+
@importer.import(file: @fixtures_dir + '/full.xml')
|
160
|
+
end
|
151
161
|
|
152
|
-
|
153
|
-
expect(
|
154
|
-
|
155
|
-
|
156
|
-
|
162
|
+
it 'transforms html entities (< and >)' do
|
163
|
+
expect(@content_service).to receive(:create_issue) do |args|
|
164
|
+
expect(args[:text]).to include("#[Solution]#\n\nApache HTTPD >= 2.0 and < 2.0.65")
|
165
|
+
OpenStruct.new(args)
|
166
|
+
end
|
157
167
|
|
158
|
-
|
168
|
+
@importer.import(file: @fixtures_dir + '/full.xml')
|
169
|
+
end
|
159
170
|
end
|
160
171
|
|
161
|
-
|
162
|
-
|
163
|
-
expect(
|
164
|
-
|
172
|
+
describe 'Importer: Full with duplicate nodes' do
|
173
|
+
it 'creates evidence for each instance of the node' do
|
174
|
+
expect(@content_service).to receive(:create_node).with(hash_including label: 'Nexpose Scan Summary').once
|
175
|
+
expect(@content_service).to receive(:create_node) do |args|
|
176
|
+
expect(args[:label]).to eq('1.1.1.1')
|
177
|
+
expect(args[:type]).to eq(:host)
|
178
|
+
create(:node, args.except(:type))
|
179
|
+
end
|
180
|
+
|
181
|
+
expect(@content_service).to receive(:create_evidence) do |args|
|
182
|
+
expect(args[:content]).to include("#[ID]#\nntp-clock-variables-disclosure\n\n")
|
183
|
+
expect(args[:issue].id).to eq('ntp-clock-variables-disclosure')
|
184
|
+
expect(args[:node].label).to eq('1.1.1.1')
|
185
|
+
end.twice
|
186
|
+
|
187
|
+
@importer.import(file: @fixtures_dir + '/full_with_duplicate_node.xml')
|
165
188
|
end
|
166
|
-
|
167
|
-
@importer.import(file: 'spec/fixtures/files/full.xml')
|
168
189
|
end
|
169
190
|
end
|
191
|
+
|
192
|
+
it 'parses the fingerprints field' do
|
193
|
+
doc = Nokogiri::XML(File.read(@fixtures_dir + '/full.xml'))
|
194
|
+
|
195
|
+
ts = Dradis::Plugins::TemplateService.new(plugin: Dradis::Plugins::Nexpose)
|
196
|
+
ts.set_template(template: 'full_node', content: "#[Fingerprints]#\n%node.fingerprints%\n")
|
197
|
+
result = ts.process_template(data: doc.at_xpath('//nodes/node'), template: 'full_node')
|
198
|
+
|
199
|
+
expect(result).to include('IOS')
|
200
|
+
end
|
170
201
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<test id="http-coldfusion-cfide-unprotected" key="/CFIDE/adminapi/base.cfc?wsdl" status="vulnerable-exploited" scan-id="4" vulnerable-since="20141110T165124356" pci-compliance-status="fail">
|
1
|
+
<test id="http-coldfusion-cfide-unprotected" key="/CFIDE/adminapi/base.cfc?wsdl" status="vulnerable-exploited" scan-id="4" vulnerable-since="20141110T165124356" pci-compliance-status="fail" port="123" protocol="udp">
|
2
2
|
<Paragraph>
|
3
3
|
<UnorderedList>
|
4
4
|
<ListItem>Running HTTP service</ListItem>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dradis-nexpose
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Martin
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-01-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dradis-plugins
|
@@ -96,7 +96,7 @@ dependencies:
|
|
96
96
|
version: 0.5.2
|
97
97
|
description: This add-on allows you to upload and parse output produced from Nexpose
|
98
98
|
scanner into Dradis.
|
99
|
-
email:
|
99
|
+
email:
|
100
100
|
executables: []
|
101
101
|
extensions: []
|
102
102
|
extra_rdoc_files: []
|
@@ -130,6 +130,7 @@ files:
|
|
130
130
|
- lib/nexpose/vulnerability.rb
|
131
131
|
- lib/tasks/thorfile.rb
|
132
132
|
- spec/fixtures/files/full.xml
|
133
|
+
- spec/fixtures/files/full_with_duplicate_node.xml
|
133
134
|
- spec/fixtures/files/simple.xml
|
134
135
|
- spec/fixtures/files/ssl.xml
|
135
136
|
- spec/nexpose_upload_spec.rb
|
@@ -156,7 +157,7 @@ homepage: https://dradis.com/integrations/nexpose.html
|
|
156
157
|
licenses:
|
157
158
|
- GPL-2
|
158
159
|
metadata: {}
|
159
|
-
post_install_message:
|
160
|
+
post_install_message:
|
160
161
|
rdoc_options: []
|
161
162
|
require_paths:
|
162
163
|
- lib
|
@@ -171,12 +172,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
171
172
|
- !ruby/object:Gem::Version
|
172
173
|
version: '0'
|
173
174
|
requirements: []
|
174
|
-
rubygems_version: 3.
|
175
|
-
signing_key:
|
175
|
+
rubygems_version: 3.3.7
|
176
|
+
signing_key:
|
176
177
|
specification_version: 4
|
177
178
|
summary: Nexpose add-on for the Dradis Framework.
|
178
179
|
test_files:
|
179
180
|
- spec/fixtures/files/full.xml
|
181
|
+
- spec/fixtures/files/full_with_duplicate_node.xml
|
180
182
|
- spec/fixtures/files/simple.xml
|
181
183
|
- spec/fixtures/files/ssl.xml
|
182
184
|
- spec/nexpose_upload_spec.rb
|