Abusing Roles/ClusterRoles in Kubernetes
Tutaj znajdziesz kilka potencjalnie niebezpiecznych konfiguracji ról i ClusterRoles.
Pamiętaj, że możesz uzyskać dostęp do wszystkich obsługiwanych zasobów za pomocą kubectl api-resources
Eskalacja uprawnień
Mówiąc o sztuce uzyskiwania dostępu do innego podmiotu w klastrze z innymi uprawnieniami (wewnątrz klastra Kubernetes lub do zewnętrznych chmur), w Kubernetes istnieją głównie 4 podstawowe techniki eskalacji uprawnień:
Być w stanie podawać się za inne użytkownika/grupy/SA z lepszymi uprawnieniami wewnątrz klastra Kubernetes lub do zewnętrznych chmur
Być w stanie tworzyć/aktualizować/wykonująć pody, gdzie można znaleźć lub dołączyć SA z lepszymi uprawnieniami wewnątrz klastra Kubernetes lub do zewnętrznych chmur
Być w stanie czytać sekrety, ponieważ tokeny SA są przechowywane jako sekrety
Być w stanie uciec do węzła z kontenera, gdzie można ukraść wszystkie sekrety kontenerów działających na węźle, poświadczenia węzła i uprawnienia węzła w chmurze, w której działa (jeśli istnieją)
Piąta technika, która zasługuje na uwagę, to możliwość uruchomienia port-forward w podzie, ponieważ możesz uzyskać dostęp do interesujących zasobów wewnątrz tego poda.
Dostęp do Dowolnego Zasobu lub Czasownika (Znak wieloznaczny)
Znak wieloznaczny (*) nadaje uprawnienia do dowolnego zasobu z dowolnym czasownikiem. Jest używany przez administratorów. Wewnątrz ClusterRole oznacza to, że atakujący mógłby nadużyć dowolnego namespace w klastrze
Uzyskiwanie dostępu do dowolnego zasobu za pomocą określonego czasownika
W RBAC pewne uprawnienia niosą ze sobą znaczne ryzyko:
create
: Udziela możliwości tworzenia dowolnego zasobu klastra, zwiększając ryzyko eskalacji uprawnień.list
: Pozwala na wyświetlanie wszystkich zasobów, potencjalnie ujawniając poufne dane.get
: Umożliwia dostęp do tajemnic z kont usług, stanowiąc zagrożenie dla bezpieczeństwa.
Tworzenie Pod - Kradzież Tokena
Atakujący posiadający uprawnienia do tworzenia poda, mógłby dołączyć uprzywilejowane konto usługi do poda i ukraść token, aby podszywać się pod to konto usługi. 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:
Tworzenie i Ucieczka z Podu
Poniższe wskazuje wszystkie uprawnienia, jakie może mieć kontener:
Dostęp uprzywilejowany (wyłączenie zabezpieczeń i ustawienie możliwości)
Wyłączenie przestrzeni nazw hostIPC i hostPid, które mogą pomóc w eskalacji uprawnień
Wyłączenie przestrzeni nazw hostNetwork, umożliwiające dostęp do kradzieży uprawnień chmury węzłów i lepszy dostęp do sieci
Zamontowanie hostów / wewnątrz kontenera
Utwórz pod z:
Jednozdaniowy z tego tweeta i z kilkoma dodatkami:
Teraz, gdy możesz uciec do węzła, sprawdź techniki post-eksploatacji w:
Ukrycie
Prawdopodobnie chcesz być bardziej skryty, na następnych stronach możesz zobaczyć, do czego mógłbyś uzyskać dostęp, tworząc pod tylko aktywując niektóre z wymienionych uprawnień w poprzednim szablonie:
Uprawnienia + hostPID
Tylko uprawnienia
hostPath
hostPID
hostNetwork
hostIPC
Przykłady tworzenia/misowania poprzednich konfiguracji uprzywilejowanych podów można znaleźć w https://github.com/BishopFox/badPods
Tworzenie Poda - Przenieś się do chmury
Jeśli możesz utworzyć pod (i opcjonalnie konto usługi), możesz być w stanie uzyskać uprawnienia w środowisku chmurowym, przypisując role chmurowe do poda lub konta usługi, a następnie uzyskując do niego dostęp. Co więcej, jeśli możesz utworzyć pod z przestrzenią nazw sieci hosta, możesz ukraść rolę IAM instancji węzła.
Aby uzyskać więcej informacji, sprawdź:
Pod Escape PrivilegesUtwórz/Zmień wdrożenie, Demonsety, Statefulsety, Kontrolery replikacji, Zbiory replikacji, Zadania i Zadania cykliczne
Możliwe jest nadużycie tych uprawnień do utworzenia nowego poda i uzyskania uprawnień, jak w poprzednim przykładzie.
Poniższy plik yaml tworzy demonset i wycieka token SA wewnątrz poda:
Wykonanie Poda
pods/exec
to zasób w kubernetes używany do wykonywania poleceń w powłoce wewnątrz poda. Pozwala to wykonywać polecenia wewnątrz kontenerów lub uzyskać dostęp do powłoki.
Dlatego możliwe jest wejście do poda i kradzież tokenu SA, lub wejście do uprzywilejowanego poda, ucieczka do węzła i kradzież wszystkich tokenów podów w węźle oraz (wy)korzystanie węzła:
port-forward
To uprawnienie pozwala na przekierowanie jednego lokalnego portu do jednego portu w określonym podzie. Ma to ułatwić debugowanie aplikacji działających wewnątrz poda, ale atakujący może nadużyć go, aby uzyskać dostęp do interesujących (jak bazy danych) lub podatnych aplikacji (strony internetowe?) wewnątrz poda:
Hosts Writable /var/log/ Escape
Zgodnie z tym badaniem, jeśli masz dostęp lub możesz utworzyć pod z zamontowanym katalogiem /var/log/
hostów, możesz uciec z kontenera.
Dzieje się tak, ponieważ gdy Kube-API próbuje pobrać logi kontenera (używając kubectl logs <pod>
), żąda pliku 0.log
poda za pomocą punktu końcowego /logs/
usługi Kubelet.
Usługa Kubelet eksponuje punkt końcowy /logs/
, który w zasadzie eksponuje system plików /var/log
kontenera.
Dlatego atakujący mający dostęp do zapisu w katalogu /var/log/ kontenera mógłby nadużyć tych zachowań na 2 sposoby:
Modyfikując plik
0.log
swojego kontenera (zazwyczaj znajdujący się w/var/logs/pods/namespace_pod_uid/container/0.log
) tak, aby był symlinkiem wskazującym na/etc/shadow
na przykład. Następnie będziesz mógł wydobyć plik shadow hostów wykonując:
Jeśli atakujący kontroluje jakiegokolwiek podmiot z uprawnieniami do odczytu
nodes/log
, może po prostu utworzyć symlink w/host-mounted/var/log/sym
do/
i podczas dostępu dohttps://<gateway>:10250/logs/sym/
wyświetli system plików główny hosta (zmiana symlinka może umożliwić dostęp do plików).
Laboratorium i zautomatyzowany exploit można znaleźć pod adresem https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts
Ominięcie ochrony readOnly
Jeśli masz szczęście i bardzo uprzywilejowana zdolność CAP_SYS_ADMIN
jest dostępna, możesz po prostu ponownie zamontować folder jako rw:
Ominięcie ochrony hostPath readOnly
Jak stwierdzono w tej analizie, możliwe jest ominięcie ochrony:
Który miał zapobiec ucieczkom takim jak poprzednie, zamiast używać montowania hostPath, używa PersistentVolume i PersistentVolumeClaim do zamontowania folderu hostów w kontenerze z dostępem do zapisu:
Podszywanie się pod uprzywilejowane konta
Z uprawnieniami podszycia się pod użytkownika, atakujący może podszyć się pod uprzywilejowane konto.
Wystarczy użyć parametru --as=<nazwa_użytkownika>
w poleceniu kubectl
, aby podszyć się pod użytkownika, lub --as-group=<grupa>
aby podszyć się pod grupę:
Albo użyj interfejsu REST API:
Wyświetlanie sekretów
Uprawnienie do wyświetlania sekretów może umożliwić atakującemu faktyczne odczytanie sekretów poprzez dostęp do punktu końcowego interfejsu API REST:
Odczytywanie tajemnicy – próba zgadywania identyfikatorów tokenów
Podczas gdy atakujący posiadający token z uprawnieniami do odczytu wymaga dokładnej nazwy tajemnicy, aby go użyć, w przeciwieństwie do szerszego uprawnienia listowania tajemnic, istnieją nadal podatności. Domyślne konta usług w systemie mogą być wyliczone, każde związane z tajemnicą. Te tajemnice mają strukturę nazwy: statyczny prefiks, a następnie losowy pięciocyfrowy alfanumeryczny token (z wyłączeniem pewnych znaków) zgodnie z kodem źródłowym.
Token jest generowany z ograniczonego zestawu 27 znaków (bcdfghjklmnpqrstvwxz2456789
), zamiast pełnego zakresu alfanumerycznego. To ograniczenie zmniejsza łączną liczbę możliwych kombinacji do 14 348 907 (27^5). W rezultacie atakujący mógłby wykonać atak brute-force w celu wydedukowania tokenu w ciągu kilku godzin, co potencjalnie prowadziłoby do eskalacji uprawnień poprzez uzyskanie dostępu do poufnych kont usług.
Wnioski o podpisywaniu certyfikatów
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 wniosków, więc w tym przypadku nie potrzebujesz dodatkowych uprawnień. W przeciwnym razie musiałbyś móc zatwierdzić wniosek, co oznacza aktualizację w certificatesigningrequests/approval
i approve
w signers
z resourceName <signerNameDomain>/<signerNamePath>
lub <signerNameDomain>/*
Przykład roli z wszystkimi wymaganymi uprawnieniami to:
Więc, po zatwierdzeniu nowego CSR węzła, możesz nadużyć specjalnych uprawnień węzłów, aby ukraść sekrety i eskalować uprawnienia.
W tym poście i tym konfiguracja GKE K8s TLS Bootstrap jest skonfigurowana z automatycznym podpisywaniem i jest nadużywana do generowania poświadczeń nowego węzła K8s, a następnie nadużywana 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.
Sposób obejścia tego polega po prostu na utworzeniu poświadczeń węzła dla nazwy węzła, na którym zamontowany jest kontener z interesującymi sekretami (ale sprawdź, jak to zrobić w pierwszym poście):
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.
Potrzebne są czasowniki update
i patch
, lub create
jeśli configmapa nie została jeszcze utworzona:
Możesz użyć aws-auth
dla trwałości umożliwiając dostęp użytkownikom z innych kont.
Jednak aws --profile other_account eks update-kubeconfig --name <cluster-name>
nie działa z innego konta. Ale faktycznie 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.
Aby kubectl
działał, upewnij się, że skonfigurowano kubeconfig ofiary i w argumentach exec aws dodaj --profile other_account_role
, aby kubectl używał profilu innego konta do uzyskania tokena i kontaktowania się z AWS.
Eskalacja w GKE
Istnieją 2 sposoby przypisywania uprawnień K8s do podmiotów GCP. W każdym przypadku podmiot musi również mieć uprawnienie container.clusters.get
, aby móc zbierać poświadczenia dostępu do klastra, lub będziesz musiał wygenerować własny plik konfiguracyjny kubectl (postępuj zgodnie z następnym odnośnikiem).
Podczas rozmowy z punktem końcowym interfejsu API K8s, zostanie wysłany token uwierzytelniający GCP. Następnie GCP, poprzez punkt końcowy interfejsu API K8s, najpierw sprawdzi, czy podmiot (za pomocą adresu e-mail) ma jakikolwiek dostęp wewnątrz klastra, a następnie sprawdzi, czy ma jakikolwiek dostęp za pośrednictwem GCP IAM. Jeśli którekolwiek z nich jest prawdziwe, zostanie udzielona odpowiedź. Jeśli nie, zostanie podana informacja o błędzie, sugerująca udzielenie uprawnień za pośrednictwem GCP IAM.
Następnie, pierwsza metoda polega na użyciu GCP IAM, uprawnienia K8s mają swoje odpowiednie uprawnienia GCP IAM, i jeśli podmiot je posiada, będzie mógł ich użyć.
GCP - Container PrivescDrugi sposób polega na przypisaniu uprawnień K8s wewnątrz klastra do identyfikacji użytkownika za pomocą jego adresu e-mail (w tym konta usług GCP).
Utwórz tokeny kont usługowych
Podmioty, które mogą tworzyć żądania tokenów (serviceaccounts/token
) Podczas rozmowy z punktem końcowym interfejsu API K8s SAs (informacje z tutaj).
ephemeralcontainers
Podmioty, które mogą aktualizować
lub poprawiać
pods/ephemeralcontainers
mogą uzyskać wykonanie kodu na innych podach, a potencjalnie wydostać się do ich węzła, dodając kontener tymczasowy z uprzywilejowanym securityContext
ValidatingWebhookConfigurations lub MutatingWebhookConfigurations
Podmioty z dowolnymi czasownikami 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.
Eskalacja
Jak można przeczytać w następnej sekcji: Zapobieganie wbudowanej eskalacji uprawnień, podmiot nie może aktualizować ani tworzyć ról ani clusterroles bez posiadania tych nowych uprawnień. O ile nie ma czasownika escalate
nad roles
lub clusterroles
.
Wtedy może aktualizować/tworzyć nowe role, clusterroles z lepszymi uprawnieniami niż te, które posiada.
Proxy węzłów
Podmioty mające dostęp do podzasobu nodes/proxy
mogą wykonywać kod na podach za pośrednictwem interfejsu API Kubelet (zgodnie z tym). Więcej informacji na temat uwierzytelniania Kubelet znajdziesz na tej stronie:
Masz przykład, jak uzyskać RCE rozmawiając z autoryzowanym interfejsem API Kubelet tutaj.
Usuwanie podów + węzły nieskalowalne
Podmioty, które mogą usuwać podsy (delete
czasownik nad zasobem pods
), lub wymuszać usunięcie podów (create
czasownik nad zasobem pods/eviction
), lub zmieniać status poda (dostęp do pods/status
) i mogą sprawić, że inne węzły staną się nieskalowalne (dostęp do nodes/status
) lub usuwać węzły (delete
czasownik nad zasobem nodes
) i mają kontrolę nad podem, mogą ukraść pody z innych węzłów, aby były wykonywane w skompromitowanym węźle, a atakujący może ukraść tokeny z tych podów.
Status usług (CVE-2020-8554)
Podmioty, które mogą modyfikować services/status
, mogą ustawić pole status.loadBalancer.ingress.ip
w celu wykorzystania niezałatanej luki CVE-2020-8554 i uruchomienia ataków MiTM na klaster. Większość zabezpieczeń przed CVE-2020-8554 zapobiega tylko usługom ExternalIP (zgodnie z tym).
Status węzłów i modułów
Podmioty posiadające uprawnienia update
lub patch
do nodes/status
lub pods/status
mogą modyfikować etykiety w celu wpływania na narzucone ograniczenia planowania.
Wbudowane zapobieganie eskalacji uprawnień
Kubernetes posiada wbudowany mechanizm zapobiegający eskalacji uprawnień.
Ten system zapewnia, że użytkownicy nie mogą podnosić swoich uprawnień poprzez modyfikowanie ról lub powiązań ról. Egzekwowanie tej reguły odbywa się na poziomie interfejsu API, zapewniając zabezpieczenie nawet wtedy, gdy autoryzator RBAC jest nieaktywny.
Reguła ta określa, że użytkownik może tworzyć lub aktualizować rolę tylko wtedy, gdy posiada wszystkie uprawnienia, z których składa się rola. Ponadto zakres istniejących uprawnień użytkownika musi być zgodny z rolą, którą próbuje utworzyć lub zmodyfikować: albo ogólnoklastrowy dla ClusterRoles, albo ograniczony do tej samej przestrzeni nazw (lub ogólnoklastrowy) dla Roles.
Istnieje wyjątek od poprzedniej reguły. Jeśli podmiot ma czasownik escalate
nad roles
lub clusterroles
, może zwiększyć uprawnienia ról i clusterroles nawet bez posiadania odpowiednich uprawnień.
Pobierz i zmodyfikuj RoleBindings/ClusterRoleBindings
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 poprzednim rozdziale. Nie możesz tworzyć/modyfikować rolebindingów, aby nadać sobie lub innemu SA pewne uprawnienia, jeśli ich nie masz.
Uprawnienie do tworzenia Rolebindings pozwala użytkownikowi powiązać role 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.
Inne ataki
Aplikacja proxy Sidecar
Domyślnie nie ma szyfrowania w komunikacji między modułami. Autoryzacja wzajemna, dwukierunkowa, moduł do modułu.
Utwórz aplikację proxy Sidecar
Utwórz swój plik .yaml
Edytuj swój plik .yaml i dodaj odkomentowane linie:
Zobacz logi proxy:
Więcej informacji pod adresem: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
Złośliwy kontroler przyjęć
Kontroler przyjęć przechwytuje żądania do serwera API Kubernetesa przed trwałością obiektu, ale po uwierzytelnieniu i autoryzacji żądania.
Jeśli atakujący w jakiś sposób zdoła wstrzyknąć kontroler przyjęć mutacji, będzie mógł modyfikować już uwierzytelnione żądania. Pozwala to potencjalnie na eskalację uprawnień oraz zazwyczaj na trwałe pozostanie w klastrze.
Przykład z https://blog.rewanthtammana.com/creating-malicious-admission-controllers:
Sprawdź status, aby zobaczyć, czy jest gotowy:
![](https://cloud.hacktricks.xyz/~gitbook/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1628433436353%2FyHUvUWugR.png%3Fauto%3Dcompress%2Cformat%26format%3Dwebp&width=768&dpr=4&quality=100&sign=fe4bc7c0&sv=1)
Następnie wdroż nową kapsułkę:
Kiedy widzisz błąd ErrImagePull
, sprawdź nazwę obrazu za pomocą jednego z poniższych zapytań:
![](https://cloud.hacktricks.xyz/~gitbook/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1628433512073%2FleFXtgSzm.png%3Fauto%3Dcompress%2Cformat%26format%3Dwebp&width=768&dpr=4&quality=100&sign=45a94e54&sv=1)
Jak widać na powyższym obrazie, próbowaliśmy uruchomić obraz nginx
, ale ostatecznie uruchomiony został obraz rewanthtammana/malicious-image
. Co właśnie się stało!!?
Techniczności
Nadużycie ról i ClusterRoles w Kubernetes
Powyższy fragment zastępuje pierwszy obraz kontenera we wszystkich podach przez rewanthtammana/malicious-image
.
Ominięcie OPA Gatekeeper
Kubernetes - OPA Gatekeeper bypassNajlepsze praktyki
Wyłączenie automatycznego montowania tokenów konta usługi
Pody i konta usług: 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 zaczynając od wersji Kubernetes 1.6.
Ograniczenie przypisania użytkownika w RoleBindings/ClusterRoleBindings
Wybiórcze uwzględnianie: Upewnij się, że do RoleBindings lub ClusterRoleBindings są uwzględnieni tylko niezbędni użytkownicy. Regularnie przeprowadzaj audyty i usuwaj nieistotnych użytkowników, aby utrzymać wysokie bezpieczeństwo.
Role specyficzne dla przestrzeni nazw zamiast roli na poziomie klastra
Role vs. ClusterRoles: Preferuj użycie Roli i RoleBindings do nadawania uprawnień specyficznych dla przestrzeni nazw, zamiast ClusterRoles i ClusterRoleBindings, które mają zastosowanie do całego klastra. Ten podejście oferuje bardziej precyzyjną kontrolę i ogranicza zakres uprawnień.
Użyj narzędzi automatyzujących
Referencje
Last updated