וואלההוגש כתב אישום נגד תושב בית שמש שניסה לרצוח את בן זוגה של גרושתו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 twoCollider‘Stranger Things’ Has Officially Lost Its Streaming EdgeDaily MaverickWHAT’S COOKING: A pair of meaty recipes to plan for Braai DayMalay MailDo not usurp the constitutional function of the DKU — Hafiz HassanThe RegisterLongtime SUSE staff asked if they'd opt for 'voluntary separation'CBS NewsIran's president heads for U.N. summit ahead of possible Trump meetingLa PresseLa revue de presse de Paul Arcand | Le PQ se rapproche de la majorité, 43 % des Québécois dépensent toute leur paie et magouille dans le ramassage des poubellesMintMint Explainer: What the Nayara vs SAP ruling means for Indian contracts caught in foreign sanctions
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.