dradis-nexpose 4.15.0 → 4.16.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 741c488c76cb9554ce3b2a61997374262453a38e3256cad93c1885602d872bca
4
- data.tar.gz: c896b751650744b60e8ddfeae40c4cba4277901d404e95bdb594674024227038
3
+ metadata.gz: 0dd759ff5965a397c6dc53aa7fe958a472377df1e4b88598c084ef710bbf7325
4
+ data.tar.gz: cc1caab7f91bf7a934b940bda4773ea0af137218320c26fe4b33e89bfe212499
5
5
  SHA512:
6
- metadata.gz: 93068f684c000bcf4cb4f5944b38dd3e57ae7152c7c9f046b8db9e65c46a76323f5b399feffa47474cb62af5da17e26746af419c4a9eacd824437d5f6d0cae0e
7
- data.tar.gz: e812c05c84e2b12e36fdb858eadd2daf02bd87b5c69cf5cc7b4cbaa9cbc8fe7eb213e12d58c8518a0c631fcb08bb0ff78973cdbd264d8f741021a84817adee8c
6
+ metadata.gz: 11ab68a5ada00fd69fc77b7f41b3e08441dc7e0ac9fdbad90ff006b62a307fd6a4a44d05d534e954c88391ce63ec5fc28b4682e4e6e4f4c488f7a489192c0e6f
7
+ data.tar.gz: f610891a766cdb60ac5f1eccb90bfc497b2ee087f3c5ef3bd52037a11e342118c4ea62938ce3e7170409682c7a78302ecbbf06fe6d2450dde8a12584a6544ceb
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ v4.16.0 (May 2025)
2
+ - Format UnorderedList/OrderedList to textile
3
+
1
4
  v4.15.0 (December 2024)
2
5
  - No changes
3
6
 
@@ -8,7 +8,7 @@ module Dradis
8
8
 
9
9
  module VERSION
10
10
  MAJOR = 4
11
- MINOR = 15
11
+ MINOR = 16
12
12
  TINY = 0
13
13
  PRE = nil
14
14
 
