За пять шагов мы разберемся в том, как строится атака на облачную инфраструктуру:

  1. Демонстрация — показываем последствия.

  2. База по облакам — здесь про облачную терминологию и сервис метаданных.

  3. Атаки с применением сервиса метаданных — разбор kill chain.

  4. Построение защиты — про превентивные и реактивные меры защиты.

  5. Заключение — чему мы сегодня научились.

Глава 1. Демонстрация

Справа у меня консоль Яндекс Облака, там открыт фолдер «prod» и видны три ну о-о-очень важные виртуальные машины. В левой части экрана терминал виртуальной машины «test-stand-yc», данная ВМ расположена в фолдере «test».

Как мы видим, запуск одной команды на тестовой виртуалке приводит к удалению всех ресурсов в фолдере «prod». Давайте разбираться. Запаситесь терпением, а я сейчас доступно объясню всю базу.

Дисклеймер: статья носит ознакомительный характер. Любые попытки злоупотребления данной информацией незаконны и могут повлечь за собой уголовное преследование в соответствии со статьями 272 и 273 УК РФ.

Глава 2. База по облакам

Рассмотрим структуру Яндекс Облака.

  • Всё начинается с облачной организации — это корень, в котором находится список облаков.

  • Каждое облако подобно директории с проектами.

  • Сами проекты называются фолдерами, и в них расположены облачные ресурсы: виртуальные машины, объектные хранилища, кластеры k8s, бессерверные контейнеры, частные сети, базы данных, балансировщики, очереди сообщений, функции и многое другое.

Как пользователь взаимодействует со всем разнообразием облачных ресурсов? Всё просто: любые действия пользователя в облаках — результат работы с API облачного провайдера. Будь то нажатие на кнопки в браузерной консоли, выполнение команд в Command Line Interface, раскатка Terraform манифестов или запросы, отправленные посредством curl. Для совершения любых действий пользователю нужен токен, который подтвердит его привилегии.

Identity and Access Management (IAM) — сервис, отвечающий за аутентификацию и авторизацию пользователя, управление правами доступа пользователей. Соответственно, именно IAM выдаёт пользователям временные IAM-токены.

В Яндекс Облаке существует три типа учетных записей:

№1. Яндекс ID — личные пользовательские учетные записи, которые имеются у каждого пользователя одноименного почтового сервиса.

№2. Федеративный аккаунт — доменные пользователи, полученные в результате настройки федерации, это по сути процесс интеграции вашего Identity Provider (IDP) с облачной организацией.

№3. Сервисный аккаунт (SA) — non human identity, аккаунт, от имени которого программы могут управлять ресурсами. Есть несколько способов работы с облаками от лица сервисного аккаунта.

Ключ доступа. Любому сервисному аккаунту можно создать ключ, используя который, программа сможет действовать от его лица. Ключей бывает три вида:

  • Статический — идентификатор из 25 символов и секретная часть из 40 символов, используется для работы с объектным хранилищем.

  • Авторизованный — JSON-файл с ключом, созданным RSA-2048 или RSA-4096. Используется для получения IAM-токена посредством отправки запроса в API.

  • API ключ — используется для работы с ограниченным списком сервисов, не поддерживающих аутентификацию с помощью IAM-токенов. Отличительная особенность API ключа — возможность указать его область действия. Иначе говоря, сервисный аккаунт имеет ряд прав доступа, а его API ключ может иметь ещё более узкую область применения.

Имперсонация — это процесс, в ходе которого пользователь обращается в IAM и обменивает свой IAM-токен на IAM-токен сервисного аккаунта. Разумеется, для совершения подобного действия у пользователя должны быть права доступа на сервисный аккаунт.

Привязка: когда при создании или изменении ресурса напрямую указывается, от имени какого сервисного аккаунта необходимо проводить интеграции с другими облачными ресурсами. Представьте, что вашей виртуальной машине необходимы права доступа на просмотр мониторинга и создание снимков других виртуальных машин, чтобы по расписанию выполнять рутинные задачи. Необходимо создать сервисный аккаунт, выдать ему необходимые сервисные роли, привязать к нужной ВМ — и, вуаля, всё работает само, без каких-либо ключей, упрощая команде работу, ведь не нужно регулярно проводить ротацию ключей доступа.

