heimdall_tools 1.3.26 → 1.3.31

Sign up to get free protection for your applications and to get access to all the features.
@@ -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