Известно, что с контейнерами бывает огромное количество разнообразных проблем, в том числе, связанных с информационной безопасностью. Как их избежать и не дать взломщику лазеек в ваш сервис — разбираемся в этой статье.
Привет, Хабр! Это Алексей Федулаев и Антон Жаболенко из Wildberries. Мы работаем в сфере информационной безопасности (ИБ) уже больше 10 лет.
Проблемы с безопасностью
Типичные проблемы, связанные с информационной безопасностью контейнеров:
Уязвимые компоненты. Когда вы деплоите и собираете контейнер с уязвимыми компонентами, то они никуда не денутся и всегда будут в нём присутствовать.
Ошибки конфигурации. Когда в среде выполнения контейнеров или в самих контейнерах допущены ошибки при конфигурировании, злоумышленник может этим воспользоваться.
Наличие root-пользователя в контейнере. Эта проблема может звучать немного по-детски. Но это бич многих компаний — часто у них запускаются продукты от привилегированного пользователя внутри контейнеров. Тоже запускаете свои приложения в контейнере под root’ом? Мы расскажем, почему так однозначно не стоит делать.
Для всех этих проблем существует большое количество решений:
Различные линтеры docker-файлов. Они могут подсветить наличие root или ещё каких-то проблем в контейнере.
Поиск CVE в образах. Чтобы не допустить уязвимости, есть различные инструменты для поиска уязвимостей в образах.
![](https://habrastorage.org/getpro/habr/upload_files/6b9/9f5/776/6b99f57765f782427b6d8e1863e77f9f.png)
Поиск мисконфигов Это специальные средства, которые позволяют выискивать мискофигурации в ваших контейнерах.
![](https://habrastorage.org/getpro/habr/upload_files/47e/bf0/a50/47ebf0a502d871aece7415cc57c03967.png)
Но, как всегда, есть один маленький огромный нюанс.
Представим ситуацию: есть целевая система, куда каким-то образом попадает злоумышленник. Он не доставляет никакие элементы эксплойт, а берёт 7z и постепенно перекладывает всё, что находится на файловой системе в запароленные архивы. Пароль, конечно, пользователю этой системы не сообщает. А когда всё перенесёт, сносит всю открытую информацию.
![](https://habrastorage.org/getpro/habr/upload_files/95a/f9d/9b3/95af9d9b3f085cef10cb4bda037c6f4c.png)
Так он зашифровывает всю систему, и пользователь не может ничего установить. Вы можете сказать, что это сюр, пример в вакууме. Но, на самом деле, нет.
Существует шифровальщик Qlocker. Он как раз атаковал сетевые хранилища данных Qnap и в своём составе использовал 7z для шифрования. Где-то около года назад у Qnap возникли проблемы: пользователей этих NAS’сов продолжительное время кошмарили через находившиеся zero-day, или когда патч реверсили и выпускали эксплойт. Подробнее с этой песней можно ознакомиться в отчёте BleepingComputer.
Получается, все инструменты, про которые мы рассказали, не смогли бы помочь обнаружить деятельность такого шифровальщика, потому что 7z — это абсолютно легитимная утилита. В итоге получается, что есть множество сканеров, но для целого класса атак они совершенно ничем не могут помочь и никак не детектируют. Давайте разбираться, почему так происходит.
Living off the Land
Существует такой класс атак, как Living off the Land (LotL) атаки. Это атаки, при которых злоумышленник использует разнообразные легитимные программы, чтобы выполнять различные вредоносные действия в целевой системе.
Когда злоумышленники используют легитимные компоненты или утилиты, сканнером или каким-то другим инструментом безопасности, такие атаки выявлять тяжело. Более того, такой инструмент может быть легитимной частью работающей системы, а значит, мы считаем, что его взаимодействие корректное.
Living off the Land в переводе с английского означает «питаться подножным кормом», то есть тем, что можно добыть на местности, что валяется у вас прямо под ногами. По аналогии операторы LotL-атак «добывают на местности» инструменты для достижения своей цели.
Если вы думаете, что это какие-то узкоспециализированные примеры, приведём некоторые вредоносные компании, которые в своей вредоносной деятельности используют LotL-атаки. Например: вымогатель BianLian, группировка Bitter APT, нацеленная на энергетический сектор в Азии. Можете ознакомиться с отчётами и посмотреть подробнее.
На самом деле в 2023 году даже некоторые виды мух освоили LotL-атаки.
![](https://habrastorage.org/getpro/habr/upload_files/d40/30a/e52/d4030ae527674106bec0a5bb939da75b.jpg)
На картинке муха вида Hydrochasma — это род мух-береговушек из подсемейства со страшным названием, которые давно освоили LotL-атаки. Понятно, что это шутка, Hydrochasma — это название очередной APT-группировки, которая использует в своих компаниях исключительно LotL-атаки. Прочитать про это можно в отчете Symantec.
Но Hydrochasma — это не единственная группировка. Есть и другие группировки, которые используют LotL:
APT-группировка Vanguard Panda;
вымогатели BlackByte;
вымогатели Evil Corp;
группировка OPERA1ER;
группировка drIBAN.
Самые популярные утилиты для LotL-атак:
Powershell;
WMI;
атаки через уязвимые легитимные компоненты;
атаки через взлом Windows Defender.
Но мы же говорили о контейнерах, казалось бы, при чём тут Defender и Powershell? Конечно, есть нативные Windows-контейнеры, правда, мы не знаем, пользуется ли ими кто-то вообще, но они существуют. А ещё вместе с тем, как растёт число пользователей Linux, растёт количество инфраструктуры на Linux. А значит, всё чаще и чаще злоумышленники направляют свой взор именно на Linux-системы. Мы видим, как растёт количество атак на ОС этого семейства. Согласно прошлогоднему отчету пользователей Technologies, число атак на ОС семейства Linux выросло с 12% до 30%
![](https://habrastorage.org/getpro/habr/upload_files/49f/937/13d/49f93713d0614b5e6959e2796c862bf6.png)
Вместе с ростом общего числа атак на Linux, растёт и число LotL-атак на Linux. На самом деле LotL-атаки исторически всегда атрибутировались именно с атаками на Windows-инфраструктуру, но в последнее время они появляются и под Linux-инфраструктуру, в том числе, в деятельности различных хакерских группировок. LotL-атаки в применении к Linux-инфраструктуре — не экзотика, а реальность. На самом деле в Linux многие атаки по умолчанию являются LotL-атаками. Для этого в Linux существует огромное количество инструментов:
vim
curl
netcat
7z
docker
и другие
Все эти популярные инструменты позволяют проводить атаки на целевую систему!
На самом деле даже существует отдельный термин GTFOBins — это легитимные программы, которые могут использоваться для обхода настроек безопасности на некорректно сконфигурированных Unix-системах
По ссылке — примеры, как с помощью разнообразных легитимных инструментов можно либо повысить привилегии в Linux, либо сделать что-то, что может быть полезно злоумышленнику в рамках развития атаки. К примеру, как с помощью утилиты less повысить привилегии.
Вам желательно ознакомиться с этими утилитами при проектировании своих систем, чтобы не допустить таких же ошибок. Но если вы — пользователь Windows, то есть LOLBAS (Living Off The Land Binaries and Scripts) и lolDrivers. С их помощью можно проводить атаку, эксплуатируя подписанные официальные драйверы.
![](https://habrastorage.org/getpro/habr/upload_files/057/1d7/888/0571d7888a3c1c8bb828c68723db8a97.png)
На самом деле, для GTFOBins хорошей практикой в работе современного Security Operations Center (SOC) станет написание алертов на почти все подозрительные действия, которые можно предпринимать с легитимными программами, перечисленными на сайте GTFOBins. Если проектируете SOC и пишете алерты, обратите на это внимание.
Таксономия LotL-атак
Разберёмся с таксономией LotL атак. Все техники можно грубо поделить на 6 типов:
Побег из ограниченного shell.
Повышение привилегий в системе.
Сохранение повышенных привилегий в атакуемой системе.
Передача файлов как в систему, так и из нее, так называемся эксфильтрация данных.
Поднятие reverse-shell.
Сетевая разведка.
Дальше приведём несколько простых примеров, как разнообразные легитимные Linux-утилиты можно использовать как составные кубики при развитии какой-то более сложной атаки. Начнём с примера, когда есть ограниченный shell.
Злодей в ограниченном shell
Администраторы, DevOps инженеры, разработчики, разворачивая какое-то приложение, часто любят попытаться зарезать этому приложению права. Например, ограничить список утилит, доступных пользователю, под которым запущено приложение. Предположим, что у нас есть такой ограниченный shell, в котором разрешено запускать только одну утилиту.
![](https://habrastorage.org/getpro/habr/upload_files/648/142/c86/648142c8652eb5428dd4934ed5970be1.jpg)
Здесь видно, что whoami и hostname не работают из-за Permission denied в нашем ограниченном shell. Рассмотрим простой пример с git. Если у нас есть возможность использовать в ограниченном shell только git, это уже позволяет выйти из ограниченного shell и получить полноценное выполнение кода в контексте той системы, на которой мы запускаемся. Делается это с помощью PAGER.
![](https://habrastorage.org/getpro/habr/upload_files/f5d/acd/bd5/f5dacdbd5c95a8f809a1a028ab215f25.jpg)
На примере выше можно увидеть, что злоумышленник вводит простую команду с git и получает полноценный shell, а whoami и hostname начинают у него работать. Получив интерактивный shell, злоумышленнику становится гораздо проще взаимодействовать с целевой системой и проводить атаки.
Но не git’ом единым. Возьмём популярный ныне npm:
![](https://habrastorage.org/getpro/habr/upload_files/4ac/4a8/3c2/4ac4a83c2e9783a16d9dc2144112cb37.jpg)
С помощью npm мы можем легко поднять интерактивный shell и начать оттуда воспроизводить какие-то команды на системе.
Что ещё можно сделать? Иногда у разработчиков и администраторов возникает желание написать собственную упрощенную систему оркестрации контейнеров, например, на основе docker. На самом деле, если у вас есть пользователь с правами выполнять только docker, он уже может изменить привилегии в системе до root. Вот как это выглядит:
![](https://habrastorage.org/getpro/habr/upload_files/389/30a/bc3/38930abc3f2840a41108ed5b2e4cb9e5.jpg)
Правда, очень легко? Он может запустить контейнер, в который примонтирует корневую директорию вашего хоста, потом chroot’нится в эту директорию и сможет работать со всеми файлами внутри этой директории с привилегиями root. Таким образом docker можно использовать для повышения привилегий.
Причем обратите внимание, достаточно, чтобы пользователь всего лишь состоял в группе docker, и docker-демон работал от root. А он по умолчанию всегда работает от root. Так мы получаем root на хостовой ОС.
Reverse shell
Часто может быть так, что мы не можем установить прямое SSH соединение атакуемого сервера из-за файрвол-ограничений. Но зато можем попробовать прокинуть бэклинк, то есть обратный shell. Это техника, которая позволяет инициировать удалённое сетевое подключение на наш хост с атакуемого хоста.
Представим такую картину: у злоумышленника есть сервер. С помощью программы netcat он начинает прослушивать порт, в данном случае 12345.
![](https://habrastorage.org/getpro/habr/upload_files/dd0/3cc/57f/dd03cc57f252dffe5924e87037f0322d.jpg)
На атакуемой системе происходит следующее:
![](https://habrastorage.org/getpro/habr/upload_files/3cb/a1d/9a9/3cba1d9a9063d60a1a2a6f9e1050763a.jpg)
Мы экспортируем хост, к которому хотим подключиться, и порт. Далее с помощью программы bash просто перенаправляем вывод в dev/tcp и получаем reverse shell.
![](https://habrastorage.org/getpro/habr/upload_files/8df/664/9b1/8df6649b1db5e764443dc9db33fc66df.jpg)
Так у нас подключился бэк-коннект, и мы можем уже интерактивно исполнять команды на атакуемой системе. Естественно, это гораздо удобнее для злоумышленника. Особенно, для злоумышленника с Macbook.
Неинтерактивное выполнение команд в целевой системе
Кроме различных способов интерактивного выполнения команд в системе, существуют способы выполнять и неинтерактивные команды. Например, для этого можно использовать команду pidstat, которая показывает статистику потребления ресурсов системы запущенным процессом.
![](https://habrastorage.org/getpro/habr/upload_files/d86/f16/662/d86f166625ab7b157ae6b14b963d235d.jpg)
Понятно, что если у злоумышленника есть возможность выполнять такую команду, он сможет с её помощью выполнить вообще любую команду в системе. Если в ограниченном shell дать возможность пользователю только дебажить какие-то процессы, на самом деле, он сможет выполнять что угодно. Похожей техникой выхода из ограниченного shell или в некоторых случаях повышения привилегий станет техника с применением утилиты xtrace, которая позволяет делать примерно то же самое.
Ещё один пример неинтерактивного выполнения команд — наш любимый crontab -e:
![](https://habrastorage.org/getpro/habr/upload_files/164/3ca/318/1643ca318a5745199f89d6e595b1e6d8.jpg)
Если зайдём в crontab, увидим строчку о том, что при перезагрузке запускается некий скрипт. Так мы сможем закрепляться в системе, оставаться незамеченными. Просто после каждой перезагрузки машины у нас будет, например, заново подниматься reverse shell.
CronRAT (31th february attack)
Хотелось бы ещё рассказать про интересную атаку, которая называется CronRAT — атака 31 февраля.
Её смысл в том, что в Cron сохранялась вредоносная нагрузка с таким интересным cron-выражением, которое стояло на 31 февраля
![](https://habrastorage.org/getpro/habr/upload_files/9e0/738/fe8/9e0738fe83ece9b3202801f471f4b636.jpg)
Это позволяло обойти многие вендоровские системы защиты, потому что 31 февраля не существует. А значит, при попытке выполнения такого кода произошла бы ошибка. Но так как 31 февраля никогда не наступает, эта ошибка тоже никогда не наступает. Соответственно, так в cron можно прятать обфусцированный код. В дальнейшем декодер проверял cron-выражение, обфусцированный код декодировался в B64, разархивировался и просто передавался на выполнение в bash.
![](https://habrastorage.org/getpro/habr/upload_files/14e/725/3de/14e7253de3cacfd5db67aa1e64ad0d81.jpg)
Причем после срабатывания и выполнения вредоносного кода, в эксплойт злоумышленники почистили crontab (в отличие от некоторых разработчиков).
На самом деле может возникнуть вопрос, зачем нужна такая техника. Часто, чтобы проэксплуатировать что-то в системе, как-то распространить атаку, нужно где-то незаметно сохранить вредоносный код. Атака CronRAT позволяет хранить вредоносный код в crontab и не сохранять его на диске, где его обнаружит какое-нибудь средство для обнаружения атак.
Выкачивание данных
Понятно, что с помощью легитимных утилит, без каких-то дополнительных привилегий, можно, например, выкачивать данные из конечных серверов, к примеру, с помощью SSH.
![](https://habrastorage.org/getpro/habr/upload_files/4a4/857/d69/4a4857d695c7290ab25d12c98718804b.jpg)
Чтение данных
Допустим, у нас есть файл 123.md, который можно прочитать. Соответственно, не имея каких-то инструментов для чтения, мы можем только с помощью bash и echo прочитать любые файлы на атакуемой системе.
![](https://habrastorage.org/getpro/habr/upload_files/58b/f94/d5d/58bf94d5dc11a58365ceb2f4e6e7e196.jpg)
Запись в файлы
Очевидно, что если у вас запрещены какие-то стандартные утилиты для записи в файл, но есть, к примеру, wget, вы всё равно можете записать что-то в файл.
![](https://habrastorage.org/getpro/habr/upload_files/4eb/7c6/589/4eb7c65890579c6a121f4c4b17099ab6.jpg)
Это тоже в рамках атаки бывает полезно.
Загрузка файлов
LotL-атака может быть частью более большой гибридной атаки, и она предшествует загрузке payload в систему. Это тоже позволяет сделать атаку.
![](https://habrastorage.org/getpro/habr/upload_files/b88/1f8/fcf/b881f8fcf56f61e67eef5accdb654ef7.jpg)
Выполнение через библиотеку
Следующий тип атак — когда у вас в доступе есть только какой-то инструмент, например, для установки пакетов — такой, как pip.
![](https://habrastorage.org/getpro/habr/upload_files/32a/d25/359/32ad25359c6131f2e52caf9ea7b2cced.jpg)
В данном случае можно создать файл setup.py, добавить строчки, которые приведены на слайде, и вы, таким образом, при вызове pip сможете выполнить произвольный код в системе, где доступен только pip. Для этого свой код нужно разместить в lib.so. Лёгким движением руки мы исполняем произвольный код на системе. У вас может быть учётная запись робота, которой доступен для выполнения только pip. Например, чтобы он что-то обновлял. Но если у робота есть возможность писать файлы и запускать pip, это уже позволяет исполнить произвольный код на системе.
Эксплуатация SUID-бита
Опытный администратор или DevOps инженер не даёт пользователю никаких привилегий, но, например, выдает SUID-бит на программу Python. SUID-бит в данном примере установлен на root. А это позволяет любому пользователю запустить программу от имени root. И вот что получается:
![](https://habrastorage.org/getpro/habr/upload_files/39b/634/ab3/39b634ab3d2dfa65a14ad6b885a33c8f.jpg)
У нас есть обычный пользователь в системе. А на Python стоит SUID, и при запуске приведённого скрипта на слайде, мы получим интерактивный shell и root на системе.
SUID бит нужен для того, чтобы у вас работали многие стандартные утилиты в Linux, например, passwd. Это бит, который позволяет запускать исполняемый файл с правами владельца этого файла. Очень часто SUID-бит используется в реальных атаках для повышения привилегий, в особенности неаккуратно выставленный.
![](https://habrastorage.org/getpro/habr/upload_files/fdb/02b/ab5/fdb02bab5459ae8c7a91f03ab9a9aac1.jpg)
Мы уже упоминали пример с docker, где пользователь был добавлен в группу docker, чтобы управлять какими-то контейнерами. Либо была добавлена какая-то автоматизация в группу docker, чтобы управлять контейнерами. Часто нерадивые администраторы, которые либо не разобрались с группой docker, либо взяли первые попавшиеся ответы на Stack Overflow, сразу идут настраивать свою систему. В результате они добавляют в исполняемый файл docker SUID-бит, который позволяет запускать docker с правами root и это, очевидно, тоже приводит к аналогичному повышению привилегий как в примере выше. Как в том анекдоте:
— «Джун, откуда ты взял код?»
— «Со Stack Overflow»
— «Из вопроса или из ответа?»
Эксплуатация sudo
Например, мы берём наш любимый vim, разрешили пользователю запускать его от sudo, и больше не разрешив ничего, мы с легкостью можем также повысить на системе привилегии до root.
![](https://habrastorage.org/getpro/habr/upload_files/b3f/0c1/040/b3f0c10403b32b8f889a138b24b09a05.jpg)
На самом деле с утилитой less, которая просто позволяет читать файлы, можно делать многое. Если добавить её в sudo, она точно также позволяет повысить привилегии, потому что позволяет заспавнить shell.
Эксплуатация capabilities
Capabilities в Linux — это расширение стандартной модели управления доступом, которое позволяет выдавать обычному пользовательскому процессу кусочки привилегий root. Например, вы хотите дать процессу возможность слушать привилегированное порты, но не хотите давать ему root. Вы можете это сделать с помощью capabilities. Администраторы, которые не знают, что такое capabilities, часто неаккуратно их выдают.
![](https://habrastorage.org/getpro/habr/upload_files/163/10c/429/16310c429e95fd7f1c0ac8d89cc16736.jpg)
В примере выше бинарнику python3 выданы capabilities на setuid — это capabilities, которые позволяют изменять user ID пользователя у исполняемого процесса. Понятно, что в этом случае можно повышать привилегии и исполнять произвольные команды от root с помощью команды, которая приведена на слайде. Мы просто выставляем uid(0), uid root и запускаем bash или shell.
Основные особенности атак
Резюмируем основные особенности таких атак:
Легитимные утилиты двойного назначения. Все они реально используются разработчиками, DevOps-инженерами, их часто можно встретить на системах.
Усложнённое обнаружение атаки.
Усложнённая атрибуция атаки. Если другой группировке нужно залезть в эксплойт, у них есть свой определённый почерк кода, и эта граница размывается.
Fileless или безфайловые атаки.
Fileless
Многие классические инструменты детектирования, которые используют безопасники, опираются на сигнатуры файлов. Они ожидают увидеть на системе файл с определённой сигнатурой, который атрибутируется как вредоносный.
Но нет файла — нет сигнатур. Зачастую у атак, построенных на LotL, есть только индикаторы атаки (IOA). Вы можете понять, что вас атакуют только по какой-то определённой последовательности действий, которая типична для конкретной атаки.
Индикаторы компрометации (IOC) появляются за счёт того, что файлов нет только когда началось взаимодействие с вредоносными серверами. То есть индикаторы компрометации IOC появляются слишком поздно — когда злоумышленник уже выносит данные из инфраструктуры.
Получается, на Unix нет вирусов, но тем временем вирусы есть, хакеры опять всех переиграли? Но нам тоже есть, чем им ответить.
Как отлаживать и тестировать контейнеры
Всё-таки тестировать их можно, но, возможно, некоторым из вас это не понравится.
Раздельные среды
Мы знаем все любимые утилиты curl, которые проверяют, поднялся сервис или нет. А всё остальное любят использовать тестировщики и разработчики для отладки. У вас должны быть раздельные среды, может быть, даже раздельные базовые img или раздельные docker-файлы.
![](https://habrastorage.org/getpro/habr/upload_files/5d3/763/ad3/5d3763ad3d9ac438b61776efd42ec78d.png)
Весь тот инструментарий, который необходим для отладки, и может быть использован в атаке, никак не должен попадать на прод. Мы собираем одни контейнеры, которые тестируются в dev вместе со всем этим окружением, в продакшен же едут другие контейнеры без этих инструментов.
Можно защищаться и иначе. Когда мы разделили среды выполнения, отделив dev от прода, то от LotL-атак защитят и классические техники харденинга.
Харденинг
Рассмотрим некоторые из них на примере docker. Помним, что все эти техники легко переносятся на другие системы контейнеризации либо оркестрации контейнеров.
На что нужно обратить внимание:
Запуск приложения под непривилегированным пользователем. Не запускаем приложения под root, привилегированным пользователем в контейнере. Это звучит как детская, простая мера, но на самом деле в контексте LotL-атак она отбивает большое количество техник, потому что злоумышленник просто не сможет выполнить их из-за недостатка привилегий.
Ограничение набора доступных capabilities и использование --no-new-privileges. Нужно аккуратно ограничивать набор capabilities, доступных вашим контейнерам. Это понижает спектр доступных привилегий для злоумышленника и усложняет атаку.
Использование read-only файловой системы. Immutable Infrastructure — наше всё. Понятно, что не везде и не всегда это можно применять на практике. Но если есть критичные для вас контейнеры, хорошо бы стремиться к использованию read-only файловой системы в них, если это возможно. Это достаточно сильно тоже усложнит жизнь злоумышленника внутри контейнера.
Ещё две более продвинутые техники:
Использование стандартных механизмов безопасности Linux — это мандатная система управления доступом AppArmor или SELinux. Они позволяют задавать для контейнеров или вообще для процессов профили безопасности, которые определяют, куда процесс может переходить, что просматривать. Это тоже может усложнить жизнь злоумышленникам.
Использование seccomp. Этот механизм позволяет ограничить набор доступных процессу системных вызовов. Если вы хорошо понимаете, что делает ваш контейнер, то можете с его помощью усложнить жизнь злоумышленнику.
Понятно, что все техники харденинга, про которые мы сказали и будем говорить дальше, невозможно использовать одновременно уже в проде. Речь про то, что их можно как-то здраво комбинировать, и это усложнит жизнь злоумышленнику.
Отключение межконтейнерного взаимодействия (--icc=false). Помним, что по дефолту в docker все контейнеры попадают в дефолтную сеть docker и доступны по сети. А значит, нам нужно отключить inter-container communication (межконтейнерное взаимодействие), чтобы исключить горизонтальное продвижение.
Ограничение использования сети. Те контейнеры, которые не должны попадать во внешнюю сеть, не должны никуда больше попадать и в в docker. То есть контейнеры не должны выходить во внешний мир, если они не осуществляют с ним коммуникацию.
Использование rootless режима для контейнеров. Например, когда docker-демон работает не от root. Используя технику побега из контейнера, у вас не получится так, что злоумышленник окажется root’ом на хостовой системе.
Использование user namespace. Когда происходит маппинг ID и пользователь в контейнере не равняется пользователю root на хостовой ОС.
Drop capabilities
Пример того, как в docker можно дропнуть все capabilities:
![](https://habrastorage.org/getpro/habr/upload_files/8c3/63f/7dc/8c363f7dc345322e50f678876ecb8306.jpg)
Думаю, многие видели этот пример. Мы можем использовать флажок drop для того, чтобы при запуске контейнера отобрать у него все capabilities, а потом нужные наборы capabilities выдать точечно, в зависимости от того, какие нужны.
Необязательно это сделать в docker, можно в Kubernetes и аналогах.
AppArmor
AppArmor — это достаточно крутая штука. Мы можем написать профиль и позапрещать всё то, что не должно там выполняться.
Пример AppArmor профайла:
![](https://habrastorage.org/getpro/habr/upload_files/1b6/7b8/83e/1b67b883e8315969c463f3198acee8d8.jpg)
В конечном итоге злоумышленник, даже попав внутрь, ничего не сможет выполнить.
![](https://habrastorage.org/getpro/habr/upload_files/739/436/fd2/739436fd2013d1965cc1d7098a873348.jpg)
Но есть интересный нюанс. Писать AppArmor профайлы больно, это достаточно тяжёлый труд. Поэтому чтобы не запрещать всё, что не используем, давайте в принципе не будем это класть в контейнер.
Осознанные сборки
Используем внутри только то, что необходимо.
Выбираем инструменты с умом. Получив сегодняшние знания, вы уже понимаете, что есть определённый набор утилит, которые могут скорее навредить, чем принести пользу.
Делаем это на этапе планирования. Ещё на этапе проектирования системы закладываем, какие инструменты не стоит использовать, потому что могут быть использованы в атаке.
Минималистичные образы
Distroless образы, тоже помогают защититься от LotL-атак, по той простой причине, что в них нет ничего, что можно использовать для развития атаки.
![](https://habrastorage.org/getpro/habr/upload_files/b6c/7a5/254/b6c7a525490961d5226429e43157cab7.png)
На диаграмме не видно подписи, но Alpine — это самый маленький дистрибутив Linux:
![](https://habrastorage.org/getpro/habr/upload_files/fc6/472/a40/fc6472a40f06ba22c235ace3217b60ae.png)
Получается, меньше образ — меньше проблем. Меньше образ — меньше кода, меньше ошибок в этом коде, меньше уязвимостей, меньше поверхность атаки и меньше шансов, что что-то смогут найти и как-то этим воспользоваться.
Поведенческий анализ
Напоследок хочется сказать, что от LotL-атак помогают различные инструменты поведенческого анализа, применимые к контейнерным инфраструктурам, например, Falco или проприетарная система Luntry, которые смотрят на то, что в контейнере делается и разнообразными способами или по заранее расписанным профилям, либо с помощью машинного обучения как-то пытаются обнаруживать в том, как ведет себя контейнер, какие-то аномалии.
![](https://habrastorage.org/getpro/habr/upload_files/d00/a71/fb1/d00a71fb1448b0ec9da45ea9daece0a8.png)
Против LotL-атак такие инструменты могут быть эффективны, потому что если даже контейнер неожиданно начал делать с помощью легитимной утилиты echo etc/ passwd, инструмент поведенческого анализа, скорее всего, сможет это обнаружить.
Выводы
Злоумышленникам зачастую не нужны хитроумные эксплойты и какие-то хакерские инструменты. На ваших системах уже и так всё есть. С помощью нативных инструментов можно проводить широкий спектр атак.
Такие инструменты не выявляются сканерами. На них не обращается достаточное внимание, потому что этот же инструмент, которым я пользуюсь — что с ним может быть не так?
В заключение ещё раз напомним, что делать, чтобы такие атаки усложнять:
разделять образы для прода и для dev;
уделять внимание харденингу контейнеров, пытаться его делать, потому что многие этот пункт просто игнорируют;
возможно, использовать системы поведенческого анализа;
желательно всё это учитывать с момента проектирования вашего приложения.
Мы уже готовим для вас новый материал о защите от хакеров — про таксономию изоляции. Ждём вас на Saint HighLoad++ 2024. А пока можете посмотреть выступление Алексея и Антона с предыдущего HighLoad.