Description: AWS Security Hub PCI Remediations Systems Manager Automation Documents and Prerequisites AWSTemplateFormatVersion: "2010-09-09" # @author Kanishk Mahajan # ## License: ## This code is made available under the MIT-0 license. See the LICENSE file. Outputs: AutomationAssumeRoleArn: Description: Arn for AutomationAssumeRole Value: !Sub 'arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}' Export: # added to export Name: AutomationAssumeRoleArn FlowLogsRoleArn: Description: Arn for FlowsLogsRole Value: !Sub 'arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${FlowLogsRole}' Export: # added to export Name: FlowLogsRoleArn FlowLogsCloudWatchLogGroupArn: Description: Arn for FlowLogs CloudWatchLogs Value: !Sub "arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:${FlowLogsCloudWatchLogs}" Export: # added to export Name: FlowLogsCloudWatchLogGroupArn FlowLogsCloudWatchLogs: Description: Name of FlowLogs CloudWatch Logs Value: !Ref FlowLogsCloudWatchLogs Export: # added to export Name: FlowLogsCloudWatchLogs RestrictLambdaVPCRoleArn: Description: Arn for RestrictLambdaVPCRole - PCI.Lambda.2 Value: !Sub 'arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${RestrictLambdaVPCRole}' Export: # added to export Name: RestrictLambdaVPCRoleArn S3BucketReplicationRoleArn: Description: Arn for S3ReplicationRole Value: !Sub 'arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${S3BucketReplicationRole}' Export: # added to export Name: S3BucketReplicationRoleArn CloudTrailLogGroupArn: Description: Arn for CloudTrail CloudWatch Logs Value: !Sub "arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:${CloudTrailLogGroup}:*" Export: # added to export Name: CloudTrailLogGroupArn SSMInstanceProfileRoleArn: Description: Arn for SSMInstanceProfileRole Value: !Sub 'arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${SSMInstanceProfileRole}' Export: # added to export Name: PCI-SSMInstanceProfileRoleArn S3ReplicationBucketFullName: Description: S3 Replication Bucket - PCI S3.3 Value: !Ref S3ReplicationBucket Export: # added to export Name: S3ReplicationBucketFullName OutputsFromNestedStackVPC: Description: VPC ID Value: !GetAtt SecureVPCStack.Outputs.vpc1id Export: # added to export Name: vpcid OutputsFromNestedStackSubnet1: Description: Subnet 1 Value: !GetAtt SecureVPCStack.Outputs.subnetvpc1A2 Export: # added to export Name: subnet1 OutputsFromNestedStackSubnet2: Description: Subnet 2 Value: !GetAtt SecureVPCStack.Outputs.subnetvpc1A3 Export: # added to export Name: subnet2 OutputsFromNestedStackSecurityGroup: Description: SecurityGroup Value: !GetAtt SecureVPCStack.Outputs.securitygroupid Export: # added to export Name: securitygroup1 PCIS3CloudTrailBucket: Description: PCI S3 CloudTrail Bucket Value: !Ref PCIS3CloudTrailBucket Export: # added to export Name: PCIS3CloudTrailBucket CloudTrailLogGroup: Description: PCI CloudTrail CloudWatch Log Group Value: !Ref CloudTrailLogGroup Export: # added to export Name: CloudTrailLogGroup PCICloudTrail: Description: PCI CloudTrail Value: 'remediation-pci-trail' Export: # added to export Name: PCICloudTrail CloudWatchRoleArn: Description: Arn for CloudTrail CloudWatch IAM Role Value: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${CloudWatchRole}" Export: # added to export Name: CloudWatchRoleArn KMSKeyArn: Description: Arn for KMS CMK Value: !Sub "arn:${AWS::Partition}:kms:${AWS::Region}:${AWS::AccountId}:key/${KmsKeyId}" Export: # added to export Name: KMSKeyArn Parameters: QSS3BucketName: AllowedPattern: '^[0-9a-zA-Z]+([0-9a-zA-Z-]*[0-9a-zA-Z])*$' ConstraintDescription: Quick Start bucket name can include numbers, lowercase letters, uppercase letters, and hyphens (-). It cannot start or end with a hyphen (-). Default: aws-securityhub-pci-quickstart Description: S3 bucket name for the Quick Start assets. Quick Start bucket name can include numbers, lowercase letters, uppercase letters, and hyphens (-). It cannot start or end with a hyphen (-). Type: String QSS3BucketRegion: Default: 'us-east-1' Description: The AWS Region where the Quick Start S3 bucket (QSS3BucketName) is hosted. When using your own bucket, you must specify this value. Type: String QSS3KeyPrefix: AllowedPattern: '^([0-9a-zA-Z-.]+/)*$' ConstraintDescription: Quick Start key prefix can include numbers, lowercase letters, uppercase letters, hyphens (-), dots (.) and forward slash (/). The prefix should end with a forward slash (/). Default: remediations/ Description: S3 key prefix for the Quick Start assets. Quick Start key prefix can include numbers, lowercase letters, uppercase letters, hyphens (-), dots (.) and forward slash (/) and it should end with a forward slash (/). Type: String Conditions: UsingDefaultBucket: !Equals - !Ref QSS3BucketName - 'aws-securityhub-pci-quickstart' Resources: # Bucket Policy for CloudTrail S3 Bucket. Restrict to allow access to only SSL transport. PCIBucketPolicy: Type: AWS::S3::BucketPolicy Properties: Bucket: !Ref PCIS3CloudTrailBucket PolicyDocument: Statement: - Action: - "s3:*" Effect: "Allow" Resource: - !Sub arn:${AWS::Partition}:s3:::${PCIS3CloudTrailBucket} - !Sub arn:${AWS::Partition}:s3:::${PCIS3CloudTrailBucket}/* Principal: AWS: - !Ref AWS::AccountId - Action: - "s3:*" Effect: "Allow" Resource: - !Sub arn:${AWS::Partition}:s3:::${PCIS3CloudTrailBucket} - !Sub arn:${AWS::Partition}:s3:::${PCIS3CloudTrailBucket}/* Principal: Service: - cloudtrail.amazonaws.com - Effect: Deny Principal: "*" Action: "*" Resource: - !Sub arn:${AWS::Partition}:s3:::${PCIS3CloudTrailBucket} - !Sub arn:${AWS::Partition}:s3:::${PCIS3CloudTrailBucket}/* Condition: Bool: aws:SecureTransport: 'false' # S3 Bucket to store CloudTrail logs PCIS3CloudTrailBucket: Type: AWS::S3::Bucket Properties: BucketName: !Sub "s3-pci-${AWS::AccountId}-${AWS::Region}" BucketEncryption: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: AES256 AccessControl: BucketOwnerFullControl LifecycleConfiguration: Rules: - AbortIncompleteMultipartUpload: DaysAfterInitiation: 3 NoncurrentVersionExpirationInDays: 3 Status: Enabled PublicAccessBlockConfiguration: BlockPublicAcls: true BlockPublicPolicy: true IgnorePublicAcls: true RestrictPublicBuckets: true Tags: - Key: Description Value: S3 Bucket for CloudTrail Logs VersioningConfiguration: Status: Enabled # S3 Bucket for Bucket Replication S3ReplicationBucket: Type: AWS::S3::Bucket Properties: BucketName: !Sub "s3-replication-${AWS::AccountId}-${AWS::Region}" BucketEncryption: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: AES256 AccessControl: BucketOwnerFullControl LifecycleConfiguration: Rules: - AbortIncompleteMultipartUpload: DaysAfterInitiation: 3 NoncurrentVersionExpirationInDays: 3 Status: Enabled PublicAccessBlockConfiguration: BlockPublicAcls: true BlockPublicPolicy: true IgnorePublicAcls: true RestrictPublicBuckets: true Tags: - Key: Description Value: S3 Destination Bucket for Replication VersioningConfiguration: Status: Enabled # SSM Automation Role AutomationAssumeRole: Type: 'AWS::IAM::Role' Properties: RoleName: !Sub pci-automationassumerole-${AWS::Region} AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - ssm.amazonaws.com - events.amazonaws.com - ec2.amazonaws.com Action: - 'sts:AssumeRole' Path: / ManagedPolicyArns: - !Sub "arn:${AWS::Partition}:iam::aws:policy/AdministratorAccess" # SSM Instance Profile Role SSMInstanceProfileRole: Type: 'AWS::IAM::Role' Properties: RoleName: !Sub pci-ssminstanceprofilerole-${AWS::Region} AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - ec2.amazonaws.com Action: - 'sts:AssumeRole' Path: / ManagedPolicyArns: - !Sub "arn:${AWS::Partition}:iam::aws:policy/AmazonSSMManagedInstanceCore" #SecureVPCStack SecureVPCStack: Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Sub - "https://${S3Bucket}.s3.amazonaws.com/${QSS3KeyPrefix}/aws-securevpcsetup.template" - S3Bucket: !If [UsingDefaultBucket, !Sub 'aws-securityhub-pci-quickstart', !Ref QSS3BucketName] #CloudTrail CW Log Group CloudTrailLogGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: !Sub DefaultLogGroup-${AWS::Region} RetentionInDays: 1827 #FlowLogs CW Log Group FlowLogsCloudWatchLogs: Type: AWS::Logs::LogGroup Properties: LogGroupName: !Sub flowlogscloudwatchlogs-${AWS::Region} RetentionInDays: 1827 # RestrictLambdaVPCRole RestrictLambdaVPCRole: Type: 'AWS::IAM::Role' Properties: RoleName: !Sub restrictlambdavpcrole-${AWS::Region} AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - 'sts:AssumeRole' Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole - arn:aws:iam::aws:policy/AmazonEC2FullAccess - arn:aws:iam::aws:policy/IAMFullAccess # Flow Logs Role FlowLogsRole: Type: AWS::IAM::Role Properties: RoleName: !Sub flowlogsrole-${AWS::Region} Policies: - PolicyName: FlowLogsPolicy PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - cloudwatch:PutMetricData Resource: '*' - Effect: Allow Action: - ssm:StartAutomationExecution - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents - logs:DescribeLogGroups - logs:DescribeLogStreams - iam:PassRole - ec2:* Resource: '*' - Effect: Allow Action: - cloudtrail:UpdateTrail - securityhub:UpdateFindings Resource: '*' AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - vpc-flow-logs.amazonaws.com - ec2.amazonaws.com Action: - sts:AssumeRole # Cloud Watch Role CloudWatchRole: Type: AWS::IAM::Role Properties: RoleName: !Sub CloudTrail_CloudWatchLogs_Role-${AWS::Region} Policies: - PolicyName: CloudWatchLogsRolePolicy PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - cloudwatch:PutMetricData Resource: '*' - Effect: Allow Action: - ssm:StartAutomationExecution - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents - logs:DescribeLogGroups - logs:DescribeLogStreams - iam:PassRole - ec2:* Resource: '*' - Effect: Allow Action: - cloudtrail:UpdateTrail - securityhub:UpdateFindings Resource: '*' AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - cloudtrail.amazonaws.com Action: - sts:AssumeRole # S3 Bucket Replication Role S3BucketReplicationRole: Type: AWS::IAM::Role Properties: RoleName: !Sub PCIDSS_S3_Replication_Role-${AWS::Region} Policies: - PolicyName: S3BucketReplicationPolicy PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - s3:GetReplicationConfiguration - s3:ListBucket Resource: - !Sub arn:aws:s3:::* - !Sub arn:aws:s3:::* - Effect: Allow Action: - s3:GetObjectVersion - s3:GetObjectVersionTagging - s3:GetObjectVersionAcl Resource: - !Sub arn:aws:s3:::* - !Sub arn:aws:s3:::* - Effect: Allow Action: - s3:ReplicateObject - s3:ReplicateDelete - s3:ReplicateTags Resource: - !Sub arn:aws:s3:::* - !Sub arn:aws:s3:::* AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - s3.amazonaws.com Action: - sts:AssumeRole # PCI KMS CMK KmsKeyId: Type: 'AWS::KMS::Key' Properties: EnableKeyRotation: true Enabled: true KeyUsage: ENCRYPT_DECRYPT KeyPolicy: Version: '2012-10-17' Statement: - Sid: Sid1 Effect: Allow Principal: AWS: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:root" Action: 'kms:*' Resource: '*' KmsKeyIdAlias: Type: AWS::KMS::Alias Properties: AliasName: alias/PCI-CMK TargetKeyId: Fn::GetAtt: - KmsKeyId - Arn PCICloudTrail1Automation: Type: AWS::SSM::Document Properties: DocumentType: Automation Name: PCICloudTrail1Automation Content: schemaVersion: '0.3' assumeRole: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" parameters: AutomationAssumeRole: type: String default: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" CloudTrailLogGroupArn: type: String default: !Sub "arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:${CloudTrailLogGroup}:*" CloudWatchRoleArn: type: String default: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${CloudWatchRole}" TrailName: type: String KMSKeyArn: type: String default: !Sub "arn:${AWS::Partition}:kms:${AWS::Region}:${AWS::AccountId}:key/${KmsKeyId}" mainSteps: - name: EncryptCloudTrail action: 'aws:executeScript' inputs: Runtime: python3.6 Handler: encrypttrail_handler Script: "def encrypttrail_handler(events, context):\r\n import boto3\r\n cloudtrail = boto3.client('cloudtrail')\r\n\r\n CloudTrailLogGroupArn = events['CloudTrailLogGroupArn']\r\n CloudWatchRoleArn = events['CloudWatchRoleArn']\r\n TrailName = events['TrailName']\r\n KMSKeyArn = events['KMSKeyArn']\r\n\r\n response = cloudtrail.update_trail(\r\n Name=TrailName,\r\n IncludeGlobalServiceEvents=True,\r\n IsMultiRegionTrail=True,\r\n EnableLogFileValidation=True,\r\n CloudWatchLogsLogGroupArn=CloudTrailLogGroupArn,\r\n CloudWatchLogsRoleArn=CloudWatchRoleArn,\r\n KmsKeyId=KMSKeyArn\r\n ) " InputPayload: AutomationAssumeRole: '{{AutomationAssumeRole}}' CloudTrailLogGroupArn: '{{CloudTrailLogGroupArn}}' CloudWatchRoleArn: '{{CloudWatchRoleArn}}' TrailName: '{{TrailName}}' KMSKeyArn: '{{KMSKeyArn}}' PCIKMS1Automation: Type: AWS::SSM::Document Properties: DocumentType: Automation Name: PCIKMS1Automation Content: schemaVersion: '0.3' assumeRole: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" parameters: KMSKeyArn: type: String AutomationAssumeRole: type: String default: !Sub "arn:${AWS::Partition}:kms:${AWS::Region}:${AWS::AccountId}:key/${KmsKeyId}" mainSteps: - name: rotatebackingkey action: 'aws:executeScript' inputs: Runtime: python3.6 Handler: rotatebackingkey_handler Script: "def rotatebackingkey_handler(events, context):\r\n import boto3\r\n client = boto3.client('kms')\r\n\r\n KMSKeyArn = events['KMSKeyArn']\r\n\r\n response = client.enable_key_rotation(\r\n KeyId=KMSKeyArn\r\n )" InputPayload: AutomationAssumeRole: '{{AutomationAssumeRole}}' KMSKeyArn: '{{KMSKeyArn}}' PCICloudTrail4Automation: Type: AWS::SSM::Document Properties: DocumentType: Automation Name: PCICloudTrail4Automation Content: description: PCI.CloudTrail.4 – Ensure CloudTrail trails are integrated with Amazon CloudWatch Logs schemaVersion: '0.3' assumeRole: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" parameters: AutomationAssumeRole: type: String default: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" CloudTrailLogGroupArn: type: String default: !Sub "arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:${CloudTrailLogGroup}:*" CloudWatchRoleArn: type: String default: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${CloudWatchRole}" TrailName: type: String mainSteps: - name: UpdateCloudTrail action: 'aws:executeScript' inputs: Runtime: python3.6 Handler: updatetrail_handler Script: "def updatetrail_handler(events, context):\r\n import boto3\r\n cloudtrail = boto3.client('cloudtrail')\r\n\r\n CloudTrailLogGroupArn = events['CloudTrailLogGroupArn']\r\n CloudWatchRoleArn = events['CloudWatchRoleArn']\r\n TrailName = events['TrailName']\r\n\r\n response = cloudtrail.update_trail(\r\n Name=TrailName,\r\n IncludeGlobalServiceEvents=True,\r\n IsMultiRegionTrail=True,\r\n EnableLogFileValidation=True,\r\n CloudWatchLogsLogGroupArn=CloudTrailLogGroupArn,\r\n CloudWatchLogsRoleArn=CloudWatchRoleArn\r\n )\r\n" InputPayload: AutomationAssumeRole: '{{AutomationAssumeRole}}' CloudTrailLogGroupArn: '{{CloudTrailLogGroupArn}}' CloudWatchRoleArn: '{{CloudWatchRoleArn}}' TrailName: '{{TrailName}}' PCIIAM8Automation: Type: AWS::SSM::Document Properties: DocumentType: Automation Name: PCIIAM8Automation Content: schemaVersion: '0.3' assumeRole: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" parameters: AutomationAssumeRole: type: String default: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" mainSteps: - name: updatepasswordpolicy action: 'aws:executeScript' inputs: Runtime: python3.6 Handler: updateiampolicy_handler Script: | def updateiampolicy_handler(events, context): import boto3 iam = boto3.client('iam') response = iam.update_account_password_policy( AllowUsersToChangePassword=True, HardExpiry=True, MaxPasswordAge=90 , MinimumPasswordLength=14, PasswordReusePrevention=24, RequireLowercaseCharacters=True, RequireNumbers=True, RequireSymbols=True, RequireUppercaseCharacters=True) InputPayload: AutomationAssumeRole: '{{AutomationAssumeRole}}' PCIIAM1Automation: Type: AWS::SSM::Document Properties: DocumentType: Automation Name: PCIIAM1Automation Content: schemaVersion: '0.3' assumeRole: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" parameters: username: type: String default: 'root' AutomationAssumeRole: type: String default: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" mainSteps: - name: deactivaterootiamaccesskey action: 'aws:executeScript' inputs: Runtime: python3.6 Handler: deactivaterootiamaccesskey_handler Script: | def deactivaterootiamaccesskey_handler(events, context): import boto3 import json import os iam = boto3.client('iam') iam_resource = boto3.resource('iam') try: username = events['username'] access_key = iam_resource.AccessKey(username, accessKeyId) access_key.deactivate() except Exception as e: print(e) raise InputPayload: AutomationAssumeRole: '{{AutomationAssumeRole}}' username: '{{username}}' PCIIAM2Automation: Type: AWS::SSM::Document Properties: DocumentType: Automation Name: PCIIAM2Automation Content: schemaVersion: '0.3' assumeRole: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" parameters: username: type: String default: 'pciadmin' findingid: type: String default: '0123' AutomationAssumeRole: type: String default: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" mainSteps: - name: detachiamuserpolicy action: 'aws:executeScript' inputs: Runtime: python3.6 Handler: detachiamuserpolicy_handler Script: | def detachiamuserpolicy_handler(events, context): import boto3 import json import os client = boto3.client('iam') securityhub = boto3.client('securityhub') iam = boto3.resource('iam') try: userName = events['username'] findingid = events['findingid'] userpolicyresponse = client.list_attached_user_policies(UserName=userName) userpolicies =[] userpolicies = userpolicyresponse.get("AttachedPolicies") newgroup = "PCI-IAM2" + "-" + userName + "-" + findingid grouplist = client.list_groups() for group in grouplist: try: if group['GroupName'] == newgroup: print("foundGroup") break else: response = client.create_group( GroupName = newgroup ) except Exception as e: print(e) group = iam.Group(newgroup) for policy in userpolicies: try: response = group.attach_policy( PolicyArn = policy['PolicyArn'] ) print(response) except Exception as e: print(e) for policy in userpolicies: try: response_1 = client.detach_user_policy( UserName=userName, PolicyArn=policy['PolicyArn'] ) except Exception as e: print(e) try: response_2 = client.add_user_to_group( GroupName = newgroup, UserName = userName ) except Exception as e: print(e) except Exception as e: print(e) raise InputPayload: AutomationAssumeRole: '{{AutomationAssumeRole}}' username: '{{username}}' findingid: '{{findingid}}' PCIIAM3Automation: Type: AWS::SSM::Document Properties: DocumentType: Automation Name: PCIIAM3Automation Content: schemaVersion: '0.3' assumeRole: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" parameters: username: type: String default: 'pciadmin' AutomationAssumeRole: type: String default: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" mainSteps: - name: detachiamfulladminpolicy action: 'aws:executeScript' inputs: Runtime: python3.6 Handler: detachiamfulladminpolicy_handler Script: | def detachiamfulladminpolicy_handler(events, context): import boto3 import json import os client = boto3.client('iam') iam = boto3.resource('iam') try: userName = events['username'] userpolicyresponse = client.list_attached_user_policies(UserName=userName) userpolicies =[] userpolicies = userpolicyresponse.get("AttachedPolicies") for policy in userpolicies: try: response = client.detach_user_policy( UserName=userName, PolicyArn=policy['PolicyArn'] ) except Exception as e: print(e) except Exception as e: print(e) raise InputPayload: AutomationAssumeRole: '{{AutomationAssumeRole}}' username: '{{username}}' PCICloudTrail3Automation: Type: AWS::SSM::Document Properties: DocumentType: Automation Name: PCICloudTrail3Automation Content: schemaVersion: '0.3' assumeRole: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" parameters: AutomationAssumeRole: type: String default: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" CloudTrailLogGroupArn: type: String default: !Sub "arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:${CloudTrailLogGroup}:*" CloudWatchRoleArn: type: String default: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${CloudWatchRole}" TrailName: type: String mainSteps: - name: EnableLogFileValidation action: 'aws:executeScript' inputs: Runtime: python3.6 Handler: updatetrail_handler Script: "def updatetrail_handler(events, context):\r\n import boto3\r\n cloudtrail = boto3.client('cloudtrail')\r\n\r\n CloudTrailLogGroupArn = events['CloudTrailLogGroupArn']\r\n CloudWatchRoleArn = events['CloudWatchRoleArn']\r\n TrailName = events['TrailName']\r\n\r\n response = cloudtrail.update_trail(\r\n Name=TrailName,\r\n IncludeGlobalServiceEvents=True,\r\n IsMultiRegionTrail=True,\r\n EnableLogFileValidation=True,\r\n CloudWatchLogsLogGroupArn=CloudTrailLogGroupArn,\r\n CloudWatchLogsRoleArn=CloudWatchRoleArn\r\n ) " InputPayload: AutomationAssumeRole: '{{AutomationAssumeRole}}' CloudTrailLogGroupArn: '{{CloudTrailLogGroupArn}}' CloudWatchRoleArn: '{{CloudWatchRoleArn}}' TrailName: '{{TrailName}}' PCIEC22Automation: Type: AWS::SSM::Document Properties: DocumentType: Automation Name: PCIEC22Automation Content: schemaVersion: '0.3' assumeRole: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" parameters: groupId: type: String IpAddressToBlock: type: String default: '0.0.0.0/0' AutomationAssumeRole: type: String default: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" mainSteps: - name: RestrictSecurityGroup action: 'aws:executeScript' inputs: Runtime: python3.6 Handler: restrict_sg Script: "def restrict_sg(events, context):\r\n import boto3\r\n import json\r\n import os\r\n ec2 = boto3.resource('ec2')\r\n defaultSecGroupId = events['groupId']\r\n try:\r\n defaultSG = ec2.SecurityGroup(defaultSecGroupId)\r\n defaultIngress = defaultSG.ip_permissions\r\n defaultEgress = defaultSG.ip_permissions_egress\r\n revokeIngress = defaultSG.revoke_ingress(IpPermissions=defaultIngress)\r\n revokeEgress = defaultSG.revoke_egress(IpPermissions=defaultEgress)\r\n except Exception as e:\r\n print(e)" InputPayload: AutomationAssumeRole: '{{AutomationAssumeRole}}' groupId: '{{groupId}}' IpAddressToBlock: '{{IpAddressToBlock}}' PCIEC23Automation: Type: AWS::SSM::Document Properties: DocumentType: Automation Name: PCIEC23Automation Content: schemaVersion: '0.3' assumeRole: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" parameters: groupId: type: String AutomationAssumeRole: type: String default: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" mainSteps: - name: RemoveSecurityGroup action: 'aws:executeScript' inputs: Runtime: python3.6 Handler: script_handler Script: "def script_handler(events, context):\r\n import boto3\r\n ec2 = boto3.client('ec2')\r\n\r\n groupId = events['groupId']\r\n \r\n response = ec2.delete_security_group(\r\n GroupId= groupId\r\n )\r\n " InputPayload: AutomationAssumeRole: '{{AutomationAssumeRole}}' groupId: '{{groupId}}' PCIEC24Automation: Type: AWS::SSM::Document Properties: DocumentType: Automation Name: PCIEC24Automation Content: schemaVersion: '0.3' assumeRole: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" parameters: AutomationAssumeRole: type: String default: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" allocationId: type: String mainSteps: - name: ReleaseEIP action: 'aws:executeScript' inputs: Runtime: python3.6 Handler: script_handler Script: "def script_handler(events, context):\r\n import boto3\r\n client = boto3.client('ec2')\r\n\r\n allocationId = events['allocationId']\r\n\r\n response = client.release_address(\r\n AllocationId= allocationId\r\n )" InputPayload: AutomationAssumeRole: '{{AutomationAssumeRole}}' allocationId: '{{allocationId}}' PCIEC25Automation: Type: AWS::SSM::Document Properties: DocumentType: Automation Name: PCIEC25Automation Content: schemaVersion: '0.3' assumeRole: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" parameters: groupId: type: String IpAddressToBlock: type: String default: '0.0.0.0/0' AutomationAssumeRole: type: String default: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" mainSteps: - name: RestrictSecurityGroup action: 'aws:executeScript' inputs: Runtime: python3.6 Handler: restrict_sg Script: "def restrict_sg(events, context):\r\n import boto3\r\n import json\r\n import os\r\n ec2 = boto3.resource('ec2')\r\n defaultSecGroupId = events['groupId']\r\n try:\r\n defaultSG = ec2.SecurityGroup(defaultSecGroupId)\r\n defaultIngress = defaultSG.ip_permissions\r\n defaultEgress = defaultSG.ip_permissions_egress\r\n revokeIngress = defaultSG.revoke_ingress(IpPermissions=defaultIngress)\r\n revokeEgress = defaultSG.revoke_egress(IpPermissions=defaultEgress)\r\n except Exception as e:\r\n print(e)" InputPayload: AutomationAssumeRole: '{{AutomationAssumeRole}}' groupId: '{{groupId}}' IpAddressToBlock: '{{IpAddressToBlock}}' PCIEC26Automation: Type: AWS::SSM::Document Properties: DocumentType: Automation Name: PCIEC26Automation Content: schemaVersion: '0.3' assumeRole: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" parameters: CloudWatchLogGroupArn: type: String default: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:log-group:${FlowLogsCloudWatchLogs}" FlowLogRoleArn: type: String default: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${FlowLogsRole}" CloudWatchLogGroupName: type: String default: !Ref FlowLogsCloudWatchLogs VpcId: type: String AutomationAssumeRole: type: String default: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" mainSteps: - name: EnableFlowLogs action: 'aws:executeScript' inputs: Runtime: python3.6 Handler: enableflowlogs_handler Script: "def enableflowlogs_handler(events, context):\r\n import boto3\r\n client = boto3.client('ec2')\r\n\r\n CloudWatchLogGroupArn = events['CloudWatchLogGroupArn']\r\n FlowLogRoleArn = events['FlowLogRoleArn']\r\n CloudWatchLogGroupName = events['CloudWatchLogGroupName']\r\n VpcId = events['VpcId']\r\n AutomationAssumeRole = events['AutomationAssumeRole']\r\n\r\n response = client.create_flow_logs(\r\n DeliverLogsPermissionArn=FlowLogRoleArn,\r\n ResourceIds=[\r\n VpcId\r\n ],\r\n ResourceType='VPC',\r\n TrafficType='REJECT',\r\n LogDestinationType='cloud-watch-logs',\r\n LogDestination=CloudWatchLogGroupArn\r\n )" InputPayload: CloudWatchLogGroupName: '{{CloudWatchLogGroupName}}' CloudWatchLogGroupArn: '{{CloudWatchLogGroupArn}}' AutomationAssumeRole: '{{AutomationAssumeRole}}' FlowLogRoleArn: '{{FlowLogRoleArn}}' VpcId: '{{VpcId}}' PCIAutoScaling1Automation: Type: AWS::SSM::Document Properties: DocumentType: Automation Name: PCIAutoScaling1Automation Content: schemaVersion: '0.3' assumeRole: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" parameters: AutomationAssumeRole: type: String default: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" ASGGroupName: type: String mainSteps: - name: AutoScalingELBHealthCheck action: 'aws:executeScript' inputs: Runtime: python3.6 Handler: script_handler Script: "def script_handler(events, context):\r\n import boto3\r\n client = boto3.client('autoscaling')\r\n ASGGroupName = events['ASGGroupName']\r\n\r\n response = client.update_auto_scaling_group(\r\n AutoScalingGroupName= ASGGroupName,\r\n HealthCheckType='ELB',\r\n HealthCheckGracePeriod=300\r\n )" InputPayload: AutomationAssumeRole: '{{AutomationAssumeRole}}' ASGGroupName: '{{ASGGroupName}}' PCICodeBuild2Automation: Type: AWS::SSM::Document Properties: DocumentType: Automation Name: PCICodeBuild2Automation Content: schemaVersion: '0.3' assumeRole: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" parameters: AutomationAssumeRole: type: String default: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" projectName: type: String mainSteps: - name: CodeBuildUpdateProject action: 'aws:executeScript' inputs: Runtime: python3.6 Handler: script_handler Script: "def script_handler(events, context):\r\n import boto3\r\n client = boto3.client('codebuild')\r\n projectName = events['projectName']\r\n\r\n response = client.batch_get_projects(\r\n names=[\r\n projectName\r\n ]\r\n )\r\n \r\n projectenv = response['projects'][0]['environment']\r\n projectenv1_type = \"projectenv type: \" + projectenv['type']\r\n projectenvvars = projectenv['environmentVariables']\r\n \r\n for i in range(len(projectenvvars)):\r\n if projectenvvars[i]['name'] == 'AWS_ACCESS_KEY_ID':\r\n del (projectenvvars[i])\r\n break\r\n \r\n for i in range(len(projectenvvars)):\r\n if projectenvvars[i]['name'] == 'AWS_SECRET_ACCESS_KEY':\r\n del (projectenvvars[i])\r\n break\r\n \r\n response['projects'][0]['environment']['environmentVariables'] = projectenvvars\r\n response1 = client.update_project(name=projectName, environment=response['projects'][0]['environment'])\r\n" InputPayload: AutomationAssumeRole: '{{AutomationAssumeRole}}' projectName: '{{projectName}}' PCIRDS1Automation: Type: AWS::SSM::Document Properties: DocumentType: Automation Name: PCIRDS1Automation Content: schemaVersion: '0.3' assumeRole: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" parameters: AutomationAssumeRole: type: String default: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" snapshotId: type: String snapshotType: type: String mainSteps: - name: ModifyRDSSnapshot action: 'aws:executeScript' inputs: Runtime: python3.6 Handler: script_handler Script: "def script_handler(events, context):\r\n import boto3\r\n client = boto3.client('rds')\r\n snapshotId = events['snapshotId']\r\n snapshotType = events['snapshotType']\r\n\r\n if snapshotType == \"AwsRdsDBClusterSnapshot\":\r\n response = client.modify_db_cluster_snapshot_attribute(\r\n DBClusterSnapshotIdentifier=snapshotId,\r\n AttributeName='restore',\r\n ValuesToRemove=[\r\n 'all',\r\n ]\r\n )\r\n else:\r\n response = client.modify_db_snapshot_attribute(\r\n DBSnapshotIdentifier=snapshotId,\r\n AttributeName='restore',\r\n ValuesToRemove=[\r\n 'all',\r\n ]\r\n )\r\n" InputPayload: AutomationAssumeRole: '{{AutomationAssumeRole}}' snapshotId: '{{snapshotId}}' snapshotType: '{{snapshotType}}' PCIRedshift1Automation: Type: AWS::SSM::Document Properties: DocumentType: Automation Name: PCIRedshift1Automation Content: schemaVersion: '0.3' assumeRole: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" parameters: AutomationAssumeRole: type: String default: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" clusterId: type: String mainSteps: - name: ModifyRedshiftCluster action: 'aws:executeScript' inputs: Runtime: python3.6 Handler: script_handler Script: "def script_handler(events, context):\r\n import boto3\r\n client = boto3.client('redshift')\r\n\r\n clusterId = events['clusterId']\r\n\r\n response = client.modify_cluster(\r\n ClusterIdentifier=clusterId,\r\n PubliclyAccessible= False\r\n )" InputPayload: AutomationAssumeRole: '{{AutomationAssumeRole}}' clusterId: '{{clusterId}}' PCIRDS2Automation: Type: AWS::SSM::Document Properties: DocumentType: Automation Name: PCIRDS2Automation Content: schemaVersion: '0.3' assumeRole: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" parameters: AutomationAssumeRole: type: String default: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" dbinstanceId: type: String mainSteps: - name: ModifyRDSDBInstance action: 'aws:executeScript' inputs: Runtime: python3.6 Handler: script_handler Script: "def script_handler(events, context):\r\n import boto3\r\n client = boto3.client('rds')\r\n dbinstanceId = events['dbinstanceId']\r\n\r\n response = client.modify_db_instance(\r\n ApplyImmediately=True,\r\n DBInstanceIdentifier=dbinstanceId,\r\n PubliclyAccessible= False\r\n )" InputPayload: AutomationAssumeRole: '{{AutomationAssumeRole}}' dbinstanceId: '{{dbinstanceId}}' PCILambda1Automation: Type: AWS::SSM::Document Properties: DocumentType: Automation Name: PCILambda1Automation Content: schemaVersion: '0.3' assumeRole: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" parameters: AutomationAssumeRole: type: String default: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" accountID: type: String functionname: type: String mainSteps: - name: RestrictLambda action: 'aws:executeScript' inputs: Runtime: python3.6 Handler: script_handler Script: "def script_handler(events, context):\r\n import boto3\r\n import json\r\n \r\n client = boto3.client('lambda')\r\n functionname = events['functionname']\r\n accountID = events['accountID']\r\n response = client.get_policy(FunctionName=functionname)\r\n policy = response['Policy']\r\n policy_json = json.loads(policy)\r\n statements = policy_json['Statement']\r\n \r\n for statement in statements:\r\n Principal = str(statement['Principal']).replace(\"{'Service': '\",\"\")[:-2]\r\n Action = statement['Action']\r\n Resource = statement['Resource']\r\n StatementId = statement ['Sid']\r\n NewStatementId = \"New\" + StatementId\r\n \r\n response_old = client.remove_permission(\r\n FunctionName=functionname,\r\n StatementId=StatementId\r\n )\r\n\r\n response = client.add_permission(\r\n FunctionName=functionname,\r\n StatementId=NewStatementId,\r\n Action=Action,\r\n Principal=Principal,\r\n SourceAccount= accountID\r\n )" InputPayload: AutomationAssumeRole: '{{AutomationAssumeRole}}' accountID: '{{accountID}}' functionname: '{{functionname}}' PCILambda2Automation: Type: AWS::SSM::Document Properties: DocumentType: Automation Name: PCILambda2Automation Content: schemaVersion: '0.3' assumeRole: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" parameters: AutomationAssumeRole: type: String default: Fn::Join: - '' - - 'arn:aws:iam::' - Ref: AWS::AccountId - ':role/' - !Ref AutomationAssumeRole functionname: type: String subnet1id: type: String subnet2id: type: String securitygroupid: type: String rolearn: type: String mainSteps: - name: RestrictLambdaVPC action: 'aws:executeScript' inputs: Runtime: python3.6 Handler: script_handler Script: "def script_handler(events, context):\r\n \r\n import boto3\r\n \r\n client = boto3.client('lambda')\r\n functionname = events['functionname']\r\n rolearn = events['rolearn']\r\n subnet1id = events['subnet1id']\r\n subnet2id = events['subnet2id']\r\n securitygroupid = events['securitygroupid']\r\n\r\n\r\n subnets = [subnet1id, subnet2id]\r\n securitygroups = [securitygroupid]\r\n vpcconfig = {}\r\n vpcconfig['SubnetIds'] = subnets\r\n vpcconfig['SecurityGroupIds'] = securitygroups\r\n\r\n response = client.update_function_configuration(\r\n FunctionName=functionname,\r\n Role=rolearn,\r\n VpcConfig=vpcconfig\r\n )" InputPayload: AutomationAssumeRole: '{{AutomationAssumeRole}}' functionname: '{{functionname}}' rolearn: '{{rolearn}}' subnet1id: '{{subnet1id}}' subnet2id: '{{subnet2id}}' securitygroupid: '{{securitygroupid}}' PCIS33Automation: Type: AWS::SSM::Document Properties: DocumentType: Automation Name: PCIS33Automation Content: schemaVersion: '0.3' assumeRole: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" parameters: AutomationAssumeRole: type: String default: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${AutomationAssumeRole}" SourceBucketName: type: String DestinationBucketName: type: String S3IAMReplicationRole: type: String mainSteps: - name: S3Replication action: 'aws:executeScript' inputs: Runtime: python3.6 Handler: script_handler Script: "def script_handler(events, context):\r\n import boto3\r\n client = boto3.client('s3')\r\n\r\n SourceBucketName = events['SourceBucketName']\r\n DestinationBucketName = events['DestinationBucketName']\r\n S3IAMReplicationRole = events['S3IAMReplicationRole']\r\n \r\n DestinationBucketArn = \"arn:aws:s3:::\" + DestinationBucketName\r\n \r\n response = client.put_bucket_replication(\r\n Bucket=SourceBucketName,\r\n ReplicationConfiguration={\r\n 'Role': S3IAMReplicationRole,\r\n 'Rules': [\r\n {\r\n 'Destination': {\r\n 'Bucket': DestinationBucketArn,\r\n 'StorageClass': 'STANDARD',\r\n },\r\n 'Prefix': '',\r\n 'Status': 'Enabled',\r\n },\r\n ],\r\n },\r\n )" InputPayload: AutomationAssumeRole: '{{AutomationAssumeRole}}' SourceBucketName: '{{SourceBucketName}}' DestinationBucketName: '{{DestinationBucketName}}' S3IAMReplicationRole: '{{S3IAMReplicationRole}}'