k8s (in)security – Telegram
k8s (in)security
12.1K subscribers
1.01K photos
38 files
1.56K links
Канал о (не)безопасности Kubernetes + микросервисных, контейнеризированных приложений.

Ведет команда www.luntry.ru

Вопросы, идеи, предложения => @Qu3b3c

https://knd.gov.ru/license?id=673ddbc21039886b1d03b7ce&registryType=bloggersPermission
Download Telegram
DAST operator — это Kubernetes operator, позволяющий реализовывать динамическое тестирование безопасности приложений и его API, на базе бесплатного и открытого решения Zed Attack Proxy (ZAP).

Данный оператор отлично ложиться в концепцию DevSecOps и хорошо смотрится в тестовом кластере при прогонке тестов для сервисов. Архитектурно от состоит из 2 reconcilers (для самого DAST и Services) и validating admission webhook для Ingress. Также для его успешной работы придётся добавить соответствующие annotations в тестируемые ресурсы + описать его собственные CRD.

Делать он сам по себе пока еще не много что умеет, но roadmap выглядит красивым. Честно я рассчитывал найти еще такой же operator на базе BurpSuite, который более любим специалистами по ИБ, но по крайней мере такого в открытом доступе не нашлось.
👍1
Сегодня хочется опять поговорить про технологии, которые будут двигать развитие контейнерных приложений и Kubernetes в том числе. Есть замечательный проект, за которым я уже давно слежу - CRIU (Checkpoint/Restore In Userspace). Суть проста, в runtime в необходимых контрольных точках (checkpoint) запоминается состояние программы, далее это состояние может быть перенесено на другую систему и программа возобновит (restore) свою работу с контрольной точки. Я лично слежу за данным проектом из-за таких сценариев его использования как "Applications behavior analysis on another machine" и "Snapshots of apps", что может быть очень полезно для security в том числе.

Проекту недавно исполнилось 7 лет и он постепенно начинает прокладывать себе дорогу в большой мир:
- В ядре 5.9 появилась новая capabilities "CAP_CHECKPOINT_RESTORE"
- В сообществе Kubernetes также работают над внедрением этой возможности во фреймворк

Есть даже PoC реализация PodMigration оператора. С ним можно поработать, но требуются измененные версии Kubernetes API, kubelet и container runtime.
В очередной раз хочется поднять проблему CAP_NET_RAW capability, да и вообще тему дефолтных (тут можно посмотреть их список) и необходимых capabilities. Так как CAP_NET_RAW просто является наиболее ярким примером из тех что есть по умолчанию. С ней появляется целый ряд известных проблем:
- Благодаря CVE-2020-14386 можно сделать container escape
- Возможность проведения MitM атак


Если ваше приложение это не использует, то можно убрать те capabilities что ему не нужны, тем самым уменьшить поверхность атаки.
Для этого в разделе securityContext в секции capabilities можно использовать описания add и drop. На пример:


securityContext:
capabilities:
drop:
- all
add:
- NED_BIND_SERVICE
Исследуя тему побега из контейнеров, я не мог не обратить свое внимание и на виртуальные машины (VM), которые можно использовать для запуска OCI образов в Kubernetes. В процессе всего этого, я встретил несколько точек зрения о будущем использования VM в Kubernetes. Кто-то считает, что:
- VM вытеснят контейнеры и те уйдут с передовой.
- такие мысли — это происки разработчиков VM, которые проигрывают на данном рынке.
- они нужны только при условии, что есть multi-tenancy
- они нужны только при определенных требованиях информационной безопасности для решение определенных задач

Естественно, речь идет о легковесных VM, типа:
- Kata containers
- Nabla containers
- Firecracker
- Toro Kernel

Что вы думаете на этот счет ?
CVE-2020-15257: containerd – containerd-shim API Exposed to Host Network Containers

Атакующий способен совершить побег из контейнера, поднять привилегии и скомпрометировать хост/ноду.

Все это возможно в условиях и благодаря, если:
- hostNetwork: true для Pod
- контейнер работает от root
- контейнер работает в host user namespace (сейчас это не исправить, но работа над этим кипит в keps/127: Support User Namespaces)

А проблема крутиться вокруг того, что containerd-shim использует abstract Unix domain sockets, который в отличие от normal Unix domain sockets привязан к network namespace процесса, а не к файлу.

В итоге злоумышленник из контейнера может делать такие операции как:
- Чтение/добавление/запись произвольного файла хоста
- Выполнение произвольных команд в контексте containerd-shim (root) на хосте
- Создание и запуск контейнера из runc config.json файла
Это, конечно, более чем достаточно для совершения побега из контейнера на хост.
Сегодня поговорим о таком стандартом ресурсе Kubernetes как RuntimeClass.

