Аудит смарт-контрактов с помощью ConsenSys Diligence Fuzzing — фаззинг как услуга

Аудит смарт-контрактов с помощью ConsenSys Diligence Fuzzing — фаззинг как услуга

9 апреля 2023 г.

Если вы работаете со смарт-контрактами  — или даже просто изучаете их  — вы, вероятно, уже знаете, что безопасность смарт-контрактов важна. Смарт-контракты неизменны после развертывания и часто связаны со значительными суммами денег. Написание безопасного и надежного кода перед развертыванием должно быть в первую очередь. А по мере того, как внедрение блокчейна ускоряется, обеспечение безопасности смарт-контрактов становится еще более важным.

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

В этой статье мы рассмотрим, как использовать фаззинг для эффективного аудита смарт-контракта. В частности, мы рассмотрим ConsenSys Diligence Fuzzing  — новое предложение фаззинга как услуги (FaaS). Мы углубимся в технические аспекты и покажем несколько примеров кода.

Что такое фаззинг?

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

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

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

Фаззинг существует уже некоторое время. Защита и Echidna и Литейный цех. Однако Diligence Fuzzing представляет собой услугу фаззинга и делает все немного проще в реализации. Что, в конечном счете, означает лучший аудит и более надежные контракты. Итак, давайте рассмотрим это подробнее.

Фаззинг ConsenSys Diligence

Diligence Fuzzing (от ConsenSys, которая также соответствует стандартам экосистемы, таким как MetaMask и Infura) — это фаззер, созданный для смарт-контрактов web3. Это:

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

И все это как услуга с минимальными усилиями с вашей стороны!

Чтобы использовать Diligence Fuzzing, выполните следующие три шага:

  1. Сначала определите спецификации смарт-контракта с помощью Scribble.
  2. Затем отправьте код в Diligence, чтобы запустить фаззинг.
  3. Наконец, с отчетом об аудите исправьте и улучшите свой код!

Фаззинг в действии

Давайте протестируем и посмотрим, как это работает. Мы будем использовать Fuzzing CLI и Scribble для фазз-тестирования образца смарт-контракта.

Шаг 1. Зарегистрируйтесь

Во-первых, зарегистрируйтесь, чтобы получить доступ к Diligence Fuzzing.

Шаг 2. Установите зависимости

Затем установите Fuzzing CLI и Scribble. ConsenSys рекомендует использовать последние версии Node и Python. Убедитесь, что вы используете как минимум Python 3.6 и Node 16. Тогда:

pip3 install diligence-fuzzing
npm i -g eth-scribble ganache truffle

Примечание. Для этого требуется Linux, Mac или подсистема Linux с Windows. В Windows Powershell есть некоторые сложности, над которыми работает команда. Вы всегда можете использовать кодовое пространство github ( который создает VScode-подобный интерфейс с чистой загрузочной сборкой) и устанавливает вышеуказанные предварительные условия через командную строку.

Шаг 3. Получите ключ API

Теперь вам нужно сгенерировать ключ API для использования CLI. Посетите страницу ключей API и нажмите Создать новый ключ API.

Шаг 4. Настройте конфигурацию фаззинга

Теперь нам нужен смарт-контракт для фаззинга! В рамках собственного руководства ConsenSys предоставляет образец смарт-контракта для использования. Давайте воспользуемся этим.

git clone https://github.com/ConsenSys/scribble-exercise-1.git

Откройте файл .fuzz.yml из проекта и добавьте свой ключ API для свойства «key» примерно в строке 25.

# .fuzz_token.yml

fuzz:
    # Tell the CLI where to find the compiled contracts and compilation artifacts
    build_directory: build/contracts

    # The following address is going to be the main target for the fuzzing campaign
    deployed_contract_address: "0xe78A0F7E598Cc8b0Bb87894B0F60dD2a88d6a8Ab"

    # We'll do fuzzing with 2 cores 🚀
    number_of_cores: 2

    # Run the campaign for just 3 minutes.
    time_limit: 3m 

    # Put the campaign in the Sribble Exercise 1 project
    project: "Scribble Exercise 1"

    # When the campaign is created it'll get a name <prefix>_<random_characters>
    campaign_name_prefix: "ERC20 campaign"

    # Point to your ganache node which holds the seed 🌱
    rpc_url: "http://localhost:8545"

    key: "INSERT YOUR API KEY HERE"

    # This is the contract that the campaign will show coverage for/ map issues to etc
    # It's a list of all the relevant contracts (don't worry about dependencies, we'll get those automatically 🙌)
    targets:
        - "contracts/vulnerableERC20.sol"

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

