Back to Blog

Систематический подход к обеспечению совместимости и безопасности EVM

Code Auditing
March 27, 2023
7 min read

Блокчейны, совместимые с EVM (Ethereum Virtual Machine), разработаны для обеспечения совместимости с функциональностью смарт-контрактов блокчейна Ethereum, его языком программирования (Solidity) и экосистемой инструментов. В этом процессе реализация EVM-совместимой виртуальной машины является одним из ключевых шагов. Однако в ходе наших исследований мы обнаружили, что поддерживать совместимость с EVM в различных реализациях непросто.

Для решения этой проблемы компания BlockSec разработала внутреннюю систему, которая может систематически обнаруживать ошибки и уязвимости безопасности в реализациях EVM. Эта система оказалась эффективной: она выявила четыре ошибки в Aurora Engine и четыре ошибки в Moonbeam. Все они были задокументированы и исправлены. Следует отметить, что эта методология тестирования также использовалась для обнаружения двух критических уязвимостей (CVE-2021–46102, CVE-2022–23066) в реализации Solana rbpf в прошлом году.

1. Предыстория

В наши дни предлагается множество различных блокчейнов с оптимизацией по низкой комиссии за газ, высокой пропускной способности и отличной производительности. В этой связи предлагаются новые виртуальные машины и языки разработки, что повышает порог перехода для разработчиков, работающих на Solidity. В этих условиях предлагается множество EVM-совместимых решений, позволяющих пользователям развёртывать свои DApp, разработанные на Solidity, в этих новых сетях. Aurora и Moonbeam являются представителями таких EVM-совместимых решений. Однако надёжность, достоверность и точность этих реализаций EVM неизвестны и заслуживают нашего внимания. С этой целью мы применяем технику дифференциального фаззинга и проверяем наличие недостатков в реализациях.

2. Дифференциальный фаззинг

Основная идея заключается в том, чтобы подавать одинаковые входные данные в эти реализации EVM (например, Aurora, Moonbeam) и в современный клиент Ethereum (т.е. geth) для проверки того, выдают ли они одинаковый результат. В частности, мы собираем исторические транзакции в Ethereum и мутируем коды контрактов и состояния транзакций с помощью различных стратегий для генерации тестовых случаев. Наши результаты показывают, что Aurora Engine и Moonbeam в ряде случаев не соответствуют спецификации. К счастью, все обнаруженные проблемы были устранены, и теперь мы поделимся подробностями.

3. Обнаруженные ошибки

Большинство этих ошибок находится в предкомпилированных контрактах, а их первопричины и последствия различны. Например, некоторые ошибки могут влиять на расчёт значения nonce, тогда как другие могут влиять на расчёт газа и в дальнейшем приводить к атаке типа DoS. Все обнаруженные ошибки противоречат предусмотренной логике выполнения спецификации EVM и могут приводить к непредвиденному поведению в определённых случаях. Подробное описание обнаруженных ошибок приведено ниже.

3.1 Некорректная валидация

Криптографическая логика сложна. В этом случае реализация соответствующей логики в байт-коде EVM может привести к значительному расходу газа. Вместо этого предкомпилированные контракты, разработанные на нативном коде, могут повысить производительность. Однако мы обнаружили несколько ошибок в предкомпилированных контрактах из-за некорректной валидации.

Aurora Engine: ecPairing

Эта ошибка обнаружена в предкомпилированном контракте ecPairing.

Входные данные ecPairing состоят из нескольких точек на двух эллиптических кривых. Согласно спецификации, точка (0, 0) лежит на обеих кривых и должна быть допустимыми входными данными:

Однако Aurora Engine (версия 2.7.0) выполняет откат, если точка (0,0) включена во входные данные.

Соответствующий PR находится здесь.

Moonbeam: ecMul

Эта ошибка находится в предкомпилированном контракте ecMul. В отличие от Aurora Engine, Moonbeam выполняет откат транзакции, когда входные данные являются допустимыми. Согласно спецификации, предкомпилированный контракт ecMul должен дополнять входные данные нулями, когда их длина меньше 64. Однако Moonbeam выполняет откат вместо операции дополнения.

