heimdall_tools 1.3.23 → 1.3.28

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 87c18b112ab38b1f06c4e7e85041c5c4d388d974c8ce256fdf928dbc4e2ecdf5
4
- data.tar.gz: f7fcefb5bc73c34fa17039cc2b40a068fbf754a8a7b9a07e35c4d6ad1dace8eb
3
+ metadata.gz: 793e9f28cb98cddc239829d4164d2f316100b2157ae9e196d2c32e5271fca664
4
+ data.tar.gz: 267e61797626c6ec797fdffda2d03bee9de9ce5ed45f918d2cfcda9af86a9957
5
5
  SHA512:
6
- metadata.gz: 983087a23a15d02b927b43e07ab5fa84451aa6d09bf6feba0acdbd3c24d2710374d2fde2e8b140650bdb1dcf90a5490a651c1672d0f8b4b2a05abc688136e041
7
- data.tar.gz: 717f833a3901385a7d15869f019c1ccacb2a9cdf9c9f4107e08b574620164596fcfcb00a050c7c4e3b9aed2aa6ff749e93fd095d3767e9d25dfbed5a8927ce91
6
+ metadata.gz: 671713a138539ad4f68615aa1c74d727ddd221b27fb0d7ea22531b8c5caa19aed0d00eabab2b685edc00566b2098ea7514e3281e30fbcbc09ea4db31c0171762
7
+ data.tar.gz: 2f589a0a0db9cfd64cf23f25420f6609229bbc0dfc8e435e7bde4eb7c19c431a8446ccae650e2bb6820cee8a04e996eb205999a2ad2429063e491818127a8c86
@@ -1,5 +1,72 @@
1
1
  # Changelog
2
2
 
