heimdall_tools 1.3.26 → 1.3.31
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 +46 -1
- data/README.md +11 -5
- data/lib/data/U_CCI_List.xml +38403 -0
- data/lib/heimdall_tools/cli.rb +2 -1
- data/lib/heimdall_tools/nessus_mapper.rb +95 -17
- metadata +5 -5
- data/lib/data/gitkeep +0 -0
data/lib/heimdall_tools/cli.rb
CHANGED
@@ -53,9 +53,10 @@ module HeimdallTools
|
|
53
53
|
def nessus_mapper
|
54
54
|
hdfs = HeimdallTools::NessusMapper.new(File.read(options[:xml])).to_hdf
|
55
55
|
|
56
|
+
puts "\nHDF Generated:"
|
56
57
|
hdfs.keys.each do | host |
|
57
58
|
File.write("#{options[:output_prefix]}-#{host}.json", hdfs[host])
|
58
|
-
puts "
|
59
|
+
puts "#{options[:output_prefix]}-#{host}.json"
|
59
60
|
end
|
60
61
|
|
61
62
|
end
|
@@ -2,10 +2,12 @@ require 'json'
|
|
2
2
|
require 'csv'
|
3
3
|
require 'heimdall_tools/hdf'
|
4
4
|
require 'utilities/xml_to_hash'
|
5
|
+
require 'nokogiri'
|
5
6
|
|
6
7
|
RESOURCE_DIR = Pathname.new(__FILE__).join('../../data')
|
7
8
|
|
8
9
|
NESSUS_PLUGINS_NIST_MAPPING_FILE = File.join(RESOURCE_DIR, 'nessus-plugins-nist-mapping.csv')
|
10
|
+
U_CCI_LIST = File.join(RESOURCE_DIR, 'U_CCI_List.xml')
|
9
11
|
|
10
12
|
IMPACT_MAPPING = {
|
11
13
|
Info: 0.0,
|
@@ -17,20 +19,33 @@ IMPACT_MAPPING = {
|
|
17
19
|
|
18
20
|
DEFAULT_NIST_TAG = ["unmapped"].freeze
|
19
21
|
|
22
|
+
# Nessus results file 800-53 refs does not contain Nist rev version. Using this default
|
23
|
+
# version in that case
|
24
|
+
DEFAULT_NIST_REV = 'Rev_4'.freeze
|
25
|
+
|
20
26
|
NA_PLUGIN_OUTPUT = "This Nessus Plugin does not provide output message.".freeze
|
21
27
|
|
22
28
|
# rubocop:disable Metrics/AbcSize
|
23
29
|
|
30
|
+
# Loading spinner sign
|
31
|
+
$spinner = Enumerator.new do |e|
|
32
|
+
loop do
|
33
|
+
e.yield '|'
|
34
|
+
e.yield '/'
|
35
|
+
e.yield '-'
|
36
|
+
e.yield '\\'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
24
40
|
module HeimdallTools
|
25
41
|
class NessusMapper
|
26
42
|
def initialize(nessus_xml, verbose = false)
|
27
43
|
@nessus_xml = nessus_xml
|
28
44
|
@verbose = verbose
|
29
|
-
|
45
|
+
read_cci_xml
|
30
46
|
begin
|
31
47
|
@cwe_nist_mapping = parse_mapper
|
32
48
|
@data = xml_to_hash(nessus_xml)
|
33
|
-
|
34
49
|
@reports = extract_report
|
35
50
|
@scaninfo = extract_scaninfo
|
36
51
|
rescue StandardError => e
|
@@ -51,6 +66,10 @@ module HeimdallTools
|
|
51
66
|
end
|
52
67
|
end
|
53
68
|
|
69
|
+
def parse_refs(refs, key)
|
70
|
+
refs.split(',').map { |x| x.split('|')[1] if x.include?(key) }.compact
|
71
|
+
end
|
72
|
+
|
54
73
|
def extract_scaninfo
|
55
74
|
begin
|
56
75
|
policy = @data['NessusClientData_v2']['Policy']
|
@@ -82,28 +101,60 @@ module HeimdallTools
|
|
82
101
|
|
83
102
|
def finding(issue, timestamp)
|
84
103
|
finding = {}
|
85
|
-
|
86
|
-
|
104
|
+
# if compliance-result field, this is a policy compliance result entry
|
105
|
+
# nessus policy compliance result provides a pass/fail data
|
106
|
+
# For non policy compliance results are defaulted to failed
|
107
|
+
if issue['compliance-result']
|
108
|
+
finding['status'] = issue['compliance-result'].eql?('PASSED') ? 'passed' : 'failed'
|
109
|
+
else
|
110
|
+
finding['status'] = 'failed'
|
111
|
+
end
|
112
|
+
|
113
|
+
if issue['description']
|
114
|
+
finding['code_desc'] = issue['description'].to_s || NA_PLUGIN_OUTPUT
|
115
|
+
else
|
116
|
+
finding['code_desc'] = issue['plugin_output'] || NA_PLUGIN_OUTPUT
|
117
|
+
end
|
87
118
|
finding['run_time'] = NA_FLOAT
|
88
119
|
finding['start_time'] = timestamp
|
89
120
|
[finding]
|
90
121
|
end
|
91
122
|
|
92
|
-
def
|
123
|
+
def read_cci_xml
|
124
|
+
@cci_xml = Nokogiri::XML(File.open(U_CCI_LIST))
|
125
|
+
@cci_xml.remove_namespaces!
|
126
|
+
rescue StandardError => e
|
127
|
+
puts "Exception: #{e.message}"
|
128
|
+
end
|
129
|
+
|
130
|
+
def cci_nist_tag(cci_refs)
|
131
|
+
nist_tags = []
|
132
|
+
cci_refs.each do | cci_ref |
|
133
|
+
item_node = @cci_xml.xpath("//cci_list/cci_items/cci_item[@id='#{cci_ref}']")[0] unless @cci_xml.nil?
|
134
|
+
unless item_node.nil?
|
135
|
+
nist_ref = item_node.xpath('./references/reference[not(@version <= preceding-sibling::reference/@version) and not(@version <=following-sibling::reference/@version)]/@index').text
|
136
|
+
end
|
137
|
+
nist_tags << nist_ref
|
138
|
+
end
|
139
|
+
nist_tags
|
140
|
+
end
|
141
|
+
|
142
|
+
def plugin_nist_tag(pluginfamily, pluginid)
|
93
143
|
entries = @cwe_nist_mapping.select { |x| (x[:pluginfamily].eql?(pluginfamily) && (x[:pluginid].eql?('*') || x[:pluginid].eql?(pluginid.to_i)) ) }
|
94
144
|
tags = entries.map { |x| [x[:nistid].split('|'), "Rev_#{x[:rev]}"] }
|
95
145
|
tags.empty? ? DEFAULT_NIST_TAG : tags.flatten.uniq
|
96
146
|
end
|
97
147
|
|
98
148
|
def impact(severity)
|
149
|
+
# Map CAT levels and Plugin severity to HDF impact levels
|
99
150
|
case severity
|
100
151
|
when "0"
|
101
152
|
IMPACT_MAPPING[:Info]
|
102
|
-
when "1"
|
153
|
+
when "1","III"
|
103
154
|
IMPACT_MAPPING[:Low]
|
104
|
-
when "2"
|
155
|
+
when "2","II"
|
105
156
|
IMPACT_MAPPING[:Medium]
|
106
|
-
when "3"
|
157
|
+
when "3","I"
|
107
158
|
IMPACT_MAPPING[:High]
|
108
159
|
when "4"
|
109
160
|
IMPACT_MAPPING[:Critical]
|
@@ -142,21 +193,48 @@ module HeimdallTools
|
|
142
193
|
def to_hdf
|
143
194
|
host_results = {}
|
144
195
|
@reports.each do | report|
|
145
|
-
# Under current version of the converter `Policy Compliance` items are ignored
|
146
|
-
report_items = report['ReportItem'].select {|x| !x['pluginFamily'].eql? 'Policy Compliance'}
|
147
|
-
|
148
196
|
controls = []
|
149
|
-
|
197
|
+
report['ReportItem'].each do | item |
|
198
|
+
printf("\rProcessing: %s", $spinner.next)
|
150
199
|
@item = {}
|
151
|
-
@item['id'] = item['pluginID'].to_s
|
152
|
-
@item['title'] = item['pluginName'].to_s
|
153
|
-
@item['desc'] = format_desc(item).to_s
|
154
|
-
@item['impact'] = impact(item['severity'])
|
155
200
|
@item['tags'] = {}
|
156
201
|
@item['descriptions'] = []
|
157
202
|
@item['refs'] = NA_ARRAY
|
158
203
|
@item['source_location'] = NA_HASH
|
159
|
-
|
204
|
+
|
205
|
+
# Nessus results field set are different for 'Policy Compliance' plug-in family vs other plug-in families
|
206
|
+
# Following if conditions capture compliance* if it exists else it will default to plugin* fields
|
207
|
+
# Current version covers STIG based 'Policy Compliance' results
|
208
|
+
# TODO Cover cases for 'Policy Compliance' results based on CIS
|
209
|
+
if item['compliance-reference']
|
210
|
+
@item['id'] = parse_refs(item['compliance-reference'],'Vuln-ID').join.to_s
|
211
|
+
else
|
212
|
+
@item['id'] = item['pluginID'].to_s
|
213
|
+
end
|
214
|
+
if item['compliance-check-name']
|
215
|
+
@item['title'] = item['compliance-check-name'].to_s
|
216
|
+
else
|
217
|
+
@item['title'] = item['pluginName'].to_s
|
218
|
+
end
|
219
|
+
if item['compliance-info']
|
220
|
+
@item['desc'] = item['compliance-info'].to_s
|
221
|
+
else
|
222
|
+
@item['desc'] = format_desc(item).to_s
|
223
|
+
end
|
224
|
+
if item['compliance-reference']
|
225
|
+
@item['impact'] = impact(parse_refs(item['compliance-reference'],'CAT').join.to_s)
|
226
|
+
else
|
227
|
+
@item['impact'] = impact(item['severity'])
|
228
|
+
end
|
229
|
+
if item['compliance-reference']
|
230
|
+
@item['tags']['nist'] = cci_nist_tag(parse_refs(item['compliance-reference'],'CCI'))
|
231
|
+
else
|
232
|
+
@item['tags']['nist'] = plugin_nist_tag(item['pluginFamily'],item['pluginID'])
|
233
|
+
end
|
234
|
+
if item['compliance-solution']
|
235
|
+
@item['descriptions'] << desc_tags(item['compliance-solution'], 'check')
|
236
|
+
end
|
237
|
+
|
160
238
|
@item['code'] = ''
|
161
239
|
@item['results'] = finding(item, extract_timestamp(report))
|
162
240
|
controls << @item
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: heimdall_tools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.31
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Thew
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date: 2020-
|
13
|
+
date: 2020-06-16 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: nokogiri
|
@@ -116,14 +116,14 @@ dependencies:
|
|
116
116
|
requirements:
|
117
117
|
- - ">="
|
118
118
|
- !ruby/object:Gem::Version
|
119
|
-
version:
|
119
|
+
version: 0.17.2
|
120
120
|
type: :runtime
|
121
121
|
prerelease: false
|
122
122
|
version_requirements: !ruby/object:Gem::Requirement
|
123
123
|
requirements:
|
124
124
|
- - ">="
|
125
125
|
- !ruby/object:Gem::Version
|
126
|
-
version:
|
126
|
+
version: 0.17.2
|
127
127
|
- !ruby/object:Gem::Dependency
|
128
128
|
name: bundler
|
129
129
|
requirement: !ruby/object:Gem::Requirement
|
@@ -209,8 +209,8 @@ files:
|
|
209
209
|
- README.md
|
210
210
|
- Rakefile
|
211
211
|
- exe/heimdall_tools
|
212
|
+
- lib/data/U_CCI_List.xml
|
212
213
|
- lib/data/cwe-nist-mapping.csv
|
213
|
-
- lib/data/gitkeep
|
214
214
|
- lib/data/nessus-plugins-nist-mapping.csv
|
215
215
|
- lib/data/owasp-nist-mapping.csv
|
216
216
|
- lib/heimdall_tools.rb
|
data/lib/data/gitkeep
DELETED
File without changes
|