Привет! Меня зовут Миша Малашин, я продакт‑менеджер маркетплейса игровых предметов CS.MONEY. Сегодня расскажу, как год назад у нас украли почти 1 миллиард рублей — это история о том, что нужно вовремя менять пароли, не давать избыточных доступов кому попало, и внимательно следить за развёрнутыми Open Source‑системами. Поехали.
Субботу в августе 2022 года я запомню надолго. Рано утром приходит алерт о том, что наш сервис по обмену скинами CS.MONEY грабят: с ботов воруют игровые предметы на сумму без малого 1 млрд рублей. Slack разрывается, в Telegram один за другим появляются новые рабочие чаты — я, продукт и остальные команды шокированы и расстроены.
А ещё мы как никогда собраны. Спустя пару дней после ограбления мы буквально, как в старых мемах, найдём злоумышленника по IP-адресу, узнаем его почту, реальный физический адрес и получим доступ к другой информации: например, обнаружим, что на нашего героя уже заведено несколько дел о мошенничестве. Затем мы пришлём ему напрямую в мессенджер все скриншоты с составом преступления, поговорим по душам и выясним, как именно он нас взломал.
Но обо всём по порядку. Давайте отмотаем назад и попытаемся понять, что произошло в день одной из самых крупных хакерских атак в истории трейдинга игровыми предметами.
Дисклеймер: CS.MONEY — это маркетплейс для покупки, продажи и обмена внутриигровых предметов, в основном CS:GO. Все предметы CS:GO принадлежат Steam. Мы зарабатываем на комиссии с прямых сделок между пользователями (p2p), или сами покупаем предметы, чтобы позже продавать их другим игрокам. Во втором случае все выкупленные скины мы храним на «складах» — наших ботах, а логистику предметов обеспечиваем при помощи аккаунтов в Steam.
Работает это так: у Steam есть API, при помощи которого можно обменивать скины между Steam-аккаунтами. Если очень упрощённо, то фронт CS.MONEY выступает в качестве витрины магазина, а бэкэнд сервиса — это обёртка поверх Steam, в которой находятся бизнес-правила работы нашего сервиса.
Пятница, (в ночь на) 13-е
Ночью 13 августа 2022 года неизвестные взломали CS.MONEY. Я узнал о проблеме из Twitter: пользователи писали, что от наших ботов им приходят торговые предложения на скины для Counter-Strike: Global Offensive (CS:GO).
Первая мысль: кто-то взломал наш API и обменивает предметы через него. Команда тут же начала переносить базы данных и виртуальные машины из OVH и self-hosted-подсистем в AWS и as Service. Часть self-hosted-баз мы вывели в RDS и закрыли от внешнего мира, ограничив доступ к ней для разработчиков (исторически сложилось, что часть инфраструктуры у нас была общедоступна).
Мы закрыли внешний доступ к основной базе данных и сбросили все доступы, кроме самых необходимых — так вся инфраструктура оказалась во внутреннем контуре. С помощью Hashicorp Vault команда начала шифровать секретные данные, которые до этого хранились в открытом виде, но это не помогло.
Вскоре стало понятно, что злоумышленники каким-то образом получили доступ к учётным данным и второму фактору, — Steam Guard, — торговых ботов. Дело в том, что у Steam хитрая система двухфакторной аутентификации: сам проверочный код генерируется по мере необходимости через мобильное приложение на основе одного статичного кода. А поскольку и учётные данные, и код для второго фактора, и сами боты хранились в основной базе, вывод очевиден: её взломали.
В итоге неизвестные захватили управление торговыми ботами CS.MONEY, на которых в тот момент хранилось 394 000 игровых предметов. После этого кто-то провёл сотни транзакций, рассылая украденное на свои и чужие аккаунты, в том числе и на учётки популярных стримеров и трейдеров, не имеющих отношения ко взлому. Наверное, так злоумышленники пытались замести следы, отвлечь наше внимание и втянуть в мошенническую схему невиновных людей.
Скины рассылали до 5 утра — в первую волну хакерской атаки компания потеряла $6 000 000. Весь день мы пытались понять, в чём проблема, пока не сбросили пароли. Казалось, это сработало: переводы скинов прекратились, но только на время. Как выяснилось позже, операции приостановились не из-за наших действий, а оттого, что злоумышленник просто устал и ушёл спать.
Проснувшись, хакер продолжил грабить сайт: последовала вторая многомиллионная волна воровства, во время которой внутриигровые предметы выводили на аккаунты с ироничным именем CS.MONEY Recovery, чтобы эти переводы выглядели как операция по защите скинов и вводили юзеров в ещё большее заблуждение.
Поиски злоумышленника и награда за голову
15 августа мы попросили помощи у сообщества, объявив награду в $100 000 за подробную информацию о взломе. В первые несколько дней в соцсети CS.MONEY и на почту прилетали десятки сообщений: нам писали и самозванцы, выдававшие себя за хакеров, и просто желающие забрать кеш, сбивая с толку расследование.
Спустя несколько дней наши ребята вычислили IP-адрес злоумышленника и выяснили, где искать украденные у CS.MONEY скины.
Коллеги проверили IP-адрес предполагаемого злоумышленника через наш сервис аналитики посещений Amplitude, и в логах нашли аккаунт и два адреса электронной почты мошенника — оказалось, хакер заходил на сайт CS.MONEY за несколько месяцев до взлома. В том числе при помощи этих данных нам удалось достать всю информацию, которая помогла найти преступника.
Отыскав контакты злоумышленника, пришло время поговорить с ним лично. Коллега из маркетинга написал мошеннику в WhatsApp, прислал скриншоты, доказывающие, что тот раскрыт, и убедил хакера вернуть учётные данные от наших ботов. Вор вернул управление и рассказал, как ему удалось нас взломать.
Как и почему ограбление года стало возможным?
Ответственность с себя не снимаем: мы крупно облажались. У нас была развёрнута Open Source-система для А/Б-тестирования GrowthBook. Когда-то давно мы захотели попробовать её, и просто не поменяли настройки, оставив их по умолчанию.
Позже выяснилось, что в GrowthBook был баг: загрузчик изображений GrowthBook вместо картинки позволял загрузить любой файл в любое место. В нашем случае злоумышленник залил Reverse Shell и захватил контроль над машиной: хакер получил доступ к окружению и узнал, какой базой данных мы пользуемся. Так произошло потому, что в GrowthBook в качестве Data Source был добавлен доступ к нашей внутренней базе. Данные о Data Source хранятся в зашифрованном виде; к сожалению, в нашем случае ключ шифрования остался стандартным: dev.
Но и это ещё не всё. GrowthBook позволял в любой момент создавать нового пользователя с любым паролем. Обычно, запуская сервис впервые, пользователь попадает на страницу ввода учётных данных. В GrowthBook обязательная проверка на возможность создания нового пользователя была только во фронтенде. А создать новую учётную запись в бэкэнде можно было когда угодно — благодаря этому багу хакер смог зайти в нашу систему и загрузить вместо картинки скрипт, получив доступ к базе.
После инцидента наш CTO сообщил авторам GrowthBook об этих уязвимостях, патч уже выпущен.
Цифровая гигиена: что другие компании могут проверить прямо сейчас, чтобы не наступить на те же грабли?
Правила «цифровой гигиены для самых маленьких» обошлись нам довольно дорого. Вот несколько важных заключений, полученных на горьком опыте.
Всё, что вы показываете внешнему миру (базы, сервисы, инфраструктуру и т. п.), нужно закрывать на 7 замков.
Обязательно должна быть двухфакторная аутентификация. От взлома это может и не защитить, но усложнит работу злоумышленникам.
Чем сложнее пароли — тем лучше. Не нужно их запоминать: генерируйте случайные комбинации длиной, например, 33 символа, и храните их в менеджере паролей.
И железный принцип: для каждого сервиса — уникальный пароль.
В современных реалиях есть смысл использовать модель Zero Trust. Её суть описана в названии: никому не доверяйте. Заставляйте всех авторизовываться, аутентифицироваться и периодически валидировать свой доступ.
Чем больше компаний будет соблюдать этим принципам, тем меньше будет утечек данных. И тем безопасней будет мир, в котором мы живём.
Уязвимость GrowthBook сыграла ключевую роль во взломе CS.MONEY. Ключевую, но не единственную. Вот ещё несколько важных моментов, на которые нужно обратить внимание:
Проверьте избыточность доступов и создавайте отдельные аккаунты для внешних сервисов. Так, у аналитиков нашей компании были избыточные доступы к базам данных продукта: вместо того, чтобы создать отдельный профиль для стороннего сервиса, по ошибке мы передали GrowthBook излишние права. Это произошло после того, как CS.MONEY добавил новый источник для обогащения поступающих в GrowthBook данных — им стала наша база с конфиденциальной информацией и доступами к ней. Всё это создало путаницу при расследовании инцидента, поиск аккаунта с подозрительным поведением занял у нас много времени. Если бы у нас был отдельный аккаунт для внешних сервисов, то обнаружить дыру в безопасности было бы значительно проще.
Перепроверьте абстракции Helm. Если вы используете Helm Charts, то делайте это очень аккуратно. У нас Helm абстрагировал важную настройку ключа, что позволило GrowthBook запуститься с конфигурацией, недопустимой для эксплуатационного окружения.
Пусть ваша оборона будет нерушимой, и да обходят вас стороной шибко умные хакеры. Удачи!
Комментарии (23)
Firsto
02.08.2023 08:06А что потом случилось со взломщиком?
mikhail_malashin Автор
02.08.2023 08:06+1Лигал заявили о киберпреступлении в соответствующие органы. В настоящее время идет расследование. Этот процесс небыстрый, но мы уверены, что злоумышленника накажут по всей строгости закона.
Hlad
02.08.2023 08:06+2Ничего ему не сделают. Скорее всего, вы просто не сможете доказать достаточный финансовый урон.
Surrogate
02.08.2023 08:06Я в подобные игры не играю, мне трудно понять и поверить
хранилось 394 000 игровых предметов
Это всего было в вас в стоке. Сколько было украдено в штуках? если
в первую волну хакерской атаки компания потеряла $6 000 000
Может в полиции сотрудники, близкие к миру игр, но даже им будет трудно поверить в такую запредельную стоимость украденных артефактов!
Существует много разных милых увлечений: например коллекционирование пивных крышек. Среди коллекционеров отдельные экземпляры пользуются огромной ценностью.
Украв коллекцию из 394.000 крышечек ее будет трудно продать. Простому обывателю это не надо, круг таких коллекционеров невелик! Кто-то сможет купить коллекцию целиком, и годами скрывать у себе в гараже.
Ваши предметы так просто не утаишь! Вангую, что желающих купить все оптом и кульками как семечки очереди не стоят. Чтобы продать украденные артефакты, за те деньги что вы озвучили могут уйти годы…
Злоумышленник похоже сделал это just for lulz! Или украл, что-то конкретное под заказ, а остальные фантики просто рассыпал по району, чтобы была непонятна цель заказа.
Hait
02.08.2023 08:06Предметы КС:ГО продаются официально на торговой площадке стима. Цены там видны
Surrogate
02.08.2023 08:06Конечно, я об этом не мог знать, никогда не слышал! Не знаю об объемах этого рынка предметов.
Не знаю, реально ли в принципе продать оптом или по предметно примерно 400к предметов, которые существуют лишь в пространстве торговой площадки Steam.
Hait
02.08.2023 08:06+1Пример одного из предметов
Surrogate
02.08.2023 08:06@Hait, спасибо буду хоть знать нижнюю границу стоимости.
А то автор темы нагнал туману:
было 400к предметов
за сотню транзакций в первый день украли N предметов на 6M$!!!
Я грешным делом подумал: стоимость всей коллекции из 400к предметов равна
капитализации Appleгодовому бюджету маленькой латиноамериканской страны!!!
vikarti
02.08.2023 08:06+1Взломщик идиот?
Если послеОтыскав контакты злоумышленника, пришло время поговорить с ним лично. Коллега из маркетинга написал мошеннику в WhatsApp, прислал скриншоты, доказывающие, что тот раскрыт, и убедил хакера вернуть учётные данные от наших ботов. Вор вернул управление и рассказал, как ему удалось нас взломать.
Все вернул вот просто так и без хоть каких то гарантий, что этим все и ограниться?
Surrogate
02.08.2023 08:06без хоть каких то гарантий
Автор ранее в комментариях писал, что сообщили куда следует на этого злодея и надеждах на тяжелый меч правосудия…
Еще вчера многие из нас и вас не слышали про этот "маркетплейс игровых предметов"…
Hlad
02.08.2023 08:06+6Хотелось бы уточнить: когда называются большие суммы - речь именно о потерях, или о недополученной прибыли?
mikhail_malashin Автор
02.08.2023 08:06-6В статье указывали именно оценочную стоимость скинов. Упущенная выгода там значительно больше
Hlad
02.08.2023 08:06+5Стоп. "Оценочная стоимость скинов" - это та сумма, которую потратили на их приобретение, или та сумма, за которую хотели продать эти скины?
mikhail_malashin Автор
02.08.2023 08:06-7Тут речь именно про реальные деньги, которые мы могли бы получить, если бы продали украденные скины у нас на сайте. У нас в стоке есть скины, которые мы купили сами, и скины, которые появились при обмене одних предметов на другие. Так что мы когда считаем сток, называем актуальную стоимость предмета на рынке, а не во сколько он нам обошелся когда-то.
chervital
02.08.2023 08:06+1Набил себе шишку на голове от фейспалмов. Особенно порадовало
исторически сложилось, что часть инфраструктуры у нас была общедоступна
Upd. Я правильно понимаю, что у вас все сервисы торчали наружу в интернет безо всяких dmz?
mikhail_malashin Автор
02.08.2023 08:06Вроде того, ага. К сожалению, во многих стартапах на этапе их зарождения принимают сомнительные решения, чтоб поскорее выехать на рынок. И не всегда задумываются о безопасности. В большинстве своем, о безопасности задумываются уже после того, как что-то произошло - вот и у нас так. Мы, конечно, начали в свое время все переделывать, но не до всего дошли руки. Так и тут. Реплика торчала во внешний мир без всяких dmz. Приходи, кто хочет. А что касается сервисов - нет. Основная часть была, как раз, во внутреннем контуре и недоступна извне. Но, опять же, не до всего дошли руки. Что и было использовано злоумышленником
Lev3250
02.08.2023 08:06+1Другой вопрос: а насколько вообще легален вывод денег за скины в фиат с точки зрения правил стима?
mikhail_malashin Автор
02.08.2023 08:06Вывод денег за скины на сторонних площадках на данный момент не регулируются Стимом.
Hasthur
Не такой уж и "шибко умный", если в статье аж три вариации одного мема