CIS AWS Benchmark Script

Recently (2-29-2016) the Center for Internet Security (CIS) came out with security benchmarks for Amazon Web Services (AWS) Foundations. I created a shell script that basically glues together all of the CIS tests so gathering the data for analysis can be easy. I condensed several of the tests, and fixed some errors that I encountered. This was tested on my own AMI (RHEL 7). There is obviously a lot of room for improvement, however, this is much better than typing commands again and again.

The script needs to be run from a server with AWS CLI  installed (http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html).

#Usage
#
#./AWS_CIS_Script_v_1_0.sh > AWS_Output.txt
#
printf "####################DATA-GATHERING######################"
echo -e "\n\nGathering Data on Instances...\n"
aws ec2 describe-instances

echo -e "\n\nGathering Data on Alarms...\n"
aws cloudwatch describe-alarms

echo -e "\n\nGenerating an IAM Credential Report...\n"
aws iam generate-credential-report

printf "#############IDENTITY AND ACCESS MANAGEMENT#############"
echo -e "\n\nCIS 1.1: Avoid the use of the 'root' account...NIST Control(s): AC-2, AC-6\n"
aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,5,11,16 | grep -B1 '<root_account>'

echo -e "\n\nCIS 1.2: Ensure multi-factor authentication (MFA) is enabled for all IAM users that have a console password...NIST Control(s): IA-2\n"
aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,4,8

echo -e "\n\nCIS 1.3: Ensure credentials unused for 90 days or greater are disabled...NIST Control(s): AC-2(3)\n"
aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,4,9,11,14,16

echo -e "\n\nCIS 1.4: Ensure access keys are rotated every 90 days or less...NIST Control(s): SC-12\n" 
aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,9,10,11,14,15,16

echo -e "\n\nCIS 1.5-1.11: Ensure IAM password policy meets organizational standards...NIST Control(s): IA-5, IA-5(1)\n"
aws iam get-account-password-policy

echo -e "\n\nCIS 1.12: Ensure no root account access key exists...NIST Control(s): AC-6"
aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,9,14 | grep -B1 '<root_account>'

echo -e "\n\nCIS 1.13: Ensure hardware MFA is enabled for the 'root' account...NIST Control(s): IA-2, IA-2(1), IA-2(8), IA-5(11), CM-6"
aws iam get-account-summary | grep "AccountMFAEnabled"

#CIS 1.14 is not scored...

echo -e "\n\nCIS 1.15: Ensure IAM policies are attached only to groups or roles...NIST Control(s): AC-2(7), AC-3, AC-6\n"
for i in $(aws iam list-users --query 'Users[*].UserName' --output text); do echo $i && aws iam list-attached-user-policies --user-name $i & aws iam list-user-policies --user-name $i; done

printf "#######################LOGGING########################"
echo -e "\n\nCIS 2.1-2.2: Ensure CloudTrail is enabled in all regions and log file validation is enabled...NIST Control(s) AU-2, AU-3, AU-6, AU-12\n"
aws cloudtrail describe-trails | grep '"Name"\|IsMultiRegionTrail\|LogFileValidationEnabled'

echo -e "\n\nCIS 2.3: Ensure the S3 bucket CloudTrail logs to is not publicly accessible...NIST Control(s) AU-9\n"
for i in $(aws cloudtrail describe-trails --query 'trailList[*].S3BucketName' | awk -F "\"" '{print $2}'); do aws s3api get-bucket-acl --bucket $i --query 'Grants[?Grantee.URI==`http://acs.amazonaws.com/groups/global/AllUsers`]' && echo "" && aws s3api get-bucket-acl --bucket $i --query 'Grants[?Grantee.URI==`http://acs.amazonaws.com/groups/global/Authenticated Users`]' && echo "" && aws s3api get-bucket-policy --bucket $i; done 

echo -e "\n\nCIS 2.4: Ensure CloudTrail trails are integrated with CloudWatch Logs...NIST Control(s):\n"
for i in $(aws cloudtrail describe-trails | grep \"Name\": | awk -F "\"" '{ print $4}'); do aws cloudtrail get-trail-status --name $i; done

#CIS 2.5 is a manual check...It can probably be scripted but the config service is not free so I didn't experiment...

echo -e "\n\nCIS 2.6: Ensure S3 bucket access logging is enabled on the CloudTrail S3 bucket...NIST Control(s): AU2, AU-6\n"
for i in $(aws cloudtrail describe-trails --query 'trailList[*].S3BucketName' | awk -F "\"" '{print $2}'); do aws s3api get-bucket-logging --bucket $i; done

echo -e "\n\nCIS 2.7: Ensure CloudTrail logs are encrypted at rest using KMS CMKs...NIST Control(s): AU-9\n"
aws cloudtrail describe-trails | grep '"Name"\|KmsKeyId'

echo -e "\n\nCIS 2.8: Ensure rotation for customer created CMKs is enabled...NIST Control(s): \n"
for i in $(aws kms list-keys | grep KeyId | awk -F "\"" '{print $4}'); do aws kms get-key-rotation-status --key-id $i; done

printf "######################MONITORING#######################"
echo -e "\n\nCIS 3.1-3.15: Ensure log metric filters and alarms exist...NIST Control(s):\n"
for i in $(aws cloudtrail describe-trails | grep CloudWatchLogsLogGroupArn | awk -F ":" '{print $8}'); do aws logs describe-metric-filters --log-group-name $i | grep '"metricName"\|filterPattern'; done
for i in $(aws cloudwatch describe-alarms | grep arn | awk -F "\"" '{print $2}' | grep arn); do aws sns list-subscriptions-by-topic --topic-arn $i; done

#CIS 3.16 is not scored...

printf "######################NETWORKING#######################"
echo -e "\n\nCIS 4.1,4.2,and 4.4: Ensure no security groups allow ingress from 0.0.0.0/0 to port 22 or 3389, and the default security group restricts all traffic...NIST Control(s):\n"
aws ec2 describe-security-groups

echo -e "\n\nCIS 4.3: Ensure VPC Flow Logging is Enabled in all Applicable Regions...NIST Control(s):\n"
aws ec2 describe-flow-logs

Creative Commons License
This work CIS AWS Benchmark Script, is a derivative of CIS Amazon Web Services Foundations v.1.0.0 – 02-29-2016 by The Center for Internet Security, used under https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode. CIS AWS Benchmark Script is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License, by Jake Miller.

Leave a Reply

Your email address will not be published. Required fields are marked *