Abusing Roles/ClusterRoles in Kubernetes
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Tutaj możesz znaleźć potencjalnie niebezpieczne konfiguracje Roles i ClusterRoles.
Pamiętaj, że możesz uzyskać wszystkie obsługiwane zasoby za pomocą kubectl api-resources
Odnosząc się do sztuki uzyskiwania dostępu do innego podmiotu w klastrze z innymi uprawnieniami (w obrębie klastra kubernetes lub do zewnętrznych chmur) niż te, które już posiadasz, w Kubernetes istnieją zasadniczo 4 główne techniki podwyższania uprawnień:
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/aktualizowania/uruchamiania podów, w których 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ść 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 obrębie tego poda.
Wildcard (*) 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ć dowolnej przestrzeni nazw w klastrze.
W RBAC niektóre uprawnienia niosą ze sobą istotne ryzyko:
create
: Przyznaje możliwość tworzenia dowolnego zasobu klastra, co stwarza ryzyko eskalacji uprawnień.
list
: Umożliwia wylistowanie wszystkich zasobów, co może prowadzić do wycieku wrażliwych danych.
get
: Zezwala na dostęp do sekretów z kont serwisowych, co stanowi zagrożenie dla bezpieczeństwa.
Atakujący z uprawnieniami do tworzenia poda, mógłby 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 serwisowego bootstrap-signer
i wyśle go do atakującego:
Poniżej przedstawiono wszystkie uprawnienia, jakie może mieć kontener:
Dostęp uprzywilejony (wyłączanie zabezpieczeń i ustawianie możliwości)
Wyłączenie przestrzeni nazw hostIPC i hostPid, co może pomóc w eskalacji uprawnień
Wyłączenie przestrzeni nazw hostNetwork, co daje dostęp do kradzieży uprawnień chmurowych węzłów i lepszego dostępu do sieci
Zamontowanie hostów / wewnątrz kontenera
Utwórz pod za pomocą:
Jednolinijkowiec z tego tweeta oraz z dodatkami:
Teraz, gdy możesz uciec do węzła, sprawdź techniki po eksploatacji w:
Prawdopodobnie chcesz być bardziej dyskretny, na następnych stronach możesz zobaczyć, do czego będziesz miał dostęp, jeśli stworzysz pod, włączając tylko niektóre z wymienionych uprawnień w poprzednim szablonie:
Privileged + hostPID
Privileged only
hostPath
hostPID
hostNetwork
hostIPC
Możesz znaleźć przykład, jak stworzyć/wykorzystać poprzednie konfiguracje podów z uprawnieniami w https://github.com/BishopFox/badPods
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. 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ź:
Pod Escape PrivilegesMożliwe jest nadużycie tych uprawnień do stworzenia nowego poda i uzyskania uprawnień, jak w poprzednim przykładzie.
Poniższy yaml tworzy daemonset i eksfiltruje token SA wewnątrz poda:
pods/exec
to zasób w kubernetes używany do uruchamiania poleceń w powłoce wewnątrz poda. Umożliwia to uruchamianie poleceń wewnątrz kontenerów lub uzyskanie powłoki wewnątrz.
Dlatego możliwe jest dostanie się do poda i kradzież tokena SA, lub wejście do uprzywilejowanego poda, ucieczka do węzła i kradzież wszystkich tokenów podów w węźle oraz (nadużycie) węzła:
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?) wewnątrz poda:
Jak wskazano w tych badaniach, jeśli możesz uzyskać dostęp lub stworzyć pod z zamontowanym katalogiem /var/log/
hosta, możesz uciec z kontenera.
Dzieje się tak głównie dlatego, że gdy Kube-API próbuje uzyskać logi kontenera (używając kubectl logs <pod>
), żąda pliku 0.log
podu, korzystając z 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:
Modyfikując plik 0.log
swojego kontenera (zwykle znajdujący się w /var/logs/pods/namespace_pod_uid/container/0.log
), aby był symlinkiem wskazującym na /etc/shadow
na przykład. Wtedy będziesz mógł wyeksfiltrować plik shadow hosta, wykonując:
Jeśli atakujący kontroluje jakikolwiek podmiot z uprawnieniami do odczytu nodes/log
, może po prostu utworzyć symlink w /host-mounted/var/log/sym
do /
i podczas dostępu do https://<gateway>:10250/logs/sym/
wyświetli system plików root hosta (zmiana symlinka może zapewnić dostęp do plików).
Laboratorium i zautomatyzowany exploit można znaleźć w https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts
Jeśli masz szczęście i wysoko uprzywilejowana zdolność CAP_SYS_ADMIN
jest dostępna, możesz po prostu ponownie zamontować folder jako rw:
Jak stwierdzono w tych badaniach, możliwe jest obejście ochrony:
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:
Dzięki uprawnieniu podszywania się pod użytkownika, atakujący może podszywać 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ę:
Lub użyj REST API:
Uprawnienie do wyświetlania sekretów może pozwolić atakującemu na rzeczywiste odczytanie sekretów uzyskując dostęp do punktu końcowego REST API:
Podczas gdy atakujący w posiadaniu tokena z uprawnieniami do odczytu wymaga dokładnej nazwy sekretu, aby go użyć, w przeciwieństwie do szerszego przywileju wyświetlania sekretów, nadal istnieją luki. Domyślne konta serwisowe w systemie mogą być enumerowane, z których każde jest powiązane 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.
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 do eskalacji uprawnień poprzez uzyskanie dostępu do wrażliwych kont serwisowych.
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ń, 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 <signerNameDomain>/<signerNamePath>
lub <signerNameDomain>/*
Przykład roli z wszystkimi wymaganymi uprawnieniami to:
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ń.
W tym poście i tym 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.
Sposobem na obejście tego jest po prostu utworzenie 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):
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:
Możesz użyć aws-auth
do utrzymania dostępu dla użytkowników z innych kont.
Jednakże, aws --profile other_account eks update-kubeconfig --name <cluster-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.
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).
Rozmawiając z punktem końcowym API K8s, token autoryzacji 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. 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 GCP IAM, a jeśli zasada je ma, będzie mogła z nich korzystać.
GCP - Container PrivescDruga metoda to przypisanie uprawnień K8s wewnątrz klastra poprzez identyfikację użytkownika po jego e-mailu (w tym konta serwisowe GCP).
Zasady, które mogą tworzyć TokenRequests (serviceaccounts/token
) podczas rozmowy z punktem końcowym API K8s SAs (informacje z tutaj).
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 ephemer container z uprzywilejowanym securityContext.
Zasady z jakimikolwiek 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.
Jak można przeczytać w następnej sekcji: Wbudowana zapobieganie eskalacji uprawnień, 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.
Zasady z dostępem do nodes/proxy
subresource mogą wykonywać kod na podach za pośrednictwem API Kubelet (zgodnie z tym). Więcej informacji na temat autoryzacji Kubelet na tej stronie:
Masz przykład, jak uzyskać RCE rozmawiając autoryzowanym z API Kubelet tutaj.
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ą sprawić, że inne węzły będą nieschedulowalne (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.
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).
Podmioty z uprawnieniami update
lub patch
do nodes/status
lub pods/status
mogą modyfikować etykiety, aby wpłynąć na wymuszone ograniczenia harmonogramowania.
Kubernetes ma wbudowany mechanizm 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 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 Roles.
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ń.
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 nadać 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.
Domyślnie nie ma żadnego szyfrowania w komunikacji między podami. Wzajemna autoryzacja, dwukierunkowa, pod do pod.
Utwórz swój .yaml
Edytuj swój plik .yaml i dodaj odkomentowane linie:
Zobacz logi proxy:
Więcej informacji na: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
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 zazwyczaj także utrzymania się w klastrze.
Przykład z https://blog.rewanthtammana.com/creating-malicious-admission-controllers:
Sprawdź status, aby zobaczyć, czy jest gotowy:
Następnie wdroż nowy pod:
Kiedy widzisz błąd ErrImagePull
, sprawdź nazwę obrazu za pomocą jednej z poniższych zapytań:
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!!?
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:
The above snippet replaces the first container image in every pod with rewanthtammana/malicious-image
.
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 konta usługi lub podów, począwszy od wersji Kubernetes 1.6.
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.
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ń.
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)