Содержание статьи
Взгляд изнутри
Несмотря на то что большинство пользователей воспринимают Stack Overflow как бесплатный ресурс для поиска ответов на технические вопросы о программировании и администрировании, это в первую очередь коммерческий проект. Сайт входит в состав глобальной сети Stack Exchange Network, объединяющей несколько порталов с вопросами и ответами в разных областях знаний, которые собраны на единой платформе. Stack Overflow, движок которого написан на С# с использованием ASP.NET, стал первым ресурсом в этой сети.
Пользователи портала могут не просто задавать вопросы и отвечать на них, но и наращивать собственную репутацию благодаря активному участию в жизни сайта. Рейтинг дает больше возможностей: дополнительный вес голоса при оценке ответов, возможность редактировать чужие тексты и посты — вплоть до модераторских полномочий. Stack Overflow быстро набрал популярность: уже спустя четыре года после появления его аудитория выросла до двух миллионов постоянных пользователей и продолжала понемногу увеличиваться.
Монетизируется площадка за счет рекламы (пользователи с высоким рейтингом видят меньше объявлений) и встроенного сервиса по подбору персонала Stack Overflow Careers (позже переименованного в Talents), который позволяет сторонним фирмам и рекрутинговым агентствам искать сотрудников среди населяющих сайт программистов. Кроме того, Stack Overflow продает бизнес‑версию своего движка и оказывает техподдержку фирмам, желающим развернуть собственный сервис вопросов‑ответов. Этот продукт нацелен на команды разработчиков и позволяет создавать базы знаний для внутрикорпоративного использования. Называется он Stack Teams.
Все эти коммерческие проекты непрерывно обновляются и совершенствуются. Программисты устраняют выявленные ошибки, добавляют новые функции, оптимизируют код, улучшают интерфейс. При разработке используются решения для тестирования и контроля версий, репозитории для хранения кода, билд‑серверы, баг‑трекеры и вики для внутренней документации. Короче, все как у больших софтверных корпораций. С той лишь разницей, что большинство сотрудников Stack Exchange работают удаленно и подключаются к необходимым ресурсам через интернет.
Эта внутренняя инфраструктура и стала целью атаки неизвестного на данный момент злоумышленника. А если точнее, он пытался добыть исходный код Stack Overflow, который не поставляется коммерческим клиентам, и этой цели ему в итоге удалось достичь.
Ход атаки
Как известно, любая хакерская атака начинается с разведки. Таинственный злоумышленник начал прощупывать инфраструктуру, связанную с сервисами хранения исходников и сборки билдов коммерческих продуктов Stack Exchange, еще 30 апреля 2019 года. По всей видимости, рекогносцировка включала в себя стандартные мероприятия вроде поиска субдоменов, общедоступных ресурсов и сканирования портов. Кроме того, он попытался зайти в служебный чат для сотрудников Stack Exchange, но не смог получить доступ туда.
На следующий день, 1 мая, хакер попытался решить свою задачу «в лоб»: представившись одним из корпоративных клиентов, он отправил запрос в техподдержку с просьбой выслать ему исходный код Enterprise-продукта в целях аудита. Не прокатило: во‑первых, Stack Exchange не предоставляет исходники своим пользователям, а во‑вторых, адрес электронной почты злоумышленника не удалось сопоставить ни с одним из реальных клиентов компании. Заявка была ожидаемо отклонена.
Но это отнюдь не остудило пыл хакера. Зарегистрировавшись в сервисе Stack Teams, он начал исследовать его возможности, отправляя приглашения присоединиться к сервису на другие свои учетки — вероятно, чтобы исследовать генерируемые при этом запросы и отклики сервера. Одновременно он внимательно изучал тематические ветки на самом Stack Overflow, связанные с продуктом Enterprise и сервисом Teams.
Воспользовавшись информацией из этих публикаций, он создал еще одно обращение в техподдержку, на сей раз он применил спуфинг адреса электронной почты реального клиента Stack Exchange. Однако по этому адресу было направлено автоматическое сообщение о создании тикета, и в итоге обращение тоже было отклонено службой техподдержки как подозрительное.
info
Спуфинг электронной почты — подделка части сообщения email и его технических параметров с целью ввести получателя в заблуждение. Письмо мошенника в таком случае выглядит так, будто оно отослано другим (доверенным) отправителем.
В последующие дни атакующий тщательно изучал профили сотрудников саппорта Stack Exchange и особенности обработки запросов от пользователей, но, видимо, не нашел ничего интересного. Зато в одном из открытых репозиториев компании на GitHub он обнаружил URL архива с исходным кодом Stack Overflow, выложенного на приватном аккаунте GitHub Enterprise. Хакер попытался скачать архив, но был перенаправлен на страницу авторизации. Снова неудача.
Наконец, 5 мая 2019 года настойчивость атакующего была вознаграждена. Настройки контроля доступа в Stack Exchange допускали имперсонацию пользователей в тестовых целях, благодаря чему злоумышленнику удалось подобрать параметры запроса, позволяющие авторизоваться в системе на уровне разработки. Вслед за этим взломщик попытался зайти на ряд внутренних ресурсов, URL которых он нашел в документации на портале поддержки Enterprise-версии продукта, но практически везде получил отказ в доступе из‑за отсутствия необходимых привилегий. Везде, кроме одного служебного портала, с помощью которого он смог повысить собственные права до Community Manager — это роль, соответствующая уровню модератора сайта.
К огромному разочарованию хакера, полученный статус все равно не открыл доступ к интересующим его служебным ресурсам Stack Exchange, и он начал искать способы повысить свои привилегии до разработчика. С этой целью хакер решил воспользоваться механизмом восстановления доступа к учетной записи.
Для сброса пароля учетки в Stack Exchange используется сообщение email с «волшебной ссылкой» — этот традиционный способ всегда считался достаточно надежным. Однако у пользователей с привилегиями Community Manager есть возможность просматривать содержимое автоматически отправляемых сайтом писем. Таким образом взломщик получил привилегии разработчика, а заодно — доступ к настройкам сайта, включающим управление многими внутренними его функциями.
В течение некоторого времени хакер увлеченно изучал открывшиеся перед ним возможности, тестировал настройки сайта и пытался понять, какими функциями он теперь может управлять. Среди прочих параметров он неожиданно наткнулся на данные учетной записи билд‑сервера TeamCity. Эта техническая учетка раньше использовалась для доступа к TeamCity REST API непосредственно из кода Stack Exchange. На время описываемых событий эту функцию уже убрали из кода, а вот учетную запись прибить почему‑то забыли.
Обрадованный хакер попытался войти с этими данными на сервер TeamCity, настроенный на возможность авторизации через интернет, и из‑за неправильной конфигурации службы назначения ролей тут же получил к нему администраторский доступ.
info
TeamCity — написанный на Java билд‑сервер производства компании JetBrains, разработанный для обеспечения непрерывной интеграции. С помощью специальных сценариев он позволяет автоматизировать многие рутинные процессы разработки, включая отслеживание изменений в разных ветках репозитория, прогон тестов, сборку приложения и его загрузку на сервер обновлений. TeamCity часто используется компаниями, которые работают со стеком технологий C#/ASP.NET.
Такой оглушительный успех, по всей видимости, стал сюрпризом для самого взломщика. Судя по тому, что он начал активно искать на Stack Overflow информацию о настройке и использовании TeamCity, с этим продуктом он столкнулся впервые. Для начала хакер смог загрузить с сервера и изучить некоторые сценарии настройки конфигурации для Enterprise-продуктов Stack. Одновременно с этим он продолжает копаться в справочных разделах на Stack Overflow в поисках сведений о настройке IIS, возможностях TeamCity и особенностях продуктов Stack Teams. Изучение матчасти заняло у него несколько дней.
В среду, 8 мая (то есть на девятый день после первой попытки проникнуть в инфраструктуру Stack Exchange), злоумышленник просматривал административные ресурсы TeamCity и случайно наткнулся на раздел диагностики, позволяющий просматривать файлы на билд‑сервере. Среди них он обнаружил хранящийся в обычном плейн‑тексте ключ SSH, который использовали агенты сборки для получения исходного кода из GitHub Enterprise. Тут следует отметить, что если в учетную запись GitHub добавлен открытый SSH-ключ, то этот ключ может использоваться для доступа к репозиторию без дополнительной аутентификации.
Этого оказалось достаточно, чтобы хакер успешно клонировал несколько ключевых репозиториев (пока шел процесс клонирования, он искал на Stack Overflow информацию о сборке проектов .NET). Одновременно злодей попытался авторизоваться в GitHub Enterprise напрямую с учетными данными службы, которые он раньше использовал для доступа к TeamCity. Но тут его ждала неудача: админы компании догадались настроить в своем экземпляре GitHub Enterprise двухфакторную аутентификацию, а скомпрометированная учетка не входила в группу Active Directory, которой был разрешен туда доступ.
На следующий день хакер безуспешно попытался подключиться к VPN Stack Exchange с использованием виртуальной машины Azure и данных учетной записи, открывшей ему доступ к TeamCity. Одновременно с этим он продолжал искать информацию на Stack Overflow об особенностях сборки приложений .NET под IIS, а также о выполнении сценариев SQL в среде Azure.
Вас заметили
11 мая злоумышленник извлек все копии клонированных им репозиториев и начал исследовать журналы сборки и конфигурации TeamCity. Затем он настроил в TeamCity сопоставление имен пользователей Git таким образом, чтобы в журналах аудита учетная запись агента сборки, с которой сопоставлен скомпрометированный ключ SSH, выглядела другой учетной записью.
После этого хакер создал в TeamCity новый проект, отключил для него проверку изменений в Git и попытался сделать несколько сборок с разными конфигурациями, чтобы получить доступ к внутренней базе данных Stack Exchange и системе управления пакетами NuGet.
После ряда неудачных попыток взломщик пошел другим путем. Он зарегистрировал на GitHub общедоступную сущность gist, содержащую набор SQL-инструкций, и создал на сервере TeamCity работающую сборку, которая выполняла с использованием этих инструкций миграцию SQL для базы данных с информацией о пользователях Stack Exchange. Это позволило взломщику повысить свои привилегии в сети Stack до администраторских.
После успешного выполнения SQL-запроса хакер начал стремительно заметать следы атаки — удалил все созданные им сборки и почистил историю в логах TeamCity. Единственное, чего он не предусмотрел, так это того, что на сервере было настроено некоторое подобие «корзины», из которой впоследствии можно восстановить удаленные объекты. Это дало исследователям возможность изучить хронологию его действий.
12 мая несколько участников сообщества уведомили админов Stack о появлении нового подозрительного пользователя, привилегии которого без видимых причин выросли до небывалых высот — он получил доступ на уровне разработчика и администратора ко всем сайтам и ресурсам в сети Stack Exchange. Эти факторы заставили ответственных сотрудников заподозрить: что‑то в сети, возможно, идет не так.
Админы обратились к базе данных, где сохраняется журнал всего трафика к общедоступным ресурсам Stack Exchange. Используя идентификатор подозрительной учетной записи, они постарались вычислить все связанные с ней IP-адреса и прочую информацию, которая помогла бы найти злоумышленника. На выходе получилось более 75 тысяч строк данных, которые им предстояло тщательно изучить.
Расследование
Сопоставив логи с информацией из других источников, исследователи пришли к выводу, что повышение привилегий неизвестного пользователя — это кульминация атаки, длящейся вот уже на протяжении 13 дней. Не имея точного представления о ее масштабе, в первую очередь они удалили подозрительную учетку и принялись искать в логах информацию о деятельности злоумышленника в сети. Именно благодаря сохранившимся в журналах данным впоследствии удалось восстановить хронологию атаки — вплоть до поисковых запросов хакера на сайте Stack Overflow.
Продолжение доступно только участникам
Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
Вариант 2. Открой один материал
Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.
Я уже участник «Xakep.ru»