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 +4 -4
- data/CHANGELOG.md +67 -0
- data/README.md +42 -4
- data/lib/data/nessus-plugins-nist-mapping.csv +108 -0
- data/lib/heimdall_tools.rb +2 -0
- data/lib/heimdall_tools/burpsuite_mapper.rb +138 -0
- data/lib/heimdall_tools/cli.rb +25 -0
- data/lib/heimdall_tools/fortify_mapper.rb +5 -1
- data/lib/heimdall_tools/hdf.rb +4 -1
- data/lib/heimdall_tools/help/burpsuite_mapper.md +5 -0
- data/lib/heimdall_tools/help/nessus_mapper.md +9 -0
- data/lib/heimdall_tools/nessus_mapper.rb +231 -0
- data/lib/heimdall_tools/sonarqube_mapper.rb +4 -2
- data/lib/heimdall_tools/zap_mapper.rb +3 -1
- metadata +9 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 793e9f28cb98cddc239829d4164d2f316100b2157ae9e196d2c32e5271fca664
|
4
|
+
data.tar.gz: 267e61797626c6ec797fdffda2d03bee9de9ce5ed45f918d2cfcda9af86a9957
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 671713a138539ad4f68615aa1c74d727ddd221b27fb0d7ea22531b8c5caa19aed0d00eabab2b685edc00566b2098ea7514e3281e30fbcbc09ea4db31c0171762
|
7
|
+
data.tar.gz: 2f589a0a0db9cfd64cf23f25420f6609229bbc0dfc8e435e7bde4eb7c19c431a8446ccae650e2bb6820cee8a04e996eb205999a2ad2429063e491818127a8c86
|
data/CHANGELOG.md
CHANGED
@@ -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
|
-
|
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
|
-
##
|
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,,,
|
data/lib/heimdall_tools.rb
CHANGED
@@ -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
|
data/lib/heimdall_tools/cli.rb
CHANGED
@@ -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
|
-
|
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
|
data/lib/heimdall_tools/hdf.rb
CHANGED
@@ -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,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: '
|
8
|
-
owasp: '
|
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
|
-
|
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.
|
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-
|
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:
|
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
|
@@ -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
|