וואלההוגש כתב אישום נגד תושב בית שמש שניסה לרצוח את בן זוגה של גרושתוBollywood HungamaEXCLUSIVE: Ajay Devgn-Rohit Jugraj’s horror thriller titled SuryasparshThe Jerusalem Post'No cure for stupidity': Israel's Football Association blasts Irish coach's calls to boycott matchRTP DesportoCorridas de Fórmula 1 mais curtas a partir de 2027PunchVIDEO: NSCDC busts illegal fruit juice factory in Lagos, arrests twoInquirerPalace on transport strike, fuel price increase: Fare hike is not the solutionSouth China Morning PostWere the Serbian military’s new robot dogs built using Chinese technology?Collider‘Stranger Things’ Has Officially Lost Its Streaming EdgeMalay MailDo not usurp the constitutional function of the DKU — Hafiz HassanThe RegisterLongtime SUSE staff asked if they'd opt for 'voluntary separation'Daily MaverickWHAT’S COOKING: A pair of meaty recipes to plan for Braai DayCBS NewsIran's president heads for U.N. summit ahead of possible Trump meeting
The Daily Newsstand · Free, Always
Tuesday, September 22, 2026

Калькулятор с ключами: как чтение одного файла привело к компрометации публичного облака

Translate

В статье разберем, как через LFR-уязвимость во внешнем сервисе облачной инфраструктуры удалось полностью скомпрометировать облако.

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

Анализ сервисов внешнего периметра

В ходе внешнего пентеста инфраструктуры крупной IT-компании команда Бастиона обнаружила публичное облако cloud.company.com, которое сразу стало одной из приоритетных целей. Это большой многокомпонентный сервис: облачный API, организации и проекты, вычислительные ресурсы, балансы и биллинг. 

В ходе разведки инфраструктуры облака мы выделили домены, названия которых указывали на связь с основным сервисом. Один из них, calc.company.com, оказался сервисом расчета тарифов. Отдельно отметили домен cloud-admin.company.com: судя по названию, он относился к административной части облака.

Цепочка атаки

1. Поиск эндпоинтов

Список известных путей сервиса собрали связкой утилит getallurls и waybackurls — они тянут URL из интернет-архива и сервисов индексации. Дополнительно прошлись по JS-коду в поисках актуальных эндпоинтов: самым интересным оказался /download_report, эндпоинт выгрузки отчетов. При обращении без параметров он отдавал ошибку «нужен параметр file_name». Очевидный кандидат на проверку уязвимостей класса LFR и SSRF.

2. Проверка на LFR

Уязвимость чтения локальных файлов (Local File Read, LFR) возникает, когда приложение отдает содержимое файла по имени, которое контролирует пользователь, и при этом не фильтрует путь. Строго говоря, это именно чтение, а не включение: файл возвращается в ответе, но не исполняется.

Обычно LFR эксплуатируют в связке с Path traversal — обходом каталогов с помощью последовательностей ../../../. Они позволяют выйти за пределы каталога, к которому приложение дописывает пользовательский ввод. 

Здесь этого не потребовалось: сервис принимал абсолютный путь. Так бывает в случаях, когда имя файла попадает в функцию чтения без фиксированного базового каталога, и тогда /etc/passwd и подобные файлы читаются как есть; либо когда базовый путь задан, но абсолютный путь его перекрывает (сегмент, начинающийся со слэша, отбрасывает всё, что стояло до него).

В параметр file_name подставили абсолютный путь к системному файлу:

GET /download_report?file_name=/etc/shadow HTTP/1.1
Host: calc.company.com

Сервер вернул содержимое /etc/shadow. Запрос не требовал авторизации, а приложение позволяло читать файлы от пользователя root.

Скриншот 1. Содержимое /etc/shadow в ответе сервера на запрос к /download_report?file_name=/etc/shadow .

Скриншот 1. Содержимое /etc/shadow в ответе сервера на запрос к /download_report?file_name=/etc/shadow .

3. От чтения файлов к секретам приложения

Возможность чтения файлов открывает несколько сценариев развития атаки. 

  • Можно выгрузить исходники приложения и поискать в них следующую уязвимость. 

  • Можно читать секреты процесса прямо из procfs: переменные окружения и аргументы запуска в /proc/self/environ и /proc/self/cmdline

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

Путь к конфигу нашли перебором файлов и директорий. На несуществующий путь сервис возвращал ошибку, на существующий — отдавал код 200, но без листинга директории.

GET /download_report?file_name=/src/config.yaml HTTP/1.1
Host: calc.company.com

В ответе лежали ключи партнерского API в открытом виде:

serverspace:
  url: https://apipartner.company.com
  key_calc: B2F04642-40E8-218E-28FB-5C8D910A7D36
  key_billing: 7E38FF3A-C714-1587-71CB-9E72302FAB3E
Скриншот 2. Ключи партнерского API в файле /src/config.yaml, полученном через LFR. Секреты key_calc и key_billing хранятся в открытом виде.

Скриншот 2. Ключи партнерского API в файле /src/config.yaml, полученном через LFR. Секреты key_calc и key_billing хранятся в открытом виде.

Два ключа: key_calc для учетной записи калькулятора и key_billing для биллинга. Оба вели к партнерскому API apipartner.company.com. Калькулятор тарифа хранил у себя ключ, которым «ходил» в биллинговый сервис облака.

4. Партнерский API

Ключи у нас были, оставалось понять, как ими авторизоваться и к каким методам обращаться.

