Abusing Roles/ClusterRoles in Kubernetes
Тут ви можете знайти деякі потенційно небезпечні конфігурації Ролей та Кластерних Ролей.
Пам'ятайте, що ви можете отримати всі підтримувані ресурси за допомогою kubectl api-resources
Підвищення привілеїв
Називаючи це мистецтвом отримання доступу до іншого принципала в межах кластера з іншими привілеями (в межах кластера Kubernetes або до зовнішніх хмар), в Kubernetes існує в основному 4 основні техніки підвищення привілеїв:
Мати можливість імперсонувати інших користувачів/групи/СА з кращими привілеями в межах кластера Kubernetes або до зовнішніх хмар
Мати можливість створювати/змінювати/виконувати pods, де ви можете знайти або приєднати СА з кращими привілеями в межах кластера Kubernetes або до зовнішніх хмар
Мати можливість читати секрети, оскільки токени СА зберігаються як секрети
Мати можливість вибратися на вузол з контейнера, де ви можете вкрасти всі секрети контейнерів, що працюють на вузлі, облікові дані вузла та дозволи вузла в межах хмари, в якій він працює (якщо такі є)
П'ята техніка, яка заслуговує на згадку, - це можливість запустити port-forward в pod, оскільки ви можете мати доступ до цікавих ресурсів в цьому pod.
Доступ до будь-якого ресурсу або дії (Зірочка)
Зірочка (*) надає дозвіл на будь-який ресурс з будь-якою дією. Використовується адміністраторами. У межах ClusterRole це означає, що зловмисник може зловживати будь-яким простором імен в кластері.
Доступ до будь-якого ресурсу з певним дієсловом
У RBAC деякі дозволи становлять значний ризик:
create
: Надає можливість створювати будь-який кластерний ресурс, загрожуючи підвищенню привілеїв.list
: Дозволяє перелічувати всі ресурси, потенційно розголошуючи чутливі дані.get
: Дозволяє отримувати доступ до секретів від облікових записів служб, створюючи загрозу безпеці.
Створення Пода - Крадіжка Токену
Атакувальник з дозволами на створення пода може додати привілейований обліковий запис служби в под та вкрасти токен для імітації облікового запису служби. Ефективно підвищуючи привілеї до нього
Приклад пода, який вкраде токен облікового запису служби bootstrap-signer
та надішле його атакувальнику:
Створення та втеча з Pod
Наступне вказує всі привілеї, які може мати контейнер:
Привілейований доступ (вимкнення захисту та встановлення можливостей)
Вимкнення просторів імен hostIPC та hostPid, що може допомогти ескалації привілеїв
Вимкнення простору імен hostNetwork, що дає доступ до викрадення привілеїв хмарних вузлів та кращий доступ до мереж
Підключення /etc/hosts з хостів всередину контейнера
Створіть pod з:
Однорядковий коментар з цього твіту з деякими додатками:
Тепер, коли ви можете втекти до вузла, перевірте техніки пост-експлуатації в:
Прихованість
Ймовірно, вам захочеться бути прихованішим, на наступних сторінках ви можете побачити, до чого ви зможете отримати доступ, якщо створите капсулу, увімкнувши лише деякі з вказаних привілеїв у попередньому шаблоні:
Привілеї + hostPID
Лише привілеї
hostPath
hostPID
hostNetwork
hostIPC
Ви можете знайти приклад того, як створити/зловживати попередніми конфігураціями привілеїв капсул в https://github.com/BishopFox/badPods
Створення капсули - Перехід до хмари
Якщо ви можете створити капсулу (і, за бажанням, обліковий запис служби), ви, можливо, зможете отримати привілеї в хмарному середовищі, призначивши хмарні ролі капсулі або обліковому запису служби, а потім отримати до них доступ. Більше інформації дивіться:
pagePod Escape PrivilegesСтворення/Зміна розгортання, демонів, наборів стану, контролерів реплікації, наборів реплік, завдань та регулярних завдань
Можливо використовувати ці дозволи для створення нової капсули та отримання привілеїв, як у попередньому прикладі.
Наступний yaml створює демон-набір та виводить токен облікового запису служби всередині капсули:
Виконання команд у контейнері
pods/exec
- це ресурс в Kubernetes, який використовується для виконання команд у оболонці всередині контейнера. Це дозволяє виконувати команди всередині контейнерів або отримувати оболонку всередині.
Отже, можливо потрапити всередину контейнера та вкрасти токен SA, або потрапити в привілейований контейнер, вибратися на вузол та вкрасти всі токени контейнерів на вузлі та (зловживати) вузлом:
port-forward
Ця дозвіл дозволяє перенаправити один локальний порт на один порт у вказаному котейнері. Це призначено для можливості легко відлагоджувати додатки, що працюють всередині котейнера, але зловмисник може використати це для доступу до цікавих (наприклад, БД) або вразливих додатків (веб?) всередині котейнера:
Запис у хостах /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
наприклад. Потім ви зможете витягти файл тіні хостів, виконавши:
Якщо зловмисник контролює будь-якого принципала з дозволами на читання
nodes/log
, він може просто створити символічне посилання в/host-mounted/var/log/sym
на/
і коли звертається доhttps://<gateway>:10250/logs/sym/
, він перегляне кореневу файлову систему хоста (зміна символічного посилання може надати доступ до файлів).
Лабораторія та автоматизований експлойт можна знайти за посиланням https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts
Обхід захисту від запису
Якщо ви маєте щастя і високопривілейована можливість CAP_SYS_ADMIN
доступна, ви можете просто повторно монтувати папку як rw:
Обхід захисту hostPath readOnly
Як зазначено в цьому дослідженні, можливо обійти захист:
Що мало запобігти втечам, подібним попереднім, шляхом використання PersistentVolume та PersistentVolumeClaim для монтування папки хоста в контейнері з можливістю запису, замість використання монтування hostPath.
Імітація привілейованих облікових записів
За допомогою привілею імітації користувача, зловмисник може імітувати привілейований обліковий запис.
Просто використовуйте параметр --as=<username>
у команді kubectl
для імітації користувача або --as-group=<group>
для імітації групи:
Або скористайтеся REST API:
Перелік секретів
Дозвіл на перегляд секретів може дозволити зловмиснику фактично прочитати секрети, отримуючи доступ до кінцевої точки REST API:
Читання секрету - перебір ідентифікаторів токенів
Хоча для атакуючого, який має токен з дозволами на читання, потрібне точне ім'я секрету для його використання, на відміну від більш широких дозволів на перелік секретів, все ще існують вразливості. Стандартні облікові записи служб у системі можуть бути перелічені, кожен з них пов'язаний з секретом. Ці секрети мають структуру імені: статичний префікс, за яким слідує випадковий п'ятизначний алфавітно-цифровий токен (з виключенням певних символів) згідно з вихідним кодом.
Токен генерується з обмеженого набору з 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-auth AWS EKS
Суб'єкти, які можуть змінювати configmaps
в просторі імен kube-system на кластерах EKS (повинні бути в AWS), можуть отримати привілеї адміністратора кластера, перезаписавши конфігураційний файл aws-auth.
Для цього потрібні дії update
та patch
, або create
, якщо конфігураційний файл ще не був створений:
Ви можете використовувати 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 на цій сторінці:
У вас є приклад того, як отримати RCE, спілкуючись з авторизованим до API Kubelet тут.
Видалення підкаштань + вузли, що не підлягають плануванню
Принципали, які можуть видаляти підкаштани (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.
Правило передбачає, що користувач може створювати або оновлювати роль лише у випадку, якщо він має всі дозволи, які включає ця роль. Крім того, обсяг існуючих дозволів користувача повинен відповідати обсягу ролей, які він намагається створити або змінити: або для всього кластера для ClusterRoles, або обмежений тією самою областю простору імен (або для всього кластера) для Roles.
Є виняток з попереднього правила. Якщо суб'єкт має дієслово escalate
над roles
або clusterroles
, він може підвищити привілеї ролей та кластерних ролей навіть без наявності власних дозволів.
Отримання та Зміна RoleBindings/ClusterRoleBindings
Здається, що ця техніка працювала раніше, але за моїми тестами вона більше не працює з тієї ж причини, що пояснено в попередньому розділі. Ви не можете створити/змінити рольбайндинг, щоб надати собі або іншому обліковому запису служби деякі привілеї, якщо у вас їх немає.
Дозвіл на створення Rolebindings дозволяє користувачеві прив'язувати ролі до облікового запису служби. Цей дозвіл потенційно може призвести до підвищення привілеїв, оскільки він дозволяє користувачеві прив'язувати адміністративні привілеї до компрометованого облікового запису служби.
Інші атаки
Додаток бічного проксі
За замовчуванням в комунікації між підпроцесами немає жодного шифрування. Взаємна аутентифікація, двостороння, від підпроцесу до підпроцесу.
Створення додатка бічного проксі
Створіть свій .yaml
Відредагуйте свій .yaml файл та додайте розкоментовані рядки:
Перегляньте логи проксі:
Додаткова інформація за посиланням: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
Зловмисний контролер прийому
Контролер прийому перехоплює запити до сервера API Kubernetes перед збереженням об'єкта, але після того, як запит був аутентифікований та авторизований.
Якщо зловмисник якимось чином вдасться впровадити контролер прийому мутацій, він зможе змінювати вже аутентифіковані запити. Це може дозволити йому піднятися в привілеях та, як правило, залишитися в кластері.
Приклад з https://blog.rewanthtammana.com/creating-malicious-admission-controllers:
Перевірте статус, щоб переконатися, що він готовий:
Потім розгорнути новий котик:
Коли ви бачите помилку ErrImagePull
, перевірте назву зображення за допомогою будь-якого з наступних запитів:
Як ви можете побачити на зображенні вище, ми спробували запустити образ nginx
, але кінцевим виконаним образом є rewanthtammana/malicious-image
. Що тільки що сталося !!?
Технічні деталі
Сценарій ./deploy.sh
встановлює контролер прийому мутаційних веб-запитів, який змінює запити до API Kubernetes, як вказано в рядках його конфігурації, впливаючи на спостережувані результати:
Найкращі практики
Вимкнення автоматичного монтування токенів облікового запису служби
Поди та облікові записи служби: За замовчуванням, поди монтуватимуть токен облікового запису служби. Для підвищення безпеки Kubernetes дозволяє вимкнути цю функцію автоматичного монтування.
Як застосувати: Встановіть
automountServiceAccountToken: false
у конфігурації облікових записів служби або подів, починаючи з версії Kubernetes 1.6.
Обмеження призначення користувачів у RoleBindings/ClusterRoleBindings
Селективне включення: Переконайтеся, що в RoleBindings або ClusterRoleBindings включені лише необхідні користувачі. Регулярно аудитуйте та видаляйте непотрібних користувачів для підтримання жорсткої безпеки.
Ролі, специфічні для простору імен, над ролями для всього кластера
Ролі проти ClusterRoles: Віддавайте перевагу використанню Ролей та RoleBindings для дозволів, специфічних для простору імен, а не ClusterRoles та ClusterRoleBindings, які застосовуються для всього кластера. Цей підхід пропонує більш дрібний контроль та обмежує обсяг дозволів.
Використання автоматизованих інструментів
Посилання
Last updated