This guide will walk you through the process of testing for common security issues that may expose an AWS account to unwanted risks
We are going to compare two existing S3 buckets:
List the first bucket:
aws s3api get-public-access-block --bucket nsrc-noc --query 'PublicAccessBlockConfiguration'
Now list the second bucket:
aws s3api get-public-access-block --bucket nsrc-temp --query 'PublicAccessBlockConfiguration'
Do you notice any difference?
Let’s see what happens when an S3 bucket is publicly accessible
aws s3 ls s3://nsrc-temp
Is there a file in the bucket?
Now let’s see if we can see the content of the file via a browser. Open the following URL in your browser:
https://nsrc-temp.s3-ap-southeast-1.amazonaws.com/index.html
Any surprises?
Let’s see why we can see the content of that file without any authentication. Run this command:
aws s3api get-bucket-policy --bucket nsrc-temp --query "Policy" --output text| jq
Note: if you have not installed the utility ‘jq’ just run:
aws s3api get-bucket-policy --bucket nsrc-temp --query "Policy" --output text
What did we learn in regards to publicly accessible S3 buckets? How would you monitor your AWS account to verify doesn’t have publicly accessible buckets?
Note:
There is a way to provide temporary access to files in an AWS bucket without an AWS account. It is done using “pre-signed” URLs. It allows the person or application in possession of URL to access a file for a limited time.
Here is a link to the AWS dcoumentation if interested:
https://docs.aws.amazon.com/AmazonS3/latest/userguide/ShareObjectPreSignedURL.html
List all IAM users
aws iam list-usersList MFA devices for a given user
aws iam list-mfa-devices --user-name <user>If we combine the above commands it makes it a bit easier to run through all users in the environment and spot those not protected by MFA
users=""
users=$(aws iam list-users --query "Users[*].UserName" --output text)
for user in $users
do
mfa=$(aws iam list-mfa-devices --user-name "$user" --query "MFADevices[].SerialNumber" --output text)
echo "User: $user MFA: $mfa"
doneIAM policies may grant excessive privileges. The definition of “excessive” is specific to each organization. However being aware of the risk and having the ability to list such permissions allow cloud administrators to verify.
List all user-defined policies
aws iam list-policies --scope Local --query "Policies[*].[PolicyName,Arn]"
The output will show the user-defined policy names and their resource locator (ARN). We will need the policy ARN to show the permissions tied to the policy
aws iam get-policy-version --policy-arn arn:aws:iam::058264411872:policy/BillingCostCategoriesReadWriteGroup --version-id v1 --query "PolicyVersion.Document" --output json
What permissions do you observe? (Try to guess what they do)
Now let’s take a look at the next policy:
aws iam get-policy-version --policy-arn arn:aws:iam::058264411872:policy/service-role/s3crr_for_nsrc-noc_80e96a --version-id v1 --query "PolicyVersion.Document" --output json
Hint: we will use this policy in future exercises this week to do S3 buckets backups :)
Rationale: In AWS EC2 service, security groups act like a firewall. Remember when you created your EC2 instance? You had to create a security group for your EC2 server to run into. The security group rules define what protocols and ports are reachable for incoming and outgoing traffic. Typically, unless your application requires very restrictive outgoing traffic, you allow all traffic out (a.k.a. “egress”)
First, let’s list all security groups
aws ec2 describe-security-groups --query "SecurityGroups[*].{GroupName:GroupName,GroupId:GroupId}"Now let’s determine if any security group allows open access (0.0.0.0/0) That means we are letting access from everywhere to the security group. We will get more granular information as we progress
First let’s see if we have any group with open access
aws ec2 describe-security-groups --query "SecurityGroups[?IpPermissions[?contains(IpRanges[].CidrIp, '0.0.0.0/0') ]].GroupId"
What are we doing here? We are taking advantage of the AWS CLI ability to search using “query” statements. We are basically saying: “Please show me the GroupId of any security group which has an IpPermission (rule) allowing traffic from every where (0.0.0.0/0)”
Do you see any group in the output?
Now let’s pick one of the groups in our list, and inspect which ports are exposed, and the level of exposure
Replace
aws ec2 describe-security-groups --query "SecurityGroups[?GroupId=='<SG_GROUP>'].{GroupId:GroupId,Inbound:IpPermissions[*]}"
Can you describe the output in terms of which ports are open to what traffic?
Feel free to inspect more security groups, you can list all the existing groups with:
aws ec2 describe-security-groups --query "SecurityGroups[].GroupId"
Generate credentials report A credentials report is a “batch” job, meaning a report is generated in the background, and as the report becomes available one can collect information on user activity and extract useful information. If a report has not been generated in the last 4 hours, AWS generates an updated one. Otherwise it uses the one currently available.
aws iam generate-credential-report
if no report available:
{
"State": "STARTED",
"Description": "No report exists. Starting a new report generation task"
}
Otherwise:
{
"State": "COMPLETE"
}Now let’s review what information is available
aws iam get-credential-report --query "Content" --output text | base64 --decode
This will generate a comma-delimited file that details credentials activity per user. You could save the report to a CSV file for further processing like this:
aws iam get-credential-report --query "Content" --output text | base64 --decode > report.csv
You could open the file in a spreadsheet processing application. If you look at the first line (the headers) describe the meaning of each column. If we use a Linux command that parses text files we can show some details (the command name is “awk” )
Let’s show when users were created:
cat report.csv | awk -F, '{print $1" "$3}'
When were the user passwords last used, and last changed?
cat report.csv | awk -F, '{print $1" "$5" "$6}'
Bonus: Who can show us the MFA status for all users?
There are several other recommended settings to improve the security posture of your AWS installation. For example:
To complete the exercise, let’s put together a shell script using the AWS CLI to help us automate some of the security checks we played with during the lab
Copy the content of the security script in the lab
Edit file (copy/paste content)
nano aws_security_check.shMake the shell script executable
chmod u+x aws_security_check.sh
Lets run the script, be patient! It takes a while:
./aws_security_check.sh