Back to Blog

Как была обнаружена и своевременно исправлена критическая уязвимость в сети Solana

Code Auditing
7 июня 2022 г.
5 min read

В апреле наша система обнаружения уязвимостей выявила проблему в rBPF от Solana (т.е. в виртуальной машине, на которой работают все dApps Solana: https://github.com/solana-labs/rbpf). После тщательного расследования мы обнаружили, что это уязвимость в системе безопасности, которая может привести к неверному пути исполнения контракта. Мы сообщили об ошибке команде безопасности Solana, и команда немедленно подтвердила и устранила уязвимость. Кроме того, наша команда получила вознаграждение в размере 800 000 долларов США в токенах SOL.

Уязвимость существует в новых версиях rBPF (от 0.2.26 до 0.2.27). К моменту, когда мы сообщили о проблеме, валидаторы, используемые в основной сети (mainnet), еще не были обновлены до затронутых версий. Наша система обнаружила проблему до того, как затронутая версия была объединена (merged), что сделало валидаторы основной сети невосприимчивыми к этой уязвимости.

Ниже мы подробно описываем детали этой уязвимости.

1. eBPF и rBPF

eBPF (Extended Berkeley Packet Filter) изначально был разработан для фильтрации пакетов в ядре. Благодаря безопасности, эффективности и масштабируемости eBPF, сейчас он используется в различных областях, таких как сети, трассировка, профилирование и т.д.. Учитывая широкие возможности eBPF, Solana использует его в качестве движка выполнения для смарт-контрактов. Для создания dApps на Solana разработчики пишут свои смарт-контракты на Rust и компилируют их в байт-код eBPF.

Solana использует rBPF, виртуальную машину, написанную на Rust, для выполнения скомпилированного байт-кода BPF. Однако неизвестно, является ли предложенная виртуальная машина (т.е. rBPF) надежной, безопасной и точной. Если внутри rBPF существуют проблемы с безопасностью, это может затронуть все валидаторы, содержащие rBPF, что приведет к огромным потерям (например, потере средств) для всей сети Solana.

2. Первопричина

Мы разработали инструмент, который может автоматически находить ошибки реализации rBPF и периодически сканировать код rBPF. В процессе сканирования в rBPF (версия 0.2.26) была выявлена одна серьезная проблема, которая может привести к неверному пути исполнения контракта.

В частности, инструкция sdiv используется как инструкция знакового деления, представленная как функция, включенная по умолчанию в rbpf 0.2.26. sdiv поддерживает деление операндов как в 32 битах (т.е. sdiv32), так и в 64 битах (sdiv64). Для инструкции sdiv32 результат вычисления сохраняется в регистр bpf, который является 64-битным. Однако если инструкции, следующие за sdiv32, считывают результат вычисления как 64-битный, результат может отличаться. Это связано с тем, что rBPF при JIT-компиляции не расширяет знак результата вычисления sdiv32 до правильного 64-битного значения.

Например, если положительное число (т.е. 12) делится на отрицательное число (т.е. -4) с помощью sdiv32, правильным результатом должно быть -3 как в 32 битах, так и в 64 битах. Ниже приведен пример кода.

После запуска и трассировки в режимах JIT и интерпретации мы смогли наблюдать различия между ними:

2.1 Режим интерпретации (Interpreted Mode)

0 [0000000000000000, 0000000400000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000200014000]    29: lddw r5, 0x10000000c
 1 [0000000000000000, 0000000400000000, 0000000000000000, 0000000000000000, 0000000000000000, 000000010000000C, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000200014000]    31: sdiv32 r5, -4
 2 [0000000000000000, 0000000400000000, 0000000000000000, 0000000000000000, 0000000000000000, FFFFFFFFFFFFFFFD, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000200014000]    32: jslt r5, 0, lbb_7
 3 [0000000000000000, 0000000400000000, 0000000000000000, 0000000000000000, 0000000000000000, FFFFFFFFFFFFFFFD, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000200014000]    36: exit

2.2 Режим JIT (JIT Mode)

0 [0000000000000000, 0000000400000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000200014000]    29: lddw r5, 0x10000000c
 1 [0000000000000000, 0000000400000000, 0000000000000000, 0000000000000000, 0000000000000000, 000000010000000C, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000200014000]    31: sdiv32 r5, -4
 2 [0000000000000000, 0000000400000000, 0000000000000000, 0000000000000000, 0000000000000000, 00000000FFFFFFFD, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000200014000]    32: jslt r5, 0, lbb_7
 3 [0000000000000000, 0000000400000000, 0000000000000000, 0000000000000000, 0000000000000000, 00000000FFFFFFFD, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000200014000]    33: lddw r0, 0x1
 4 [0000000000000001, 0000000400000000, 0000000000000000, 0000000000000000, 0000000000000000, 00000000FFFFFFFD, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000200014000]    35: exit

В режиме интерпретации регистр r5 устанавливается в 0xFFFFFFFFFFFFFFFD (-3 как в 32-битной, так и в 64-битной форме), тогда как в режиме JIT r5 устанавливается в 0x00000000FFFFFFFD. В этом случае r5 будет распознан как положительное число (т.е. 0x00000000FFFFFFFD) для инструкции jslt, которая получает 64-битное значение. После этого путь выполнения будет полностью неверным.

3. Влияние

Эта неправильная реализация может привести к неверному пути исполнения контракта и вызвать серьезные проблемы.

Например, если важная операция в смарт-контракте опирается на результат инструкции sdiv32, это может привести к неверным результатам выполнения и быть использовано злоумышленниками.

Эта проблема была введена в https://github.com/solana-labs/rbpf/pull/283, что означает, что rBPF был уязвим начиная с версии 0.2.26. Мы выявили проблему и сообщили о ней команде безопасности Solana 28 апреля 2022 года. Команда оперативно ответила на наш отчет и за несколько часов исправила проблему, добавив операцию расширения знака для инструкции sdiv32. Исправление находится по адресу https://github.com/solana-labs/rbpf/pull/310. Благодаря своевременному обнаружению и отчету нашей команды, валидаторы основной сети не пострадали от этой уязвимости.

Эта проблема была классифицирована как ошибка жизнеспособности протокола (protocol liveness bug), что привело к выплате вознаграждения в размере 800 000 долларов США от Solana.

Хронология

  • 28.04.2022: Мы сообщили о проблеме команде безопасности Solana
  • 29.04.2022: Уязвимость была устранена
  • 09.05.2022: Был назначен CVE-2022-23066
  • 01.06.2022: Было предоставлено вознаграждение за обнаружение ошибки

О BlockSec

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

Twitter: [BlockSecTeam]

Medium: https://blocksecteam.medium.com

Веб-сайт: https://www.blocksec.com

Sign up for the latest updates
За пределами смарт-контракта: операционная безопасность доменов и DNS в Web3
Security Insights

За пределами смарт-контракта: операционная безопасность доменов и DNS в Web3

Аудит контрактов не проверяет сам контракт. Мы провели 800 SEAL-проверок DNS и регистраторов для 100 доменов из TVL Top 100 DefiLlama — лишь один домен прошёл все. Каких четырёх мер защиты не хватает большинству и почему это критично для пользователя.

Поверхности атаки Web3: обзор тестирования на проникновение

Поверхности атаки Web3: обзор тестирования на проникновение

Крипто-организации сохраняют все традиционные уязвимости и добавляют цепочку работы с деньгами. Статья описывает систему через четыре компонента: приложение, авторизацию и подпись, взаимодействие с блокчейном, инфраструктуру — с их зонами атак, а также пять специфичных для web3 областей: от эксплуатации и подписания до вывода средств и контрактов.

Потеряно ~23 млн $: эксплойты Cosmos EVM и Moonwell | BlockSec Weekly
Security Insights

Потеряно ~23 млн $: эксплойты Cosmos EVM и Moonwell | BlockSec Weekly

За период (22.08.2026–30.08.2026): 5 инцидентов, ~$22,7 млн убытков; Tectonic — $74–119,5 млн, откачены на Cronos. Взлом Cosmos EVM (~$5,7 млн) на TAC Chain, Moonwell, Ajna, Rain Card Exploit (Ed25519) на Solana.

Best Security Auditor for Web3

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

BlockSec Audit
Как была обнаружена и своевременно исправлена критическая уязвимость в сети Solana