Шаг 5. Определите свойства фаззинга

Обратите внимание, что у нас есть смарт-контракт: contracts/vulnerableERC20.sol.

Далее нам нужно определить свойства, которые мы хотим, чтобы фаззер проверял в смарт-контракте. Для этого шага мы будем использовать Scribble. Scribble — это язык спецификаций, который переводит высокоуровневые спецификации в код Solidity. Это позволяет вам аннотировать ваши контракты свойствами, а затем преобразовывать эти аннотации в конкретные утверждения, которые могут использоваться инструментами тестирования (такими как Diligence Fuzzing). Довольно круто!

Мы добавим выделенные сегменты кода в наш контракт:

pragma solidity ^0.6.0;

/// #invariant "balances are in sync"
unchecked_sum(_balances) == _totalSupply;
contract VulnerableToken {

Эта аннотация обеспечит синхронизацию нашего общего запаса и баланса.

Шаг 6. Запустите

Теперь мы фаззим! Просто запустите эту команду:

make fuzz

Шаг 7. Оцените результаты

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

Глядя на свойства, мы можем увидеть, что подвергается фаззингу, и любые нарушения. И угадай что? Мы нашли ошибку! Нажмите на кнопку расположения строки, чтобы увидеть оскорбительный код.

Чтобы получить дополнительные сведения, нажмите Показать сведения о транзакции. Мы видим фаззер под названием «перевод»:

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

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

function transfer(address _to, uint256 _value) external returns (bool) {


 address from = msg.sender;


   require(_value <= _balances[from]);


   uint256 newBalanceFrom = _balances[from] - _value;
   uint256 newBalanceTo = _balances[_to] + _value;


   _balances[from] = newBalanceFrom;
   _balances[_to] = newBalanceTo;


   emit Transfer(msg.sender, _to, _value);


   return true;


 }

Ага! Мы видим, что когда отправитель и получатель совпадают, строки 30 и 31 становятся немного странными — одна изменяет значение учетной записи «от», а другая — значение учетной записи «кому». Код предполагает, что это разные учетные записи. Но поскольку это одна и та же учетная запись, к тому времени, когда мы дойдем до строки 31, значение, которое мы имеем, не соответствует ожидаемому значению. Предыдущая строка уже изменила его.

Мы можем исправить это, добавив выделенные строки кода ниже:

function transfer(address _to, uint256 _value) external returns (bool) {
 address from = msg.sender;
   require(_value <= _balances[from]);


   _balances[from] -= _value;
   _balances[_to] += _value;


   uint256 newBalanceFrom = _balances[from] - _value;
   uint256 newBalanceTo = _balances[_to] + _value;


   _balances[from] = newBalanceFrom;
   _balances[_to] = newBalanceTo;


   emit Transfer(msg.sender, _to, _value);


   return true;
 }

Вот еще несколько технических деталей, о которых следует знать:

* Сценарий seed.js выполняет некоторую настройку за вас. Он развертывает контракт на тестовом узле. Он также может делать такие вещи, как чеканка токенов, открытые пулы и т. д. Это дает фаззеру правильное состояние для запуска. * В файле yml есть много параметров конфигурации, которые вы можете изучить. В частности, адрес контракта для фаззинга, ключ API, time_limit для фаззинга и некоторые другие. * CLI поставляется с генератором автоконфигурации. Запустите fuzz generate-config, чтобы получить полезные вопросы и ответы по созданию конфигурации.

Аудит смарт-контрактов — Используйте фаззинг!

Фаззинг и Diligence Fuzzing-as-a-service — это мощный инструмент для тестирования аудита смарт-контрактов блокчейна Ethereum. Независимо от того, работаете ли вы в области децентрализованных финансов (DeFi), NFT или только начинаете разработку смарт-контрактов, это может вывести вас на новый уровень выявления и устранения уязвимостей в ваших смарт-контрактах. Наряду с ручными проверками, модульными тестами, ручным тестированием, тестированием на проникновение, проверкой кода и т. д. фаззинг должен быть ключевой частью процесса аудита безопасности вашего смарт-контракта, чтобы сделать кодовую базу более безопасной и надежной.

Хорошего дня!


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE