15 мая 2022 года примерно в 20:20 (UTC) наша система мониторинга обнаружила, что контракт FEGexPRO проекта FEGtoken был взломан. Злоумышленник провел серию атак как в основной сети ETH, так и в BSC, а общая сумма ущерба составила около 1,3 млн долларов США (согласно сообщению в сети, отправленному проектом).
@FEGtoken Параметр `path` в вашем контракте FEGexPRO (0x818E2013dD7D9bf4547AaabF6B617c1262578bc7) должен быть проверен заранее! Наша система мониторинга только что сообщила об атаке на контракт FEGexPRO, из которого были похищены fBNB и FEG. pic.twitter.com/A4obANAMhW
— BlockSec (@BlockSecTeam) 16 мая 2022
Более подробную информацию об этом инциденте можно найти в официальном Twitter-аккаунте проекта. В этом отчете мы подробно разберем детали, чтобы раскрыть первопричину данного инцидента.
0x1 Анализ уязвимости: первый взгляд
Уязвимый контракт FEGexPRO развернут как в ETH, так и в BSC, а уязвимой функцией контракта является swapToSwap, представленная ниже:

Как было отмечено в социальных сетях, первый параметр под названием path функции swapToSwap может быть задан вызывающим функцию лицом. Таким образом, злоумышленник мог использовать это для совершения произвольного одобрения (arbitrary approval) (см. строку 682 функции swapToSwap).
На данный момент здесь нет ничего нового, поскольку это очередной случай непроверенного параметра (или параметров). Однако следы атаки показывают, что эту атаку нельзя однозначно объяснить только лишь произвольным одобрением. На самом деле существует тонкая уловка, и именно здесь все становится интересным.
0x2 Анализ атаки
0x2.1 Предварительный анализ атаки
Мы возьмем одну транзакцию атаки в BSC в качестве примера для иллюстрации процедуры атаки, а след атаки, направленной на актив fBNB, кратко суммирован следующим образом:

- Шаг 1: подготовка средств и поддельных
путей(paths). Злоумышленник берет флэш-кредит (flashloan) на сумму около 915 BNB из DVM и обменивает часть из них на 116 fBNB. Затем злоумышленник создает ряд контрактов, которые будут использоваться в качестве поддельныхпутей. - Шаг 2: внесение первоначального депозита. Внеся 115 fBNB в контракт FEGexPRO, злоумышленник увеличивает свои
balances2(балансы) в целевом контракте. - Шаг 3: выполнение произвольного одобрения. Затем злоумышленник вызывает функцию
swapToSwapи передает поддельныйpathв качестве первого параметра, что приводит к тому, что контракт FEGexPRO одобряет этотpathна списание 114 fBNB. - Шаг 4: еще одно одобрение путем вызова функции
depositInternalи функцииswapToSwap. Контракт FEGexPRO одобряет еще одинpathна списание 114 fBNB.
Злоумышленник неоднократно повторяет Шаг 4, чтобы получить больше одобрений. В конце концов, злоумышленник использует одобренные поддельные пути для вывода всех fBNB из FEGexPRO и обменивает часть из них на BNB для погашения флэш-кредита.
Очевидно, что мы можем легко прийти к выводу о том, что контракт определенно должен был проверять параметр path.
ОДНАКО, чтобы полностью понять эту атаку, необходимо решить еще один вопрос: даже если контракт FEGexPRO одобряет поддельный path, операция approve основывается на том, что значение balances2 пользователя должно быть немедленно уменьшено (строка 684 функции swapToSwap), то есть одобренные средства поступают именно из суммы, внесенной на Шаге 3. Другими словами, злоумышленник просто одобряет использование своих собственных внесенных средств для поддельного path. После этого злоумышленник не должен иметь возможности делать одобрения для других поддельных путей из-за уменьшения balances2.
Возникает вопрос: какую именно уловку использует злоумышленник, чтобы совершать другие одобрения и получать дополнительную прибыль?
0x2.2 Углубленный анализ атаки
Чтобы ответить на этот вопрос, мы должны вернуться к функции swapToSwap.
Внимательно изучив код, мы обнаружили, что уловка заключается не только в поддельном path, но и в поддельном swap (обмене), что приводит к несоответствию между фактическим значением баланса целевого контракта и записанным в нем значением. В результате это несоответствие можно использовать для повторного совершения одобрения путем вызова функции depositInternal для восстановления суммы депозита злоумышленника.
В частности, функция depositInternal изменяет значение balances2 пользователя главным образом на основе разницы между Main.balanceOf контракта и _totalSupply2 (строка 651 функции depositInternal).

