strix/skills/cloud/aws.md
AWS misconfigurations frequently expose credentials, data, and lateral movement paths. This skill covers direct AWS API testing and post-compromise enumeration from EC2/Lambda/container workloads. For SSRF-mediated metadata access, combine with the ssrf skill.
Identity
Storage & Data
Compute
169.254.169.254Network
Management
Credential Discovery
AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN~/.aws/credentials, ~/.aws/config, CI/CD env vars, .env filesUnauthenticated Enumeration
Use two separate checks — they answer different questions and must not be conflated:
1. Bucket existence (does the name resolve?)
Goal: learn whether a bucket name exists in AWS, without needing s3:ListBucket.
head-bucket or curl -I HTTP status is the signal — not aws s3 ls.403 Forbidden → bucket exists but you lack access (private or wrong account).404 Not Found → bucket does not exist in that region, or name is wrong.aws s3api head-bucket --bucket target-bucket --no-sign-request 2>&1
curl -I https://target-bucket.s3.amazonaws.com/
2. Public listing (is ListBucket granted to anonymous users?)
Goal: confirm s3:ListBucket is publicly granted — a separate and stronger finding than existence alone.
aws s3 ls for this step; a successful listing returns object keys/prefixes.aws s3 ls s3://target-bucket --no-sign-request
Authenticated Enumeration (with any credentials)
aws sts get-caller-identity
aws iam get-account-authorization-details 2>/dev/null
aws iam list-users
aws iam list-roles
aws iam list-attached-user-policies --user-name <user>
aws s3 ls
aws ec2 describe-instances
public-read, policy "Principal":"*")http://acs.amazonaws.com/groups/global/AuthenticatedUsers)backup/, db/, .env, config/, logs/Test:
aws s3 ls s3://BUCKET --no-sign-request
aws s3 cp s3://BUCKET/sensitive-file . --no-sign-request
curl https://BUCKET.s3.amazonaws.com/
Common escalation paths (verify with aws iam simulate-principal-policy when possible):
| Permission | Escalation |
|---|---|
iam:CreatePolicyVersion | Attach admin policy version to self |
iam:SetDefaultPolicyVersion | Roll back to older permissive policy version |
iam:PassRole + lambda:CreateFunction | Create Lambda with admin role, invoke |
iam:PassRole + ec2:RunInstances | Launch EC2 with instance profile |
sts:AssumeRole on overprivileged role | Cross-account or same-account pivot |
iam:UpdateAssumeRolePolicy | Add self to trust policy of privileged role |
iam:AttachUserPolicy / PutUserPolicy | Self-grant admin |
Test:
aws iam list-attached-user-policies --user-name $(aws sts get-caller-identity --query Arn --output text | cut -d/ -f2)
aws iam simulate-principal-policy --policy-source-arn <arn> --action-names iam:CreateAccessKey --resource-arns "*"
IMDSv1 (no token required)
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/<role-name>
curl http://169.254.169.254/latest/user-data
IMDSv2 bypass contexts
X-aws-ec2-metadata-tokenaws ec2 describe-snapshots --restorable-by-user-names allPublic launch permission containing secrets or keysAdministratorAccess on Lambda role)lambda:GetFunctionConfiguration)custom:role, custom:admin)Principal: * or overly broad accounts/ with GetParameter for unauthenticated or low-priv callersCross-Account Role Assumption
* or external accounts broadlyCloudFront Origin Exposure
Resource-Based Policy Gaps
s3:GetObject from unintended principalsPrincipal: * with weak condition keysget-caller-identity, map effective permissionss3:ListBucket on empty marketing bucketget-caller-identity first to know your effective principalPrefer credential-light, install-once CLIs. The sandbox has awscli/python/pipx/go and build-time egress.
aws sts get-caller-identity.git clone https://github.com/andresriancho/enumerate-iam && cd enumerate-iam
pip install -r requirements.txt
python enumerate-iam.py --access-key AKIA... --secret-key ...
pipx install cloudsplaining
aws iam get-account-authorization-details > auth.json
cloudsplaining scan --input-file auth.json
cloudfox aws --profile <profile> all-checksiam__privesc_scan module automates the escalation table above. Use for a full exploitation session (run iam__enum_permissions, then run iam__privesc_scan).AWS security requires least-privilege IAM, blocked public data paths, IMDSv2 with hop limits, and tight resource policies. Enumerate from any credential found — even limited read access often reveals escalation chains.