В документации облака описан только основной API: ключ к нему передается в заголовке CLOUD-API-KEY. О партнерском API, к которому вели key_calc и key_billing, в документации не было ничего.

Мы предположили, что ключи — это сессионные идентификаторы, и передали их в стандартном заголовке Authorization: Bearer. Сработало: Authorization: Bearer {key_billing} авторизовал запрос.

Базовый адрес партнерского API был в том же конфиге (url: https://apipartner.company.com). Пути к методам взяли из документации основного облачного API: там они шли через /v1/. Документации по партнерскому API не было, поэтому мы попробовали ту же структуру, но с /v2/. Сработало.

https://apipartner.company.com/v2/accounts

/v2/accounts вернул полный список пользователей облака с их ролями и метаданными.

Скриншот 3. Ответ /v2/accounts. Перечисление пользователей облака с ролями, включая привилегированные учетные записи.

Скриншот 3. Ответ /v2/accounts. Перечисление пользователей облака с ролями, включая привилегированные учетные записи.

Среди учетных записей выбрали привилегированные. Две оказались с полными правами — все роли, которые есть в системе. Кроме них нашлось еще десять учетных записей с ролями admin, manager, help. Ключ сервиса, который считает тарифы, дал нам возможность получить все административные учетные записи в облаке.

5. Подбор пароля привилегированной учетной записи

Выбрали две учетные записи с полными правами и запустили подбор пароля по словарю. Rate-limit на форме входа был, но привязывался к IP-адресу, а не к учетной записи. Ротация IP сняла это ограничение, и мы смогли подобрать словарный пароль к одной из этих учетных записей.

6. Вход в панель управления облаком

С полученной парой логин-пароль мы авторизовались в панели:

https://cloud.company.com

После входа система автоматически перенаправила нас в административный компонент (Admin Area):

https://cloud-admin.company.com/
Скриншот 4. Административная панель облака от имени привилегированной учетной записи: список организаций и управление ими. Интерфейс панели анонимизирован.

Скриншот 4. Административная панель облака от имени привилегированной учетной записи: список организаций и управление ими. Интерфейс панели анонимизирован.

Учетная запись с полными правами в панели позволяет:

  • получить доступ к любой учетной записи в облаке;

  • получить доступ к вычислительным ресурсам любой организации;

  • создавать промокоды на пополнение баланса;

  • управлять конфигурацией облака.

Скриншот 5. Раздел «Аккаунты» под той же учетной записью: видны все учетные записи облака, у текущего пользователя роль Admin. Интерфейс панели анонимизирован.

Скриншот 5. Раздел «Аккаунты» под той же учетной записью: видны все учетные записи облака, у текущего пользователя роль Admin. Интерфейс панели анонимизирован.

Такой уровень доступа означает, что мы можем управлять любой учетной записью и вычислительными ресурсами в облаке. Фактически это полный контроль над ИТ-инфраструктурой любой организации-клиента.

Схема 1. Цепочка атаки на облачную инфраструктуру

Схема 1. Цепочка атаки на облачную инфраструктуру

Разбираемся в причинах

Атака стала возможной из-за сочетания трех факторов. Ни один из них сам по себе не привел бы к полной компрометации облака, но вместе они сложились в полную цепочку — от чтения локальных файлов до отсутствия 2FA (двухфакторной авторизации).

  1. Импакт LFR-уязвимости определяется не самой возможностью чтения, а тем, как ее эксплуатируют. В большинстве случаев LFR — не финальная находка, а точка входа: импакт зависит от того, что делать дальше. Системные файлы (/etc/passwd, /etc/shadow) подтверждают сам факт чтения. Настоящая цель — артефакты приложения: конфиги, файлы окружения, исходники, логи, приватные ключи. Дальше процесс раскручивается в зависимости от стека и функциональности приложения: до SSRF, до выгрузки исходников и поиска в них следующей уязвимости, а если чтение удается довести до включения (LFI/RFI), то и до прямого выполнения кода.

  2. Второстепенный сервис не должен носить ключ с привилегиями биллинга. Калькулятор держал в конфиге ключ к биллинговому API, и этот ключ открывал /v2/accounts, то есть перечисление всех пользователей облака вместе с их ролями. Для расчета тарифа такие права не нужны: калькулятору достаточно узкого набора методов (тарифные планы, цены), но никак не списка всех администраторов платформы. Будь у калькулятора только правильно ограниченный ключ, утечка конфига через LFR не дала бы доступа к привилегированным методам партнерского API.

  3. Привилегированная учетная запись со словарным паролем и без второго фактора. Самые ценные аккаунты в системе, учетные записи full admin, были защищены только паролем и одним фактором. У одной из них пароль оказался словарным. После того как мы получили список привилегированных УЗ из API, между нами и полным контролем над облаком остался только перебор по словарю. Помог и небезопасно реализованный механизм rate-limit: он считал попытки по IP-адресу, а не по учетной записи, поэтому ротация адресов позволила его обойти.

Что в итоге

Путь от чтения файлов на вспомогательном сервисе до полного контроля над облаком занял пять шагов. Сработала цепочка рядовых мисконфигураций: уязвимый к LFR параметр в стороннем сервисе, секреты в конфиге, ключ с избыточными правами, rate-limit по IP вместо учетной записи и словарный пароль администратора.

PURP — Telegram-канал, где кибербезопасность раскрывается с обеих сторон баррикад

t.me/purp_sec — инсайды и инсайты из мира этичного хакинга и бизнес‑ориентированной защиты от специалистов Бастиона

View the original on Хабр

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.