Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.3.2] - 2021-11-09
- Corrected CIS 3.1 filter pattern
- Corrected SNS Access Policy for SO0111-SHARR-LocalAlarmNotification
- Corrected KMS CMK Access Policy used by the SNS topic to allow CloudWatch use
- EvaluationPeriods for CIS 3.x alarms changed from 240 (20 hours) to 12 (1 hour)

## [1.3.1] - 2021-09-10

### Changed
Expand Down
2 changes: 1 addition & 1 deletion deployment/build-s3-dist.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
# This controls the CDK and AWS Solutions Constructs version. Solutions
# Constructs versions map 1:1 to CDK versions. When setting this value,
# choose the latest AWS Solutions Constructs version.
required_cdk_version=1.117.0
required_cdk_version=1.132.0

# Functions to reduce repetitive code
# do_cmd will exit if the command has a non-zero return code.
Expand Down
6 changes: 2 additions & 4 deletions source/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,10 @@
},
"devDependencies": {
"@aws-cdk/assert": "~###CDK###",
"@types/node": "16.7.1",
"@types/node": "16.11.7",
"aws-cdk": "~###CDK###",
"ts-node": "^10.2.1",
"typescript": "^4.3.5"
},
"dependencies": {
"typescript": "^4.3.5",
"@aws-cdk/aws-events": "~###CDK###",
"@aws-cdk/aws-iam": "~###CDK###",
"@aws-cdk/aws-kms": "~###CDK###",
Expand Down
117 changes: 58 additions & 59 deletions source/playbooks/CIS120/ssmdocs/scripts/cis_get_input_values.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,135 +16,134 @@

CIS_mappings = {
"3.1": {
"filter_name": "SHARR_Filter_CIS_1_2_Finding_3_1",
"filter_pattern": '{$.errorCode = "AccessDenied" || $.errorCode = "UnauthorizedOperation"}',
"metric_name": "SHARR_CIS_1_2_Finding_3_1_UnauthorizedAPICalls",
"filter_name": "UnauthorizedAPICalls",
"filter_pattern": '{($.errorCode="*UnauthorizedOperation") || ($.errorCode="AccessDenied*")}',
"metric_name": "UnauthorizedAPICalls",
"metric_value": 1,
"alarm_name": "SHARR_Alarm_CIS_1_2_Finding_3_1_UnauthorizedAPICalls",
"alarm_desc": "Alarm for CIS finding 3.1-UnauthorizedAPICalls",
"alarm_name": "UnauthorizedAPICalls",
"alarm_desc": "Alarm for UnauthorizedAPICalls > 0",
"alarm_threshold": 1
},
"3.2": {
"filter_name": "SHARR_Filter_CIS_1_2_Finding_3_2_ConsoleSigninWithoutMFA",
"filter_name": "ConsoleSigninWithoutMFA",
"filter_pattern": '{($.eventName="ConsoleLogin") && ($.additionalEventData.MFAUsed !="Yes")}',
"metric_name": "SHARR_CIS_1_2_Finding_3_2_ConsoleSigninWithoutMFA",
"metric_name": "ConsoleSigninWithoutMFA",
"metric_value": 1,
"alarm_name": "SHARR_Alarm_CIS_1_2_Finding_3_2_ConsoleSigninWithoutMFA",
"alarm_desc": "Alarm for CIS finding 3.2 ConsoleSigninWithoutMFA",
"alarm_name": "ConsoleSigninWithoutMFA",
"alarm_desc": "Alarm for ConsoleSigninWithoutMFA > 0",
"alarm_threshold": 1
},
"3.3": {
"filter_name": "SHARR_Filter_CIS_1_2_Finding_3_3_RootAccountUsage",
"filter_name": "RootAccountUsage",
"filter_pattern": '{$.userIdentity.type="Root" && $.userIdentity.invokedBy NOT EXISTS && $.eventType !="AwsServiceEvent"}',
"metric_name": "SHARR_CIS_1_2_Finding_3_3_RootAccountUsage",
"metric_name": "RootAccountUsage",
"metric_value": 1,
"alarm_name": "SHARR_Alarm_CIS_1_2_Finding_3_3_RootAccountUsage",
"alarm_desc": "Alarm for CIS finding 3.3 RootAccountUsage",
"alarm_name": "RootAccountUsage",
"alarm_desc": "Alarm for RootAccountUsage > 0",
"alarm_threshold": 1

},
"3.4": {
"filter_name": "SHARR_Filter_CIS_1_2_Finding_3_4_IAMPolicyChanges",
"filter_name": "IAMPolicyChanges",
"filter_pattern": '{($.eventName=DeleteGroupPolicy) || ($.eventName=DeleteRolePolicy) || ($.eventName=DeleteUserPolicy) || ($.eventName=PutGroupPolicy) || ($.eventName=PutRolePolicy) || ($.eventName=PutUserPolicy) || ($.eventName=CreatePolicy) || ($.eventName=DeletePolicy) || ($.eventName=CreatePolicyVersion) || ($.eventName=DeletePolicyVersion) || ($.eventName=AttachRolePolicy) || ($.eventName=DetachRolePolicy) || ($.eventName=AttachUserPolicy) || ($.eventName=DetachUserPolicy) || ($.eventName=AttachGroupPolicy) || ($.eventName=DetachGroupPolicy)}',
"metric_name": "SHARR_CIS_1_2_Finding_3_4_IAMPolicyChanges",
"metric_name": "IAMPolicyChanges",
"metric_value": 1,
"alarm_name": "SHARR_Alarm_CIS_1_2_Finding_3_4_IAMPolicyChanges",
"alarm_desc": "Alarm for CIS finding 3.4 IAMPolicyChanges",
"alarm_name": "IAMPolicyChanges",
"alarm_desc": "Alarm for IAMPolicyChanges > 0",
"alarm_threshold": 1
},
"3.5": {
"filter_name": "SHARR_Filter_CIS_1_2_Finding_3_5_CloudTrailChanges",
"filter_name": "CloudTrailChanges",
"filter_pattern": '{($.eventName=CreateTrail) || ($.eventName=UpdateTrail) || ($.eventName=DeleteTrail) || ($.eventName=StartLogging) || ($.eventName=StopLogging)}',
"metric_name": "SHARR_CIS_1_2_Finding_3_5_CloudTrailChanges",
"metric_name": "CloudTrailChanges",
"metric_value": 1,
"alarm_name": "SHARR_Alarm_CIS_1_2_Finding_3_5_CloudTrailChanges",
"alarm_desc": "Alarm for CIS finding 3.5 CloudTrailChanges",
"alarm_name": "CloudTrailChanges",
"alarm_desc": "Alarm for CloudTrailChanges > 0",
"alarm_threshold": 1
},
"3.6": {
"filter_name": "SHARR_Filter_CIS_1_2_Finding_3_6_ConsoleAuthenticationFailure",
"filter_name": "ConsoleAuthenticationFailure",
"filter_pattern": '{($.eventName=ConsoleLogin) && ($.errorMessage="Failed authentication")}',
"metric_name": "SHARR_CIS_1_2_Finding_3_6_ConsoleAuthenticationFailure",
"metric_name": "ConsoleAuthenticationFailure",
"metric_value": 1,
"alarm_name": "SHARR_Alarm_CIS_1_2_Finding_3_6_ConsoleAuthenticationFailure",
"alarm_desc": "Alarm for CIS finding 3.6 ConsoleAuthenticationFailure",
"alarm_name": "ConsoleAuthenticationFailure",
"alarm_desc": "Alarm for ConsoleAuthenticationFailure > 0",
"alarm_threshold": 1
},
"3.7": {
"filter_name": "SHARR_Filter_CIS_1_2_Finding_3_7_DisableOrDeleteCMK",
"filter_name": "DisableOrDeleteCMK",
"filter_pattern": '{($.eventSource=kms.amazonaws.com) && (($.eventName=DisableKey) || ($.eventName=ScheduleKeyDeletion))}',
"metric_name": "SHARR_CIS_1_2_Finding_3_7_DisableOrDeleteCMK",
"metric_name": "DisableOrDeleteCMK",
"metric_value": 1,
"alarm_name": "SHARR_Alarm_CIS_1_2_Finding_3_7_DisableOrDeleteCMK",
"alarm_desc": "Alarm for CIS finding 3.7 DisableOrDeleteCMK",
"alarm_name": "DisableOrDeleteCMK",
"alarm_desc": "Alarm for DisableOrDeleteCMK > 0",
"alarm_threshold": 1
},
"3.8": {
"filter_name": "SHARR_Filter_CIS_1_2_Finding_3_8_S3BucketPolicyChanges",
"filter_name": "S3BucketPolicyChanges",
"filter_pattern": '{($.eventSource=s3.amazonaws.com) && (($.eventName=PutBucketAcl) || ($.eventName=PutBucketPolicy) || ($.eventName=PutBucketCors) || ($.eventName=PutBucketLifecycle) || ($.eventName=PutBucketReplication) || ($.eventName=DeleteBucketPolicy) || ($.eventName=DeleteBucketCors) || ($.eventName=DeleteBucketLifecycle) || ($.eventName=DeleteBucketReplication))}',
"metric_name": "SHARR_CIS_1_2_Finding_3_8_S3BucketPolicyChanges",
"metric_name": "S3BucketPolicyChanges",
"metric_value": 1,
"alarm_name": "SHARR_Alarm_CIS_1_2_Finding_3_8_S3BucketPolicyChanges",
"alarm_desc": "Alarm for CIS finding 3.8 S3BucketPolicyChanges",
"alarm_name": "S3BucketPolicyChanges",
"alarm_desc": "Alarm for S3BucketPolicyChanges > 0",
"alarm_threshold": 1
},
"3.9": {
"filter_name": "SHARR_Filter_CIS_1_2_Finding_3_9_AWSConfigChanges",
"filter_name": "AWSConfigChanges",
"filter_pattern": '{($.eventSource=config.amazonaws.com) && (($.eventName=StopConfigurationRecorder) || ($.eventName=DeleteDeliveryChannel) || ($.eventName=PutDeliveryChannel) || ($.eventName=PutConfigurationRecorder))}',
"metric_name": "SHARR_CIS_1_2_Finding_3_9_AWSConfigChanges",
"metric_name": "AWSConfigChanges",
"metric_value": 1,
"alarm_name": "SHARR_Alarm_CIS_1_2_Finding_3_9_AWSConfigChanges",
"alarm_desc": "Alarm for CIS finding 3.9 AWSConfigChanges",
"alarm_name": "AWSConfigChanges",
"alarm_desc": "Alarm for AWSConfigChanges > 0",
"alarm_threshold": 1
},
"3.10": {
"filter_name": "SHARR_Filter_CIS_1_2_Finding_3_10_SecurityGroupChanges",
"filter_name": "SecurityGroupChanges",
"filter_pattern": '{($.eventName=AuthorizeSecurityGroupIngress) || ($.eventName=AuthorizeSecurityGroupEgress) || ($.eventName=RevokeSecurityGroupIngress) || ($.eventName=RevokeSecurityGroupEgress) || ($.eventName=CreateSecurityGroup) || ($.eventName=DeleteSecurityGroup)}',
"metric_name": "SHARR_CIS_1_2_Finding_3_10_SecurityGroupChanges",
"metric_name": "SecurityGroupChanges",
"metric_value": 1,
"alarm_name": "SHARR_Alarm_CIS_1_2_Finding_3_10_SecurityGroupChanges",
"alarm_desc": "Alarm for CIS finding 3.10 SecurityGroupChanges",
"alarm_name": "SecurityGroupChanges",
"alarm_desc": "Alarm for SecurityGroupChanges > 0",
"alarm_threshold": 1
},
"3.11": {
"filter_name": "SHARR_Filter_CIS_1_2_Finding_3_11_NetworkACLChanges",
"filter_name": "NetworkACLChanges",
"filter_pattern": '{($.eventName=CreateNetworkAcl) || ($.eventName=CreateNetworkAclEntry) || ($.eventName=DeleteNetworkAcl) || ($.eventName=DeleteNetworkAclEntry) || ($.eventName=ReplaceNetworkAclEntry) || ($.eventName=ReplaceNetworkAclAssociation)}',
"metric_name": "SHARR_CIS_1_2_Finding_3_11_NetworkACLChanges",
"metric_name": "NetworkACLChanges",
"metric_value": 1,
"alarm_name": "SHARR_Alarm_CIS_1_2_Finding_3_11_NetworkACLChanges",
"alarm_desc": "Alarm for CIS finding 3.11 NetworkACLChanges",
"alarm_name": "NetworkACLChanges",
"alarm_desc": "Alarm for NetworkACLChanges > 0",
"alarm_threshold": 1
},
"3.12": {
"filter_name": "SHARR_Filter_CIS_1_2_Finding_3_12_NetworkGatewayChanges",
"filter_name": "NetworkGatewayChanges",
"filter_pattern": '{($.eventName=CreateCustomerGateway) || ($.eventName=DeleteCustomerGateway) || ($.eventName=AttachInternetGateway) || ($.eventName=CreateInternetGateway) || ($.eventName=DeleteInternetGateway) || ($.eventName=DetachInternetGateway)}',
"metric_name": "SHARR_CIS_1_2_Finding_3_12_NetworkGatewayChanges",
"metric_name": "NetworkGatewayChanges",
"metric_value": 1,
"alarm_name": "SHARR_Alarm_CIS_1_2_Finding_3_12_NetworkGatewayChanges",
"alarm_desc": "Alarm for CIS finding 3.12 NetworkGatewayChanges",
"alarm_name": "NetworkGatewayChanges",
"alarm_desc": "Alarm for NetworkGatewayChanges > 0",
"alarm_threshold": 1
},
"3.13": {
"filter_name": "SHARR_Filter_CIS_1_2_Finding_3_13_RouteTableChanges",
"filter_name": "RouteTableChanges",
"filter_pattern": '{($.eventName=CreateRoute) || ($.eventName=CreateRouteTable) || ($.eventName=ReplaceRoute) || ($.eventName=ReplaceRouteTableAssociation) || ($.eventName=DeleteRouteTable) || ($.eventName=DeleteRoute) || ($.eventName=DisassociateRouteTable)}',
"metric_name": "SHARR_CIS_1_2_Finding_3_13_RouteTableChanges",
"metric_name": "RouteTableChanges",
"metric_value": 1,
"alarm_name": "SHARR_Alarm_CIS_1_2_Finding_3_13_RouteTableChanges",
"alarm_desc": "Alarm for CIS finding 3.13 RouteTableChanges",
"alarm_name": "RouteTableChanges",
"alarm_desc": "Alarm for RouteTableChanges > 0",
"alarm_threshold": 1
},
"3.14": {
"filter_name": "SHARR_Filter_CIS_1_2_Finding_3_14_VPCChanges",
"filter_name": "VPCChanges",
"filter_pattern": '{($.eventName=CreateVpc) || ($.eventName=DeleteVpc) || ($.eventName=ModifyVpcAttribute) || ($.eventName=AcceptVpcPeeringConnection) || ($.eventName=CreateVpcPeeringConnection) || ($.eventName=DeleteVpcPeeringConnection) || ($.eventName=RejectVpcPeeringConnection) || ($.eventName=AttachClassicLinkVpc) || ($.eventName=DetachClassicLinkVpc) || ($.eventName=DisableVpcClassicLink) || ($.eventName=EnableVpcClassicLink)}',
"metric_name": "SHARR_CIS_1_2_Finding_3_14_VPCChanges",
"metric_name": "VPCChanges",
"metric_value": 1,
"alarm_name": "SHARR_Alarm_CIS_1_2_Finding_3_14_VPCChanges",
"alarm_desc": "Alarm for CIS finding 3.14 VPCChanges",
"alarm_name": "VPCChanges",
"alarm_desc": "Alarm for VPCChanges > 0",
"alarm_threshold": 1
}
}


def verify(event, context):

return CIS_mappings.get(event['ControlId'], None)
return CIS_mappings.get(event['ControlId'], None)
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,9 @@ def put_metric_filter(cw_log_group, filter_name, filter_pattern, metric_name, me
{
'metricName': metric_name,
'metricNamespace': metric_namespace,
'metricValue': str(metric_value)
},
'metricValue': str(metric_value),
'unit': 'Count'
}
]
)
except Exception as e:
Expand Down Expand Up @@ -99,10 +100,12 @@ def put_metric_alarm(alarm_name, alarm_desc, alarm_threshold, metric_name, metri
Namespace=metric_namespace,
Statistic='Sum',
Period=300,
Unit='Seconds',
EvaluationPeriods=240,
Unit='Count',
EvaluationPeriods=12,
DatapointsToAlarm=1,
Threshold=alarm_threshold,
ComparisonOperator='GreaterThanOrEqualToThreshold'
ComparisonOperator='GreaterThanOrEqualToThreshold',
TreatMissingData='notBreaching'
)
except Exception as e:
exit("Exception occurred while putting metric alarm: " + str(e))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#!/usr/bin/python
###############################################################################
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. #
# #
# Licensed under the Apache License Version 2.0 (the "License"). You may not #
# use this file except in compliance with the License. A copy of the License #
# is located at #
# #
# http://www.apache.org/licenses/LICENSE-2.0 #
# #
# or in the "license" file accompanying this file. This file is distributed #
# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express #
# or implied. See the License for the specific language governing permis- #
# sions and limitations under the License. #
###############################################################################