Благодаря данному ресурсу можно назначать на каком container runtime будет исполняться тот или иной Pod. Да все так - на вашем кластере моет одновременно существовать несколько container runtime.

Данный тип ресурса пришел на смену sandboxed runtime (описанию в annotations) и как пишут его авторы в KEP: "These implementations could stick with scheme ("trusted" and "untrusted"), but the preferred approach is a non-binary one wherein arbitrary handlers can be configured with a name that can be matched against the specified RuntimeHandler."

Это можно использовать для запуска специфичных подов. На пример, можно использовать gVisor, firecracker, kata или любой другой CRI runtime с более сильной изоляцией, чем у шустрого runc для запуска Pod'ов:
- не доверенных
- подозрительных
- сторонних разработок
- не прошедших pentest или аудит безопасности
- с большим количеством уязвимостей в image
Недавно опубликовали CHANGELOG для Kubernetes v1.20.0-rc.0.

По мне по версии 1.20 можно хорошо понять всю суматошность некоторых решений, применяемых по изменениям в Kubernetes. (Хотя я уверен вы знаете и более яркие примеры, но сточки зрения безопасности я подметил сейчас).

1) В v1.20.0-alpha.0: __"Dockershim security: pod sandbox now always run with no-new-privileges and runtime/default seccomp profile dockershim seccomp: custom profiles can now have smaller seccomp profiles when set at pod level"__ и __"Kuberuntime security: pod sandbox now always runs with runtime/default seccomp profile kuberuntime seccomp: custom profiles can now have smaller seccomp profiles when set at pod level"__
2) А уже в `v1.20.0-beta.1`: __"Docker support in the kubelet is now deprecated and will be removed in a future release. The kubelet uses a module called "dockershim" which implements CRI support for Docker and it has seen maintenance issues in the Kubernetes community. We encourage you to evaluate moving to a container runtime that is a full-fledged implementation of CRI (v1alpha1 or v1 compliant) as they become available."__


Касаемо Kuberuntime security все отлично теперь Pod будет по умолчанию подтягивать "runtime/default" для seccomp. Но улучшать dockershim security и затем деприкейтить его по мне странно). Сам деприкейт dockershim логичен и обоснован.

Также касаемо безопасности fsGroupChangePolicy (часть securityContext) поднялось в стадию beta. Имеет значения OnRootMismatch и Always (по умолчанию).
Аудиторам/пентестерам на вооружение, а защитникам (Blue team, DevSecOps) на заметку.
Щит и меч как известно две стороны одной медали.

Рассмотрим сегодня классную технику побега из контейнера или, с другой стороны, очень опасную конфигурацию workload.
Если внутрь Pod смонтирована директория /var/log и атакующего есть ServiceAccount token на чтение nodes/log, то он может общаться в Kube API Server, используя этот token. Он может считать все данные с файловой системы Node на которой работает Pod из которого он шлет запросы.

В проекте kube-pod-escape автор реализовал полностью подобную ситуацию и еще 3 полезные команды для проведения самой атаки:
- lsh - аналог ls, для работы из контейнера на хосте
- cath - аналог cat, для работы из контейнера на хосте
- find_sensitive_files.py - считывает с хоста критичные файлы типа private keys и других ServiceAccount token

Согласитесь с первого взгляда монтирование логов и обращение к ним не смотрится как что-то что может привести к побегу из контейнера, и как то что нужно запрещать на том или ином уровне.
"Kernel privilege escalation: how Kubernetes container isolation impacts privilege escalation attacks"

Отличная статья, наглядно демонстрирующая чем отличается работа kernel privilege escalation эксплоита в не контейнера для поднятия привилегий и в контейнере для побега из контейнера. Для примера в статье взята CVE-2017-7308 (опять привет CAP_NET_RAW capability).

Наглядность заключается в том, что автор с помощью отладчика показывает, какие и почему структуры данных необходимо модифицировать для успешной эксплотации. Вы познакомитесь тут и с дефолтным root'ом и с различными namespaces (ОС, а не Kubernetes - не путайте их) и ,конечно, capabilities.

А напоследок увидите как даже дефолтный seccomp профиль, способен сделать не пригодным данную технику эксплотации.

P.S. Статья является такой прям квинтэссенцией моей любви к бинарной эксплотации и безопасности `Kubernetes` =)
CVE-2020-8554: Man-in-the-middle using LoadBalancer or ExternalIPs

Почитав описание многие из вас, могут задаться вопросом: "Правда CVE??!".