А работает этот механизм благодаря сервису метаданных.

Сервис метаданных

Instance Metadata Service (IMDS), известный как сервис метаданных, необходим для авторизации облачных ресурсов. Сервис предоставляет виртуальной машине доступ к двум каталогам данных:

  1. computeMetadata — здесь можно найти id облака и фолдера, название, описание, спецификацию виртуальной машины, а самое главное — IAM-токен привязанного сервисного аккаунта. Токен доступен по ключу instance/service-accounts/default/token.

  2. user-data — название говорит само за себя, здесь лежат пользовательские данные. Например, cloud-init скрипты, те, что необходимы для настройки ВМ, после установки базового образа.

Amazon (AWS)

Google (GCP)

Microsoft (Azure)

V1
GET

V2
PUT + GET

GET + заголовок

Metadata-Flavor: Google

Get + заголовок

Metadata: true

Изначально для получения IAM токена от сервиса метаданных в облаках AWS достаточно было выполнить один GET-запрос и получить в ответе токен.

Примерно в 2019 году в Amazon осознали, что наличие уязвимого веб-сервера сильно упрощает злоумышленникам горизонтальные перемещения и повышение привилегий. Так появилась вторая версия, которая требует PUT-запрос, получить ответ и направить GET-запрос.

Google Cloud platform, оглядываясь на опыт Amazon, решили, что для получения токена необходимо отправить GET-запрос, но с указанием заголовка «Metadata-FLavor: Google», обосновывая это тем, что уязвимые веб-серверы, разрешающие подставить кастомный заголовок в запрос — крайне редкое явление.

Microsoft со своим Azure пошли аналогичным путем: GET-запрос + заголовок «Metadata: true».

Яндекс Облако же поддерживало AWS V1, но сейчас метаданные доступные только в формате GCP. Вообще виртуальная машина постоянно взаимодействует с сервисом метаданных.

Google_guest_agent — утилита, которая предустановлена в каждом базовом образе, предлагаемом Яндекс Облаком. Если ВМ развёрнута не из базового образа, то на GitHub есть публичный репозиторий, содержащий эту же утилиту для других, менее популярных образов. В документации мне не удавалось найти статьи о данной утилите, обнаружил её при запуске команды socket statistics. Так для чего же нужен этот агент:

  • Сборка метаданных (каждые 30 секунд агент обращается к IMDS).

  • Управление SSH ключами.

  • Обработка команд с GCP (OS Login, shutdown и т.п.).

  • Мониторинг.

В Яндекс Облаке сервис метаданных находится в подсети link-local по адресу 169.254.169.254, точно так же, как у Amazon, Google и Microsoft. Подсеть 169.254.0.0/16 является частной, описана в RFC 3927, не маршрутизируется и предназначена для тех случаев, когда в сети отсутствует DHCP-сервер или произошёл конфликт (кто-то назначил статический IP-адрес, используя уже зарезервированный). Работает это вот как: компьютер выполняет ARP-пробу, сгенерировав себе адрес при помощи генератора псевдослучайных чисел, до тех пор, пока не найдёт себе свободный адрес.

Скриншот с Wireshark: работа google_guest_agent
Скриншот с Wireshark: работа google_guest_agent

На скриншоте выше видно, что информация от сервиса метаданных поступает по протоколу HTTP в открытом виде. Допустим, что злоумышленник получил доступ к публичной виртуальной машине, к которой не привязан сервисный аккаунт. И у него возникает непреодолимое желание прослушать трафик и найти там IAM-токены, полученные другими ВМ, находящимися с нами в одной сети. Ну или расчехлить Bettercap, провести ARP spoofing и всем соседним ВМ рассказать, что мы — сервис метаданных, за токеном надо ходить к нам.

