Топ-3 инструмента аудита смарт-контрактов

09.08.2022

Средства анализа безопасности смарт-контрактов

Ранее мы писали о договорах в цифровую эпоху, раскрыв основы работы и безопасности смарт-контрактов. Сегодня, в продолжение темы безопасности смарт-контрактов, мы делимся с вами нашим обзором самых распространенных инструментов для аудита смарт-контрактов.

На данный момент наша цель – сравнить наиболее популярные программные инструменты для анализа безопасности смарт-контрактов. Для этого мы использовали смарт-контракты, признанные безопасными с высокой степенью вероятности (далее для простоты – заведомо безопасные или безопасные смарт-контракты), а также заведомо уязвимые, или просто уязвимые смарт-контракты. В общей сложности для анализа было использовано 20 смарт-контрактов DeFi из блокчейн-сети Ethereum, написанных на языке программирования Solidity.

В качестве безопасных смарт-контрактов мы отобрали только те контракты, которые имели отчеты по профессиональному аудиту безопасности, разработанные авторитетными аудиторами. С помощью ресурса etherscan.io были определены 10 смарт-контрактов, которые имели одну или более успешно проведенных транзакций, а также исправленные уязвимости, указанные в профессиональных независимых аудиторских отчетах. Ниже представлен список этих заведомо безопасных смарт-контрактов.

Название смарт-контрактаАдрес смарт-контракта
BAToken0x0D8775F648430679A709E98d2b0Cb6250d2887EF
HumanStandardToken0x0F4CA92660Efad97a9a70CB0fe969c755439772C
HBToken0x6f259637dcD74C767781E37Bc6133cd6A68aa161
NPXSToken0xA15C7Ebe1f07CaF6bFF097D8a589fb8AC49Ae5B3
FunctionXToken0x8c15Ef5b4B21951d50E53E4fbdA8298FFAD25057
BlockWRKICO0x0407B4c4eAEd35CE3C5B852bDFA1640B09EeEDF4
ThePoolz0x000BaB4F6b5560d7942AC88cf0233b6028B5B465
EternalStorageProxy0x69c707d975e8d883920003CC357E556a4732CD03
Layerx0xfe56E974C1C85e9351325fb2D62963A022Ad624F
sHakka0xd9958826Bce875A75cc1789D5929459E6ff15040

Также, для определения эффективности средств аудита, мы выбрали смарт-контракты с общеизвестными верифицированными уязвимостями. Эти смарт-контракты были специально разработаны крипто-энтузиастами для целей тестирования, обучения и т. п.

Список заведомо уязвимых смарт-контрактов:

Тип уязвимостиНазвание смарт-контракта
Access controlUnprotected0
ArithmeticOverflowSingleTx
Bad randomnessLottery
Denial of serviceDosSimple
Front runningFindThisHash
ReentrancyReentrancySimple
Short addressesShortAddressExample
Time manipulationRoulette
Unchecked low-level callsLotto
OtherNaiveReceiver

Для проведения аудита смарт-контрактов и анализа результатов мы отобрали три наиболее распространенных и актуальных инструмента с открытым исходным кодом, а именно:

  • Mythril
  • Securify
  • Slither

Мы установили их на виртуальную машину Oracle VirtualBox под управлением Linux Ubuntu 21.10. Также, для нормальной работы инструментов мы установили платформу Docker, языки программирования Python 3 и ряд библиотек Python. Мы использовали исключительно консольные версии средств аудита.

Суть нашего исследования заключается в определении эффективности инструментального аудита смарт-контрактов путем анализа каждым инструментом безопасных смарт-контрактов и уязвимых смарт-контрактов. Для безопасных смарт-контрактов любые уязвимости, найденные инструментами и не указанные в отчетах по независимому аудиту, будут считаться ложными срабатываниями (ложноположительными результатами, ошибками первого рода, false positive). Для уязвимых смарт-контрактов невыявленные известные уязвимости будут считаться пропусками событий (ложноотрицательными результатами, ошибками второго рода, false negative).