Поскольку адрес path, переданный в swapToSwap, является поддельным path, контролируемым злоумышленником, фактически ничего не переводится. Как следствие, возвращаемое значение Main.balanceOf остается таким же, как было на Шаге 3. Обратите внимание, что _totalSupply2 было уменьшено в функции swapToSwap, поэтому, как только злоумышленник вносит депозит, увеличенное значение balance2 неизбежно будет больше, чем фактически внесенная сумма.
Следовательно, на Шаге 4 злоумышленник сначала восстанавливает сумму депозита, вызывая функцию depositInternal, а затем выполняет одобрение и поддельный swap, вызывая функцию swapToSwap.
Заметьте, что сумма депозита, используемая злоумышленником, составляет лишь почти 0 (т.е. 1 / 1e18) fBNB, поэтому функция depositInternal восстанавливает balances2 злоумышленника почти до того же количества, которое было на Шаге 3, как объяснялось выше (что также подтверждается следом следующего одобрения).

Злоумышленник может увеличить объем «урожая», неоднократно выполняя Шаг 4.
Наконец, стоит отметить, что описанная выше атака — лишь один из путей, использованных злоумышленником. В той же транзакции атаки злоумышленник также нацелился на актив FEG:

0x3 Первопричина
Здесь мы резюмируем первопричину этой атаки:
- Во-первых, это произвольное одобрение, вызванное непроверенным параметром в функции
swapToSwap. - Во-вторых, это несоответствие между фактическим значением баланса целевого контракта и записанным в нем значением из-за поддельного процесса swap в функции
swapToSwap. Это используется для многократного совершения одобрений путем восстановления суммы депозита злоумышленника.
Объединив эти факторы, злоумышленник успешно вывел все средства из целевого контракта.
0x4 Другие связанные атаки
На момент написания этой статьи мы также наблюдали другие связанные атаки, проведенные другим злоумышленником.
ROX(https://t.co/NWvSy5faY3) не имеет открытого исходного кода, но что-то не так.
— BlockSec (@BlockSecTeam) 17 мая 2022
Взгляните на следующую транзакцию:https://t.co/chPxcDoFOD@Mudit__Gupta
Опять же, атакам подверглись контракты, развернутые как в Ethereum, так и в BSC. Интересно, что следы атаки отличаются от тех, что мы только что обсудили. Хотя целевые контракты не имеют открытого исходного кода, мы твердо подозреваем, что злоумышленник использовал ту же самую уязвимость с похожим методом атаки.
0x5 Выводы
Обеспечение безопасности DeFi-проектов — непростая задача. Помимо аудита кода, мы считаем, что сообществу следует использовать проактивный метод мониторинга статуса проекта и блокировать атаку еще до того, как она произойдет.
О компании BlockSec
BlockSec — это передовая компания в области блокчейн-безопасности, основанная в 2021 году группой всемирно признанных экспертов по безопасности. Компания стремится повысить безопасность и удобство использования развивающегося мира Web3, чтобы способствовать его массовому внедрению. Для достижения этой цели BlockSec предоставляет услуги по аудиту безопасности смарт-контрактов и EVM-цепочек, платформу Phalcon для разработки безопасности и проактивной блокировки угроз, платформу MetaSleuth для отслеживания и расследования средств, а также расширение MetaDock для эффективной работы Web3-разработчиков в криптомире.
На сегодняшний день компания обслужила более 300 уважаемых клиентов, таких как MetaMask, Uniswap Foundation, Compound, Forta и PancakeSwap, и получила десятки миллионов долларов США в ходе двух раундов финансирования от выдающихся инвесторов, включая Matrix Partners, Vitalbridge Capital и Fenbushi Capital.
Официальный сайт: https://blocksec.com/
Официальный Twitter-аккаунт: https://twitter.com/BlockSecTeam