Идеи интересные, но нереализуемые. Связано это с изоляцией на уровне гипервизора. Дело в том, что виртуальные машины не имеют сетевого интерфейса в link-local, всё взаимодействие с сервисом метаданных идёт через гипервизор. Таким образом, подслушать трафик или отравить кэш ARP не представляется возможным. А вот вдогонку ещё пару облачных терминов, которые нам понадобятся:

Virttual Private Cloud (VPC) — частная сеть, по умолчанию содержит три подсети в различных зонах доступности (это необходимо для повышения отказоустойчивости) и default группу безопасности, которая не ограничивает входящий и исходящий трафик. В Яндекс Облаке не предусмотрена маршрутизация между двумя VPC. Другими словами, нет сетевой связности между двумя облачными сетями. Если таковая требуется, то в рамках одного облака можно подсеть перенести из одного фолдера в другой, можно создать VPN туннель через публичный Интернет или наладить сетевое взаимодействие через interconnect.

Security Group — группы безопасности — механизм разграничения сетевых доступов в облаках. Работает следующим образом: есть список разрешений для входящего и исходящего трафика, если нужно с ВМ сходить в публичный репозиторий, то нет необходимости открывать входящий трафик от публичной репы до виртуалки, достаточно разрешить исходящий трафик, ведь SG работают как Statefull firewall, то есть сохраняют состояние соединения. Если для трафика не находится разрешающего правила, то он не пройдет, здесь всё довольно просто.

Глава 3. Атаки с применением сервиса метаданных

А теперь самый интересный блок: разберёмся, как устроены атаки на облачную инфраструктуру. Начнём с описания тестового стенда: в облаке website-4-leads есть два фолдера: test и prod. В тестовом проекте расположена виртуальная машина test-stand-yc и к ней привязан сервисный аккаунт.

Представим, что на test-stand-yc запущен веб-сервер, уязвимый к SSRF-атакам. Server Side Request Forgery хорошо известная атака, когда клиент запрашивает у сервера информацию, размещённую на третьем ресурсе. Если сервер не фильтрует запросы клиента и возвращает ответ, то данное поведение не является ожидаемым.

SSRF
SSRF

На демонстрации выше видно как на терминале справа (test-stand-yc) запускается уязвимый веб сервер, затем клиент на терминале слева (shark) выполняет запрос curl: http://10.129.0.15:8080/fetch?url=http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token

В ответ от сервера получает IAM-токен. Имея IAM-токен можно отправлять запросы в API Яндекс Облака и разобраться в правах доступа полученного сервисного аккаунта.

bash скрипт
bash скрипт

Ключевой этап получения валидного токена пройден. Теперь я продемонстрирую открытые нам возможности.

Запустим bash-скрипт, который расположен в моём публичном репозитории. Скрипт исследует права доступа сервисного аккаунта и предлагает уничтожить все виртуальные машины, указав id фолдера. Как мы видим, сервисный аккаунт test-stand-sa имеет роль admin на всё облако, что позволяет ему удалить ресурсы в проекте prod.

Подведем итоги нашего kill chain:

  1. Получению первоначального доступа способствует наличие публично доступной виртуальной машины.

  2. Для исполнения требуется SSRF или RCE (Remote Code Execution, произвольное выполнение кода).

  3. Недостаточная сетевая сегментация позволит злоумышленнику сканировать другие облачные ресурсы в поисках SSRF и RCE.

  4. При нахождении привилегированного сервисного аккаунта злоумышленник сможет действовать от его лица. Право сервисного аккаунта авторизовываться на ВМ с помощью OS login также стоит считать высокой привилегией, так как позволяет действовать от лица другого SA, привязанного к ресурсу.

  5. IAM-токен – заветная цель, расширяющая возможности злоумышленника. Имея токен с высокими привилегиями, можно управлять облачной инфраструктурой.

Глава 4. Построение защиты

Превентивные меры

№1. Модель угроз

Помогает определить актуальные угрозы, оценить вероятность и последствия их успешной реализации (читай — оценить риски реализации этих угроз), разработать меры митигации. 