Мы также обнаружили, что предкомпилированные контракты ecAdd и modexp имеют ту же проблему.

Moonbeam: ecRecover

Эта ошибка находится в предкомпилированном контракте ecRecover, который используется для восстановления адреса Ethereum.

Согласно спецификации, входные данные input[32..63] v представляют собой идентификатор типа U256 и ожидается, что он будет равен 27 или 28; в противном случае ecRecover не должен ничего возвращать (но вся транзакция не должна откатываться).

Однако Moonbeam допускает две ошибки:

  • Он проверяет только input[63] вместо преобразования input[32..63] в тип U256 с последующей проверкой значения.
  • Входные данные считаются допустимыми, когда идентификатор равен 0 или 1 (допустимыми должны быть только значения 27 или 28).

Moonbeam: ecPairing

Эта ошибка находится в предкомпилированном контракте ecPairing. Moonbeam не выполняет откат транзакции при недопустимых входных данных. Согласно спецификации, входные данные предкомпилированного контракта ecPairing должны быть кратны 192. В противном случае транзакция должна быть откатана.

Однако Moonbeam не выполняет откат транзакции, когда вышеупомянутые требования не соблюдены.

3.2 Некорректный расчёт газа

Каждый предкомпилированный контракт имеет алгоритм определения расхода газа. Некорректный расчёт газа может привести к атаке типа DoS.

Мы обнаружили две ошибки как в Aurora Engine, так и в Moonbeam, связанные с некорректным расчётом газа.

Aurora Engine: modexp

Ошибка находится в предкомпилированном контракте modexp. Алгоритм расчёта расхода газа определён в EIP-2565. Расход газа связан с количеством итераций.

Алгоритм расчёта количества итераций выглядит следующим образом.

def calculate_iteration_count(exponent_length, exponent):
   iteration_count = 0
   if exponent_length <= 32 and exponent == 0: iteration_count = 0
   elif exponent_length <= 32: iteration_count = exponent.bit_length() - 1
   elif exponent_length > 32: iteration_count = (8 * (exponent_length - 32)) + ((exponent & (2**256 - 1)).bit_length() - 1)
   return max(iteration_count, 1)

Согласно приведённому алгоритму, количество итераций составляет не менее одной. Однако Aurora Engine возвращает iteration_count напрямую вместо max(iteration_count, 1). В этом случае возвращаемое значение (т.е. iteration_count) может быть равно 0, что означает, что Aurora будет взимать значительно меньшую комиссию за газ, чем ожидается, в определённых случаях.

Ссылка на соответствующую задачу находится здесь.

Moonbeam: modexp

Ошибка также находится в функции calculate_iteration_count предкомпилированного контракта modexp, но обнаружена в Moonbeam.

Когда exponent_length больше 32, iteration_count вычисляется по следующему алгоритму.

(8 * (exponent_length - 32)) + ((exponent & (2**256 - 1)).bit_length() - 1)

Обратите внимание, что здесь используется exponent & (2**256 - 1), что берёт младшие 32 байта exponent, и реализация Moonbeam следует этому алгоритму.

Однако согласно спецификации формула расчёта газа должна использовать старшие 32 байта exponent:

3.3 Ошибка инкремента nonce

Nonce аккаунта, принадлежащего внешнему пользователю (EOA), указывает количество успешных транзакций, подписанных этим адресом. Однако мы заметили, что nonce может быть увеличен путём отправки недопустимых транзакций в Aurora Engine.

Согласно EIP-1559, перед выполнением транзакции EVM должна убедиться, что подписант имеет достаточный баланс для покрытия переводимого нативного токена (например, ETH) и необходимого газа. В противном случае транзакция должна быть отклонена, а nonce подписанта не должен увеличиваться.