3
+ ## [Unreleased](https://github.com/mitre/heimdall_tools/tree/HEAD)
4
+
5
+ [Full Changelog](https://github.com/mitre/heimdall_tools/compare/v1.3.27...HEAD)
6
+
7
+ **Closed issues:**
8
+
9
+ - Map 'Policy Compliance' entries for nessus\_mapper [\#49](https://github.com/mitre/heimdall_tools/issues/49)
10
+
11
+ **Merged pull requests:**
12
+
13
+ - Add code to translate Policy compliance results [\#51](https://github.com/mitre/heimdall_tools/pull/51) ([rx294](https://github.com/rx294))
14
+
15
+ ## [v1.3.27](https://github.com/mitre/heimdall_tools/tree/v1.3.27) (2020-05-22)
16
+
17
+ [Full Changelog](https://github.com/mitre/heimdall_tools/compare/v1.3.26...v1.3.27)
18
+
19
+ **Merged pull requests:**
20
+
21
+ - Updated the Dockerfile to run in an alpine ruby container [\#47](https://github.com/mitre/heimdall_tools/pull/47) ([jsa5593](https://github.com/jsa5593))
22
+ - Require a newer version of git-lite-version-bump for Windows support [\#46](https://github.com/mitre/heimdall_tools/pull/46) ([rbclark](https://github.com/rbclark))
23
+
24
+ ## [v1.3.26](https://github.com/mitre/heimdall_tools/tree/v1.3.26) (2020-05-06)
25
+
26
+ [Full Changelog](https://github.com/mitre/heimdall_tools/compare/v1.3.25...v1.3.26)
27
+
28
+ **Implemented enhancements:**
29
+
30
+ - Converter: Nessus Transform for Audit results and vulnerability scan results [\#29](https://github.com/mitre/heimdall_tools/issues/29)
31
+
32
+ **Merged pull requests:**
33
+
34
+ - Nessus Mapper [\#45](https://github.com/mitre/heimdall_tools/pull/45) ([rx294](https://github.com/rx294))
35
+
36
+ ## [v1.3.25](https://github.com/mitre/heimdall_tools/tree/v1.3.25) (2020-04-16)
37
+
38
+ [Full Changelog](https://github.com/mitre/heimdall_tools/compare/v1.3.24...v1.3.25)
39
+
40
+ **Closed issues:**
41
+
42
+ - Add minimum required json fields to work heimdall server [\#5](https://github.com/mitre/heimdall_tools/issues/5)
43
+
44
+ **Merged pull requests:**
45
+
46
+ - Make sure the fields we are looking for in Fortify exist before we parse the element [\#44](https://github.com/mitre/heimdall_tools/pull/44) ([rbclark](https://github.com/rbclark))
47
+ - Update actions to use ruby/setup-ruby [\#43](https://github.com/mitre/heimdall_tools/pull/43) ([Bialogs](https://github.com/Bialogs))
48
+
49
+ ## [v1.3.24](https://github.com/mitre/heimdall_tools/tree/v1.3.24) (2020-04-07)
50
+
51
+ [Full Changelog](https://github.com/mitre/heimdall_tools/compare/v1.3.23...v1.3.24)
52
+
53
+ **Implemented enhancements:**
54
+
55
+ - Converter: Burp Suite Pro [\#28](https://github.com/mitre/heimdall_tools/issues/28)
56
+
57
+ **Fixed bugs:**
58
+
59
+ - \[Bug\] Import mapping csvs by relative path [\#41](https://github.com/mitre/heimdall_tools/issues/41)
60
+
61
+ **Merged pull requests:**
62
+
63
+ - Update to pull data csvs by relative path [\#42](https://github.com/mitre/heimdall_tools/pull/42) ([rx294](https://github.com/rx294))
64
+ - Burpsuite mapper [\#40](https://github.com/mitre/heimdall_tools/pull/40) ([rx294](https://github.com/rx294))
65
+
66
+ ## [v1.3.23](https://github.com/mitre/heimdall_tools/tree/v1.3.23) (2020-03-31)
67
+
68
+ [Full Changelog](https://github.com/mitre/heimdall_tools/compare/v1.3.23.pre5...v1.3.23)
69
+
3
70
  ## [v1.3.23.pre5](https://github.com/mitre/heimdall_tools/tree/v1.3.23.pre5) (2020-03-31)
4
71
 
5
72
  [Full Changelog](https://github.com/mitre/heimdall_tools/compare/v1.3.23.pre4...v1.3.23.pre5)
data/README.md CHANGED
@@ -1,7 +1,6 @@
1
1
  # Heimdall Tools
2
2
 
3
3
  ![Overall Status](https://github.com/mitre/heimdall_tools/workflows/heimdall_tools/badge.svg)
4
-
5
4
  ![Heimdall Tools Build](https://github.com/mitre/heimdall_tools/workflows/Build%20and%20release%20gem/badge.svg)
6
5
 
7
6
  HeimdallTools supplies several methods to convert output from various tools to "Heimdall Data Format"(HDF) format to be viewable in Heimdall. The current converters are:
@@ -9,8 +8,8 @@ HeimdallTools supplies several methods to convert output from various tools to "
9
8
  - **sonarqube_mapper** - open-source static code analysis tool
10
9
  - **fortify_mapper** - commercial static code analysis tool
11
10
  - **zap_mapper** - OWASP ZAP - open-source dynamic code analysis tool
12
-
13
- # Prerequisites
11
+ - **burpsuite_mapper** - commercial dynamic analysis tool
12
+ - **nessus_mapper** - commercial vulnerability scanner
14
13
 
15
14
  Ruby 2.4 or higher (check using "ruby -v")
16
15
 
@@ -55,6 +54,13 @@ Verify the installed version number:
55
54
  On the Command Line, `heimdall_tools help` will print a listing of all the command with a short description.
56
55
  For detailed help on any command, run `heimdall_tools help [COMMAND]`. Help can also be called with the `-h, --help` flags after any command, like `heimdall_tools fortify_mapper -h`.
57
56
 
57
+ For Docker usage, replace the `heimdall_tools` command with the correct Docker command below for your operating system:
58
+
59
+ - **On Linux and Mac:** `docker run -it -v$(pwd):/share mitre/heimdall_tools`
60
+ - **On Windows CMD:** `docker run -it -v%cd%:/share mitre/heimdall_tools`
61
+
62
+ Note that all of the above Docker commands will mount your current directory on the Docker container. Ensure that you have navigated to the directory you intend to convert files in before executing the command.
63
+
58
64
  ## sonarqube_mapper
59
65
 
60
66
  sonarqube_mapper pulls SonarQube results, for the specified project, from the API and outputs in HDF format Json to be viewed on Heimdall
@@ -107,7 +113,39 @@ FLAGS:
107
113
  example: heimdall_tools zap_mapper -j zap_results.json -n site_name -o scan_results.json
108
114
  ```
109
115
 
110
- ## version
116
+ ## burpsuite_mapper
117
+
118
+ burpsuite_mapper translates an BurpSuite Pro exported XML results file into HDF format json to be viewable in Heimdall
119
+
120
+ ```
121
+ USAGE: heimdall_tools burpsuite_mapper [OPTIONS] -x <burpsuite-xml> -o <scan-results.json>
122
+
123
+ FLAGS:
124
+ -x <burpsuite_xml> : path to BurpSuitePro exported XML results file.
125
+ -o --output <scan-results> : path to output scan-results json.
126
+ -V --verbose : verbose run [optional].
127
+
128
+ example: heimdall_tools burpsuite_mapper -x burpsuite_results.xml -o scan_results.json
129
+ ```
130
+
131
+ ## nessus_mapper
132
+
133
+ nessus_mapper translates a Nessus-exported XML results file into HDF format json to be viewable in Heimdall
134
+
135
+ Note: A separate HDF JSON file is generated for each host reported in the Nessus Report.
136
+
137
+ ```
138
+ USAGE: heimdall_tools nessus_mapper [OPTIONS] -x <nessus-results-xml> -o <hdf-file-prefix>
139
+
140
+ FLAGS:
141
+ -x <nessus-results-xml> : path to Nessus-exported XML results file.
142
+ -o --output_prefix <prefix> : path to output scan-results json.
143
+ -V --verbose : verbose run [optional].
144
+
145
+ example: heimdall_tools nessus_mapper -x nessus-results.xml -o test-env
146
+ ```
147
+
148
+ ## version
111
149
 
112
150
  Prints out the gem version
113
151
 
@@ -0,0 +1,108 @@
1
+ pluginFamily,pluginID,NIST-ID,Rev
2
+ AIX Local Security Checks,*,SI-2|RA-5,4
3
+ Amazon Linux Local Security Checks,*,SI-2|RA-5,4
4
+ CentOS Local Security Checks,*,SI-2|RA-5,4
5
+ Debian Local Security Checks,*,SI-2|RA-5,4
6
+ F5 Networks Local Security Checks,*,SI-2|RA-5,4
7
+ Fedora Local Security Checks,*,SI-2|RA-5,4
8
+ FreeBSD Local Security Checks,*,SI-2|RA-5,4
9
+ Gentoo Local Security Checks,*,SI-2|RA-5,4
10
+ HP-UX Local Security Checks,*,SI-2|RA-5,4
11
+ Huawei Local Security Checks,*,SI-2|RA-5,4
12
+ Junos Local Security Checks,*,SI-2|RA-5,4
13
+ MacOS X Local Security Checks,*,SI-2|RA-5,4
14
+ Mandriva Local Security Checks,*,SI-2|RA-5,4
15
+ NewStart CGSL Local Security Checks,*,SI-2|RA-5,4
16
+ Oracle Linux Local Security Checks,*,SI-2|RA-5,4
17
+ OracleVM Local Security Checks,*,SI-2|RA-5,4
18
+ Palo Alto Local Security Checks,*,SI-2|RA-5,4
19
+ PhotonOS Local Security Checks,*,SI-2|RA-5,4
20
+ Red Hat Local Security Checks,*,SI-2|RA-5,4
21
+ Scientific Linux Local Security Checks,*,SI-2|RA-5,4
22
+ Slackware Local Security Checks,*,SI-2|RA-5,4
23
+ Solaris Local Security Checks,*,SI-2|RA-5,4
24
+ SuSE Local Security Checks,*,SI-2|RA-5,4
25
+ Ubuntu Local Security Checks,*,SI-2|RA-5,4
26
+ VMware ESX Local Security Checks,*,SI-2|RA-5,4
27
+ Virtuozzo Local Security Checks,*,SI-2|RA-5,4
28
+ Backdoors,,,
29
+ Brute force attacks,,,
30
+ CGI abuses,,,
31
+ CGI abuses : XSS,,,
32
+ CISCO,,,
33
+ DNS,,,
34
+ Databases,,,
35
+ Default Unix Accounts,,,
36
+ Denial of Service,,,
37
+ FTP,,,
38
+ Firewalls,56310,SC-7,4
39
+ Gain a shell remotely,,,
40
+ General,133964,AC-3(4),4
41
+ General,117530,UM-1,4
42
+ General,110483,CM-7,4
43
+ General,95928,AC-2,4
44
+ General,90191,CM-8,4
45
+ General,86420,CM-8,4
46
+ General,70544,AC-17(2)|SC-13,4
47
+ General,66334,SI-2|RA-5,4
48
+ General,64582,CM-8,4
49
+ General,57582,SC-12,4
50
+ General,57041,AC-17(2)|SC-13,4
51
+ General,56984,AC-17(2)|SC-13,4
52
+ General,56468,CM-8,4
53
+ General,55472,CM-8,4
54
+ General,54615,CM-8,4
55
+ General,51192,SC-12,4
56
+ General,45590,CM-8,4
57
+ General,45432,CM-8,4
58
+ General,45410,SC-12,4
59
+ General,39520,SI-2|RA-5,4
60
+ General,35351,CM-8,4
61
+ General,34098,CM-8,4
62
+ General,33276,CM-8,4
63
+ General,25220,SC-8,4
64
+ General,25203,CM-8,4
65
+ General,25202,CM-8,4
66
+ General,22869,CM-8,4
67
+ General,21643,AC-17(2)|SC-13,4
68
+ General,12053,CM-8,4
69
+ General,11936,CM-8,4
70
+ General,10881,AC-17(2)|SC-13,4
71
+ General,10863,SC-12,4
72
+ General,10287,CM-8,4
73
+ General,10114,CM-6,4
74
+ Misc.,118237,CM-8,4
75
+ Misc.,97993,CM-8,4
76
+ Misc.,90707,CM-8,4
77
+ Misc.,84821,AC-17(2)|SC-13,4
78
+ Misc.,83875,AC-17(2)|SC-13,4
79
+ Misc.,70657,AC-17(2)|SC-13,4
80
+ Misc.,58651,AC-17,4
81
+ Mobile Devices,,,
82
+ Netware,,,
83
+ Peer-To-Peer File Sharing,,,
84
+ Policy Compliance,,,
85
+ Port scanners,14272,CM-8,4
86
+ RPC,53335,CM-8,4
87
+ RPC,10223,CM-8,4
88
+ SCADA,,,
89
+ SMTP problems,,,
90
+ SNMP,,,
91
+ Service detection,121010,AC-17(2)|SC-13,4
92
+ Service detection,104743,AC-17(2)|SC-13,4
93
+ Service detection,25221,CM-8,4
94
+ Service detection,22964,CM-8,4
95
+ Service detection,11111,CM-8,4
96
+ Service detection,10884,AU-8(1),4
97
+ Service detection,10267,AC-17(2),4
98
+ Settings,117887,UM-1,4
99
+ Settings,110095,UM-1,4
100
+ Settings,19506,UM-1,4
101
+ Web Servers,85805,SC-8|SC-13,4
102
+ Web Servers,84502,AC-17(2)|SC-13,4
103
+ Web Servers,43111,CM-8,4
104
+ Web Servers,24260,CM-8,4
105
+ Web Servers,10107,CM-8,4
106
+ Windows,,,
107
+ Windows : Microsoft Bulletins,,,
108
+ Windows : User management,,,
@@ -8,4 +8,6 @@ module HeimdallTools
8
8
  autoload :FortifyMapper, 'heimdall_tools/fortify_mapper'
9
9
  autoload :ZapMapper, 'heimdall_tools/zap_mapper'
10
10
  autoload :SonarQubeMapper, 'heimdall_tools/sonarqube_mapper'
11
+ autoload :BurpSuiteMapper, 'heimdall_tools/burpsuite_mapper'
12
+ autoload :NessusMapper, 'heimdall_tools/nessus_mapper'
11
13
  end
@@ -0,0 +1,138 @@
1
+ require 'json'
2
+ require 'csv'
3
+ require 'heimdall_tools/hdf'
4
+ require 'utilities/xml_to_hash'
5
+
6
+ RESOURCE_DIR = Pathname.new(__FILE__).join('../../data')
7
+
8
+ CWE_NIST_MAPPING_FILE = File.join(RESOURCE_DIR, 'cwe-nist-mapping.csv')
9
+
10
+ IMPACT_MAPPING = {
11
+ High: 0.7,
12
+ Medium: 0.5,
13
+ Low: 0.3,
14
+ Information: 0.3
15
+ }.freeze
16
+
17
+ CWE_REGEX = 'CWE-(\d*):'.freeze
18
+
19
+ DEFAULT_NIST_TAG = ["SA-11", "RA-5", "Rev_4"].freeze
20
+
21
+ # rubocop:disable Metrics/AbcSize
22
+
23
+ module HeimdallTools
24
+ class BurpSuiteMapper
25
+ def initialize(burps_xml, name=nil, verbose = false)
26
+ @burps_xml = burps_xml
27
+ @verbose = verbose
28
+
29
+ begin
30
+ @cwe_nist_mapping = parse_mapper
31
+ data = xml_to_hash(burps_xml)
32
+
33
+ @issues = data['issues']['issue']
34
+ @burpVersion = data['issues']['burpVersion']
35
+ @timestamp = data['issues']['exportTime']
36
+
37
+ rescue StandardError => e
38
+ raise "Invalid Burpsuite XML file provided Exception: #{e}"
39
+ end
40
+
41
+ end
42
+
43
+ def parse_html(block)
44
+ Nokogiri::HTML(block['#cdata-section']).text.to_s.strip unless block.nil?
45
+ end
46
+
47
+ def finding(issue)
48
+ finding = {}
49
+ finding['status'] = 'failed'
50
+ finding['code_desc'] = format_code_desc(issue)
51
+ finding['run_time'] = NA_FLOAT
52
+ finding['start_time'] = @timestamp
53
+ [finding]
54
+ end
55
+
56
+ def format_code_desc(issue)
57
+ desc = ''
58
+ desc += "Host: ip: #{issue['host']['ip']}, url: #{issue['host']['text']}\n"
59
+ desc += "Location: #{parse_html(issue['location'])}\n"
60
+ desc += "issueDetail: #{parse_html(issue['issueDetail'])}\n" unless issue['issueDetail'].nil?
61
+ desc += "confidence: #{issue['confidence']}\n" unless issue['confidence'].nil?
62
+ desc
63
+ end
64
+
65
+ def nist_tag(cweid)
66
+ entries = @cwe_nist_mapping.select { |x| cweid.include? x[:cweid].to_s }
67
+ tags = entries.map { |x| [x[:nistid], "Rev_#{x[:rev]}"] }
68
+ tags.empty? ? DEFAULT_NIST_TAG : tags.flatten.uniq
69
+ end
70
+
71
+ def parse_cwe(text)
72
+ reg = Regexp.new(CWE_REGEX, Regexp::IGNORECASE)
73
+ text.scan(reg).map(&:first)
74
+ end
75
+
76
+ def impact(severity)
77
+ IMPACT_MAPPING[severity.to_sym]
78
+ end
79
+
80
+ def parse_mapper
81
+ csv_data = CSV.read(CWE_NIST_MAPPING_FILE, { encoding: 'UTF-8',
82
+ headers: true,
83
+ header_converters: :symbol,
84
+ converters: :all })
85
+ csv_data.map(&:to_hash)
86
+ end
87
+
88
+ def desc_tags(data, label)
89
+ { "data": data || NA_STRING, "label": label || NA_STRING }
90
+ end
91
+
92
+ # Burpsuite report could have multiple issue entries for multiple findings of same issue type.
93
+ # The meta data is identical across entries
94
+ # method collapse_duplicates return unique controls with applicable findings collapsed into it.
95
+ def collapse_duplicates(controls)
96
+ unique_controls = []
97
+
98
+ controls.map { |x| x['id'] }.uniq.each do |id|
99
+ collapsed_results = controls.select { |x| x['id'].eql?(id) }.map {|x| x['results']}
100
+ unique_control = controls.find { |x| x['id'].eql?(id) }
101
+ unique_control['results'] = collapsed_results.flatten
102
+ unique_controls << unique_control
103
+ end
104
+ unique_controls
105
+ end
106
+
107
+ def to_hdf
108
+ controls = []
109
+ @issues.each do |issue|
110
+ @item = {}
111
+ @item['id'] = issue['type'].to_s
112
+ @item['title'] = parse_html(issue['name'])
113
+ @item['desc'] = parse_html(issue['issueBackground'])
114
+ @item['impact'] = impact(issue['severity'])
115
+ @item['tags'] = {}
116
+ @item['descriptions'] = []
117
+ @item['descriptions'] << desc_tags(parse_html(issue['issueBackground']), 'check')
118
+ @item['descriptions'] << desc_tags(parse_html(issue['remediationBackground']), 'fix')
119
+ @item['refs'] = NA_ARRAY
120
+ @item['source_location'] = NA_HASH
121
+ @item['tags']['nist'] = nist_tag(parse_cwe(parse_html(issue['vulnerabilityClassifications'])))
122
+ @item['tags']['cweid'] = parse_html(issue['vulnerabilityClassifications'])
123
+ @item['tags']['confidence'] = issue['confidence'].to_s
124
+ @item['code'] = ''
125
+ @item['results'] = finding(issue)
126
+
127
+ controls << @item
128
+ end
129
+ controls = collapse_duplicates(controls)
130
+ results = HeimdallDataFormat.new(profile_name: 'BurpSuite Pro Scan',
131
+ version: @burpVersion,
132
+ title: "BurpSuite Pro Scan",
133
+ summary: "BurpSuite Pro Scan",
134
+ controls: controls)
135
+ results.to_hdf
136
+ end
137
+ end
138
+ end
@@ -35,6 +35,31 @@ module HeimdallTools
35
35
  File.write(options[:output], hdf)
36
36
  end
37
37
 
38
+ desc 'burpsuite_mapper', 'burpsuite_mapper translates Burpsuite xml report to HDF format Json be viewed on Heimdall'
39
+ long_desc Help.text(:burpsuite_mapper)
40
+ option :xml, required: true, aliases: '-x'
41
+ option :output, required: true, aliases: '-o'
42
+ option :verbose, type: :boolean, aliases: '-V'
43
+ def burpsuite_mapper
44
+ hdf = HeimdallTools::BurpSuiteMapper.new(File.read(options[:xml])).to_hdf
45
+ File.write(options[:output], hdf)
46
+ end
47
+
48
+ desc 'nessus_mapper', 'nessus_mapper translates nessus xml report to HDF format Json be viewed on Heimdall'
49
+ long_desc Help.text(:nessus_mapper)
50
+ option :xml, required: true, aliases: '-x'
51
+ option :output_prefix, required: true, aliases: '-o'
52
+ option :verbose, type: :boolean, aliases: '-V'
53
+ def nessus_mapper
54
+ hdfs = HeimdallTools::NessusMapper.new(File.read(options[:xml])).to_hdf
55
+
56
+ hdfs.keys.each do | host |
57
+ File.write("#{options[:output_prefix]}-#{host}.json", hdfs[host])
58
+ puts "HDF Generated: #{options[:output_prefix]}-#{host}.json"
59
+ end
60
+
61
+ end
62
+
38
63
  desc 'version', 'prints version'
39
64
  def version
40
65
  puts VERSION
@@ -43,7 +43,11 @@ module HeimdallTools
43
43
  traces.each do |trace|
44
44
  entries = trace['Primary']['Entry']
45
45
  entries = [entries] unless entries.is_a?(Array)
46
- entries = entries.reject { |x| x['Node'].nil? }
46
+ # This is just regular array access, it is just written in a manner that allows us
47
+ # to use Ruby's safe navigation operator. We rely on
48
+ # entry['Node']['SourceLocation']['snippet'] to exist on all of our entries, so if any
49
+ # of those are empty we reject that element.
50
+ entries = entries.reject { |x| x&.[]('Node')&.[]('SourceLocation')&.[]('snippet').nil? }
47
51
  entries.each do |entry|
48
52
  findings << process_entry(entry)
49
53
  end
@@ -2,6 +2,7 @@ require 'json'
2
2
  require 'heimdall_tools/version'
3
3
  require 'openssl'
4
4
 
5
+ NA_STRING = "".freeze
5
6
  NA_TAG = nil.freeze
6
7
  NA_ARRAY = [].freeze
7
8
  NA_HASH = {}.freeze
@@ -27,12 +28,14 @@ module HeimdallTools
27
28
  depends: NA_ARRAY,
28
29
  groups: NA_ARRAY,
29
30
  status: 'loaded',
30
- controls: NA_TAG)
31
+ controls: NA_TAG,
32
+ target_id: NA_TAG)
31
33
 
32
34
  @results_json = {}
33
35
  @results_json['platform'] = {}
34
36
  @results_json['platform']['name'] = 'Heimdall Tools'
35
37
  @results_json['platform']['release'] = HeimdallTools::VERSION
38
+ @results_json['platform']['target_id'] = target_id.to_s
36
39
  @results_json['version'] = HeimdallTools::VERSION
37
40
 
38
41
  @results_json['statistics'] = {}
@@ -0,0 +1,5 @@
1
+ burpsuite_mapper translates an BurpSuite Pro exported XML results file into HDF format json to be viewable in Heimdall
2
+
3
+ Examples:
4
+
5
+ heimdall_tools burpsuite_mapper -x burpsuite_results.xml -o scan_results.json
@@ -0,0 +1,9 @@
1
+ nessus_mapper translates an Nessus exported XML results file into HDF format json to be viewable in Heimdall
2
+
3
+ The current iteration maps all plugin families except 'Policy Compliance'
4
+
5
+ A separate HDF JSON is generated for each host reported in the Nessus Report.
6
+
7
+ Examples:
8
+
9
+ heimdall_tools nessus_mapper -x nessus_results.xml -o file-prefix
@@ -0,0 +1,231 @@
1
+ require 'json'
2
+ require 'csv'
3
+ require 'heimdall_tools/hdf'
4
+ require 'utilities/xml_to_hash'
5
+
6
+ RESOURCE_DIR = Pathname.new(__FILE__).join('../../data')
7
+
8
+ NESSUS_PLUGINS_NIST_MAPPING_FILE = File.join(RESOURCE_DIR, 'nessus-plugins-nist-mapping.csv')
9
+
10
+ IMPACT_MAPPING = {
11
+ Info: 0.0,
12
+ Low: 0.3,
13
+ Medium: 0.5,
14
+ High: 0.7,
15
+ Critical: 0.9,
16
+ }.freeze
17
+
18
+ DEFAULT_NIST_TAG = ["unmapped"].freeze
19
+
20
+ # Nessus results file 800-53 refs does not contain Nist rev version. Using this default
21
+ # version in that case
22
+ DEFAULT_NIST_REV = 'Rev_4'.freeze
23
+
24
+ NA_PLUGIN_OUTPUT = "This Nessus Plugin does not provide output message.".freeze
25
+
26
+ # rubocop:disable Metrics/AbcSize
27
+
28
+ module HeimdallTools
29
+ class NessusMapper
30
+ def initialize(nessus_xml, verbose = false)
31
+ @nessus_xml = nessus_xml
32
+ @verbose = verbose
33
+
34
+ begin
35
+ @cwe_nist_mapping = parse_mapper
36
+ @data = xml_to_hash(nessus_xml)
37
+
38
+ File.write("273970.json", @data.to_json)
39
+
40
+ @reports = extract_report
41
+ @scaninfo = extract_scaninfo
42
+ rescue StandardError => e
43
+ raise "Invalid Nessus XML file provided Exception: #{e}"
44
+ end
45
+
46
+ end
47
+
48
+ def extract_report
49
+ begin
50
+ # When there are multiple hosts in the nessus report ReportHost field is an array
51
+ # When there is only one host in the nessus report ReportHost field is a hash
52
+ # Array() converts ReportHost to array in case there is only one host
53
+ reports = @data['NessusClientData_v2']['Report']['ReportHost']
54
+ reports.kind_of?(Array) ? reports : [reports]
55
+ rescue StandardError => e
56
+ raise "Invalid Nessus XML file provided Exception: #{e}"
57
+ end
58
+ end
59
+ def parse_refs(refs, key)
60
+ refs.split(',').map { |x| x.split('|')[1] if x.include?(key) }.compact
61
+ end
62
+
63
+ def extract_scaninfo
64
+ begin
65
+ policy = @data['NessusClientData_v2']['Policy']
66
+ info = {}
67
+
68
+ info['policyName'] = policy['policyName']
69
+ info['version'] = policy['Preferences']['ServerPreferences']['preference'].select {|x| x['name'].eql? 'sc_version'}.first['value']
70
+ info
71
+ rescue StandardError => e
72
+ raise "Invalid Nessus XML file provided Exception: #{e}"
73
+ end
74
+ end
75
+
76
+ def extract_timestamp(report)
77
+ begin
78
+ timestamp = report['HostProperties']['tag'].select {|x| x['name'].eql? 'HOST_START'}.first['text']
79
+ rescue StandardError => e
80
+ raise "Invalid Nessus XML file provided Exception: #{e}"
81
+ end
82
+ end
83
+
84
+ def format_desc(issue)
85
+ desc = ''
86
+ desc += "Plugin Family: #{issue['pluginFamily']}; "
87
+ desc += "Port: #{issue['port']}; "
88
+ desc += "Protocol: #{issue['protocol']};"
89
+ desc
90
+ end
91
+
92
+ def finding(issue, timestamp)
93
+ finding = {}
94
+ # if compliance-result field, this is a policy compliance result entry
95
+ # nessus policy compliance result provides a pass/fail data
96
+ # For non policy compliance results are defaulted to failed
97
+ if issue['compliance-result']
98
+ finding['status'] = issue['compliance-result'].eql?('PASSED') ? 'passed' : 'failed'
99
+ else
100
+ finding['status'] = 'failed'
101
+ end
102
+
103
+ if issue['description']
104
+ finding['code_desc'] = issue['description'].to_s || NA_PLUGIN_OUTPUT
105
+ else
106
+ finding['code_desc'] = issue['plugin_output'] || NA_PLUGIN_OUTPUT
107
+ end
108
+ finding['run_time'] = NA_FLOAT
109
+ finding['start_time'] = timestamp
110
+ [finding]
111
+ end
112
+
113
+ def nist_tag(pluginfamily, pluginid)
114
+ entries = @cwe_nist_mapping.select { |x| (x[:pluginfamily].eql?(pluginfamily) && (x[:pluginid].eql?('*') || x[:pluginid].eql?(pluginid.to_i)) ) }
115
+ tags = entries.map { |x| [x[:nistid].split('|'), "Rev_#{x[:rev]}"] }
116
+ tags.empty? ? DEFAULT_NIST_TAG : tags.flatten.uniq
117
+ end
118
+
119
+ def impact(severity)
120
+ # Map CAT levels and Plugin severity to HDF impact levels
121
+ case severity
122
+ when "0"
123
+ IMPACT_MAPPING[:Info]
124
+ when "1","III"
125
+ IMPACT_MAPPING[:Low]
126
+ when "2","II"
127
+ IMPACT_MAPPING[:Medium]
128
+ when "3","I"
129
+ IMPACT_MAPPING[:High]
130
+ when "4"
131
+ IMPACT_MAPPING[:Critical]
132
+ else
133
+ -1
134
+ end
135
+ end
136
+
137
+ def parse_mapper
138
+ csv_data = CSV.read(NESSUS_PLUGINS_NIST_MAPPING_FILE, { encoding: 'UTF-8',
139
+ headers: true,
140
+ header_converters: :symbol,
141
+ converters: :all })
142
+ csv_data.map(&:to_hash)
143
+ end
144
+
145
+ def desc_tags(data, label)
146
+ { "data": data || NA_STRING, "label": label || NA_STRING }
147
+ end
148
+
149
+ # Nessus report could have multiple issue entries for multiple findings of same issue type.
150
+ # The meta data is identical across entries
151
+ # method collapse_duplicates return unique controls with applicable findings collapsed into it.
152
+ def collapse_duplicates(controls)
153
+ unique_controls = []
154
+
155
+ controls.map { |x| x['id'] }.uniq.each do |id|
156
+ collapsed_results = controls.select { |x| x['id'].eql?(id) }.map {|x| x['results']}
157
+ unique_control = controls.find { |x| x['id'].eql?(id) }
158
+ unique_control['results'] = collapsed_results.flatten
159
+ unique_controls << unique_control
160
+ end
161
+ unique_controls
162
+ end
163
+
164
+ def to_hdf
165
+ host_results = {}
166
+ @reports.each do | report|
167
+ controls = []
168
+ report['ReportItem'].each do | item |
169
+ @item = {}
170
+ @item['tags'] = {}
171
+ @item['descriptions'] = []
172
+ @item['refs'] = NA_ARRAY
173
+ @item['source_location'] = NA_HASH
174
+
175
+ # Nessus results field set are different for 'Policy Compliance' plug-in family vs other plug-in families
176
+ # Following if conditions capture compliance* if it exists else it will default to plugin* fields
177
+ # Current version covers STIG based 'Policy Compliance' results
178
+ # TODO Cover cases for 'Policy Compliance' results based on CIS
179
+ if item['compliance-reference']
180
+ @item['id'] = parse_refs(item['compliance-reference'],'Vuln-ID').join.to_s
181
+ else
182
+ @item['id'] = item['pluginID'].to_s
183
+ end
184
+ if item['compliance-check-name']
185
+ @item['title'] = item['compliance-check-name'].to_s
186
+ else
187
+ @item['title'] = item['pluginName'].to_s
188
+ end
189
+ if item['compliance-info']
190
+ @item['desc'] = item['compliance-info'].to_s
191
+ else
192
+ @item['desc'] = format_desc(item).to_s
193
+ end
194
+ if item['compliance-reference']
195
+ @item['impact'] = impact(parse_refs(item['compliance-reference'],'CAT').join.to_s)
196
+ else
197
+ @item['impact'] = impact(item['severity'])
198
+ end
199
+ if item['compliance-reference']
200
+ # TODO: Cover cases where 800-53 refs are not provided in nessus `compliance-reference` field
201
+ @item['tags']['nist'] = parse_refs(item['compliance-reference'],'800-53') << DEFAULT_NIST_REV
202
+ else
203
+ @item['tags']['nist'] = nist_tag(item['pluginFamily'],item['pluginID'])
204
+ end
205
+ if item['compliance-solution']
206
+ # TODO: Cover cases where 800-53 refs are not provided in nessus `compliance-reference` field
207
+ @item['tags']['nist'] = parse_refs(item['compliance-reference'],'800-53') << DEFAULT_NIST_REV
208
+ else
209
+ @item['tags']['nist'] = nist_tag(item['pluginFamily'],item['pluginID'])
210
+ end
211
+ if item['compliance-solution']
212
+ @item['descriptions'] << desc_tags(item['compliance-solution'], 'check')
213
+ end
214
+
215
+ @item['code'] = ''
216
+ @item['results'] = finding(item, extract_timestamp(report))
217
+ controls << @item
218
+ end
219
+ controls = collapse_duplicates(controls)
220
+ results = HeimdallDataFormat.new(profile_name: "Nessus #{@scaninfo['policyName']}",
221
+ version: @scaninfo['version'],
222
+ title: "Nessus #{@scaninfo['policyName']}",
223
+ summary: "Nessus #{@scaninfo['policyName']}",
224
+ controls: controls,
225
+ target_id: report['name'])
226
+ host_results[report['name']] = results.to_hdf
227
+ end
228
+ host_results
229
+ end
230
+ end
231
+ end
@@ -3,9 +3,11 @@ require 'json'
3
3
  require 'csv'
4
4
  require 'heimdall_tools/hdf'
5
5
 
6
+ RESOURCE_DIR = Pathname.new(__FILE__).join('../../data')
7
+
6
8
  MAPPING_FILES = {
7
- cwe: './lib/data/cwe-nist-mapping.csv'.freeze,
8
- owasp: './lib/data/owasp-nist-mapping.csv'.freeze
9
+ cwe: File.join(RESOURCE_DIR, 'cwe-nist-mapping.csv'),
10
+ owasp: File.join(RESOURCE_DIR, 'owasp-nist-mapping.csv')
9
11
  }.freeze
10
12
 
11
13
  IMPACT_MAPPING = {
@@ -4,7 +4,9 @@ require 'csv'
4
4
  require 'heimdall_tools/hdf'
5
5
 
6
6
 
7
- CWE_NIST_MAPPING_FILE = './lib/data/cwe-nist-mapping.csv'.freeze
7
+ RESOURCE_DIR = Pathname.new(__FILE__).join('../../data')
8
+
9
+ CWE_NIST_MAPPING_FILE = File.join(RESOURCE_DIR, 'cwe-nist-mapping.csv')
8
10
 
9
11
  # rubocop:disable Metrics/AbcSize
10
12
 
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.23
4
+ version: 1.3.28
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-03-31 00:00:00.000000000 Z
13
+ date: 2020-05-28 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
@@ -211,16 +211,21 @@ files:
211
211
  - exe/heimdall_tools
212
212
  - lib/data/cwe-nist-mapping.csv
213
213
  - lib/data/gitkeep
214
+ - lib/data/nessus-plugins-nist-mapping.csv
214
215
  - lib/data/owasp-nist-mapping.csv
215
216
  - lib/heimdall_tools.rb
217
+ - lib/heimdall_tools/burpsuite_mapper.rb
216
218
  - lib/heimdall_tools/cli.rb
217
219
  - lib/heimdall_tools/command.rb
218
220
  - lib/heimdall_tools/fortify_mapper.rb
219
221
  - lib/heimdall_tools/hdf.rb
220
222
  - lib/heimdall_tools/help.rb
223
+ - lib/heimdall_tools/help/burpsuite_mapper.md
221
224
  - lib/heimdall_tools/help/fortify_mapper.md
225
+ - lib/heimdall_tools/help/nessus_mapper.md
222
226
  - lib/heimdall_tools/help/sonarqube_mapper.md
223
227
  - lib/heimdall_tools/help/zap_mapper.md
228
+ - lib/heimdall_tools/nessus_mapper.rb
224
229
  - lib/heimdall_tools/sonarqube_mapper.rb
225
230
  - lib/heimdall_tools/version.rb
226
231
  - lib/heimdall_tools/zap_mapper.rb