7.8 KiB
name, description
| name | description |
|---|---|
| gcp | GCP cloud security testing covering IAM misconfigurations, public storage buckets, metadata abuse, and service account privilege escalation |
Google Cloud Platform (GCP)
GCP misconfigurations expose project data, service account keys, and lateral movement paths across Compute, Cloud Storage, Cloud Functions, and GKE. This skill covers direct GCP API testing and post-compromise enumeration from VMs/containers. For SSRF-mediated metadata access, combine with the ssrf skill.
Attack Surface
Identity
- IAM policies: project/folder/org level bindings
- Service accounts, keys (JSON), Workload Identity, impersonation
- OAuth scopes on compute instances and Cloud Functions
Storage & Data
- Cloud Storage (GCS) buckets and objects
- BigQuery datasets, Cloud SQL instances, Firestore (see
firebase_firestoreskill) - Secret Manager, Cloud KMS keys
Compute
- Compute Engine VMs, Cloud Run, Cloud Functions, GKE clusters
- Metadata server at
http://metadata.google.internal/computeMetadata/v1/ - Startup scripts, instance templates, custom images
Management
- Cloud Console, gcloud CLI, Deployment Manager, Terraform state buckets
- Cloud Logging, Error Reporting, Cloud Build triggers
Reconnaissance
Credential Discovery
- Service account JSON keys in repos, CI/CD,
.env, backup buckets GOOGLE_APPLICATION_CREDENTIALSenvironment variable- Default Compute Engine service account on VMs (often overprivileged)
- OAuth tokens in browser/local
gcloudconfig (~/.config/gcloud/)
Unauthenticated Enumeration
Avoid gsutil for anonymous checks — it can use ambient gcloud or application-default credentials and produce false public-bucket findings. Unset GOOGLE_APPLICATION_CREDENTIALS and use unauthenticated HTTP instead.
# GCS bucket existence (403 = exists but private, 404 = not found/wrong region)
curl -I https://storage.googleapis.com/target-bucket/
# Anonymous listing (no Authorization header; confirms allUsers/allAuthenticatedUsers List)
curl https://storage.googleapis.com/target-bucket/
# Alternate URL forms
curl -I https://target-bucket.storage.googleapis.com/
Authenticated Enumeration
gcloud auth list
gcloud config get-value project
gcloud projects get-iam-policy PROJECT_ID
gcloud iam service-accounts list
gcloud storage ls
gcloud compute instances list
gcloud container clusters list
Key Vulnerabilities
Cloud Storage Misconfigurations
- Public buckets:
allUsersorallAuthenticatedUserswithroles/storage.objectViewerorobjectAdmin - Listable buckets revealing object keys: backups,
.env,terraform.tfstate, SA keys - Uniform bucket-level access disabled with legacy ACL public-read
- Signed URL with excessive TTL or overly broad object prefix
Test:
gsutil iam get gs://BUCKET # requires credentials
curl https://storage.googleapis.com/BUCKET/ # anonymous listing check
curl -I https://storage.googleapis.com/BUCKET/sensitive.sql
IAM Privilege Escalation
Common escalation paths (verify with gcloud iam / policy simulator):
| Permission | Escalation |
|---|---|
iam.serviceAccounts.actAs + compute.instances.create |
VM with privileged SA |
iam.serviceAccountKeys.create |
Export key for higher-priv SA |
iam.serviceAccounts.setIamPolicy |
Grant yourself roles on SA |
cloudfunctions.functions.create + actAs |
Deploy function as privileged SA |
run.services.create (Cloud Run) + actAs |
Deploy service with admin SA |
storage.buckets.update + setIamPolicy |
Open bucket to public or self |
Test:
gcloud projects get-iam-policy PROJECT --flatten="bindings[].members" --filter="bindings.members:user:YOU"
gcloud iam roles list --project=PROJECT
Metadata Server Abuse
From any code execution on a GCP VM, Cloud Run (if metadata accessible), or compromised pod:
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/instance/service-accounts/default/email
- Default compute SA may have
editorrole on project (legacy projects) - Requested OAuth scopes may allow
cloud-platformfull access - Workload Identity misconfiguration in GKE → cross-namespace SA token theft
GKE Misconfigurations
- Dashboard/UI exposed, anonymous RBAC (see
kubernetesskill for K8s layer) - Workload Identity not enforced; pods use node SA with broad GCP permissions
kubectlproxy orkubeletread-only port exposed- Secrets in ConfigMaps; GCR/Artifact Registry images pulling without auth
Cloud Functions / Cloud Run
- HTTP-triggered functions without authentication (
--allow-unauthenticated) - Environment variables containing API keys (
gcloud functions describe) - Overprivileged runtime service account (
roles/editor) - Event triggers accepting attacker-controlled Pub/Sub messages
BigQuery & Cloud SQL
- Public datasets (
allUserson dataset IAM) - Cloud SQL public IP with weak/no password
- Exported snapshots in public GCS buckets
Secret Manager & KMS
secretmanager.versions.accessgranted to unintended principals- Secrets replicated to logs via misconfigured Cloud Functions env vars
- KMS cryptoKey IAM with
allAuthenticatedUsers
Advanced Techniques
Terraform State in GCS
terraform.tfstatein listable bucket → all resource addresses, sometimes secrets in plain text
Service Account Impersonation Chain
roles/iam.serviceAccountTokenCreatoron target SA → short-lived access tokens
Org/Fold Policy Gaps
- Project-level deny policies not applied; child project inherits permissive folder IAM
Testing Methodology
- Discover credentials — Keys in code, metadata, SSRF, public buckets
- Identify principal —
gcloud auth list, effective project IAM - Enumerate storage — Public/listable buckets, sensitive object names
- Escalation paths — Map
actAs, key creation, function deploy permissions - Metadata — From any shell in GCP workload, fetch SA token and scopes
- GKE layer — Pivot from GCP IAM to cluster (combine with
kubernetesskill)
Validation
- Demonstrate unauthorized GCS object read/list with bucket URL and object key
- Show IAM escalation path with exact role/member binding and resulting access
- Prove metadata token theft from compute context with redacted token scope
- Document project ID, resource name, and IAM binding root cause
- Confirm fix blocks the specific principal/permission/resource combination
False Positives
- Intentionally public static asset bucket with no sensitive objects
- Metadata server unreachable from tested context (no RCE/SSRF)
- SA token from metadata has only
devstorage.read_onlyon single bucket (note scope, not full breach) 403on bucket HEAD indicating existence but not readable content
Impact
- Mass data exfiltration from GCS/BigQuery/Cloud SQL backups
- Project or org compromise via SA key theft or IAM escalation
- Lateral movement from GKE pod to cloud control plane
- Regulatory exposure (PII in public buckets or exports)
Pro Tips
- Always check both
gsutil iam getand anonymouscurl— IAM and ACL layers differ - Search public buckets for
*.jsonservice account keys andterraform.tfstate - Default compute SA email:
PROJECT_NUMBER-compute@developer.gserviceaccount.com - Combine with
kubernetesskill when target runs on GKE - Firebase-hosted apps often use GCP project underneath — pivot from web to GCP project ID in configs
Summary
GCP security requires least-privilege IAM, no public data paths, tight metadata/scopes on compute, and protected service account keys. Enumerate from any credential or shell — even read-only GCS access often reveals escalation artifacts.