Несмотря на то что Aurora Engine отклоняет транзакцию в этой ситуации, она всё равно увеличивает nonce подписанта.

Соответствующий PR находится здесь.

3.4 Некорректная реализация опкода

Эта ошибка касается реализации конкретного опкода (т.е. PUSH). Когда байты, следующие за опкодом PUSH, неполны, они должны быть выровнены по правому краю. Например, байт-код 0x64ffff может быть декодирован как:

PUSH5 0xffff

Поскольку операнд должен быть выровнен по правому краю, в стек должно быть помещено значение 0xffff000000. Однако реализации EVM как в Aurora Engine, так и в Moonbeam помещают 0xffff вместо этого, что является некорректным.

Соответствующий PR находится здесь.

4. Наши услуги

В BlockSec мы понимаем важность поддержания совместимости с EVM и безопасности в различных реализациях блокчейна. Именно поэтому мы разработали систематический подход к обнаружению ошибок, который позволяет легко находить уязвимости в реализациях EVM.

Наша внутренняя система продемонстрировала высокую эффективность в обнаружении ошибок и уязвимостей безопасности в реализациях EVM. Она успешно выявила и помогла исправить четыре ошибки в Aurora Engine и четыре ошибки в Moonbeam. Кроме того, наша методология тестирования использовалась для обнаружения двух критических уязвимостей (CVE-2021–46102, CVE-2022–23066) в реализации Solana rbpf в прошлом году, что подчёркивает эффективность нашего подхода.

Внедряя наш систематический подход к обнаружению ошибок, наши клиенты могут быть уверены в безопасности и надёжности своих реализаций EVM. Мы стремимся предоставлять первоклассные решения для обеспечения совместимости с EVM и безопасности, помогая нашим клиентам завоёвывать доверие своих пользователей и заинтересованных сторон.

О компании BlockSec

Команда BlockSec сосредоточена на безопасности экосистемы блокчейна и сотрудничает с ведущими DeFi-проектами для защиты их продуктов. Команда основана выдающимися исследователями в области безопасности и опытными экспертами из академической среды и индустрии. Они опубликовали несколько научных работ по безопасности блокчейна на престижных конференциях, сообщили о нескольких атаках нулевого дня на DeFi-приложения и опубликовали подробные аналитические отчёты о резонансных инцидентах в сфере безопасности.

Официальный сайт | Twitter | Medium

Sign up for the latest updates
~$5.98M Потеряно: Aztec, Raydium и другие | Еженедельник BlockSec
Security Insights

~$5.98M Потеряно: Aztec, Raydium и другие | Еженедельник BlockSec

Еженедельный отчёт о безопасности блокчейна (8–15 июня 2026 г.): 4 инцидента в Ethereum и Solana, общие потери ~$5,98 млн. Aztec Connect: отсутствие валидации входных данных привело к рассинхронизации rollup и L1. Raydium: уязвимость в AMM v3 позволила дренировать 4 пула.

Анализ уязвимости Zcash Orchard | Еженедельник BlockSec
Security Insights

Анализ уязвимости Zcash Orchard | Еженедельник BlockSec

Критическая уязвимость в цепи Orchard Zcash: отсутствие ограничения равенства в гаджете ECC halo2 позволяло незаметно подделывать ZEC через двойное расходование. Уязвимость существовала 4+ лет, обнаружена ИИ-аудитом (Anthropic Opus 4.8, исследователь Тейлор Хорнби), устранена экстренным обновлением NU6.2.

Информационный бюллетень — май 2026 г.
Security Insights

Информационный бюллетень — май 2026 г.

В мае 2026 года в DeFi произошло 3 взлома: Echo Protocol ($76,7 млн, компрометация ключа), StablR ($12,8 млн, брешь в multisig) и Verus-Ethereum Bridge ($11,7 млн, ошибка проверки типов). Общий ущерб — около $101,2 млн.

Best Security Auditor for Web3

Validate design, code, and business logic before launch. Aligned with the highest industry security standards.

BlockSec Audit