В этом блоге мы хотим рассмотреть весь процесс взлома Poly Network и обсудить извлечённые уроки.
Мы узнали, что Poly Network был взломан 10 августа 2021 года (в этом блоге мы используем часовой пояс +8). Однако не было никаких сведений о том, как именно происходил взлом и в чём заключается его первопричина. Как команда по исследованию безопасности, мы начали своё расследование.
Шаг 1: Найти атакующую транзакцию
Мы воспроизвели атакующую транзакцию 0xd8c1f7424593ddba11a0e072b61082bf3d931583cb75f7843fc2a8685d20033a в нашей системе виртуализации транзакций (https://tx.blocksecteam.com).

Трассировка весьма проста, что отличает её от других атак, манипулирующих ценой. Обычно они имеют очень сложные цепочки вызовов функций (см. взлом Popsicle.)
Шаг 2: Анализ кода контракта
Получив трассировку атаки, нам необходимо было изучить исходный код контракта. К удивлению, Poly Network НЕ имеет верифицированного исходного кода на Etherscan. Тем не менее нам удалось найти опубликованный исходный код на GitHub.
После изучения исходного кода мы не обнаружили никаких очевидных уязвимостей. Мы также сравнили трассировку атаки с трассировкой легитимной транзакции и выяснили, что они схожи.
Шаг 3: Восстановление критических состояний
Затем мы восстановили критические состояния во время атаки. Поскольку атака инициируется вызовом VerifyHeaderAndExecuteTxEvent, мы восстановили несколько критических значений переменных, которыми поделились в нашем первом анализе [1].

В ходе этого процесса мы обнаружили, что существует только один хранитель (keeper) (см. рисунок выше). Поскольку значение было получено из трассировки атаки, а атакующая транзакция прошла всю проверку подписей, мы предположили, что потенциальной причиной могла быть утечка закрытого ключа или ошибка в процессе подписания на стороне сервера [1].
Однако мы допустили ошибку. Анализ атаки похож на чистку луковицы. Вы снимаете её слой за слоем, пока не доберётесь до настоящей «первопричины первопричин». В тот момент мы не стали снимать следующий слой, чтобы проверить, не был ли изменён хранитель!
Шаг 4: Новая зацепка
Спустя несколько часов Kelvin и slow mist опубликовали в Twitter новые зацепки, показывающие, что хранитель был изменён. Процесс изменения злоупотребляет коллизией хешей для вызова мощной функции — «умный» взлом.
Теперь мы осознали, что наш первый анализ был неполным. Основываясь на последней информации, мы воспроизвели транзакцию, изменившую хранителя. Трассировка снова оказалась очень простой.

Но помните, что в ходе этой транзакции было четыре хранителя (а не один). Все эти ключи совпадают с ключами других легитимных транзакций — то есть ключи являются легитимными. И здесь возникает вопрос: почему транзакция, изменяющая хранителя, вообще смогла попасть в цепочку и быть исполненной?

Шаг 5: Найти исходную транзакцию

Затем мы попытались найти исходную транзакцию, поскольку Poly Network является кросс-чейн мостом. Где-то должна существовать исходная транзакция. Мы сделали это, декодировав критическую переменную (как показано на следующем рисунке). Она показывает хеш транзакции исходной цепочки и цепочки poly.
Есть один нюанс, который нигде больше не упоминался. Значение хеша транзакции в переменной имеет иное представление по сравнению с официальным значением в цепочке poly. Например, хеш транзакции цепочки poly на рисунке — 0x80cc978479eb082e1e656993c63dee7a5d08a00dc2b2aab88bc0e465cfa0721a. Но в обозревателе цепочки poly значение хеша выглядит так: 1a72a0cf65e4c08bb8aab2c20da0085d7aee3dc69369651e2e08eb798497cc80 (видите разницу?). Мы поделились своими выводами в группе EthereumSecurity в Telegram 11 августа в 16:55.

Шаг 6: Найти первопричину
Но мы по-прежнему не могли ответить на вопрос: почему транзакция для изменения хранителя смогла попасть в цепочку? Чтобы ответить на этот вопрос, мы начали с цепочки Ontology и обнаружили следующий поток транзакций:
Транзакция Ontology -> Ретранслятор Ontology -> Цепочка Poly -> Ретранслятор Ethereum -> Ethereum
Затем мы изучили исходный код цепочки Ontology и ретрансляторов. Спустя несколько часов мы обнаружили, что ретранслятор Ontology не выполняет достаточной проверки кросс-чейн транзакций. Это позволяет злонамеренной транзакции попасть в цепочку poly. После этого система оказывается скомпрометирована.
После внутреннего обсуждения и проверки мы опубликовали наши выводы 12 августа в 02:41 в Twitter и на Medium [3].

Уроки
-
Безопасность по замыслу. Безопасность должна присутствовать на всех этапах DeFi-проекта. Пользователи доверяют проекту свои средства, и проект должен это доверие оправдывать. К сожалению, мы увидели пренебрежение безопасностью со стороны Poly Network. Например, отсутствие валидации — это уязвимость старой школы, которую я преподаю на курсе для бакалавров.
-
Для DeFi-проекта с TVL более 600 миллионов долларов нет верифицированного исходного кода. Основой децентрализованной инфраструктуры является доверие, а фундаментом доверия — прозрачность. К сожалению, пользователи готовы вкладывать деньги в проект-«чёрный ящик», что меня одновременно удивляет и беспокоит. Как повысить уровень осознания безопасности у пользователей — вероятно, требует нового подхода.
Ссылки
[1]https://blocksecteam.medium.com/the-initial-analysis-of-the-polynetwork-hack-270ac6072e2a
[2]https://twitter.com/kelvinfichter/status/1425290462076747777
[3]https://blocksecteam.medium.com/the-further-analysis-of-the-poly-network-attack-6c459199c057
Авторы: Yufeng Hu, Siwei Wu, Lei Wu, Yajin Zhou @ BlockSecTeam