import json
import boto3
from botocore.config import Config
from botocore.exceptions import ClientError

boto_config = Config(
retries ={
'mode': 'standard'
}
)

def connect_to_sns():
return boto3.client('sns', config=boto_config)

def connect_to_ssm():
return boto3.client('ssm', config=boto_config)

def create_encrypted_topic(event, context):

kms_key_arn = event['kms_key_arn']
new_topic = False
topic_arn = ''
topic_name = event['topic_name']

try:
sns = connect_to_sns()
topic_arn = sns.create_topic(
Name=topic_name,
Attributes={
'KmsMasterKeyId': kms_key_arn.split('key/')[1]
}
)['TopicArn']
new_topic = True

except ClientError as client_exception:
exception_type = client_exception.response['Error']['Code']
if exception_type == 'InvalidParameter':
print(f'Topic {topic_name} already exists. This remediation may have been run before.')
print('Ignoring exception - remediation continues.')
topic_arn = sns.create_topic(
Name=topic_name
)['TopicArn']
else:
exit(f'ERROR: Unhandled client exception: {client_exception}')

except Exception as e:
exit(f'ERROR: could not create SNS Topic {topic_name}: {str(e)}')

if new_topic:
try:
ssm = connect_to_ssm()
ssm.put_parameter(
Name='/Solutions/SO0111/SNS_Topic_CIS3.x',
Description='SNS Topic for AWS Config updates',
Type='String',
Overwrite=True,
Value=topic_arn
)
except Exception as e:
exit(f'ERROR: could not create SNS Topic {topic_name}: {str(e)}')