@@ -0,0 +1,81 @@
1
+ module Dradis::Plugins::Nexpose
2
+ class XmlFormatter
3
+ def format_html_content(source)
4
+ result = format_list(source)
5
+
6
+ cleanup_html(result)
7
+ end
8
+
9
+ def cleanup_html(source)
10
+ result = source.to_s
11
+ result.gsub!(/<ContainerBlockElement>(.*?)<\/ContainerBlockElement>/m) { |m| "#{ $1 }" }
12
+ result.gsub!(/<Paragraph preformat=\"true\">(\s*)<Paragraph preformat=\"true\">(.*?)<\/Paragraph>(\s*)<\/Paragraph>/mi) do
13
+ text = $2
14
+ text[/\n/] ? "\nbc.. #{ text }\n\np. " : "@#{text}@"
15
+ end
16
+ result.gsub!(/<Paragraph preformat=\"true\">(.*?)<\/Paragraph>/mi) do
17
+ text = $1
18
+ text[/\n/] ? "\nbc.. #{ text }\n\np. " : "@#{text}@"
19
+ end
20
+ result.gsub!(/<Paragraph>(.*?)<\/Paragraph>/m) { |m| "#{ $1 }\n" }
21
+ result.gsub!(/<Paragraph>|<\/Paragraph>/, '')
22
+ result.gsub!(/ /, '')
23
+ result.gsub!(/ /, '')
24
+ result.gsub!(/\t\t/, '')
25
+ result.gsub!(/<URLLink(.*)LinkURL=\"(.*?)\"(.*?)>(.*?)<\/URLLink>/im) { "\"#{$4.strip}\":#{$2.strip} " }
26
+ result.gsub!(/<URLLink LinkTitle=\"(.*?)\"(.*?)LinkURL=\"(.*?)\"\/>/i) { "\"#{$1.strip}\":#{$3.strip} " }
27
+ result.gsub!(/<URLLink LinkURL=\"(.*?)\"(.*?)LinkTitle=\"(.*?)\"\/>/i) { "\"#{$3.strip}\":#{$1.strip} " }
28
+ result.gsub!(/&gt;/, '>')
29
+ result.gsub!(/&lt;/, '<')
30
+ result
31
+ end
32
+
33
+ def cleanup_nested(source)
34
+ result = source.to_s
35
+ result.gsub!(/<references>/, '')
36
+ result.gsub!(/<\/references>/, '')
37
+ result.gsub!(/<reference source=\"(.*?)\">(.*?)<\/reference>/i) { "#{$1.strip}: #{$2.strip}\n" }
38
+ result.gsub!(/<tags>/, '')
39
+ result.gsub!(/<\/tags>/, '')
40
+ result.gsub!(/<tag>(.*?)<\/tag>/) { "#{$1}\n" }
41
+ result.gsub!(/ /, '')
42
+ result
43
+ end
44
+
45
+ private
46
+
47
+ def format_list(source)
48
+ if source.xpath('./UnorderedList | ./OrderedList').any?
49
+ format_nexpose_list(source)
50
+ else
51
+ source
52
+ end
53
+ end
54
+
55
+ def format_nexpose_list(xml, depth = 1)
56
+ xml.xpath('./UnorderedList | ./OrderedList').map do |list|
57
+ list_item_element = list.name == 'UnorderedList' ? '*' : '#'
58
+
59
+ list.xpath('./ListItem').map do |list_item|
60
+ paragraphs = list_item.xpath('./Paragraph')
61
+
62
+ list_item_text =
63
+ if paragraphs.any?
64
+ paragraphs.map do |paragraph|
65
+ # <Paragraph> nodes can either have more lists or just text
66
+ if paragraph.xpath('./UnorderedList | ./OrderedList').any?
67
+ format_nexpose_list(paragraph, depth + 1)
68
+ else
69
+ cleanup_html(paragraph.to_s).chomp
70
+ end
71
+ end.join("\n")
72
+ else
73
+ list_item.text
74
+ end
75
+
76
+ ''.ljust(depth, list_item_element) + ' ' + list_item_text
77
+ end.join("\n")
78
+ end.join("\n")
79
+ end
80
+ end
81
+ end
@@ -11,3 +11,4 @@ require 'dradis/plugins/nexpose/full/importer'
11
11
  require 'dradis/plugins/nexpose/mapping'
12
12
  require 'dradis/plugins/nexpose/simple/importer'
13
13
  require 'dradis/plugins/nexpose/version'
14
+ require 'dradis/plugins/nexpose/xml_formatter'
@@ -20,7 +20,7 @@ module Nexpose
20
20
  def supported_tags
21
21
  [
22
22
  # attributes
23
- :added, :cvss_score, :cvss_vector, :modified, :nexpose_id, :pci_severity,
23
+ :added, :cvss_score, :cvss_vector, :modified, :nexpose_id, :pci_severity,
24
24
  :published, :risk_score, :severity, :title,
25
25
 
26
26
  # simple tags
@@ -34,10 +34,9 @@ module Nexpose
34
34
  ]
35
35
  end
36
36
 
37
-
38
37
  # This allows external callers (and specs) to check for implemented
39
38
  # properties
40
- def respond_to?(method, include_private=false)
39
+ def respond_to?(method, include_private = false)
41
40
  return true if supported_tags.include?(method.to_sym)
42
41
  super
43
42
  end
@@ -49,7 +48,6 @@ module Nexpose
49
48
  # attribute, simple descendent or collection that it maps to in the XML
50
49
  # tree.
51
50
  def method_missing(method, *args)
52
-
53
51
  # We could remove this check and return nil for any non-recognized tag.
54
52
  # The problem would be that it would make tricky to debug problems with
55
53
  # typos. For instance: <>.potr would return nil instead of raising an
@@ -62,11 +60,11 @@ module Nexpose
62
60
  # First we try the attributes. In Ruby we use snake_case, but in XML
63
61
  # CamelCase is used for some attributes
64
62
  translations_table = {
65
- :nexpose_id => 'id',
66
- :pci_severity => 'pciSeverity',
67
- :risk_score => 'riskScore',
68
- :cvss_score => 'cvssScore',
69
- :cvss_vector =>'cvssVector'
63
+ nexpose_id: 'id',
64
+ pci_severity: 'pciSeverity',
65
+ risk_score: 'riskScore',
66
+ cvss_score: 'cvssScore',
67
+ cvss_vector: 'cvssVector'
70
68
  }
71
69
 
72
70
  method_name = translations_table.fetch(method, method.to_s)
@@ -78,13 +76,14 @@ module Nexpose
78
76
  nest = @xml.xpath("./#{method_name}").first
79
77
 
80
78
  # We need to clean up tags that have HTML content in them
79
+ formatter = Dradis::Plugins::Nexpose::XmlFormatter.new
81
80
  if tags_with_html_content.include?(method)
82
- result = cleanup_html(tag)
81
+ result = formatter.format_html_content(tag)
83
82
  result = add_bc_to_ssl_cipher_list(result) if SSL_CIPHER_VULN_IDS.include?(@xml.attributes['id'].value)
84
83
  return result
85
84
  # And we need to clean up the tags with nested content in them
86
85
  elsif tags_with_nested_content.include?(method)
87
- return cleanup_nested(nest)
86
+ return formatter.cleanup_nested(nest)
88
87
  else
89
88
  return tag
90
89
  end
@@ -96,7 +95,7 @@ module Nexpose
96
95
  return @xml.xpath("//test[@id='#{vuln_id}']/Paragraph").
97
96
  text.split("\n").
98
97
  collect(&:strip).
99
- reject{|line| line.empty?}.join("\n")
98
+ reject { |line| line.empty? }.join("\n")
100
99
  end
101
100
 
102
101
  nil
@@ -106,46 +105,7 @@ module Nexpose
106
105
 
107
106
  def add_bc_to_ssl_cipher_list(source)
108
107
  result = source.to_s
109
- result.gsub!(/\n(.*?)!(.*?)/){"\nbc. #{ $1 }!#{ $2 }\n"}
110
- result
111
- end
112
-
113
- def cleanup_html(source)
114
- result = source.to_s
115
- result.gsub!(/<ContainerBlockElement>(.*?)<\/ContainerBlockElement>/m){|m| "#{ $1 }"}
116
- result.gsub!(/<Paragraph preformat=\"true\">(\s*)<Paragraph preformat=\"true\">(.*?)<\/Paragraph>(\s*)<\/Paragraph>/mi) do
117
- text = $2
118
- text[/\n/] ? "\nbc.. #{ text }\n\np. " : "@#{text}@"
119
- end
120
- result.gsub!(/<Paragraph preformat=\"true\">(.*?)<\/Paragraph>/mi) do
121
- text = $1
122
- text[/\n/] ? "\nbc.. #{ text }\n\np. " : "@#{text}@"
123
- end
124
- result.gsub!(/<Paragraph>(.*?)<\/Paragraph>/m){|m| "#{ $1 }\n"}
125
- result.gsub!(/<Paragraph>|<\/Paragraph>/, '')
126
- result.gsub!(/<UnorderedList(.*?)>(.*?)<\/UnorderedList>/m){|m| "#{ $2 }"}
127
- result.gsub!(/<OrderedList(.*?)>(.*?)<\/OrderedList>/m){|m| "#{ $2 }"}
128
- result.gsub!(/<ListItem>|<\/ListItem>/, '')
129
- result.gsub!(/ /, '')
130
- result.gsub!(/ /, '')
131
- result.gsub!(/\t\t/, '')
132
- result.gsub!(/<URLLink(.*)LinkURL=\"(.*?)\"(.*?)>(.*?)<\/URLLink>/im) { "\"#{$4.strip}\":#{$2.strip} " }
133
- result.gsub!(/<URLLink LinkTitle=\"(.*?)\"(.*?)LinkURL=\"(.*?)\"\/>/i) { "\"#{$1.strip}\":#{$3.strip} " }
134
- result.gsub!(/<URLLink LinkURL=\"(.*?)\"(.*?)LinkTitle=\"(.*?)\"\/>/i) { "\"#{$3.strip}\":#{$1.strip} " }
135
- result.gsub!(/&gt;/, '>')
136
- result.gsub!(/&lt;/, '<')
137
- result
138
- end
139
-
140
- def cleanup_nested(source)
141
- result = source.to_s
142
- result.gsub!(/<references>/, '')
143
- result.gsub!(/<\/references>/, '')
144
- result.gsub!(/<reference source=\"(.*?)\">(.*?)<\/reference>/i) {"#{$1.strip}: #{$2.strip}\n"}
145
- result.gsub!(/<tags>/, '')
146
- result.gsub!(/<\/tags>/, '')
147
- result.gsub!(/<tag>(.*?)<\/tag>/) {"#{$1}\n"}
148
- result.gsub!(/ /, '')
108
+ result.gsub!(/\n(.*?)!(.*?)/) { "\nbc. #{ $1 }!#{ $2 }\n" }
149
109
  result
150
110
  end
151
111
 
@@ -156,6 +116,5 @@ module Nexpose
156
116
  def tags_with_nested_content
157
117
  [:references, :tags]
158
118
  end
159
-
160
119
  end
161
120
  end
@@ -127,11 +127,27 @@
127
127
  <ContainerBlockElement>
128
128
  <UnorderedList>
129
129
  <ListItem>
130
+ <Paragraph>Microsoft Windows</Paragraph>
130
131
  <Paragraph>
131
- <Paragraph>You can remove inode information from the ETag header by adding the following directive to your Apache config:</Paragraph>
132
- <Paragraph preformat="true">FileETag MTime Size</Paragraph>
132
+ <OrderedList>
133
+ <ListItem>Open the Windows Control Panel.</ListItem>
134
+ <ListItem>Select &quot;Administrative Tools&quot;.</ListItem>
135
+ </OrderedList>
133
136
  </Paragraph>
134
137
  </ListItem>
138
+ <ListItem>
139
+ <Paragraph>Microsoft Windows</Paragraph>
140
+ <Paragraph>
141
+ <OrderedList>
142
+ <ListItem>Open the &quot;Performance and Maintenance&quot; control panel.</ListItem>
143
+ <ListItem>Select &quot;Administrative Tools&quot;.</ListItem>
144
+ <ListItem>Restart the system for the changes to take effect.</ListItem></OrderedList></Paragraph></ListItem>
145
+ <ListItem>
146
+ <Paragraph>Microsoft Windows</Paragraph>
147
+ <Paragraph>
148
+ <OrderedList>
149
+ <ListItem>Open the &quot;Administrative Tools&quot; control panel.</ListItem>
150
+ <ListItem>Restart the system for the changes to take effect.</ListItem></OrderedList></Paragraph></ListItem>
135
151
  <ListItem>
136
152
  <Paragraph>OpenBSD</Paragraph>
137
153
  <Paragraph>Download and apply the patch from:
@@ -0,0 +1,26 @@
1
+ <ContainerBlockElement>
2
+ <UnorderedList>
3
+ <ListItem>
4
+ <Paragraph>Microsoft Windows</Paragraph>
5
+ <Paragraph>
6
+ <OrderedList>
7
+ <ListItem>Open the Windows Control Panel.</ListItem>
8
+ <ListItem>Select &quot;Administrative Tools&quot;.</ListItem>
9
+ </OrderedList>
10
+ </Paragraph>
11
+ </ListItem>
12
+ <ListItem>
13
+ <Paragraph>Microsoft Windows</Paragraph>
14
+ <Paragraph>
15
+ <OrderedList>
16
+ <ListItem>Open the &quot;Performance and Maintenance&quot; control panel.</ListItem>
17
+ <ListItem>Select &quot;Administrative Tools&quot;.</ListItem>
18
+ <ListItem>Restart the system for the changes to take effect.</ListItem></OrderedList></Paragraph></ListItem>
19
+ <ListItem>
20
+ <Paragraph>Microsoft Windows</Paragraph>
21
+ <Paragraph>
22
+ <OrderedList>
23
+ <ListItem>Open the &quot;Administrative Tools&quot; control panel.</ListItem>
24
+ <ListItem>Restart the system for the changes to take effect.</ListItem></OrderedList></Paragraph></ListItem>
25
+ </UnorderedList>
26
+ </ContainerBlockElement>
@@ -54,5 +54,157 @@ describe 'Nexpose upload plugin' do
54
54
  expect(@result).to include('n/a')
55
55
  end
56
56
  end
57
+
58
+ describe 'Importer: Full' do
59
+ it 'creates nodes, issues, notes and an evidences as needed' do
60
+ expect(@content_service).to receive(:create_node).with(hash_including label: 'Nexpose Scan Summary').once
61
+ expect(@content_service).to receive(:create_note) do |args|
62
+ expect(args[:text]).to include("#[Title]#\nUSDA_Internal (4)")
63
+ expect(args[:node].label).to eq('Nexpose Scan Summary')
64
+ end.once
65
+
66
+ expect(@content_service).to receive(:create_node) do |args|
67
+ expect(args[:label]).to eq('1.1.1.1')
68
+ expect(args[:type]).to eq(:host)
69
+ create(:node, args.except(:type))
70
+ end
71
+
72
+ expect(@content_service).to receive(:create_note) do |args|
73
+ expect(args[:text]).to include("#[Title]#\n1.1.1.1")
74
+ expect(args[:node].label).to eq('1.1.1.1')
75
+ end.once
76
+
77
+ expect(@content_service).to receive(:create_note) do |args|
78
+ expect(args[:text]).to include("#[Title]#\nService name: NTP")
79
+ expect(args[:node].label).to eq('1.1.1.1')
80
+ end.once
81
+
82
+ expect(@content_service).to receive(:create_note) do |args|
83
+ expect(args[:text]).to include("#[Title]#\nService name: SNMP")
84
+ expect(args[:node].label).to eq('1.1.1.1')
85
+ end.once
86
+
87
+ expect(@content_service).to receive(:create_issue) do |args|
88
+ expect(args[:text]).to include("#[Title]#\nApache HTTPD: error responses can expose cookies (CVE-2012-0053)")
89
+ expect(args[:id]).to eq('ntp-clock-variables-disclosure')
90
+ OpenStruct.new(args)
91
+ end.once
92
+
93
+ expect(@content_service).to receive(:create_issue) do |args|
94
+ expect(args[:text]).to include("#[Title]#\nApache HTTPD: ETag Inode Information Leakage (CVE-2003-1418)")
95
+ expect(args[:id]).to eq('test-02')
96
+ OpenStruct.new(args)
97
+ end.once
98
+
99
+ expect(@content_service).to receive(:create_evidence) do |args|
100
+ expect(args[:content]).to include("#[ID]#\nntp-clock-variables-disclosure\n\n")
101
+ expect(args[:issue].id).to eq('ntp-clock-variables-disclosure')
102
+ expect(args[:node].label).to eq('1.1.1.1')
103
+ end.once
104
+
105
+ expect(@content_service).to receive(:create_evidence) do |args|
106
+ expect(args[:content]).to include("#[ID]#\ntest-02\n\n")
107
+ expect(args[:issue].id).to eq('test-02')
108
+ expect(args[:node].label).to eq('1.1.1.1')
109
+ end.once
110
+
111
+ @importer.import(file: @fixtures_dir + '/full.xml')
112
+
113
+ expect(Node.find_by(label: '1.1.1.1').properties[:os]).to eq('IOS')
114
+ end
115
+
116
+ it 'wraps ciphers inside ssl issues in code blocks' do
117
+ expect(@content_service).to receive(:create_issue) do |args|
118
+ expect(args[:text]).to include('bc. ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256')
119
+ OpenStruct.new(args)
120
+ end.once
121
+
122
+ @importer.import(file: @fixtures_dir + '/ssl.xml')
123
+ end
124
+
125
+ # Regression test for github.com/dradis/dradis-nexpose/issues/1
126
+ it 'populates solutions regardless of if they are wrapped in paragraphs or lists' do
127
+ expect(@content_service).to receive(:create_issue) do |args|
128
+ expect(args[:text]).to include("#[Solution]#\n\nApache HTTPD >= 2.0 and < 2.0.65")
129
+ OpenStruct.new(args)
130
+ end.once
131
+
132
+ expect(@content_service).to receive(:create_issue) do |args|
133
+ expect(args[:text]).to include("#[Solution]#\n")
134
+ expect(args[:text]).to include('You can remove inode information from the ETag header')
135
+ OpenStruct.new(args)
136
+ end.once
137
+
138
+ @importer.import(file: @fixtures_dir + '/full.xml')
139
+ end
140
+
141
+ it 'populates tests regardless of if they contain paragraphs or containerblockelements' do
142
+ expect(@content_service).to receive(:create_evidence) do |args|
143
+ expect(args[:content]).to include("#[Content]#\nThe following NTP variables")
144
+ OpenStruct.new(args)
145
+ end.once
146
+
147
+ expect(@content_service).to receive(:create_evidence) do |args|
148
+ expect(args[:content]).to include("#[Content]#\nVulnerable URL:")
149
+ OpenStruct.new(args)
150
+ end.once
151
+
152
+ @importer.import(file: @fixtures_dir + '/full.xml')
153
+ end
154
+
155
+ it 'transforms html entities (&lt; and &gt;)' do
156
+ expect(@content_service).to receive(:create_issue) do |args|
157
+ expect(args[:text]).to include("#[Solution]#\n\nApache HTTPD >= 2.0 and < 2.0.65")
158
+ OpenStruct.new(args)
159
+ end
160
+
161
+ @importer.import(file: @fixtures_dir + '/full.xml')
162
+ end
163
+
164
+ it 'formats the list to textile lists' do
165
+ expect(@content_service).to receive(:create_issue) do |args|
166
+ expect(args[:text]).to include("#[Title]#\nApache HTTPD: error responses can expose cookies (CVE-2012-0053)")
167
+ OpenStruct.new(args)
168
+ end.once
169
+
170
+ expect(@content_service).to receive(:create_issue) do |args|
171
+ expect(args[:text]).to include('* Microsoft Windows')
172
+ expect(args[:text]).to include('## Open the Windows Control Panel.')
173
+ expect(args[:text]).to include('## Select "Administrative Tools".')
174
+ OpenStruct.new(args)
175
+ end.once
176
+
177
+ @importer.import(file: @fixtures_dir + '/full.xml')
178
+ end
179
+ end
180
+
181
+ describe 'Importer: Full with duplicate nodes' do
182
+ it 'creates evidence for each instance of the node' do
183
+ expect(@content_service).to receive(:create_node).with(hash_including label: 'Nexpose Scan Summary').once
184
+ expect(@content_service).to receive(:create_node) do |args|
185
+ expect(args[:label]).to eq('1.1.1.1')
186
+ expect(args[:type]).to eq(:host)
187
+ create(:node, args.except(:type))
188
+ end
189
+
190
+ expect(@content_service).to receive(:create_evidence) do |args|
191
+ expect(args[:content]).to include("#[ID]#\nntp-clock-variables-disclosure\n\n")
192
+ expect(args[:issue].id).to eq('ntp-clock-variables-disclosure')
193
+ expect(args[:node].label).to eq('1.1.1.1')
194
+ end.twice
195
+
196
+ @importer.import(file: @fixtures_dir + '/full_with_duplicate_node.xml')
197
+ end
198
+ end
199
+ end
200
+
201
+ it 'parses the fingerprints field' do
202
+ doc = Nokogiri::XML(File.read(@fixtures_dir + '/full.xml'))
203
+
204
+ ts = Dradis::Plugins::TemplateService.new(plugin: Dradis::Plugins::Nexpose)
205
+ ts.set_template(template: 'full_node', content: "#[Fingerprints]#\n%node.fingerprints%\n")
206
+ result = ts.process_template(data: doc.at_xpath('//nodes/node'), template: 'full_node')
207
+
208
+ expect(result).to include('IOS')
57
209
  end
58
210
  end
@@ -0,0 +1,23 @@
1
+ # Run the spec by running the command: rspec spec/xml_formatter_spec.rb"
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Dradis::Plugins::Nexpose::XmlFormatter do
6
+ let(:source) { File.read(File.expand_path('../fixtures/files/lists.xml', __FILE__)) }
7
+
8
+ it 'parses the <UnorderedList> and <OrderedList> elements' do
9
+ xml = Nokogiri::XML(source).at_xpath('./ContainerBlockElement')
10
+ expect(Dradis::Plugins::Nexpose::XmlFormatter.new.format_html_content(xml)).to eq(
11
+ "* Microsoft Windows\n"\
12
+ "## Open the Windows Control Panel.\n"\
13
+ "## Select \"Administrative Tools\".\n"\
14
+ "* Microsoft Windows\n"\
15
+ "## Open the \"Performance and Maintenance\" control panel.\n"\
16
+ "## Select \"Administrative Tools\".\n"\
17
+ "## Restart the system for the changes to take effect.\n"\
18
+ "* Microsoft Windows\n"\
19
+ "## Open the \"Administrative Tools\" control panel.\n"\
20
+ '## Restart the system for the changes to take effect.'
21
+ )
22
+ end
23
+ end
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.15.0
4
+ version: 4.16.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: 2024-12-20 00:00:00.000000000 Z
11
+ date: 2025-05-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dradis-plugins
@@ -122,6 +122,7 @@ files:
122
122
  - lib/dradis/plugins/nexpose/mapping.rb
123
123
  - lib/dradis/plugins/nexpose/simple/importer.rb
124
124
  - lib/dradis/plugins/nexpose/version.rb
125
+ - lib/dradis/plugins/nexpose/xml_formatter.rb
125
126
  - lib/nexpose/endpoint.rb
126
127
  - lib/nexpose/node.rb
127
128
  - lib/nexpose/scan.rb
@@ -131,12 +132,14 @@ files:
131
132
  - lib/tasks/thorfile.rb
132
133
  - spec/fixtures/files/full.xml
133
134
  - spec/fixtures/files/full_with_duplicate_node.xml
135
+ - spec/fixtures/files/lists.xml
134
136
  - spec/fixtures/files/simple.xml
135
137
  - spec/fixtures/files/ssl.xml
136
138
  - spec/nexpose/full/importer_spec.rb
137
139
  - spec/nexpose/simple/importer_spec.rb
138
140
  - spec/nexpose_upload_spec.rb
139
141
  - spec/spec_helper.rb
142
+ - spec/xml_formatter_spec.rb
140
143
  - templates/full_evidence.sample
141
144
  - templates/full_node.sample
142
145
  - templates/full_scan.sample
@@ -169,9 +172,11 @@ summary: Nexpose add-on for the Dradis Framework.
169
172
  test_files:
170
173
  - spec/fixtures/files/full.xml
171
174
  - spec/fixtures/files/full_with_duplicate_node.xml
175
+ - spec/fixtures/files/lists.xml
172
176
  - spec/fixtures/files/simple.xml
173
177
  - spec/fixtures/files/ssl.xml
174
178
  - spec/nexpose/full/importer_spec.rb
175
179
  - spec/nexpose/simple/importer_spec.rb
176
180
  - spec/nexpose_upload_spec.rb
177
181
  - spec/spec_helper.rb
182
+ - spec/xml_formatter_spec.rb