Да, большинство специалистов в области информационной безопасности знают это словосочетание и закатывают глаза, когда его слышат. Я точно так же реагировал, пока не сделал первую действительно на что-то годящуюся модель. Соль в том, что есть уже готовая матрица действий злоумышленника от MITRE, которая всё описывает высокоуровнево.

Пример матрицы

Получение доступа

Исполнение

Закрепление

Повышение привилегий

Обход мер защиты

Получение доступа к секретам

Разведка

Перемещение по инфре

Сбор данных

Воздействие

Фишинг

Облачные ресурсы

Атака на цепочки поставок

Эскалация на уровне виртуальной машины / сервиса

Отключение средств защиты

Получение аутентификационных данных

Обнаружение учетных записей и групп пользователей

Таргетированный фишинг

Сбор данных с облачных ресурсов

Деструктивные действия над данными

Эксплуатация уязвимости на публично доступном ресурсе

Средства администрирования

Создание новых объектов

Эскалация на уровне гипервизора

Некорректная конфигурация средств защиты

Чтение из хранилища секретов

Обнаружение облачных ресурсов

Сервисы удаленного управления

Сбор учетных записей из IAM

Дефейс

Злоупотребление доверием

Бессерверные вычисления

Изменение конфигурации

Эскалация на уровне IAM облачного провайдера

Скрытие присутствия

Перехват пользовательской сессии

Обнаружение логов

Заражение общедоступных ресурсов

Кража финансовых активов

Использование действительных аутентификационных данных

Платформа CI/CD

Создание задач, исполняемых по триггеру, в планировщике задач

Эскалация на уровне домена корпоративной службы каталогов

Изменение иерархии

Поиск уязвимых ресурсов

Нецелевое использование ресурсов

Под спойлером находится моя вольная интерпретация матрицы MITRE, а вот алгоритм составления модели угроз по данной матрице:

  • Сначала для каждой техники составляется описание, включающее источник угрозы (внутренний или внешний), CWE уязвимостей, защищаемые активы.

  • Анализируются уже реализованные вокруг и на самом защищаемом активе технические и организационные меры защиты и контрольные процедуры (различные регулярные аудиты, периодические инструментальные проверки и т.д.).

  • Определяются и применяются правила оценки вероятности успешной реализации угроз с учётом полноты, достаточности, эффективности мер и контролей.

  • Оцениваются последствия воздействия как непосредственно на защищаемый актив (что можно украсть, какой бизнес-процесс встанет, сколько клиентов почувствует на себе боль утраты любимого сервиса).

На выходе, если всё сделаете правильно, сможете понять, кто и что вам действительно угрожает (если не хотите бороться с фантомами), сколько какая угроза будет стоить с учетом вероятности.

В общем получите базовую оценку риска (низкий, средний, высокий, только не забудьте шкалу определить). А уже с ней сможете не только понять, какие меры делать и с каким приоритетом, а чем можно (или даже нужно, да-да и такое бывает) пренебречь.

Особенно такой подход должен понравиться, если вы не Скрудж Макдак и ваш бюджет на защиту ограничен. Оказывается, что если не делать документ ради галочки, то модель угроз, основанная на матрице MITRE, может покрыть большинство инцидентов, даже если вы не знаете в деталях весь kill chain каждой конкретной атаки.

№2. Сетевые доступы

Корректная сетевая сегментация не позволит злоумышленнику перемещаться по вашей инфраструктуре. Что нужно сделать:

  1. Отказаться от Default-групп безопасности вида any-any 0.0.0.0/0. Да, это не так просто, если вы уже выпустили все проекты, не контролируя их сетевое взаимодействие. Нужно будет окунуться в нюансы доступов для managed Kubernetes и прочих ресурсов.

  2. Убедиться в отсутствии роутинга между VPC на маршрутизаторах в интерконнекте. Любая крупная компания будет стремиться расширить канал связи с облачным провайдером и приходит к сервису interconnect. Простыми словами, это когда в ЦОДе облачного провайдера и его клиента устанавливается оборудование для шифрования трафика в нескольких точках присутствия, и локальные сети клиента анонсируются в облако. Таким образом, в клиентских подсетях можно будет размещать облачные ресурсы, и они будут ощущаться как часть инфраструктуры клиента, а не внешняя сущность. Подводный камень здесь кроется в Virtual Routing and Forwarding (VRF): каждая VPC должна жить в своём виртуальном маршрутизаторе, иначе появляется сетевая связность между двумя облачными VPC, минуя контур клиента.

  3. Фильтрация на бордере. Любой трафик исходящий от клиента до облака и наоборот должен фильтроваться на вашем NGFW.