Суть в том, что LoadBalancer делает то, для чего и предназначен. Ему указали IP для LoadBalancer и бэканда - он и использует их, не проверяя и не зная о допустимых значениях. А так автор PoC предлагает использовать данное свойство для использования LoadBalancer как MITM инструмент, указывая на свой подконтрольный Pod. Такое свойство известно с 2016 года если что. Все детали данного поведения/проблемы можно прочитать в этом коротком и емком треде. А проблема как всегда может быть решена с помощью admission controllers ;)

Так что не пугайтесь описание в конце паспорта уязвимости: "This issue is a design flaw that cannot be mitigated without user-facing changes."
В связи с новостью об удалении/отказе/замене от Pod Security Policies и анализом последних уязвимостей, атак, в голове образовалась следующая параллель с развитием методов атак и защит из мира бинарной эксплуатации (скорее всего большинство далеки от данной темы, но я надеюсь мысль уловите).

Сначала для перехвата потока управления программы атакующие влияли тем или иным способом на Код. Чтобы это предотвратить Код обложили большим количеством механизмов безопасности типа DEP/SEHOP/ASLR/CFG/PAC/.... В итоге, были придуманы так называемые Data-Oriented Attacks, Data-only Attacks - они в свою очередь помогали перехватить поток управления не через влияния на Код, а Данные. Защиты от таких атак можно встретить только в академических работах, ввиду большого overhead'а и ряда других ограничений. При этом Данные как вы понимаете у каждой программы различаются очень сильно - нельзя стандартизировать.

Вот так же и с PodSecurityPolicy. Он был заточен только под контроль workload (Pod'ов). А в итоге, атакующий может сделать много всего “интересного” и без влияния на сущности, представляющие workload'ы - через kubernetes ресурсы чисто описывающие некоторые настройки. Тут примеры и с `PersistentVolumes и с LoadBalancer и т.д. Но ввиду что эти ресурсы (Данные и все есть `YAML) стандартизированы и есть как минимум такой механизм как Admission Controller это все можно проверять перед применением. На лицо преимущество декларативной системы и подхода Something as Code в целом.
Service Mesh сети очень часто (когда это нужно и выгодно) выставляют и позиционируют как отличный механизм безопасности. Хотя на мой взгляд это наверно самая слабая их функциональность. И давно эта мысль крутилось у меня в голове, но не знал как это правильно написать и тут наткнулся на цитату с которой полностью согласен и отражает всю суть: "Because service mesh network policies are defined at the service level, they are not effective at protecting your underlying infrastructure from a compromised pod." от Liz Rice
"ABSTRACT SHIMMER (CVE-2020-15257): Host Networking is root-Equivalent, Again" - отличный технический рассказ с примерами кода о том, как находилась, исследовалась уязвимость CVE-2020-15257, о которой я писал раньше.

При прочтении вы узнаете о том, как работает containerd-shim, как закрыли данную уязвимость и как ее можно проэксплуатировать. Сам исходный код эксплоита автор собирается выложить 11 января, НО по статье его можно написать и самостоятельно.
Готовя/актуализируя свой тренинг по безопасности cloud native приложений в Kubernetes, обнаружил что (в версии 1.19) альфа фича DynamicAuditing и auditregistration.k8s.io/v1alpha1 API были депрекейтнуты и удалены. А данная фича мне очень нравилась - можно было очень быстро и удобно управлять своими обработчиками логов через ресурс AuditSink.

Так что в качестве backend остались только: Log backend и Webhook backend.
CVE-2020-8569: snapshot-controller DoS

