heimdall_tools 1.3.36 → 1.3.37

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 34a80978c354919fb48f33582e9a6b4e2676eb884c1868e8d710daeb6c8bfb9f
4
- data.tar.gz: 58a1f7cde61bf0ad07454fd3cc90448ad40385a9f9d8dd951f24901ccce7a79d
3
+ metadata.gz: b6e9d50bdf3b2f06cdd02be70517a574ca2a4f979abdb80d705682f02fe7dd45
4
+ data.tar.gz: a695c5f4f843802da69e4e150befbbbc9914a87d4aa20319a8156fbf376e9805
5
5
  SHA512:
6
- metadata.gz: 49faba0d70053387a28208efc837a3978bb100e44d65436e0c8f9f6d335d1d8639987b77b44607a2d195cbafaf4646e2e4b80894a8ebb06a7206a929e2a115d3
7
- data.tar.gz: 42c71d905a92366eb864113d86de09997cf1043133049d6e16efbc34967a5af2d648d4cb31b6a92fb17874941be8c92f367abcad3d37c26bb8f6b4d46d600f56
6
+ metadata.gz: 2295f30b0e973d2e59f2860d7ed7fcfa2dd75367a5731f250d1c6b5842326d9df984db383ee8a03b9aedc741a73729c8a0b6d6fb5ef13bc463cfe3b750238801
7
+ data.tar.gz: 56a80ca04c456e1aff7769ce3f0f554a5a7c533a801cfff800812898d9a888d96264e5da0c08c86576432e7e690fbfe7aad4bc3f21f59c9107bfc1c12bb425ed
data/README.md CHANGED
@@ -14,6 +14,7 @@ HeimdallTools supplies several methods to convert output from various tools to "
14
14
  - **nikto_mapper** - open-source web server scanner
15
15
  - **jfrog_xray_mapper** - package vulnerability scanner
16
16
  - **dbprotect_mapper** - database vulnerability scanner
17
+ - **aws_config_mapper** - assess, audit, and evaluate AWS resources
17
18
 
18
19
  Ruby 2.4 or higher (check using "ruby -v")
19
20
 
@@ -213,6 +214,26 @@ FLAGS:
213
214
  example: heimdall_tools dbprotect_mapper -x check_results_details_report.xml -o db_protect_hdf.json