№3. Ролевая модель

Чем больше проектов, тем больше ролей необходимо выдать командам функционального сопровождения. У вас должно быть чёткое понимание: какие роли можно выдавать, а какие нельзя, а также кому и какая роль уже выдана. В облаках есть базовые и сервисные роли. Базовая роль (admin, editor, viewer, auditor) выдаваемая на организацию, облако или фолдер, означает, что у пользователя есть соответствующий доступ ко всем сервисам. Следует выдавать роли гранулярно, используя сервисные роли, например для загрузки файлов в объектное хранилище не требуются права администратора, достаточно выдать сервисную роль storage.uploader.

Сетевой доступ и ролевая модель равнозначны в своей важности. Если перед вами стоит вопрос: что делать в первую очередь, то начните с того, что вам ближе, проще и что быстрее получится завершить.

Реактивные меры

№1. Cloud Security Posture Management (CSPM) — инструмент, осуществляющий анализ конфигурации облачной инфраструктуры.

Для его работы нужен только сервисный аккаунт с ролью auditor и железо, на котором будет работать сам сканер. В консоли CSPM можно наблюдать красивые отчёты о найденных мисконфигах, разбитые по категориям, ресурсам и критичности. Это направление еще только набирает обороты и на рынке не так много продуктов. По своей сути это API-клиент, который шлет запросы на сторону облачного провайдера, делает выводы о конфигурации ресурсов и выдаёт отчеты в красивом UI.

Пример: обнаружения публично доступной ВМ с высокими привилегиями.

  1. Получить список сервисных аккаунтов — метод ServiceAccounts.list.

  2. Получить список прав доступа на организацию — метод Organization.ListAccessBindings.

  3. Получить список облаков — метод Cloud.List.

  4. Получить список прав доступа на облако — метод Cloud.ListAccessBindings.

  5. Получить список фолдеров — метод Folder.List.

  6. Получить список прав доступа на фолдер — метод Folder.ListAccessBindings.

  7. Получить список виртуальных машины — метод Instance.List.

  8. Получить список групп безопасности — метод SecurityGroup.List.

Далее если на публичной ВМ с default группой безопасности назначен сервисный аккаунт, имеющий одну из указанных ниже ролей, мы формируем описание мисконфига для отчёта.

Список привилегированных ролей
bad_roles_list = [
    'access-transparency.admin',
    'admin',
    'alb.admin',
    'audit-trails.admin',
    'audit-trails.editor',
    'billing.accounts.admin',
    'cic.admin',
    'cic.editor',
    'cloud-router.admin',
    'cloud-router.editor',
    'compute.admin',
    'compute.editor',
    'container-registry.admin',
    'datalens.admin',
    'datalens.creator',
    'datalens.instances.admin',
    'dns.admin',
    'dspm.admin',
    'editor',
    'iam.serviceAccounts.admin',
    'k8s.admin',
    'load-balancer.admin',
    'logging.admin',
    'mdb.admin',
    'organization-manager.organizations.owner',
    



'organization-manager.admin',
    'organization-manager.federations.admin',
    'resource-manager.admin',
    'smart-captcha.admin',
    'smart-web-security.admin',
    'speech-sense.editor',
    'storage.admin',
    'quota-manager.requestOperator',
    'vpc.admin',
    'vpc.securityGroups.admin',
    'ydb.admin'
]

№2. SOC playbook — сценарии реагирования на облачные инциденты.

В Яндекс Облаке есть сервис Audit Trails, он поставляет Control и Dataplane логи. Для упрощения понимания: Control — изменение конфигурации, создание учётных записей, а Dataplane — конкретные запросы пользователя к БД, события создания и удаления объекта в хранилище.

