21 февраля 2025 года биржа Bybit потеряла около 1,5 миллиарда долларов после того, как злоумышленник скомпрометировал компьютер разработчика Safe{Wallet} с помощью социальной инженерии. Атакующий внедрил вредоносный JavaScript в S3-бакет AWS, принадлежащий Safe{Wallet}, специально нацелившись на транзакции Bybit. Внедренный код изменял содержимое транзакции в процессе подписания: интерфейс Safe{Wallet} отображал легитимную транзакцию, в то время как фактический полезный код (payload), отправленный на устройства Ledger подписантов, обновлял Safe-контракт Bybit до вредоносной реализации, что давало злоумышленнику полный контроль. После того как транзакция была подписана и исполнена, злоумышленник вывел все активы из контракта. Подробный технический разбор доступен в нашем предыдущем отчете [1].
Предыстория
Safe{Wallet} (ранее GnosisSafe) — это инфраструктура мультиподписных кошельков, использующая модель n-of-m: выполнение транзакции требует как минимум n подписей от m общего числа подписантов.
Каждый кошелек Safe разворачивается как прокси-контракт. Две переменные хранилища играют ключевую роль в этом инциденте:
masterCopy(слот 0): адрес контракта реализации. Этот контракт содержит всю логику исполнения, включая проверку подписей и механизмы обновления. Прокси делегирует все вызовыmasterCopyчерезdelegatecall.threshold(слот 4): минимальное количество требуемых подписей (n). Для Safe-кошелька Bybit это число равнялось 3.
Поскольку прокси использует delegatecall, любая функция, вызванная в masterCopy, выполняется в контексте хранилища прокси. Это означает, что цель delegatecall может напрямую перезаписать masterCopy в слоте 0, заменив всю реализацию за одну транзакцию.
Анализ уязвимости
Путь атаки пролегал через три уровня системы, каждый из которых содержал структурное условие, использованное злоумышленником:
Модель предоставления фронтенда. Фронтенд-код JavaScript для Safe{Wallet} размещался в S3-бакете AWS. В такой архитектуре любой, у кого есть доступ на запись в бакет, может изменить код, формирующий транзакции для подписантов. Механизмы верификации целостности, такие как хеши SRI (Subresource Integrity) или подписание кода, могут снизить этот риск, но они еще не стали стандартной практикой для большинства фронтендов dApp. Злоумышленник получил доступ на запись через скомпрометированный компьютер разработчика и незаметно изменил размещенный JavaScript.
Разрыв между отображением в интерфейсе и полезной нагрузкой для подписи. Внедренный JavaScript отображал транзакцию, выглядящую легитимно, в интерфейсе Safe{Wallet}, отправляя при этом другой полезный код на аппаратные кошельки Ledger. Детали транзакции, показанные на экране Ledger, отличались от данных в интерфейсе, однако интерпретация «сырых» данных транзакции на экране аппаратного кошелька — непростая задача, особенно при выполнении сложных операций с мультиподписью. Этот разрыв позволил злоумышленнику собрать три валидные подписи для вредоносной транзакции.
Модель обновления прокси. Как описано в разделе «Предыстория», delegatecall выполняет код цели в контексте хранилища прокси. Архитектура прокси Safe направляет все вызовы через единый указатель masterCopy в слоте 0. Перезапись этого указателя перенаправляет прокси на совершенно иную реализацию, включая логику проверки подписей, всего за одну транзакцию. Модель n-of-m определяет, кто может инициировать транзакцию, но после того как транзакция одобрена и исполнена, она может изменить саму реализацию. Если новая реализация исключает проверку подписей, защита мультиподписью фактически перестает действовать для всех последующих операций.
Анализ атаки
Атака состояла из трех этапов: Внедрение вредоносного кода, Замена реализации и Кража активов.
Этап 1: Внедрение вредоносного кода
Злоумышленник скомпрометировал компьютер разработчика Safe{Wallet} и внедрил вредоносный JavaScript в S3-бакет AWS, обслуживающий фронтенд. Внедренный код был специфично настроен на транзакции с адреса Safe-кошелька Bybit. Согласно словам гендиректора Bybit Бена Чжоу [2], в интерфейсе Safe{Wallet} отображалась легитимная транзакция, в то время как на устройства Ledger подписантов отправлялся другой код. Подписанты подтвердили транзакцию в том виде, в котором она была представлена в интерфейсе, предоставив злоумышленнику три валидные подписи для вредоносной нагрузки.
Этап 2: Замена реализации
Злоумышленник отправил вредоносную транзакцию с тремя собранными подписями. Прокси Safe делегировал вызов masterCopy, чей метод execTransaction() проверил подписи, а затем выполнил полезную нагрузку транзакции: delegatecall к контракту злоумышленника (0x962214...5c7242). Поскольку этот delegatecall выполняется в контексте хранилища прокси, функция transfer() злоумышленника перезаписала значение masterCopy в слоте 0 адресом вредоносной реализации (0xbDd077...9516). С этого момента все вызовы контракта Safe делегировались коду злоумышленника.
Этап 3: Кража активов
Теперь, когда masterCopy указывал на реализацию злоумышленника, требование мультиподписи больше не применялось. Злоумышленник вызвал SweepERC20() и SweepETH() напрямую в контракте Safe. Эти функции, определенные в контракте реализации злоумышленника, вывели все хранимые активы без какой-либо проверки подписей. Было выполнено пять транзакций по выводу средств, суммарно составивших около 1,5 миллиарда долларов потерь.
Связанные контракты и транзакции
| Тип | Описание | Адрес / Хеш |
|---|---|---|
| Контракт | Safe-контракт Bybit | 0x1Db92e2EeBC8E0c075a02BeA49a2935BcD2dFCF4 |
| Контракт | Оригинальный контракт masterCopy | 0x34CfAC646f301356fAa8B21e94227e3583Fe3F5F |
| Контракт | Вредоносный контракт masterCopy | 0xbDd077f651EBe7f7b3cE16fe5F2b025BE2969516 |
| Контракт | Контракт злоумышленника (т.е. transfer()) | 0x96221423681A6d52E184D440a8eFCEbB105C7242 |
| Транзакция | Тх, заменившая контракт masterCopy | 0x46deef0f52e3a983b67abf4714448a41dd7ffd6d32d32da69d62081c68ad7882 |
| Транзакция | Тх, выведшая 15 000 cmETH | 0x847b8403e8a4816a4de1e63db321705cdb6f998fb01ab58f653b863fda988647 |
| Транзакция | Тх, выведшая 90 375 stETH | 0xa284a1bc4c7e0379c924c73fcea1067068635507254b03ebbbd3f4e222c1fae0 |
| Транзакция | Тх, выведшая 8 000 mETH | 0xbcf316f5835362b7f1586215173cc8b294f5499c60c029a3de6318bf25ca7b20 |
| Транзакция | Тх, выведшая 401 346 ETH | 0xb61413c495fdad6114a7aa863a00b2e3c28945979a10885b12b30316ea9f072c |
| Транзакция | Тх, выведшая 90 USDT | 0x25800d105db4f21908d646a7a3db849343737c5fba0bc5701f782bf0e75217c9 |
Итоги
Этот инцидент продемонстрировал, как компрометация внесетевой (off-chain) инфраструктуры может перерасти в катастрофические потери в сети (on-chain). Злоумышленник объединил взлом Web2-инфраструктуры, манипуляцию фронтендом и обновление прокси в единую цепочку атаки, которая позволила обойти защиту мультиподписью, не используя ни одной уязвимости в смарт-контрактах.
Основные выводы:
- Целостность фронтенда заслуживает такого же внимания, как и безопасность в сети. Цепочка атаки началась на уровне обслуживания фронтенда. Поскольку dApps все чаще выступают посредниками в транзакциях с высокой стоимостью, защита фронтенд-кода с помощью верификации целостности (SRI, подписание кода, воспроизводимые сборки) и мониторинг несанкционированных изменений становится базовым требованием.
- Верификация на аппаратных кошельках остается сложной задачей на практике. Аппаратные кошельки могут отображать фактические данные для подписи, но интерпретация данных сложной транзакции с мультиподписью на маленьком экране — известная проблема юзабилити. Улучшение читаемости сводок транзакций на устройстве — открытая проблема для экосистемы кошельков.
- Механизмы обновления прокси — высокорисковые цели. Архитектура прокси Safe направляет всю логику через единый обновляемый указатель. Любой механизм, допускающий замену реализации в один шаг, концентрирует риск. Добавление временных блокировок (timelock), второго этапа подтверждения или независимого гаранта для обновлений может снизить воздействие от компрометации отдельной транзакции.
Справочные материалы
О компании BlockSec
BlockSec — поставщик услуг по обеспечению безопасности блокчейна полного цикла и соблюдению нормативных требований (крипто-комплаенс). Мы создаем продукты и услуги, помогающие клиентам проводить аудит кода (смарт-контрактов, блокчейнов и кошельков), перехватывать атаки в режиме реального времени, анализировать инциденты, отслеживать незаконные средства и выполнять обязательства AML/CFT на протяжении всего жизненного цикла протоколов и платформ.
BlockSec опубликовала множество работ по безопасности блокчейнов на престижных конференциях, сообщила о нескольких атаках «нулевого дня» на DeFi-приложения, пресекла множество попыток взлома, спасая более 20 миллионов долларов, и обеспечила безопасность криптовалютных активов на миллиарды долларов.
-
Официальный сайт: https://blocksec.com/
-
Официальный аккаунт в Twitter: https://twitter.com/BlockSecTeam



