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.
@@ -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 "HDF Generated: #{options[:output_prefix]}-#{host}.json"
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
- finding['status'] = 'failed'
86
- finding['code_desc'] = issue['plugin_output'] || NA_PLUGIN_OUTPUT
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 nist_tag(pluginfamily, pluginid)
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
- report_items.each do | item |
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
- @item['tags']['nist'] = nist_tag(item['pluginFamily'],item['pluginID'])
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.26
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-05-06 00:00:00.000000000 Z
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: '0.17'
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: '0.17'
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
File without changes