Уязвимость среднего уровня критичности может привести к отказу в обслуживании компонента snapshot-controller через неавторизованный API запрос. Связано с тем, что атакующий может указать такой `VolumeSnapshot, который будет ссылаться на несуществующий PersistentVolumeClaim. Данный компонент будет падать, перезапускаться и снова падать. Доступ же к самим snapshots атакующий получить не сможет.

snapshot-controller это опциональный компонент Kubernetes, который включает volume snapshot фичу. Если вы его не используете, то и беспокоиться не о чем.
Наконец полностью изучил документ Cloud Native Security Whitepaper.

Остались смешанные ощущения, но он определенно мне понравился. Я это связываю с тем, что его писала большая группа людей и поэтому он получился очень неравномерным. В каких-то моментах он очень хорош, а в каких-то начинает путать, и противоречить самому себе.

Целевая аудитория у него и в правду это CISO, CSO, CTO, Architects и люди, которым надо быстро вникнуть в суть Cloud Native Security подходов/решений что представлены на рынке. Там перечислено все что только возможно, но далеко не все из этого нужно и, конечно, не все всё себе из этого могут позволить.

А некоторые интересные моменты я обязательно рассмотрю на канале.

P.S. Приятно было найти что наше виденье и новые идеи, которое мы закладываем в наш продукт, здесь также нашли свое отражение.
Risk8s Business: Risk Analysis of Kubernetes Clusters

Отличный гайд в стиле "zero-to-hero" по управлению рисками в Kubernetes. Читается очень просто, быстро и понятно - очень рекомендую.

Основную мысль, которую вы должны вынести после прочтения это вы должны понимать свое окружение (контекст очень важен), чтобы правильно оценивать риски и правильно выбирать подходы/методы/инструменты для их минимизации и/или избавления. Безопасность это процесс управления рисками! Все бизнесы, все сервисы, все Kubernetes разные. Не действуйте вслепую!

Закончу прекрасной цитатой автора: "While there are some things you should consider tooling up for like vulnerability scanning, runtime security verification, and storage permission checks, you’ll never be able to definitively conclude its overall risk without the context of its environment."
Крохотная заметка от авторов сетевого плагина Cilium о возможности данного CNI из коробки работать без использования kube-proxy и тем самым быть не подверженным MitM атаке из-за CVE-2020-8554: "we don't translate an ExternalIP address for traffic sourced from pods unless the ExternalIP is associated with a known node."

Еще в заметке немного общих данных о MitM атаках в Kubernetes. Также немного разговора о Zero Trust Networking и то, что они стараются смягчить возможности общеизвестных MitM атак (насколько это правда еще нужно поисследовать).

Напомню, что Cilium базируется на технологии eBPF.
В версии 1.20 до GA ветки добрались фичи для улучшения безопасности service account tokens.

Теперь Pods могут запрашивать service account tokens с улучшенной безопасностью.
Теперь kubelet может проецировать service account token в Pod с желаемыми свойствами, такими как аудитория и срок действия (для default token это не работает). При этом этот token станет недействительным для API при удалении Pod или ServiceAccount. Такое поведение можно сконфигурировать в PodSpec используя ProjectedVolume тип под названием ServiceAccountToken. kubelet будет заниматься ротации, но само приложения ответственно за подтягивание нового token.

Для всего этого вам придётся сконфигурировать соответствующие флаги для kube-apiserver (по умолчанию это не включено).


Какая из этого огромная польза для безопасности можете прочитать в KEP раздела Background (на скрине).
Инструмент DEEPCE, название которого является абревиатурой от фразы Docker Enumeration, Escalation of Privileges and Container Escapes. Название говорит само за себя.

Для максимальной совместимости весь инструмент написан на sh без каких-либо зависимостей (1234 LoC). Но для ряда задач он все же ожидает что внутри также окажутся тулзы: curl, nmap, nslookup, dig. Также учитывайте, что при эксплуатации ряда векторов он может создавать контейнеры, перезапускать runC, что потенциально может навредить системе - будьте осторожны. При этом есть классная возможность скачать и запустить его без записи на диск:

wget -O - https://github.com/stealthcopter/deepce/raw/master/deepce.sh | sh

Поддерживаемые эксплоиты:
- DOCKER - использование docker group
- PRIVILEGED - использование привилегированного контейнера
- SOCK - использование docker sock
- CVE-2019-5736
- CVE-2019-5021
- CVE-2019-13139

Применимо ли это в Kubernetes? Да! Инструмент даже знает про kubectl ;)
Сегодня пост из категории мысли в слух.

За последнее время появилось достаточно много статических анализаторов ресурсов (Terraform, Helm, Kubernetes и т.д.) для проверки их в репозитариях, которые по заветам GitOps являются единственным источником правды. Это могут быть проверки как на best-practices, так и на security.

Но есть ли уверенность в том, что мы увидим тоже самое после выкатки этих ресурсов? Ответ: совсем не обязательно - статическая и динамическая картина могут отличаться.

В процессе выкатки, MutatingAdmissionWebhook может внести туда множество изменений. В качестве примера: переменные окружения, init и sidecar контейнеры, изменение LimitRange и ResourceQuota, установку privileged режима, монтирование директорий и т.д. Это может быть как с благими, так и с вредоносными намерениями (ну или для обхода ограничений в угоду более быстрой разработки).

Может помочь ValidatingAdmissionWebhook, но не стоит забывать, что если условие было добавлено спустя какое-то время, то в инфраструктуре уже могут существовать ресурсы, не подходящие под его условия. В одном из своих постов я уже писал, что возможно и создание вредоносных ValidatingAdmissionWebhook. Создание вредоносного MutatingAdmissionWebhook злоумышленником/инсайдером или просто не очень квалифицированным сотрудником также возможно.

Динамическая природа Kubernetes вносит свои коррективы в жизнь ресурсов и это надо учитывать, как и строгий контроль того кто и что делает с помощью MutatingAdmissionWebhook и ValidatingAdmissionWebhook.