18 января наша система мониторинга обнаружила атаку на проект AnySwap (также известный как Multichain). Уязвимость связана с некорректной функцией anySwapOutUnderlyingWithPermit(), механизм верификации которой можно было обойти для вывода одобренных токенов.
Хотя проект использовал различные подходы (например, отправку транзакций пользователям, как показано на рисунке 1) для уведомления затронутых пользователей, многие из них не смогли своевременно принять меры (то есть отозвать одобрения) для защиты своих средств. В результате злоумышленники могли непрерывно проводить атаку для получения средств жертв.

Чтобы защитить потенциальных жертв, после долгих размышлений наша команда решила провести экстренное спасение для уязвимого контракта AnySwap (0x6b7a87899490EcE95443e979cA9485CBE7E71522) в сети Ethereum. В частности, мы могли перевести средства уязвимого аккаунта на наш white hat-кошелёк, представляющий собой мультисиг-кошелёк (0xd186540FbCc460f6a3A9e705DC6d2406cBcc1C47) в сети Ethereum.
Чтобы сделать наше white hat-спасение прозрачным, мы задокументировали наши намерения в PDF-файле и поделились хэшем этого файла с сообществом. Это позволило отличить нашу экстренную спасательную операцию от атаки, при этом не раскрывая детали (так как уязвимость всё ещё могла быть использована). Мы проводили экстренное спасение с 21 января 2022 года по 11 марта 2022 года, и соответствующие сообщения были опубликованы следующим образом:


Экстренное спасение — не тривиальная задача. Действительно, существует несколько проблем, как технических, так и нетехнических, которые необходимо решить для успешного спасения. Поскольку экстренное спасение уже завершено, мы можем всесторонне рассмотреть весь процесс и поделиться полученными уроками. Мы считаем, что этот опыт может прояснить некоторые аспекты обеспечения безопасности экосистемы DeFi.
Ключевые выводы (TL;DR)
- Между различными участниками, включая white hat'ов и атакующих, существует конкуренция. Плата за использование Flashbots быстро росла со временем.
- Flashbots не всегда работали. Напротив, некоторые атакующие переходили на использование обычного мемпула для успешного проведения атаки, применяя сложные стратегии.
- Некоторые атакующие были «отмыты», вернув часть украденных средств, оставив при этом остальное в качестве награды за баунти. Это явление, хотя и не первое, вызывает споры в сообществе, поскольку такой стимул может быть несправедливым по отношению к настоящим white hat'ам.
- Чтобы убедить сообщество, white hat'у рекомендуется заранее публично объявлять о своих действиях, не раскрывая при этом подробную конфиденциальную информацию.
- Сообщество может работать совместно для более эффективного и результативного проведения спасательных операций. Например, создание механизма координации для снижения/избежания конкуренции между white hat'ами.
Далее мы сначала представим общую картину спасательных операций и атак за этот период. Затем мы расскажем о том, как мы проводили спасение, и о проблемах, которые необходимо было решить. После этого мы обсудим некоторые уроки, которые мы извлекли из этого спасения. Наконец, мы поделимся некоторыми мыслями/предложениями, которые могут быть полезны для обеспечения безопасности экосистемы.
0x1 Спасения и атаки
0x1.1 Общий результат
Атаки и спасения, которые мы наблюдали и исследовали в этом отчёте, продолжались несколько месяцев, с блока 14028474 (18 января 2022 года) по блок 14421215 (20 марта 2022 года).
Аккаунты, которые проводили спасательные операции и атаки, обобщены в следующей таблице. Для простоты указаны только первые четыре символа адреса для представления EOA. Аккаунт может быть либо спасательным, либо атакующим. Стоит отметить, что тип аккаунта определяется либо на основе меток, присвоенных Etherscan.io, либо на основе наблюдаемых нами адресов назначения переводов.
В общей сложности было 9 спасательных аккаунтов, которые спасли 483,027693 ETH (с комиссией 295,970554 ETH, то есть 61,27% от общей суммы), и 21 атакующий аккаунт, который собрал 1433,092224 ETH (с комиссией 148,903707 ETH, то есть 10,39% от общей суммы). Стоит отметить, что потери являются приблизительной оценкой из-за некоторых сложных взаимодействий. Например, атакующий аккаунт мог превратиться в спасательный после переговоров с AnySwap, и мы рассмотрим это явление позже. Последний столбец таблицы указывает комиссию, отправленную майнеру, которая использовалась для победы в конкуренции за использование Flashbots.
| № | Аккаунт | Тип | # жертв | # потерь (ETH) | # комиссии (ETH) |
|---|---|---|---|---|---|
| 1 | 0x14ca** | Спасательный аккаунт | 50 | 432.958062 | 287.849654 |
| 2 | 0x9a65** | Спасательный аккаунт | 23 | 22.569429 | 0.000000 |
| 3 | 0x9117** | Спасательный аккаунт | 14 | 18.897622 | 7.213585 |
| 4 | 0x17d2** | Спасательный аккаунт | 3 | 3.552833 | 0.000000 |
| 5 | 0x6360** | Спасательный аккаунт | 21 | 3.540061 | 0.907168 |
| 6 | 0x0edd** | Спасательный аккаунт | 7 | 1.498706 | 0.000000 |
| 7 | 0x281e** | Спасательный аккаунт | 1 | 0.006000 | 0.000000 |
| 8 | 0xd83b** | Спасательный аккаунт | 1 | 0.004000 | 0.000000 |
| 9 | 0x8af3** | Спасательный аккаунт | 6 | 0.000980 | 0.000147 |
| 10 | 0x4986** | Атакующий аккаунт | 332 | 456.004547 | 0.000000 |
| 11 | 0xfa27** | Атакующий аккаунт | 42 | 433.438935 | 46.636389 |
| 12 | 0x48e9** | Атакующий аккаунт | 66 | 312.014657 | 0.000000 |
| 13 | 0x5738** | Атакующий аккаунт | 67 | 83.589240 | 62.587238 |
| 14 | 0x34b2** | Атакующий аккаунт | 7 | 63.599821 | 20.642705 |
| 15 | 0xd374** | Атакующий аккаунт | 86 | 45.452703 | 12.824763 |
| 16 | 0x1fe7** | Атакующий аккаунт | 9 | 12.817241 | 0.000000 |
| 17 | 0x98f5** | Атакующий аккаунт | 20 | 8.381273 | 0.000000 |
| 18 | 0x455d** | Атакующий аккаунт | 11 | 5.047377 | 0.544263 |
| 19 | 0x1b45** | Атакующий аккаунт | 6 | 4.942442 | 3.074813 |
| 20 | 0x3ec7** | Атакующий аккаунт | 6 | 3.705686 | 0.741137 |
| 21 | 0xbca4** | Атакующий аккаунт | 1 | 2.784250 | 1.392125 |
| 22 | 0xb0ab** | Атакующий аккаунт | 18 | 0.834068 | 0.296000 |
| 23 | 0x0a5b** | Атакующий аккаунт | 1 | 0.286750 | 0.143375 |
| 24 | 0x2d3a** | Атакующий аккаунт | 2 | 0.080090 | 0.000000 |
| 25 | 0x835d** | Атакующий аккаунт | 5 | 0.063945 | 0.000000 |
| 26 | 0x1dbd** | Атакующий аккаунт | 1 | 0.027431 | 0.012893 |
| 27 | 0x813d** | Атакующий аккаунт | 1 | 0.019528 | 0.008007 |
| 28 | 0x85dd** | Атакующий аккаунт | 6 | 0.002240 | 0.000000 |
| 29 | 0x2394** | Атакующий аккаунт | 1 | 0.000000 | 0.000000 |
| 30 | 0x6360** | Атакующий аккаунт | 2 | 0.000000 | 0.000000 |
0x1.2 Тенденция комиссии для участия в торгах Flashbots
Как упоминалось ранее, white hat'ам необходимо конкурировать с атакующими за отправку транзакций. В результате процент комиссии майнеру (в транзакциях Flashbots) может отражать уровень конкуренции. Для количественной оценки мы исследовали процент комиссии (включая атакующие и спасательные транзакции соответственно) для каждого блока.
На рисунке 4 показана наблюдаемая нами тенденция (от блока 14028474 до блока 14369199). Первые несколько атакующих транзакций не включали комиссию, что означает, что в тот период конкуренция была минимальной (или отсутствовала вовсе). Это объяснимо, поскольку о ранних атаках, возможно, мало кто знал.
На самом деле первая атака с комиссией (10%) произошла в блоке 14029765. С тех пор процент комиссии быстро рос по мере увеличения числа участников. Например, процент достиг 80% в блоке 14072385 и вскоре достиг 91% в блоке 14129449.
Короче говоря, эта тенденция указывает на то, что победа в конкуренции путём увеличения комиссии майнеру(ам) — это однозначно гонка вооружений.