214
215
  ```
215
216
 
217
+ ## aws_config_mapper
218
+
219
+ aws_config_mapper pulls Ruby AWS SDK data to translate AWS Config Rule results into HDF format json to be viewable in Heimdall
220
+
221
+ ### AWS Config Rule Mapping:
222
+ The mapping of AWS Config Rules to 800-53 Controls was sourced from [this link](https://docs.aws.amazon.com/config/latest/developerguide/operational-best-practices-for-nist-800-53_rev_4.html).
223
+
224
+ ### Authentication with AWS:
225
+ [Developer Guide for configuring Ruby AWS SDK for authentication](https://docs.aws.amazon.com/sdk-for-ruby/v3/developer-guide/setup-config.html)
226
+
227
+ ```
228
+ USAGE: heimdall_tools aws_config_mapper [OPTIONS] -o <hdf-scan-results.json>
229
+
230
+ FLAGS:
231
+ -o --output <scan-results> : path to output scan-results json.
232
+ -V --verbose : verbose run [optional].
233
+
234
+ example: heimdall_tools aws_config_mapper -o aws_config_results_hdf.json
235
+ ```
236
+
216
237
  ## version
217
238
 
218
239
  Prints out the gem version
@@ -0,0 +1,107 @@
1
+ AwsConfigRuleName,NIST-ID,Rev
2
+ secretsmanager-scheduled-rotation-success-check,AC-2(1)|AC-2(j),4
3
+ iam-user-group-membership-check,AC-2(1)|AC-2(j)|AC-3|AC-6,4
4
+ iam-password-policy,AC-2(1)|AC-2(f)|AC-2(j)|IA-2|IA-5(1)(a)(d)(e)|IA-5(4),4
5
+ access-keys-rotated,AC-2(1)|AC-2(j),4
6
+ iam-user-unused-credentials-check,AC-2(1)|AC-2(3)|AC-2(f)|AC-3|AC-6,4
7
+ securityhub-enabled,AC-2(1)|AC-2(4)|AC-2(12)(a)|AC-2(g)|AC-17(1)|AU-6(1)(3)|CA-7(a)(b)|SA-10|SI-4(2)|SI-4(4)|SI-4(5)|SI-4(16)|SI-4(a)(b)(c),4
8
+ guardduty-enabled-centralized,AC-2(1)|AC-2(4)|AC-2(12)(a)|AC-2(g)|AC-17(1)|AU-6(1)(3)|CA-7(a)(b)|RA-5|SA-10|SI-4(1)|SI-4(2)|SI-4(4)|SI-4(5)|SI-4(16)|SI-4(a)(b)(c),4
9
+ cloud-trail-cloud-watch-logs-enabled,AC-2(4)|AC-2(g)|AU-2(a)(d)|AU-3|AU-6(1)(3)|AU-7(1)|AU-12(a)(c)|CA-7(a)(b)|SI-4(2)|SI-4(4)|SI-4(5)|SI-4(a)(b)(c),4
10
+ cloudtrail-enabled,AC-2(4)|AC-2(g)|AU-2(a)(d)|AU-3|AU-12(a)(c),4
11
+ multi-region-cloudtrail-enabled,AC-2(4)|AU-2(a)(d)|AU-3|AU-12(a)(c),4
12
+ rds-logging-enabled,AC-2(4)|AC-2(g)|AU-2(a)(d)|AU-3|AU-12(a)(c),4
13
+ cloudwatch-alarm-action-check,AC-2(4)|AU-6(1)(3)|AU-7(1)|CA-7(a)(b)|IR-4(1)|SI-4(2)|SI-4(4)|SI-4(5)|SI-4(a)(b)(c),4
14
+ redshift-cluster-configuration-check,AC-2(4)|AC-2(g)|AU-2(a)(d)|AU-3|AU-12(a)(c)|SC-13|SC-28,4
15
+ iam-root-access-key-check,AC-2(f)|AC-2(j)|AC-3|AC-6|AC-6(10),4
16
+ s3-bucket-logging-enabled,AC-2(g)|AU-2(a)(d)|AU-3|AU-12(a)(c),4
17
+ cloudtrail-s3-dataevents-enabled,AC-2(g)|AU-2(a)(d)|AU-3|AU-12(a)(c),4
18
+ root-account-mfa-enabled,AC-2(j)|IA-2(1)(11),4
19
+ emr-kerberos-enabled,AC-2(j)|AC-3|AC-5(c)|AC-6,4
20
+ iam-group-has-users-check,AC-2(j)|AC-3|AC-5(c)|AC-6|SC-2,4
21
+ iam-policy-no-statements-with-admin-access,AC-2(j)|AC-3|AC-5(c)|AC-6|SC-2,4
22
+ iam-user-no-policies-check,AC-2(j)|AC-3|AC-5(c)|AC-6,4
23
+ s3-bucket-public-write-prohibited,AC-3|AC-4|AC-6|AC-21(b)|SC-7|SC-7(3),4
24
+ lambda-function-public-access-prohibited,AC-3|AC-4|AC-6|AC-21(b)|SC-7|SC-7(3),4
25
+ rds-snapshots-public-prohibited,AC-3|AC-4|AC-6|AC-21(b)|SC-7|SC-7(3),4
26
+ redshift-cluster-public-access-check,AC-3|AC-4|AC-6|AC-21(b)|SC-7|SC-7(3),4
27
+ s3-bucket-policy-grantee-check,AC-3|AC-6|SC-7|SC-7(3),4
28
+ s3-bucket-public-read-prohibited,AC-3|AC-4|AC-6|AC-21(b)|SC-7|SC-7(3),4
29
+ s3-account-level-public-access-blocks,AC-3|AC-4|AC-6|AC-21(b)|SC-7|SC-7(3),4
30
+ dms-replication-not-public,AC-3|AC-4|AC-6|AC-21(b)|SC-7|SC-7(3),4
31
+ ebs-snapshot-public-restorable-check,AC-3|AC-4|AC-6|AC-21(b)|SC-7|SC-7(3),4
32
+ sagemaker-notebook-no-direct-internet-access,AC-3|AC-4|AC-6|AC-21(b)|SC-7|SC-7(3),4
33
+ rds-instance-public-access-check,AC-4|AC-6|AC-21(b)|SC-7|SC-7(3),4
34
+ lambda-inside-vpc,AC-4|SC-7|SC-7(3),4
35
+ ec2-instances-in-vpc,AC-4|SC-7|SC-7(3),4
36
+ restricted-common-ports,AC-4|CM-2|SC-7|SC-7(3),4
37
+ restricted-ssh,AC-4|SC-7|SC-7(3),4
38
+ vpc-default-security-group-closed,AC-4|SC-7|SC-7(3),4
39
+ vpc-sg-open-only-to-authorized-ports,AC-4|SC-7|SC-7(3),4
40
+ acm-certificate-expiration-check,AC-4|AC-17(2)|SC-12,4
41
+ ec2-instance-no-public-ip,AC-4|AC-6|AC-21(b)|SC-7|SC-7(3),4
42
+ elasticsearch-in-vpc-only,AC-4|SC-7|SC-7(3),4
43
+ emr-master-no-public-ip,AC-4|AC-21(b)|SC-7|SC-7(3),4
44
+ internet-gateway-authorized-vpc-only,AC-4|AC-17(3)|SC-7|SC-7(3),4
45
+ codebuild-project-envvar-awscred-check,AC-6|IA-5(7)|SA-3(a),4
46
+ ec2-imdsv2-check,AC-6,4
47
+ iam-no-inline-policy-check,AC-6,4
48
+ alb-http-to-https-redirection-check,AC-17(2)|SC-7|SC-8|SC-8(1)|SC-13|SC-23,4
49
+ redshift-require-tls-ssl,AC-17(2)|SC-7|SC-8|SC-8(1)|SC-13,4
50
+ s3-bucket-ssl-requests-only,AC-17(2)|SC-7|SC-8|SC-8(1)|SC-13,4
51
+ elb-acm-certificate-required,AC-17(2)|SC-7|SC-8|SC-8(1)|SC-13,4
52
+ alb-http-drop-invalid-header-enabled,AC-17(2)|SC-7|SC-8|SC-8(1)|SC-23,4
53
+ elb-tls-https-listeners-only,AC-17(2)|SC-7|SC-8|SC-8(1)|SC-23,4
54
+ api-gw-execution-logging-enabled,AU-2(a)(d)|AU-3|AU-12(a)(c),4
55
+ elb-logging-enabled,AU-2(a)(d)|AU-3|AU-12(a)(c),4
56
+ vpc-flow-logs-enabled,AU-2(a)(d)|AU-3|AU-12(a)(c),4
57
+ wafv2-logging-enabled,AU-2(a)(d)|AU-3|AU-12(a)(c)|SC-7|SI-4(a)(b)(c),4
58
+ cloud-trail-encryption-enabled,AU-9|SC-13|SC-28,4
59
+ cloudwatch-log-group-encrypted,AU-9|SC-13|SC-28,4
60
+ s3-bucket-replication-enabled,AU-9(2)|CP-9(b)|CP-10|SC-5|SC-36,4
61
+ cw-loggroup-retention-period-check,AU-11|SI-12,4
62
+ ec2-instance-detailed-monitoring-enabled,CA-7(a)(b)|SI-4(2)|SI-4(a)(b)(c),4
63
+ rds-enhanced-monitoring-enabled,CA-7(a)(b),4
64
+ ec2-instance-managed-by-systems-manager,CM-2|CM-7(a)|CM-8(1)|CM-8(3)(a)|SA-3(a)|SA-10|SI-2(2)|SI-7(1),4
65
+ ec2-managedinstance-association-compliance-status-check,CM-2|CM-7(a)|CM-8(3)(a)|SI-2(2),4
66
+ ec2-stopped-instance,CM-2,4
67
+ ec2-volume-inuse-check,CM-2|SC-4,4
68
+ elb-deletion-protection-enabled,CM-2|CP-10,4
69
+ cloudtrail-security-trail-enabled,CM-2,4
70
+ ec2-managedinstance-patch-compliance-status-check,CM-8(3)(a)|SI-2(2)|SI-7(1),4
71
+ db-instance-backup-enabled,CP-9(b)|CP-10|SI-12,4
72
+ dynamodb-pitr-enabled,CP-9(b)|CP-10|SI-12,4
73
+ elasticache-redis-cluster-automatic-backup-check,CP-9(b)|CP-10|SI-12,4
74
+ dynamodb-in-backup-plan,CP-9(b)|CP-10|SI-12,4
75
+ ebs-in-backup-plan,CP-9(b)|CP-10|SI-12,4
76
+ efs-in-backup-plan,CP-9(b)|CP-10|SI-12,4
77
+ rds-in-backup-plan,CP-9(b)|CP-10|SI-12,4
78
+ dynamodb-autoscaling-enabled,CP-10|SC-5,4
79
+ rds-multi-az-support,CP-10|SC-5|SC-36,4
80
+ s3-bucket-versioning-enabled,CP-10|SI-12,4
81
+ vpc-vpn-2-tunnels-up,CP-10,4
82
+ elb-cross-zone-load-balancing-enabled,CP-10|SC-5,4
83
+ root-account-hardware-mfa-enabled,IA-2(1)(11),4
84
+ mfa-enabled-for-iam-console-access,IA-2(1)(2)(11),4
85
+ iam-user-mfa-enabled,IA-2(1)(2)(11),4
86
+ guardduty-non-archived-findings,IR-4(1)|IR-6(1)|IR-7(1)|RA-5|SA-10|SI-4(a)(b)(c),4
87
+ codebuild-project-source-repo-url-check,SA-3(a),4
88
+ autoscaling-group-elb-healthcheck-required,SC-5,4
89
+ rds-instance-deletion-protection-enabled,SC-5,4
90
+ alb-waf-enabled,SC-7|SI-4(a)(b)(c),4
91
+ elasticsearch-node-to-node-encryption-check,SC-7|SC-8|SC-8(1),4
92
+ cmk-backing-key-rotation-enabled,SC-12,4
93
+ kms-cmk-not-scheduled-for-deletion,SC-12|SC-28,4
94
+ api-gw-cache-enabled-and-encrypted,SC-13|SC-28,4
95
+ efs-encrypted-check,SC-13|SC-28,4
96
+ elasticsearch-encrypted-at-rest,SC-13|SC-28,4
97
+ encrypted-volumes,SC-13|SC-28,4
98
+ rds-storage-encrypted,SC-13|SC-28,4
99
+ s3-bucket-server-side-encryption-enabled,SC-13|SC-28,4
100
+ sagemaker-endpoint-configuration-kms-key-configured,SC-13|SC-28,4
101
+ sagemaker-notebook-instance-kms-key-configured,SC-13|SC-28,4
102
+ sns-encrypted-kms,SC-13|SC-28,4
103
+ dynamodb-table-encrypted-kms,SC-13,4
104
+ s3-bucket-default-lock-enabled,SC-28,4
105
+ ec2-ebs-encryption-by-default,SC-28,4
106
+ rds-snapshot-encrypted,SC-28,4
107
+ cloud-trail-log-file-validation-enabled,SI-7|SI-7(1),4
@@ -14,4 +14,5 @@ module HeimdallTools
14
14
  autoload :NiktoMapper, 'heimdall_tools/nikto_mapper'
15
15
  autoload :JfrogXrayMapper, 'heimdall_tools/jfrog_xray_mapper'
16
16
  autoload :DBProtectMapper, 'heimdall_tools/dbprotect_mapper'
17
+ autoload :AwsConfigMapper, 'heimdall_tools/aws_config_mapper'
17
18
  end
@@ -0,0 +1,284 @@
1
+ require 'aws-sdk-configservice'
2
+ require 'heimdall_tools/hdf'
3
+ require 'csv'
4
+ require 'json'
5
+
6
+ RESOURCE_DIR = Pathname.new(__FILE__).join('../../data')
7
+
8
+ AWS_CONFIG_MAPPING_FILE = File.join(RESOURCE_DIR, 'aws-config-mapping.csv')
9
+
10
+ NOT_APPLICABLE_MSG = 'No AWS resources found to evaluate complaince for this rule'.freeze
11
+ INSUFFICIENT_DATA_MSG = 'Not enough data has been collectd to determine compliance yet.'.freeze
12
+
13
+ ##
14
+ # HDF mapper for use with AWS Config rules.
15
+ #
16
+ # Ruby AWS Ruby SDK for ConfigService:
17
+ # - https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/ConfigService/Client.html
18
+ #
19
+ # rubocop:disable Metrics/AbcSize, Metrics/ClassLength
20
+ module HeimdallTools
21
+ class AwsConfigMapper
22
+ def initialize(custom_mapping, verbose = false)
23
+ @verbose = verbose
24
+ @default_mapping = get_rule_mapping(AWS_CONFIG_MAPPING_FILE)
25
+ @custom_mapping = custom_mapping.nil? ? {} : get_rule_mapping(custom_mapping)
26
+ @client = Aws::ConfigService::Client.new
27
+ @issues = get_all_config_rules
28
+ end
29
+
30
+ ##
31
+ # Convert to HDF
32
+ #
33
+ # If there is overlap in rule names from @default_mapping and @custom_mapping,
34
+ # then the tags from both will be added to the rule.
35
+ def to_hdf
36
+ controls = @issues.map do |issue|
37
+ @item = {}
38
+ @item['id'] = issue[:config_rule_name]
39
+ @item['title'] = issue[:config_rule_name]
40
+ @item['desc'] = issue[:description]
41
+ @item['impact'] = 0.5
42
+ @item['tags'] = hdf_tags(issue)
43
+ @item['descriptions'] = hdf_descriptions(issue)
44
+ @item['refs'] = NA_ARRAY
45
+ @item['source_location'] = { ref: issue[:config_rule_arn], line: 1 }
46
+ @item['code'] = ''
47
+ @item['results'] = issue[:results]
48
+ # Avoid duplicating rules that exist in the custom mapping as 'unmapped' in this loop
49
+ if @custom_mapping.include?(issue[:config_rule_name]) && !@default_mapping.include?(issue[:config_rule_name])
50
+ nil
51
+ else
52
+ @item
53
+ end
54
+ end
55
+ results = HeimdallDataFormat.new(
56
+ profile_name: 'AWS Config',
57
+ title: 'AWS Config',
58
+ summary: 'AWS Config',
59
+ controls: controls,
60
+ statistics: { aws_config_sdk_version: Aws::ConfigService::GEM_VERSION }
61
+ )
62
+ results.to_hdf
63
+ end
64
+
65
+ private
66
+
67
+ ##
68
+ # Read in a config rule -> 800-53 control mapping CSV.
69
+ #
70
+ # Params:
71
+ # - path: The file path to the CSV file
72
+ #
73
+ # Returns: A mapped version of the csv in the format { rule_name: row, ... }
74
+ def get_rule_mapping(path)
75
+ Hash[CSV.read(path, headers: true).map { |row| [row[0], row] }]
76
+ end
77
+
78
+ ##
79
+ # Fetches information on all of the config rules available to the
80
+ # AWS account.
81
+ #
82
+ # https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/ConfigService/Client.html#describe_config_rules-instance_method
83
+ #
84
+ # Returns: list of hash for all config rules available
85
+ def get_all_config_rules
86
+ config_rules = []
87
+
88
+ # Fetch all rules with pagination
89
+ response = @client.describe_config_rules
90
+ config_rules += response.config_rules
91
+ while response.next_token
92
+ response = @client.describe_config_rules(next_token: response.next_token)
93
+ config_rules += response.config_rules
94
+ end
95
+ config_rules = config_rules.map(&:to_h)
96
+
97
+ # Add necessary data to rules using helpers
98
+ add_compliance_to_config_rules(config_rules)
99
+ add_results_to_config_rules(config_rules)
100
+ end
101
+
102
+ ##
103
+ # Adds compliance information for config rules to the config rule hash
104
+ # from AwsConfigMapper::get_all_config_rules.
105
+ #
106
+ # `complaince_type` may be any of the following:
107
+ # ["COMPLIANT", "NON_COMPLIANT", "NOT_APPLICABLE", "INSUFFICIENT_DATA"]
108
+ #
109
+ # Params:
110
+ # - config_rules: The list of hash from AwsConfigMapper::get_all_config_rules
111
+ #
112
+ # Returns: The same config_rules array with `compliance` key added to each rule
113
+ def add_compliance_to_config_rules(config_rules)
114
+ mapped_compliance_results = fetch_all_compliance_info(config_rules)
115
+
116
+ # Add compliance to config_rules
117
+ config_rules.each do |rule|
118
+ rule[:compliance] = mapped_compliance_results[rule[:config_rule_name]]&.dig(:compliance, :compliance_type)
119
+ end
120
+
121
+ config_rules
122
+ end
123
+
124
+ ##
125
+ # Fetch and combine all compliance information for the config rules.
126
+ #
127
+ # AWS allows passing up to 25 rules at a time to this endpoint.
128
+ #
129
+ # https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/ConfigService/Client.html#describe_compliance_by_config_rule-instance_method
130
+ #
131
+ # Params:
132
+ # - config_rules: The list of hash from AwsConfigMapper::get_all_config_rules
133
+ #
134
+ # Returns: Results mapped by config rule in the format { name: {<response>}, ... }
135
+ def fetch_all_compliance_info(config_rules)
136
+ compliance_results = []
137
+
138
+ config_rules.each_slice(25).each do |slice|
139
+ config_rule_names = slice.map { |r| r[:config_rule_name] }
140
+ response = @client.describe_compliance_by_config_rule(config_rule_names: config_rule_names)
141
+ compliance_results += response.compliance_by_config_rules
142
+ end
143
+
144
+ # Map based on name for easy lookup
145
+ Hash[compliance_results.collect { |r| [r.config_rule_name, r.to_h] }]
146
+ end
147
+
148
+ ##
149
+ # Takes in config rules and formats the results for hdf format.
150
+ #
151
+ # https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/ConfigService/Client.html#get_compliance_details_by_config_rule-instance_method
152
+ #
153
+ # Example hdf results:
154
+ # [
155
+ # {
156
+ # "code_desc": "This rule...",
157
+ # "run_time": 0.314016,
158
+ # "start_time": "2018-11-18T20:21:40-05:00",
159
+ # "status": "passed"
160
+ # },
161
+ # ...
162
+ # ]
163
+ #
164
+ # Status may be any of the following: ['passed', 'failed', 'skipped', 'loaded']
165
+ #
166
+ # Params:
167
+ # - rule: Rules from AwsConfigMapper::get_all_config_rules
168
+ #
169
+ # Returns: The same config_rules array with `results` key added to each rule.
170
+ def add_results_to_config_rules(config_rules)
171
+ config_rules.each do |rule|
172
+ response = @client.get_compliance_details_by_config_rule(config_rule_name: rule[:config_rule_name], limit: 100)
173
+ rule_results = response.to_h[:evaluation_results]
174
+ while response.next_token
175
+ response = @client.get_compliance_details_by_config_rule(next_token: response.next_token, limit: 100)
176
+ rule_results += response.to_h[:evaluation_results]
177
+ end
178
+
179
+ rule[:results] = []
180
+ rule_results.each do |result|
181
+ hdf_result = {}
182
+ # code_desc
183
+ hdf_result['code_desc'] = result.dig(:evaluation_result_identifier, :evaluation_result_qualifier)&.map do |k, v|
184
+ "#{k}: #{v}"
185
+ end&.join(', ')
186
+ # start_time
187
+ hdf_result['start_time'] = if result.key?(:config_rule_invoked_time)
188
+ DateTime.parse(result[:config_rule_invoked_time].to_s).strftime('%Y-%m-%dT%H:%M:%S%:z')
189
+ end
190
+ # run_time
191
+ hdf_result['run_time'] = if result.key?(:result_recorded_time) && result.key?(:config_rule_invoked_time)
192
+ (result[:result_recorded_time] - result[:config_rule_invoked_time]).round(6)
193
+ end
194
+ # status
195
+ hdf_result['status'] = case result.dig(:compliance_type)
196
+ when 'COMPLIANT'
197
+ 'passed'
198
+ when 'NON_COMPLIANT'
199
+ 'failed'
200
+ else
201
+ 'skipped'
202
+ end
203
+ hdf_result['message'] = "(#{hdf_result['code_desc']}): #{result[:annotation] || 'Rule does not pass rule compliance'}" if hdf_result['status'] == 'failed'
204
+ rule[:results] << hdf_result
205
+ end
206
+ next unless rule[:results].empty?
207
+
208
+ case rule[:compliance]
209
+ when 'NOT_APPLICABLE'
210
+ rule[:impact] = 0
211
+ rule[:results] << {
212
+ 'run_time': 0,
213
+ 'code_desc': NOT_APPLICABLE_MSG,
214
+ 'skip_message': NOT_APPLICABLE_MSG,
215
+ 'start_time': DateTime.now.strftime('%Y-%m-%dT%H:%M:%S%:z'),
216
+ 'status': 'skipped'
217
+ }
218
+ when 'INSUFFICIENT_DATA'
219
+ rule[:results] << {
220
+ 'run_time': 0,
221
+ 'code_desc': INSUFFICIENT_DATA_MSG,
222
+ 'skip_message': INSUFFICIENT_DATA_MSG,
223
+ 'start_time': DateTime.now.strftime('%Y-%m-%dT%H:%M:%S%:z'),
224
+ 'status': 'skipped'
225
+ }
226
+ end
227
+ end
228
+
229
+ config_rules
230
+ end
231
+
232
+ ##
233
+ # Takes in a config rule and pulls out tags that are useful for HDF.
234
+ #
235
+ # Params:
236
+ # - config_rule: A single config rule from AwsConfigMapper::get_all_config_rules
237
+ #
238
+ # Returns: Hash containing all relevant HDF tags
239
+ def hdf_tags(config_rule)
240
+ result = {}
241
+
242
+ @default_mapping
243
+ @custom_mapping
244
+
245
+ # NIST tag
246
+ result['nist'] = []
247
+ default_mapping_match = @default_mapping[config_rule[:config_rule_name]]
248
+
249
+ result['nist'] += default_mapping_match[1].split('|') unless default_mapping_match.nil?
250
+
251
+ custom_mapping_match = @custom_mapping[config_rule[:config_rule_name]]
252
+
253
+ result['nist'] += custom_mapping_match[1].split('|').map { |name| "#{name} (user provided)" } unless custom_mapping_match.nil?
254
+
255
+ result['nist'] = ['unmapped'] if result['nist'].empty?
256
+
257
+ result
258
+ end
259
+
260
+ def check_text(config_rule)
261
+ params = (JSON.parse(config_rule[:input_parameters]).map { |key, value| "#{key}: #{value}" }).join('<br/>')
262
+ check_text = config_rule[:config_rule_arn]
263
+ check_text += "<br/>#{params}" unless params.empty?
264
+ check_text
265
+ end
266
+
267
+ ##
268
+ # Takes in a config rule and pulls out information for the descriptions array
269
+ #
270
+ # Params:
271
+ # - config_rule: A single config rule from AwsConfigMapper::get_all_config_rules
272
+ #
273
+ # Returns: Array containing all relevant descriptions information
274
+ def hdf_descriptions(config_rule)
275
+ [
276
+ {
277
+ 'label': 'check',
278
+ 'data': check_text(config_rule)
279
+ }
280
+ ]
281
+ end
282
+ end
283
+ end
284
+ # rubocop:enable Metrics/AbcSize, Metrics/ClassLength
@@ -98,7 +98,7 @@ module HeimdallTools
98
98
  puts "\r\HDF Generated:\n"
99
99
  puts "#{options[:output]}"
100
100
  end
101
-
101
+
102
102
  desc 'dbprotect_mapper', 'dbprotect_mapper translates dbprotect results xml to HDF format Json be viewed on Heimdall'
103
103
  long_desc Help.text(:dbprotect_mapper)
104
104
  option :xml, required: true, aliases: '-x'
@@ -111,6 +111,18 @@ module HeimdallTools
111
111
  puts "#{options[:output]}"
112
112
  end
113
113
 
114
+ desc 'aws_config_mapper', 'aws_config_mapper pulls Ruby AWS SDK data to translate AWS Config Rule results into HDF format Json to be viewable in Heimdall'
115
+ long_desc Help.text(:aws_config_mapper)
116
+ # option :custom_mapping, required: false, aliases: '-m'
117
+ option :output, required: true, aliases: '-o'
118
+ option :verbose, type: :boolean, aliases: '-V'
119
+ def aws_config_mapper
120
+ hdf = HeimdallTools::AwsConfigMapper.new(options[:custom_mapping]).to_hdf
121
+ File.write(options[:output], hdf)
122
+ puts "\r\HDF Generated:\n"
123
+ puts "#{options[:output]}"
124
+ end
125
+
114
126
  desc 'version', 'prints version'
115
127
  def version
116
128
  puts VERSION
@@ -29,7 +29,8 @@ module HeimdallTools
29
29
  groups: NA_ARRAY,
30
30
  status: 'loaded',
31
31
  controls: NA_TAG,
32
- target_id: NA_TAG)
32
+ target_id: NA_TAG,
33
+ statistics: NA_HASH)
33
34
 
34
35
  @results_json = {}
35
36
  @results_json['platform'] = {}
@@ -40,6 +41,7 @@ module HeimdallTools
40
41
 
41
42
  @results_json['statistics'] = {}
42
43
  @results_json['statistics']['duration'] = duration || NA_TAG
44
+ @results_json['statistics'].merge! statistics
43
45
 
44
46
  @results_json['profiles'] = []
45
47
 
@@ -0,0 +1,30 @@
1
+ aws_config_mapper pulls Ruby AWS SDK data to translate AWS Config Rule results into HDF format json to be viewable in Heimdall
2
+
3
+ AWS Config Rule Mapping:
4
+ The mapping of AWS Config Rules to 800-53 Controls was sourced from [this link](https://docs.aws.amazon.com/config/latest/developerguide/operational-best-practices-for-nist-800-53_rev_4.html).
5
+
6
+ Authentication with AWS:
7
+ [Developer Guide for configuring Ruby AWS SDK for authentication](https://docs.aws.amazon.com/sdk-for-ruby/v3/developer-guide/setup-config.html)
8
+
9
+ Authentication Example:
10
+
11
+ - Create `~/.aws/credentials`
12
+ - Add contents to file, replacing with your access ID and key
13
+
14
+ ```
15
+ [default]
16
+ aws_access_key_id = your_access_key_id
17
+ aws_secret_access_key = your_secret_access_key
18
+ ```
19
+
20
+ - (optional) set AWS region through `~/.aws/config` file with contents
21
+
22
+ ```
23
+ [default]
24
+ output = json
25
+ region = us-gov-west-1
26
+ ```
27
+
28
+ Examples:
29
+
30
+ heimdall_tools aws_config_mapper -o aws_config_results.json
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.36
4
+ version: 1.3.37
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Thew
@@ -12,6 +12,20 @@ bindir: exe
12
12
  cert_chain: []
13
13
  date: 2021-03-01 00:00:00.000000000 Z
14
14
  dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: aws-sdk-configservice
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - "~>"
20
+ - !ruby/object:Gem::Version
21
+ version: '1'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - "~>"
27
+ - !ruby/object:Gem::Version
28
+ version: '1'
15
29
  - !ruby/object:Gem::Dependency
16
30
  name: nokogiri
17
31
  requirement: !ruby/object:Gem::Requirement
@@ -181,11 +195,13 @@ files:
181
195
  - Rakefile
182
196
  - exe/heimdall_tools
183
197
  - lib/data/U_CCI_List.xml
198
+ - lib/data/aws-config-mapping.csv
184
199
  - lib/data/cwe-nist-mapping.csv
185
200
  - lib/data/nessus-plugins-nist-mapping.csv
186
201
  - lib/data/nikto-nist-mapping.csv
187
202
  - lib/data/owasp-nist-mapping.csv
188
203
  - lib/heimdall_tools.rb
204
+ - lib/heimdall_tools/aws_config_mapper.rb
189
205
  - lib/heimdall_tools/burpsuite_mapper.rb
190
206
  - lib/heimdall_tools/cli.rb
191
207
  - lib/heimdall_tools/command.rb
@@ -193,6 +209,7 @@ files:
193
209
  - lib/heimdall_tools/fortify_mapper.rb
194
210
  - lib/heimdall_tools/hdf.rb
195
211
  - lib/heimdall_tools/help.rb
212
+ - lib/heimdall_tools/help/aws_config_mapper.md
196
213
  - lib/heimdall_tools/help/burpsuite_mapper.md
197
214
  - lib/heimdall_tools/help/dbprotect_mapper.md
198
215
  - lib/heimdall_tools/help/fortify_mapper.md