Дополнительно мы проверили, смогут ли инструменты найти уязвимости, которые были исправлены в безопасных смарт-контрактах по результатам независимых аудиторских отчетов. Мы были практически уверены, что уязвимости не будут найдены, но такая проверка повысит объективность анализа.

Для общей оценки эффективности работы инструментов мы использовали следующие их характеристики:

  • Количество ошибочно обнаруженных уязвимостей.
  • Количество ошибочно не обнаруженных (пропущенных) уязвимостей.
  • Время выполнения аудита.
  • Возможность поиска путей оптимизации расхода газа.
  • Дополнительный функционал и детализация полученных результатов.

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

Что такое Mythril, и как он работает

Mythril – один из самых распространенных инструментов для аудита байт-кода виртуальных машин Ethereum. Тестирование смарт-контрактов происходит конколическим методом, включающим в себя символьное исполнение, вычисление SMT и taint-анализ (анализ испорченности). С помощью инструмента Mythril можно найти такие уязвимости, как переполнение численных значений, перезапись владельца, повторный запуск функции и т. д. Ниже приведен пример отчета Mythril.

==== Unprotected Selfdestruct ====
SWC ID: 106
Severity: High
Contract: KillBilly
Function name: commencekilling()
PC address: 354
Estimated Gas Usage: 574 - 999
The contract can be killed by anyone.
Anyone can kill this contract and withdraw its balance to an arbitrary address.
--------------------
In file: killbilly.sol:22

selfdestruct(msg.sender)

Кроме сети Ethereum, инструмент способен анализировать смарт-контракты сетей, поддерживающих EVM. Среди них: Hedera, Quorum, Vechain, Roostock, Tron и другие.

Для запуска анализа необходимо выполнить команду «myth analyze ExampleName.sol». Также есть возможность указать максимальное количество тестовых транзакций, которые нужно выполнить, и максимальную продолжительность выполнения анализа в секундах. Для этого в команду запуска необходимо добавить параметры «-t» и «–execution-timeout» соответственно.

Инструмент предоставляет достаточно подробный и удобный отчет по аудиту. Это позволяет легко найти выделенную часть кода в оригинальном файле и проверить потенциальные уязвимости вручную. Mythril не имеет возможностей поиска путей экономии расхода газа.

Что такое Securify, и как он работает

Securify – инструмент аудита безопасности смарт-контрактов, разработанный Ethereum Foundation и ChainSecurity в 2017 году. С начала запуска проекта с использованием Securify было просканировано более 22 тысяч смарт-контрактов Ethereum. Это помогло их разработчикам исправить большое количество уязвимостей разных уровней риска.

Securify статически анализирует байт-код виртуальных машин Ethereum и получает всю информацию об алгоритме работы и потоке данных в нем. Этот процесс полностью автоматизирован с помощью Souffle, языка программирования, который создавался для статического анализа программного обеспечения Oracle и др. После этого происходит проверка полученных фактов для поиска уязвимостей и предоставляются рекомендации по их устранению.

Ниже изображены основные этапы работы инструмента Securify:

Анализ проходит в три основных этапа:

  1. Парсинг байт-кода EVM и его декомпиляция в форму, пригодную к анализу.
  2. Определение семантических фактов о смарт-контракте.
  3. Сочетание шаблонов и правил для определения уязвимых мест.

Для старта аудита локально сохраненного смарт-контракта необходимо выполнить следующую команду:

securify <contract_source>.sol [–use-patterns Pattern1]

Также можно сканировать смарт-контракты в сети Ethereum:

securify <contract_address> –from-blockchain [–key <key-file>]

После выполнения одной из этих команд можно получить следующий отчет:

Severity:    CRITICAL
Pattern:     Transaction Order Affects Execution of Ether Transfer
Description: Ether transfers whose execution can be manipulated by
             other transactions must be inspected for unintended
             behavior.
