Abusing Roles/ClusterRoles in Kubernetes
Тут ви можете знайти деякі потенційно небезпечні конфігурації ролей та кластерів.
Пам'ятайте, що ви можете отримати всі підтримувані ресурси за допомогою kubectl api-resources
Ескалація привілеїв
Це мистецтво отримання доступу до іншого принципала в кластері з іншими привілеями (в межах кластера kubernetes або до зовнішніх хмар), ніж ті, які ви вже маєте. У Kubernetes є в основному 4 основні техніки для ескалації привілеїв:
Можливість вдаватись в інших користувачів/групи/SA з кращими привілеями в межах кластера kubernetes або до зовнішніх хмар
Можливість створювати/покращувати/виконувати поди, де ви можете знайти або приєднати SA з кращими привілеями в межах кластера kubernetes або до зовнішніх хмар
Можливість читати секрети, оскільки токени SA зберігаються як секрети
Можливість втекти на вузол з контейнера, де ви можете вкрасти всі секрети контейнерів, що працюють на вузлі, облікові дані вузла та дозволи вузла в межах хмари, в якій він працює (якщо такі є)
П'ята техніка, яка заслуговує на згадку, - це можливість запускати port-forward в поді, оскільки ви можете отримати доступ до цікавих ресурсів у цьому поді.
Доступ до будь-якого ресурсу або дієслова (Wildcard)
Джокер (*) надає дозвіл на будь-який ресурс з будь-яким дієсловом. Його використовують адміністратори. Усередині ClusterRole це означає, що зловмисник може зловживати будь-яким простором імен у кластері.
Доступ до будь-якого ресурсу з певним дієсловом
У RBAC певні дозволи становлять значні ризики:
create
: Надає можливість створювати будь-який кластерний ресурс, що ризикує ескалацією привілеїв.list
: Дозволяє перераховувати всі ресурси, потенційно витікаючи чутливі дані.get
: Дозволяє доступ до секретів з облікових записів служб, що становить загрозу безпеці.
Pod Create - Steal Token
Атакуючий, який має дозволи на створення пода, може прикріпити привілейований обліковий запис служби до пода та вкрасти токен для підробки облікового запису служби. Фактично підвищуючи привілеї до нього.
Приклад пода, який вкраде токен облікового запису служби bootstrap-signer
і надішле його атакуючому:
Pod Create & Escape
Наступне вказує на всі привілеї, які може мати контейнер:
Привілейований доступ (вимкнення захистів і налаштування можливостей)
Вимкнення простору імен hostIPC та hostPid, що може допомогти підвищити привілеї
Вимкнення простору імен hostNetwork, що надає доступ для крадіжки привілеїв вузлів у хмарі та кращого доступу до мереж
Монтування хостів / всередині контейнера
Створіть под з:
Однорядковий код з цього твітту та з деякими доповненнями:
Тепер, коли ви можете втекти до вузла, перевірте техніки пост-експлуатації в:
Стелс
Ви, напевно, хочете бути менш помітними, на наступних сторінках ви можете побачити, до чого ви зможете отримати доступ, якщо створите под, активувавши лише деякі з вказаних привілеїв у попередньому шаблоні:
Привілейований + hostPID
Тільки привілейований
hostPath
hostPID
hostNetwork
hostIPC
Ви можете знайти приклад того, як створити/зловживати попередніми конфігураціями привілейованих подів у https://github.com/BishopFox/badPods
Створення пода - Перехід до хмари
Якщо ви можете створити под (і, за бажанням, обліковий запис служби), ви можете отримати привілеї в хмарному середовищі, призначивши хмарні ролі поду або обліковому запису служби і потім отримавши до нього доступ. Більше того, якщо ви можете створити под з простором імен мережі хоста, ви можете вкрасти IAM роль вузла екземпляра.
Для отримання додаткової інформації перегляньте:
Створення/оновлення розгортання, демонсетів, станів, контролерів реплікацій, реплікаційних наборів, завдань та крон-завдань
Можливо зловживати цими дозволами, щоб створити новий под і отримати привілеї, як у попередньому прикладі.
Наступний yaml створює демонсет і ексфільтрує токен SA всередині пода:
Pods Exec
pods/exec
- це ресурс у kubernetes, який використовується для виконання команд у оболонці всередині пода. Це дозволяє виконувати команди всередині контейнерів або отримати оболонку всередині.
Отже, можливо потрапити всередину пода і вкрасти токен SA, або зайти в привілейований под, втекти на вузол і вкрасти всі токени подів на вузлі та (зловживати) вузлом:
port-forward
Ця дозволяє перенаправити один локальний порт на один порт у вказаному поді. Це призначено для того, щоб легко налагоджувати програми, що працюють всередині пода, але зловмисник може зловживати цим, щоб отримати доступ до цікавих (наприклад, БД) або вразливих програм (веб?) всередині пода:
Hosts Writable /var/log/ Escape
Як вказано в цьому дослідженні, якщо ви можете отримати доступ або створити под з підключеним каталогом /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
наприклад. Тоді ви зможете ексфільтрувати файл тіней хостів, виконавши:
Якщо зловмисник контролює будь-який принципал з дозволами на читання
nodes/log
, він може просто створити symlink у/host-mounted/var/log/sym
на/
, і коли він отримує доступ доhttps://<gateway>:10250/logs/sym/
, він отримає список кореневої файлової системи хоста (зміна symlink може надати доступ до файлів).
Лабораторія та автоматизований експлойт можна знайти за адресою https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts
Обхід захисту readOnly
Якщо вам пощастить, і високо привілейована можливість CAP_SYS_ADMIN
доступна, ви можете просто змонтувати папку з правами на запис:
Обхід захисту hostPath readOnly
Як зазначено в цьому дослідженні, можливо обійти захист:
Який мав на меті запобігти втечам, подібним до попередніх, шляхом використання не hostPath монту, а PersistentVolume та PersistentVolumeClaim для монтування папки хоста в контейнер з правами на запис:
Імітація привілейованих облікових записів
З привілеєм імітації користувача зловмисник може імітувати привілейований обліковий запис.
Просто використовуйте параметр --as=<username>
в команді kubectl
, щоб імітувати користувача, або --as-group=<group>
, щоб імітувати групу:
Або використовуйте REST API:
Listing Secrets
Дозвіл на перегляд секретів може дозволити зловмиснику фактично прочитати секрети, отримуючи доступ до REST API кінцевої точки:
Читання секрету – брутфорсинг ID токенів
Хоча зловмисник, що має токен з правами на читання, потребує точну назву секрету для його використання, на відміну від ширшого привілею переліку секретів, все ще існують вразливості. За замовчуванням облікові записи служб у системі можуть бути перераховані, кожен з яких асоційований з секретом. Ці секрети мають структуру назви: статичний префікс, за яким слідує випадковий п'ятисимвольний алфавітно-цифровий токен (за винятком певних символів) відповідно до джерела коду.
Токен генерується з обмеженого набору з 27 символів (bcdfghjklmnpqrstvwxz2456789
), а не з повного алфавітно-цифрового діапазону. Це обмеження зменшує загальну кількість можливих комбінацій до 14,348,907 (27^5). Відповідно, зловмисник може здійснити брутфорс-атаку, щоб вивести токен за кілька годин, що потенційно призведе до ескалації привілеїв шляхом доступу до чутливих облікових записів служб.
Запити на підписання сертифікатів
Якщо у вас є дієслова create
в ресурсі certificatesigningrequests
(або принаймні в certificatesigningrequests/nodeClient
). Ви можете створити новий CeSR для нового вузла.
Згідно з документацією, можливо автоматично схвалити ці запити, тому в цьому випадку вам не потрібні додаткові дозволи. Якщо ні, вам потрібно буде мати можливість схвалити запит, що означає оновлення в certificatesigningrequests/approval
та approve
в signers
з resourceName <signerNameDomain>/<signerNamePath>
або <signerNameDomain>/*
Приклад ролі з усіма необхідними дозволами:
Отже, з новим затвердженим CSR вузла, ви можете зловживати спеціальними дозволами вузлів, щоб вкрасти секрети та підвищити привілеї.
У цьому пості та цьому конфігурація GKE K8s TLS Bootstrap налаштована з автоматичним підписанням, і це зловживається для генерації облікових даних нового вузла K8s, а потім ці облікові дані зловживаються для підвищення привілеїв шляхом крадіжки секретів. Якщо ви маєте згадані привілеї, ви могли б зробити те ж саме. Зверніть увагу, що перший приклад обминає помилку, яка заважає новому вузлу отримувати доступ до секретів всередині контейнерів, оскільки вузол може отримувати доступ лише до секретів контейнерів, змонтованих на ньому.
Спосіб обійти це - просто створити облікові дані вузла для імені вузла, де змонтовано контейнер з цікавими секретами (але просто перевірте, як це зробити в першому пості):
AWS EKS aws-auth configmaps
Принципали, які можуть змінювати configmaps
в просторі імен kube-system на кластерах EKS (потрібно бути в AWS), можуть отримати привілеї адміністратора кластера, перезаписуючи aws-auth configmap.
Необхідні дії - це update
та patch
, або create
, якщо configmap не був створений:
Ви можете використовувати 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.
Ескалація в GKE
Є 2 способи призначити K8s дозволи для GCP принципів. У будь-якому випадку принцип також потребує дозволу container.clusters.get
, щоб мати можливість отримати облікові дані для доступу до кластера, або вам потрібно буде згенерувати свій власний файл конфігурації kubectl (перейдіть за наступним посиланням).
Коли ви спілкуєтеся з кінцевою точкою API K8s, токен автентифікації GCP буде надіслано. Потім GCP, через кінцеву точку API K8s, спочатку перевірить, чи має принцип (за електронною поштою) доступ всередині кластера, потім перевірить, чи має він будь-який доступ через GCP IAM. Якщо будь-який з цих пунктів істинний, він отримає відповідь. Якщо ні, буде надана помилка, що пропонує надати дозволи через GCP IAM.
Отже, перший метод - це використання GCP IAM, дозволи K8s мають свої еквівалентні дозволи GCP IAM, і якщо принцип має їх, він зможе їх використовувати.
Другий метод - це призначення дозволів K8s всередині кластера шляхом ідентифікації користувача за його електронною поштою (включаючи облікові записи служб GCP).
Створення токена serviceaccounts
Принципи, які можуть створювати TokenRequests (serviceaccounts/token
) при спілкуванні з кінцевою точкою API K8s SAs (інформація з тут).
ephemeralcontainers
Принципи, які можуть оновлювати
або патчити
pods/ephemeralcontainers
, можуть отримати виконання коду на інших подах, і потенційно вийти на свій вузол, додавши епhemeral контейнер з привілейованим securityContext.
ValidatingWebhookConfigurations або MutatingWebhookConfigurations
Принципи з будь-якими з дієслів create
, update
або patch
над validatingwebhookconfigurations
або mutatingwebhookconfigurations
можуть бути здатні створити одну з таких webhookconfigurations, щоб мати можливість ескалації привілеїв.
Для прикладу mutatingwebhookconfigurations
перегляньте цей розділ цього посту.
Ескалація
Як ви можете прочитати в наступному розділі: Вбудоване запобігання ескалації привілеїв, принцип не може оновлювати або створювати ролі чи кластерні ролі, не маючи самих цих нових дозволів. За винятком випадків, коли він має дієслово escalate
над roles
або clusterroles
.
Тоді він може оновлювати/створювати нові ролі, кластерні ролі з кращими дозволами, ніж ті, що у нього є.
Проксі вузлів
Принципи з доступом до підресурсу nodes/proxy
можуть виконувати код на подах через API Kubelet (згідно з цим). Більше інформації про автентифікацію Kubelet на цій сторінці:
У вас є приклад того, як отримати RCE, спілкуючись з авторизованим Kubelet API тут.
Видалення подів + незаплановані вузли
Принципи, які можуть видаляти поди (delete
дієслово над pods
ресурсом), або виселяти поди (create
дієслово над pods/eviction
ресурсом), або змінювати статус пода (доступ до pods/status
) і можуть зробити інші вузли незапланованими (доступ до nodes/status
) або видаляти вузли (delete
дієслово над nodes
ресурсом) і мають контроль над подом, можуть вкрасти поди з інших вузлів, щоб вони були виконані на компрометованому вузлі, і зловмисник може вкрасти токени з цих подів.
Стан служб (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 неактивний.
Правило stipulates, що користувач може створювати або оновлювати роль лише якщо він має всі дозволи, які містить роль. Більше того, обсяг існуючих дозволів користувача повинен відповідати обсягу ролі, яку він намагається створити або модифікувати: або на рівні кластера для ClusterRoles, або обмежений тим же простором імен (або на рівні кластера) для Roles.
Існує виняток з попереднього правила. Якщо принципал має дію escalate
над roles
або clusterroles
, він може підвищити привілеї ролей і кластерних ролей, навіть не маючи самих дозволів.
Отримати та модифікувати RoleBindings/ClusterRoleBindings
Очевидно, ця техніка працювала раніше, але згідно з моїми тестами, вона більше не працює з тієї ж причини, що й у попередньому розділі. Ви не можете створити/модифікувати прив'язку ролі, щоб надати собі або іншому SA якісь привілеї, якщо у вас їх вже немає.
Привілей створювати Rolebindings дозволяє користувачу прив'язувати ролі до облікового запису служби. Цей привілей може потенційно призвести до ескалації привілеїв, оскільки дозволяє користувачу прив'язувати адміністративні привілеї до скомпрометованого облікового запису служби.
Інші атаки
Додаток проксі-сайду
За замовчуванням у комунікації між подами немає жодного шифрування. Взаємна аутентифікація, двостороння, под до пода.
Створити додаток проксі-сайду
Створіть свій .yaml
Редагуйте свій .yaml і додайте розкоментовані рядки:
Перегляньте журнали проксі:
Більше інформації за адресою: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
Зловмисний Admission Controller
Admission controller перехоплює запити до API сервера Kubernetes перед збереженням об'єкта, але після того, як запит аутентифіковано та авторизовано.
Якщо зловмиснику вдасться впровадити Mutationg Admission Controller, він зможе модифікувати вже аутентифіковані запити. Це може дозволити потенційно підвищити привілеї, а зазвичай і зберігатися в кластері.
Приклад з https://blog.rewanthtammana.com/creating-malicious-admission-controllers:
Перевірте статус, щоб дізнатися, чи готовий він:
Тоді розгорніть новий под:
Коли ви бачите помилку ErrImagePull
, перевірте назву зображення за допомогою одного з запитів:
Як ви можете бачити на зображенні вище, ми намагалися запустити образ nginx
, але в кінцевому підсумку виконаний образ - rewanthtammana/malicious-image
. Що тільки що сталося!!?
Технічні деталі
Скрипт ./deploy.sh
встановлює контролер доступу з мутацією вебхука, який модифікує запити до API Kubernetes відповідно до його конфігураційних рядків, впливаючи на спостережувані результати:
Вищенаведений фрагмент замінює перше зображення контейнера в кожному поді на rewanthtammana/malicious-image
.
OPA Gatekeeper обхід
Найкращі практики
Вимкнення автоматичного монтування токенів облікових записів служби
Поди та облікові записи служби: За замовчуванням, поди монтують токен облікового запису служби. Для підвищення безпеки Kubernetes дозволяє вимкнути цю функцію автоматичного монтування.
Як застосувати: Встановіть
automountServiceAccountToken: false
у конфігурації облікових записів служби або подів, починаючи з версії Kubernetes 1.6.
Обмежене призначення користувачів у RoleBindings/ClusterRoleBindings
Селективне включення: Переконайтеся, що лише необхідні користувачі включені в RoleBindings або ClusterRoleBindings. Регулярно перевіряйте та видаляйте нерелевантних користувачів для підтримки високої безпеки.
Ролі, специфічні для простору імен, замість ролей на рівні кластера
Ролі проти ClusterRoles: Віддавайте перевагу використанню Roles і RoleBindings для дозволів, специфічних для простору імен, замість ClusterRoles і ClusterRoleBindings, які застосовуються на рівні кластера. Цей підхід забезпечує більш точний контроль і обмежує обсяг дозволів.
Використовуйте автоматизовані інструменти
Посилання
Last updated