create_topic_policy(topic_arn)

return {"topic_arn": topic_arn}

def create_topic_policy(topic_arn):
sns = connect_to_sns()
try:
topic_policy = {
"Id": "Policy_ID",
"Statement": [
{
"Sid": "AWSConfigSNSPolicy",
"Effect": "Allow",
"Principal": {
"Service": "cloudwatch.amazonaws.com"
},
"Action": "SNS:Publish",
"Resource": topic_arn,
}]
}

sns.set_topic_attributes(
TopicArn=topic_arn,
AttributeName='Policy',
AttributeValue=json.dumps(topic_policy)
)
except Exception as e:
exit(f'ERROR: Failed to SetTopicAttributes for {topic_arn}: {str(e)}')
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,9 @@ def test_put_metric_filter_pass(mocker):
{
'metricName': event['MetricName'],
'metricNamespace':event['MetricNamespace'],
'metricValue': str (event['MetricValue'])
},
'metricValue': str (event['MetricValue']),
'unit': 'Count'
}
]
}
)
Expand Down Expand Up @@ -179,10 +180,12 @@ def test_put_metric_alarm(mocker):
'Namespace': event['MetricNamespace'],
'Statistic': 'Sum',
'Period': 300,
'Unit': 'Seconds',
'EvaluationPeriods': 240,
'Unit': 'Count',
'EvaluationPeriods': 12,
'DatapointsToAlarm': 1,
'Threshold': (event['AlarmThreshold']),
'ComparisonOperator': 'GreaterThanOrEqualToThreshold'
'ComparisonOperator': 'GreaterThanOrEqualToThreshold',
'TreatMissingData': 'notBreaching'
}
)
cloudwatch_stubber.activate()
Expand Down
Loading