Начать можно с составления перечня недопустимых событий. Затем дополняем это всё контактной информацией, ищем нужные нам логи в документации и описываем меры реагирования. Мало составить плейбук — нужен SIEM для сбора логов, затем нужен IRP для написания правил реагирования и, самое важное, — команда специалистов, которая умеет работать с этими продуктами и даже заранее знает, какие события хочет отслеживать.

Пример 1: обнаружение подбора кред к базе данных.

Событие DatabaseUserLogin завершилось со статусом "User login failed" более N раз за заданный промежуток времени.

Пример 2: Выдана высоко привилегированная роль.

Рассматриваем события UpdateServiceAccountAccessBindings, UpdateFolderAccessBindings, UpdateCloudAccessBindings, UpdateOrganizationAccessBindings, описанные в документации и ищем выдачу высоко привилегированной роли.

Как выглядит событие:
"request_parameters":{
  "folder_id": "xxxxxxxxxx",
  "access_bindings_deltas": [
    {
      "action": "ADD",
      "access_binding": {
        "role_id": "admin",
        "subject": {
          "id": "xxxxxxxxxx",
          "type": "serviceAccount"
        }
      }
    }
  ]
}

Глава 5. Заключение

В заключении приведу слайд с Yandex Cloud Security Day, где коллеги собрали статистику по получению первоначального доступа к облачной инфраструктуре. Первые три строчки отлично вписываются в разобранный нами сегодня вектор атаки.

Что делать теперь?

Специалистам по информационной безопасности — разработать ролевую модель, если её нет и проверить выданные пользователям и сервисным аккаунтам права доступа.

Облачным инженерам — проверить свою инфраструктуру, поискать публичные ресурсы, привилегированные сервисные аккаунты, возможно, даже доступ для публичных групп пользователей к вашим ресурсам.

Application Security — пересмотреть найденные ранее SSRF и RCE. Для облачных ресурсов критичность данной уязвимости может вырасти в разы.

Сетевым инженерам — проверить сетевую сегментацию, выданные ранее доступа, присмотреться к интерконнекту, если он используется.


А если вам нравится искать уязвимости, приглашаем на соревнование по спортивному хакингу, где вам предстоит решать таски на поиск уязвимостей в системах. Призовой фонд: 3 100 000 рублей, на команду можно получить до 450 000. Соревнование ройдет с 13 по 14 сентября в 2-х форматах: онлайн или офлайн по дополнительной регистрации в IT-хабах Москвы, Санкт-Петербурга и Екатеринбурга.

  • Регистрируйтесь на соревнование Capture The Flag (CTF) по ссылке.

  • Собирайте команду или готовьтесь к игре в соло (если вы не можете найти напарников, мы вам поможем и объединим с другими игроками).

  • Выбирайте один из 3 треков (для IT-специалистов, для профи или для студентов).

  • Решите как можно больше тасков 13-14 сентября.

  • Получите награду.

Ждём вас — будем вместе сёрфить на CTF!


Рекомендуемые статьи:

Я управляю тестированием ИИ-моделей 4 года. Что я понял за это время?
Привет! Меня зовут Валентин, я — руководитель направления тестирования моделей машинного обучения в ...
habr.com
Расчёты уровня «Хард» для задачи распределения бюджета в категорийном кэшбэке
Часто нам нужно распределить бюджет какой-то акции/программы так, чтобы… Это «чтобы» может отличатьс...
habr.com
Куда пойти учиться?
Я уже ответила себе на этот вопрос, но спустя 15 лет вернулась к нему как организатор магистратуры и...
habr.com
«Банкоматный» тур по Корее: краткий фотоочерк
Всем привет! Меня зовут Александр Лещев, недавно я попутешествовал по Корее. Поездка была рабочей, т...
habr.com
Вы точно их собеседовали: 8 личностей, которые приходят на интервью
Сейчас я активно нанимаю ПМ-ов, и на собеседования приходят совершенно разные кандидаты. Половина из...
habr.com

Комментарии (0)