Type:        Violation
Contract:    Layerx
Line:        383
Source: 
>         
>         if(rwds.eth > 0) { msg.sender.transfer(rwds.eth); }
>                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>     }


Severity:    HIGH
Pattern:     Unhandled Exception
Description: The return value of statements that may return error
             values must be explicitly checked.
Type:        Warning
Contract:    Layerx
Line:        270
Source: 
>         require(payment > 0, 'Payment must be greater than 0.');
>         require(UNILAYER.balanceOf(msg.sender) >= payment, 'Holder does not have enough tokens.');
>                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>         require(UNILAYER.allowance(msg.sender, address(this)) >= payment, 'Call Approve function firstly.');

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

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

Что такое Slither, и как он работает

Slither – инструмент для статического анализа кода смарт-контрактов. Кроме автоматического поиска уязвимостей, Slither способен находить возможности оптимизации кода и визуализировать алгоритм работы, помогающий аудиторам лучше и быстрее понять, как именно устроен смарт-контракт. Инструмент имеет возможность работать без дополнительных настроек с такими фреймворками, как Truffle, Hardhat, Embark и Dapp.

Алгоритм работы Slither:

  1. Представление исходного кода в виде абстрактного синтаксического дерева с помощью компилятора Solidity.
  2. Построение графика наследования элементов, графика потока управления и списка всех выражений смарт-контракта.
  3. Изображение кода смарт-контракта в виде внутреннего репрезентативного языка Slither, упрощающего анализ.
  4. Вся полученная информация передается в модули поиска уязвимостей.
  5. Аудит и предоставление отчета.

Ниже представлено схематическое изображение алгоритма работы Slither:

Установить инструмент можно с использованием Pypi, загрузив из репозитория Github, или как часть образа Docker под названием eth-security-toolbox. Для начала аудита необходимо выполнить следующую команду: slither examplename.sol.

Пример отчета Slither:

