Аналіз принципу вразливості підміни довільної адреси в ERC2771 Multicall від SharkTeam

robot
Генерація анотацій у процесі

8 грудня 2023 OpenZeppelin випустив важне попередження про безпеку. Виявляється, при спільному використанні стандарту ERC-2771 та функцій типу Multicall існує ризик підміни адреси! Я глибоко вивчив цю уразливість і хочу поділитися своїми знахідками.

Аналіз атаки

Розглянемо одну з атак:

  • Атакуюючий: 0xFDe0d1575Ed8E06FBf36256bcdfA1F359281455A
  • Транзакція: 0xecdd111a60debfadc6533de30fb7f55dc5ceed01dfadd30e4a7ebdb416d2f6b6

Схема атаки геніально проста:

  1. Зловмисник обміняв 5 WETH на приблизно 3,455,399,346 TIME
  2. Потім сконструював хитрі параметри calldata і викликав [Forwarder].execute
  3. Ця функція запустила multicall в контракті TIME, а залишковий calldata використовувався для burn() - знищення токенів у пулі!

Як це працює?

В цій атаці зійшлися зірки: ERC-2771, Multicall і ретельно складені дані. Контракт TOKEN успадковує ERC2771Context, і тут починається найцікавіше!

ERC-2771 надає віртуальний msg.sender, дозволяючи делегувати транзакції третій стороні. При цьому справжня адреса додається в calldata. Коли [Forwarder] викликає контракт, _msgSender() перевіряє ці дані та обрізає останні 20 байтів як "справжній" msg.sender.

Multicall ж перетворює один виклик на кілька, економлячи газ. Він приймає масив викликів і виконує їх через deleGatecall().

І ось тут пастка! Атакуючий зміщує calldata так, що перші 4 байти нових даних відповідають функції burn(), а параметр - величезна сума токенів. У рядку 0x20 додається адреса TIME-ETH пулу ліквідності, який стає "очікуваним" msg.sender!

Корінь проблеми

В ERC-2771 [Forwarder] ніколи не планувався для роботи з multicall! Атакуючий додав параметри _msgSender() до зовнішнього виклику multicall. Всередині функції multicall деякі функції теж додавали ці параметри, що дозволило імітувати виклик від ЛЮБОГО адреси!

Заходи безпеки

  1. Нова версія OpenZeppelin Multicall тепер зберігає довжину контексту ERC-2771 і враховує її при кожному дочірньому виклику.

  2. ThirdWeb пішов далі і заборонив будь-яким контрактам викликати multicall, запобігаючи використанню [Forwarder].

Ця уразливість - яскравий приклад того, як комбінація безпечних окремо компонентів може створити катастрофічну брешу! Усі розробники повинні пам'ятати: завжди перевіряйте взаємодію між різними стандартами.

ETH1.17%
Переглянути оригінал
Ця сторінка може містити контент третіх осіб, який надається виключно в інформаційних цілях (не в якості запевнень/гарантій) і не повинен розглядатися як схвалення його поглядів компанією Gate, а також як фінансова або професійна консультація. Див. Застереження для отримання детальної інформації.
  • Нагородити
  • Прокоментувати
  • Репост
  • Поділіться
Прокоментувати
0/400
Немає коментарів
  • Закріпити