0x2 Наше спасение и проблемы
0x2.1 Способ проведения спасения
Базовая идея проведения спасения довольно проста. В частности, нам нужно отслеживать аккаунты, которые одобрили WETH для уязвимого контракта. Когда на такой аккаунт поступает перевод WETH, мы можем напрямую перевести его на наш мультисиг-кошелёк, используя уязвимость в контракте AnySwap. Ключевые требования:
- R1: эффективное обнаружение транзакций, которые переводят токены на аккаунты жертв. Далее мы называем такие транзакции транзакциями-переводами.
- R2: корректное составление транзакций для проведения спасения. Далее мы называем такие транзакции спасательными транзакциями.
- R3: успешное опережение (фронтраннинг) транзакций, отправленных атакующими (и любыми другими третьими сторонами). Далее мы называем такие транзакции атакующими транзакциями.
R1 и R2 не являлись препятствиями для нас. В частности, мы создали внутреннюю систему для мониторинга мемпула, которая позволяет нам своевременно обнаруживать транзакции-переводы. Кроме того, мы разработали инструмент для автоматического составления транзакций.
Однако R3 оставалось проблемой. Можно было бы ожидать, что для победы в конкуренции можно использовать Flashbots. Однако достичь этой цели не так просто. Во-первых, атакующие также могли использовать Flashbots. Поскольку это система торгов на основе комиссии, успешность может зависеть от размера комиссии, указанной майнеру. Необходимо было определить стратегию установки комиссии. Во-вторых, использование Flashbots могло быть не лучшим выбором из-за интенсивной конкуренции. Поэтому мы также отправляли обычные транзакции через мемпул. Чтобы гарантировать успех, необходимо было учитывать стратегию размещения транзакции в правильной позиции. Наконец, мы также боролись с другими white hat'ами, поведение которых в некоторых случаях выглядело подозрительным.
0x2.2 Конкуренция, в которой мы участвовали
В общей сложности мы пытались защитить 171 уникального потенциального жертву, из которых 10 защитили себя сами, отозвав одобрения непосредственно перед тем, как мы попытались провести спасение. Из оставшихся 161 реальной жертвы нам удалось спасти только 14 из-за конкуренции. Неудачные случаи обобщены в следующей таблице, включая 3 спасательных аккаунта и 16 атакующих аккаунтов.
| № | Аккаунт | Тип | # жертв | # потерь (ETH) | # комиссии (ETH) | Средний % комиссии |
|---|---|---|---|---|---|---|
| 1 | 0x14ca** | Спасательный аккаунт | 44 | 431.651020 | 286.891724 | 66.46% |
| 2 | 0x9a65** | Спасательный аккаунт | 7 | 11.321441 | 0.000000 | 0.00% |
| 3 | 0x6360** | Спасательный аккаунт | 3 | 3.300000 | 0.891000 | 27.00% |
| 4 | 0x48e9** | Атакующий аккаунт | 35 | 301.681589 | 0.000000 | 0.00% |
| 5 | 0x5738** | Атакующий аккаунт | 58 | 78.482472 | 58.851862 | 74.99% |
| 6 | 0x34b2** | Атакующий аккаунт | 2 | 53.591712 | 17.685265 | 33.00% |
| 7 | 0xd374** | Атакующий аккаунт | 6 | 23.658698 | 10.073638 | 42.58% |
| 8 | 0x4986** | Атакующий аккаунт | 16 | 22.900105 | 0.000000 | 0.00% |
| 9 | 0x1fe7** | Атакующий аккаунт | 6 | 12.057241 | 0.000000 | 0.00% |
| 10 | 0x1b45** | Атакующий аккаунт | 5 | 4.402442 | 3.010013 | 68.37% |
| 11 | 0xbca4** | Атакующий аккаунт | 1 | 2.784250 | 1.392125 | 50.00% |
| 12 | 0x98f5** | Атакующий аккаунт | 8 | 2.339543 | 0.000000 | 0.00% |
| 13 | 0x455d** | Атакующий аккаунт | 3 | 0.741817 | 0.175454 | 23.65% |
| 14 | 0xfa27** | Атакующий аккаунт | 3 | 0.320288 | 0.032590 | 10.18% |
| 15 | 0x0a5b** | Атакующий аккаунт | 1 | 0.286750 | 0.143375 | 50.00% |
| 16 | 0x3ec7** | Атакующий аккаунт | 1 | 0.245000 | 0.049000 | 20.00% |
| 17 | 0xee7e** | Атакующий аккаунт | 1 | 0.190000 | 0.096900 | 51.00% |
| 18 | 0x835d** | Атакующий аккаунт | 3 | 0.024533 | 0.000000 | 0.00% |
| 19 | 0xb0ab** | Атакующий аккаунт | 1 | 0.000618 | 0.000000 | 0.00% |
Таким образом, есть несколько уроков, которые мы хотели бы поделиться с сообществом.
0x3 Некоторые извлечённые уроки
0x3.1 Как определить размер комиссии для майнера Flashbots?
В итоге нас обошли 12 конкурентов, включая 2 спасательных и 10 атакующих аккаунтов, использовавших Flashbots.
Наша стратегия установки комиссии майнеру была довольно консервативной. В частности, мы стремились защитить жертв, затрачивая как можно меньше средств на комиссию. Поэтому мы не активно использовали/увеличивали комиссию, если только некоторые успешные атакующие транзакции уже не установили определённую комиссию. Например, если атакующий устанавливал комиссию в размере 10% от суммы средств, то мы могли использовать 11% для следующего спасения, чтобы конкурировать с этим атакующим. Однако результат показывает, что эта стратегия не работала, поскольку атакующие (а иногда и некоторые white hat'ы) часто (если не всегда) агрессивно повышали комиссию, чтобы обойти других, как показано ниже:
- Рисунок 5 показывает, что атакующий 0x5738** установил процент комиссии на уровне 70% в блоке 14071986.
- Рисунок 6 показывает, что white hat 0x14ca** установил процент комиссии на уровне 79% в блоке 14072255.
- Рисунок 7 показывает, что white hat 0x14ca** установил процент комиссии на уровне 80% в блоке 14072385.
- Рисунок 8 показывает, что white hat 0x9117** установил процент комиссии на уровне 81% в блоке 14072417.
- Рисунок 9 показывает, что атакующий 0x5738** установил процент комиссии на уровне 86% в блоке 14073395.





Короче говоря, это похоже на игру с нулевой суммой, которая требует моделирования поведения различных участников для победы в конкуренции.
На практике, однако, сложно определить более эффективные/оптимальные стратегии, одновременно снижая затраты как можно больше.
0x3.2 Как расположиться на правильной позиции в мемпуле?
Теперь казалось бы, что спасение будет зависеть от гонки вооружений в конкуренции за комиссию для торгов Flashbots. Однако мы обнаружили, что использование Flashbots не было панацеей из-за интенсивной конкуренции со стороны других участников, не имевших никакого отношения к спасению и атаке. В таком случае даже самая высокая комиссия, указанная в атакующей транзакции, не гарантировала победу в возможности использования Flashbots.
В качестве альтернативы обычная транзакция с правильной позицией в мемпуле могла иметь шанс достичь цели. Правильная позиция здесь означает, что спасательная/атакующая транзакция должна быть расположена сразу после транзакции-перевода, и эта позиция должна быть очень близкой к транзакции-переводу (чем ближе, тем лучше). Обратите внимание, что, используя эту стратегию, атакующий 0x48e9** собрал 312,014657 ETH, не заплатив при этом никакой комиссии майнерам Flashbots.
Следующие четыре рисунка демонстрируют две самые крупные прибыли, которые получил атакующий:
- Рисунок 10 показывает, что жертва внесла 50 ETH на позиции 65 блока 14051020, а рисунок 11 показывает, что атакующий собрал эти 50 ETH на позиции 66 того же блока.
- Рисунок 12 показывает, что жертва внесла 200 ETH на позиции 161 блока 14052155, а рисунок 13 показывает, что атакующий собрал эти 200 ETH на позиции 164 того же блока.




Очевидно, что эта сложная стратегия весьма полезна и показательна, и заслуживает большего внимания и усилий для извлечения из неё уроков.
0x4 Некоторые другие мысли
0x4.1 White hat-хак или атака?
Когда речь заходит о признании white hat-хаков, они могут быть не такими однозначными, как может ожидаться.
Например, адрес 0xfa27 был помечен Etherscan.io как Multichain Exploiter 4 (Whitehat). На самом деле, в самом начале он был помечен как Multichain Exploiter 4. После нескольких раундов переговоров между атакующим и проектом AnySwap атакующего убедили вернуть часть украденных средств.
- В транзакции 0x3c3d** AnySwap связался с атакующим:
First and foremost thanks for getting the weth. I was not aware of the hack and realized the situation only because the weth never arrived in my wallet after the cowswap transaction. Considering the amount at stake, would you accept 50 eth as a fair tip? Here is mine txn: 0x2db9a6a51604e2be8b2c3469773afb201f0b48a318fb7e5f5e49175e818df5ba 0xe50ed602bd916fc304d53c4fed236698b71691a95774ff0aeeb74b699c6227f7
- В транзакции 0xd360** атакующий ответил:
pls verify by sending me back a tx. I will send you the rest 258 eth. 39 eth went to the miners because there other attackers so I have to pay that tip to save the money.
- В транзакции 0x354f** AnySwap выразил благодарность после получения средств:
Well received, thank you for your honesty.
Очевидно, что этот атакующий был «отмыт» и также получил некоторую прибыль от атаки. Подобные случаи происходили несколько раз и ранее, и они до сих пор вызывают споры в сообществе, поскольку такой стимул может быть несправедливым.
0x4.2 Конкуренция между white hat-хаками?
Необходимо создать механизм координации для снижения/избежания конкуренции между white hat'ами. Такая конкуренция неизбежно приводит к растрате спасательных ресурсов. В ходе этого спасения было 54 жертвы (с суммой средств 450 ETH), которых защитили три других white hat'а, хотя мы также пытались провести спасение.
Конкуренция между white hat'ами не только привела к растрате спасательных ресурсов, но и повысила стоимость проведения спасения. Например, как показано на рисунках 7 и 8, комиссия, затраченная на две спасательные транзакции разных white hat'ов, составила 80% и 81% соответственно.
К сожалению, white hat'ы не будут уступать друг другу, если не существует какого-либо механизма координации между ними. В противном случае невозможно устранить такую конкуренцию.
0x4.3 Как сделать спасение лучше
С одной стороны, чтобы убедить сообщество, white hat'у рекомендуется заранее публично объявлять о своих действиях, не раскрывая при этом подробную конфиденциальную информацию. На это есть достаточно времени, поскольку спасение обычно представляет собой затяжную борьбу с множеством попыток, что отличается от разовых усилий, таких как блокировка конкретной атаки. Конечно, подробная информация об уязвимостях не должна раскрываться.
Для этого подробная информация не раскрывается в самом начале и раскрывается сообществу только после завершения спасения, как мы и сделали в случае спасения AnySwap. Однако хэш документа с намерениями white hat'а можно сразу же поделиться с сообществом.
С другой стороны, сообщество может сделать больше для более эффективного и результативного проведения спасательных операций, включая, но не ограничиваясь следующим:
- Flashbots/майнеры могли бы предоставлять «зелёный канал» для сертифицированных white hat'ов. Такой зелёный канал мог бы обеспечивать высокий приоритет для опережения (фронтраннинга) транзакций атакующих и избегать конкуренции между white hat'ами.
- Проекты, подвергшиеся атаке, могли бы покрывать расходы на Flashbots/майнеров.
- Проекты могли бы применять удобные и быстрые механизмы уведомления пользователей.
- Проекты могли бы применять механизм экстренного реагирования в коде.
О компании BlockSec
BlockSec — это передовая компания в области блокчейн-безопасности, основанная в 2021 году группой всемирно известных экспертов по безопасности. Компания стремится повышать безопасность и удобство использования для развивающегося мира Web3, чтобы способствовать его массовому внедрению. С этой целью BlockSec предоставляет услуги аудита безопасности смарт-контрактов и EVM-совместимых блокчейнов, платформу Phalcon для безопасной разработки и упреждающего блокирования угроз, платформу MetaSleuth для отслеживания средств и расследований, а также расширение MetaSuites для разработчиков web3, позволяющее эффективно работать в криптомире.
На сегодняшний день компания обслужила более 300 авторитетных клиентов, таких как MetaMask, Uniswap Foundation, Compound, Forta и PancakeSwap, и привлекла десятки миллионов долларов США в рамках двух раундов финансирования от ведущих инвесторов, включая Matrix Partners, Vitalbridge Capital и Fenbushi Capital.
Официальный сайт: https://blocksec.com/
Официальный аккаунт в Twitter: https://twitter.com/BlockSecTeam



