Cloud Security: IAM Exploits on AWS — Part I

SecurityGOAT
6 min readJan 1, 2021

--

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

Oh no :(

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

Metadata Service contains compute instance’s details including the credentials of the IAM role attached to it

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

Keys to the kingdom xP

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

maintenance-role is attached to this EC2 instance

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 this 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”

Default policy version is v6

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. That’s a treat for an attacker!!

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

S3FullRead profile looks interesting!

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

Getting the region information

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

Retrieving the IAM Instance Profile Association ID for the attached instance profile

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

Replacing the instance profile associated with the EC2 instance

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

Voila! We have assumed the role for S3FullRead instance profile

Let’s see if we can list the S3 buckets now:

Command: aws s3 ls

Superb!! We can list the S3 buckets now :)

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

And we own the bucket contents!! PWNED xD

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!

--

--

SecurityGOAT
SecurityGOAT

Written by SecurityGOAT

Wannabe Hacker! Teaching Infosec in my own insightful ways :) Twitter: twitter.com/_SecurityGOAT | Support: buymeacoffee.com/SecurityGOAT

No responses yet