AWS Security Reference.
IAM modeling, cross-account boundaries, and the highest-leverage misconfigurations to look for first on AWS.
IAM — model and traps
- Policy evaluation logic. Explicit Deny > Org SCP > Resource policy > Identity policy > Permissions boundary. A single explicit Deny anywhere kills the action. Default = implicit deny.
- The five overly-broad patterns.
"Action":"*","Resource":"*","Principal":"*","Condition":{}empty,"Effect":"Allow"at root. Any combination of two = high-impact finding. - iam:PassRole misuse. Principal can pass a role to a service that they themselves can't assume.
iam:PassRoleon*= path to any service role. - Confused deputy. Trusted third-party (Lambda, GitHub OIDC) can be tricked into using your role on attacker's behalf. Defense:
aws:SourceArn+aws:SourceAccountconditions on trust policies. - Wildcard in resource ARN.
arn:aws:s3:::data-*matches future buckets nameddata-attacker— register the bucket name, gain implicit access.
Cross-account boundaries
- Trust-relationship discovery. Walk every role's
AssumeRolePolicyDocumentforPrincipal: {"AWS": "arn:aws:iam::OTHER_ACCOUNT:root"}entries. Every such entry is an external-account access vector. - AssumeRole chain. AWS supports role-chaining (assume role A, then use A to assume B). Each hop drops one hour from max session duration.
aws sts decode-authorization-messagefor chain-failure debug. - SCP at OU boundary. SCPs apply to all accounts in the OU but only restrict identity-based and resource-based policies — they don't grant. A child account loses access if parent SCP denies.
- Org-wide blast radius. Single overly-trusting role in a management account = entire org compromise via Organizations API.
Highest-leverage misconfigs — triage sequence
- Public S3 buckets.
aws s3api list-buckets, thenaws s3api get-bucket-acl+get-bucket-policyon each. Block Public Access settings at account level should be ON. - Stale IAM users with access keys.
aws iam list-users+list-access-keys+get-access-key-last-used. Keys unused for >90 days = revoke immediately. - EC2 instance metadata v1 still allowed.
aws ec2 describe-instances+ checkHttpTokens.optional= SSRF can grab role creds. Forcerequired. - RDS snapshots public.
aws rds describe-db-snapshots --include-public. Public snapshot = entire database leaked to anyone in AWS. - Lambda function URLs with auth NONE.
aws lambda list-function-url-configs.AuthType: NONE= unauthenticated invoke. - Sigv4 unsigned services. Any API Gateway or Lambda URL exposed without auth.
- KMS key policy too permissive.
"Principal":"*"on a KMS key = anyone in your org (or, with cross-account allow, anywhere) can decrypt with it. - CloudTrail not multi-region or not enabled.
aws cloudtrail describe-trails. Single-region trail = blind to other regions.
Post-compromise pivots on AWS
- EC2 instance-profile cred theft. SSRF → IMDS →
/latest/meta-data/iam/security-credentials/<role>→ temporary creds. - Lambda env var leak. Many Lambdas store secrets in env vars.
aws lambda get-function-configuration --function-name X. - Secrets Manager scan.
aws secretsmanager list-secrets --max-results 100, thenget-secret-valueper secret your role can read. - SSM Parameter Store. Same pattern.
aws ssm describe-parameters+get-parameters --names X.
Rule of thumbDon't enumerate by walking every API. Run
pacu or cloudfox first — both do the recon in minutes and produce a triage list. Manual API walking is for confirming the specific finding, not for discovery.From reference to evidence