Escalate (squ1rrel CTF 2025)

The objective of this challenge was to escalate privileges within an AWS environment and gain access to the s3 buckets. For guidance, I referred to AWS IAM Privilege Escalation GitHub repository by RhinoSecurityLabsarrow-up-right, specifically:

2. Setting the default policy version to an existing version Description: An attacker with the iam:SetDefaultPolicyVersion permission may be able to escalate privileges through existing policy versions that are not currently in use. If a policy that they have access to has versions that are not the default, they would be able to change the default version to any other existing version. Required Permission(s): iam:SetDefaultPolicyVersion

In this challenge, I leveraged this technique to switch to a more permissive version of UserPolicy.


Step‑1: Analyze the Environment

List IAM Roles

I enumerated the roles in the account:

aws iam list-roles

Key Roles Identified:

  • AWSServiceRoleForOrganizations

  • AWSServiceRoleForSSO

  • AWSServiceRoleForSupport

  • AWSServiceRoleForTrustedAdvisor

  • MagicRole

  • OrganizationAccountAccessRole

I reviewed the details of MagicRole (a likely pivot point) using:

Output:

But inspecting other roles also and trying to assume them did not work

List S3 Buckets

Trying to see if we are directly allowed to access s3 buckets:

Output:

List and Inspect IAM Policies

I listed the local policies to understand the permissions available:

Output:

The two policies of interest were UserPolicy and MagicPolicy.

UserPolicy Permissions

I inspected UserPolicy (default version v2):

Output (v2):

Then, I reviewed the inactive version v1:

Output (v1):

Analysis: The key difference is that v1 includes the iam:PassRole permission, which is critical for passing roles to Lambda functions.

MagicPolicy Permissions

I also reviewed MagicPolicy:

Output:

The policy explicitly grants the s3:ListBucket action on the bucket identified by the ARN:arn:aws:s3:::squ1rrel-ctf-flags. This indicates that we somehow need to access this bucket.


Step‑2: Escalation via Default Policy Version Change

Given the presence of multiple policy versions and with the iam:SetDefaultPolicyVersion permission at our disposal, I applied the technique from the RhinoSecurityLabs article:

2. Setting the default policy version to an existing version If a policy that they have access to has versions that are not the default, they can change the default version to any other existing version.

I switched UserPolicy to version v1:

This action activated v1, granting me the iam:PassRole permission that was missing in the default version (v2).


Step‑3: Leverage Lambda Permissions

Check for Existing Lambda Functions

Before creating a new function, I checked if any Lambda functions already existed, as my permissions included various Lambda actions:

Output:

Since no pre-existing functions were found, I proceeded to create one.

Create and Deploy a Lambda Function

  1. Prepare Lambda Code: I created a file named lambda_function.py with the following content:

  2. Package the Function: Then zip lambda_function.py into a ZIP file called function.zip

  3. Create the Lambda Function Using MagicRole: With the new iam:PassRole permission, I created the function:

    Output:


Step‑4: Invoke and Troubleshoot the Lambda Function

I invoked the Lambda function:

Output:

A output.json file was created and while viewing its contents:

Flag: squ1rrel{dont_you_love_aws}

Last updated