C.increment() (etheno-examples/ConstantinopleGasUsage/constantinople.sol#7-11) ignores return value by address(this).call(abi.encodeWithSignature(setStored(int256),newValue)) (etheno-examples/ConstantinopleGasUsage/constantinople.sol#10)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#unchecked-low-level-calls

Pragma version^0.5.4 (etheno-examples/ConstantinopleGasUsage/constantinople.sol#1) allows old versions
solc-0.5.5 is known to contain severe issues (https://solidity.readthedocs.io/en/latest/bugs.html)Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-versions-of-solidity

Low level call in C.increment() (etheno-examples/ConstantinopleGasUsage/constantinople.sol#7-11):
	- address(this).call(abi.encodeWithSignature(setStored(int256),newValue)) (etheno-examples/ConstantinopleGasUsage/constantinople.sol#10)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#low-level-calls

setStored(int256) should be declared external:
	- C.setStored(int256) (etheno-examples/ConstantinopleGasUsage/constantinople.sol#4-6)
increment() should be declared external:
	- C.increment() (etheno-examples/ConstantinopleGasUsage/constantinople.sol#7-11)
echidna_() should be declared external:
	- C.echidna_() (etheno-examples/ConstantinopleGasUsage/constantinople.sol#12-14)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#public-function-that-could-be-declared-external 

Отчет состоит из подробных описаний найденных уязвимостей, строк в коде, где находятся уязвимые функции, и ссылок на внешние ресурсы с рекомендациями. Уровень риска уязвимости можно определить по цвету: красный – критический и высокий, желтый – средний уровень, зеленый – низкий уровень.

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

Сравнение результатов

Результаты аудита безопасных смарт-контрактов.

Название безопасного смарт-контрактаКоличество ложных срабатыванийВремя выполнения аудита (секунды)
MythrilSecurifySlitherMythrilSecurifySlither
BAToken24351122
BlockWRKICO3022792
EternalStorageProxy0321301
FunctionXToken222521
HBToken051161181
LayerX203222
NPXSToken210133163
sHakka001222
ThePoolz113551
HumanStandardToken102232
Итого1325206859917

В результате проведения аудита, инструмент Mythril допустил от 1 до 3 ложных срабатываний в 7 из 10 безопасных смарт-контрактов, Securify – от 1 до 10 ложных срабатываний в 6 из 10 безопасных смарт-контрактов. Все обнаруженные уязвимости имели уровни риска «Warning» и «Informational», что расценивается как низкий уровень риска.

Slither допустил от 1 до 3 ложных срабатываний во всех 10 безопасных смарт-контрактах. К тому же некоторым из срабатываний был назначен средний и высокий уровень риска.

Результаты аудита уязвимых смарт-контрактов.

Название уязвимого смарт-контрактаОбнаружены заведомо имеющиеся уязвимости?Время выполнения аудита (секунды)
MythrilSecurifySlitherMythrilSecurifySlither
unprotected0нетданет322
overflow_single_txданетнет992
lotteryнетдада3303
dos_simpleданетнет322
FindThisHashдадада1921
reentrancy_simpleдадада232
short_address_exampeнетнетнет221
rouletteдадада2522
lottoдадада2312
NaiveReceiverнетнетнет1092
Итого665789219

Среди уязвимых смарт-контрактов инструменты Mythril и Securify правильно определили проблемы в 6 из 10 смарт-контрактах DeFi, а Slither – в 5 из 10.

Securify обозначил большую часть ошибок как Violation, что можно интерпретировать как высокую уверенность инструмента в корректном определении уязвимостей безопасности. Кроме того, Securify обнаружил проблемы отсутствия валидации данных, контролируемых пользователем, и использование низкоуровневых вызовов call, что не соответствует лучшим практикам безопасной разработки на языке программирования Solidity.

В уязвимых смарт-контрактах все интрументы также обнаружили уязвимости, которые не были заявлены разработчиками:

Название уязвимого смарт-контрактаКоличество найденных незаявленных уязвимостей
MythrilSecurifySlither
unprotected0004
overflow_single_tx061
lottery111
dos_simple001
FindThisHash011
reentrancy_simple031
short_address_exampe101
roulette011
lotto052
NaiveReceiver143
Итого32116

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

Выводы

Мы рассмотрели три самых популярных инструмента для автоматизированного поиска уязвимостей в смарт-контрактах, а именно Mythril, Securify и Slither.

Изучение инструментов проводилось путем анализа десяти заведомо безопасных смарт-контрактов, проверенных независимыми аудиторами, и десяти заведомо уязвимых смарт-контрактов, разработанных для обучения, тестирования и т.д.

Для понимания общего набора уязвимостей приводим диаграмму общего количества найденных уязвимостей в безопасных и уязвимых смарт-контрактах по результатам работы всех трех инструментов.

schedule

В результате анализа мы определили точность, скорость, полноту результатов и дополнительные функции самых популярных инструментов аудита смарт-контрактов. 

Относительный вес ложных срабатываний (ошибок первого рода) в общей оценке мы считали меньшим, чем вес пропусков событий (ошибок второго рода), потому что первые легче верифицировать, чем последние.

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

MythrilSecurifySlither
Ложные срабатывания4.543
Пропуски событий221.5
Скорость анализа4.545
Детализация и функционал444.5
Общая оценка3.75
3.5 stars
3.5
3.5 stars
3.5
3.5 stars

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

Различные инструменты автоматического анализа смарт-контрактов дают ошибочные результаты разного типа и находят неодинаковые проблемы в определенном фиксированном наборе смарт-контрактов. Основной и дополнительный функционал разных инструментов значительно отличается.

Как ожидалось, ни один из инструментов не нашёл в безопасных смарт-контрактах уязвимостей, устранённых по результатам профессиональных независимых аудиторских отчётов. 

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

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

В случае возникновения дополнительных вопросов в сфере безопасности Web3 и блокчейн, пожалуйста, обратитесь к нам за получением бесплатной консультации.

Другие посты

17/09/2022
Взломы CeFi и блокчейн-мостов
29/08/2022
ТОП инцидентов Web3 и их причины