• XSS.stack #1 – первый литературный журнал от юзеров форума

Взлом Solidity: целочисленное переполнение и недополнение

вавилонец

CPU register
Пользователь
Регистрация
17.06.2021
Сообщения
1 116
Реакции
1 265

Взлом Solidity: целочисленное переполнение и недополнение


1653537324622.png



Немного базовых знаний

Целое число — это целое число, поэтому оно не имеет дробных частей. Целые числа могут быть как положительными, так и отрицательными. Существует множество различных диапазонов целых чисел, которые могут использоваться в языках программирования, но Solidity использует диапазон 256-битных целых чисел без знака. Это означает, что числа начинаются с 0 и идут до 115792089237316195423570985008687907853269984665640564039457584007913129639935 (в десятичной системе).
Solidity выдаст ошибку, если вы попытаетесь присвоить значение, не являющееся целым числом, переменной, объявленной как единица. Вы можете проверить, что происходит, попробовав установить логическую (true/false) переменную, равную целому числу.
Когда вы используете целые числа с математическими операциями, вам нужно знать, что происходит, когда значения становятся слишком большими или маленькими для своего диапазона. Переполнение происходит, когда превышено максимальное значение, а недополнение происходит, когда превышено минимальное значение.

Solidity — это контрактно-ориентированный язык высокого уровня для реализации смарт-контрактов. На него повлияли C++, Python и JavaScript, и он предназначен для виртуальной машины Ethereum (EVM). Solidity имеет статическую типизацию, поддерживает наследование, библиотеки и сложные определяемые пользователем типы среди других функций.

Целочисленное переполнение и недополнение​

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

В Solidity целые числа подписываются, если они не отмечены буквой «U» в верхнем регистре в конце. Целое число без знака имеет тип uint; целое число со знаком имеет тип int.

Диапазон значений 256-битного числа со знаком (int256) — от -(2²⁵⁵) до 2²⁵⁵ — 1. Диапазон значений 256-битного числа без знака (uint256) — от 0 до 2²⁵⁶ — 1.


1653537419234.png




Пример кода контракта​


Код:
    function deposit() public payable{

    _balance[msg.sender] = _balance[msg.sender].add(msg.value); //Add method of SafeMath library is used to add two numbers and throws an error if the calculation overflows/underflows a type

    }

    function withdraw(uint256 amount) public {

    require(_balance[msg.sender] >= amount, “Insufficient balance”); //checking for sufficient balance before withdrawing funds

    _balance[msg.sender] = _balance[msg.sender].sub(amount); //Subtract method of SafeMath library is used to subtract two numbers and throws an error if the calculation overflows/underflows a type

    msg.sender.transfer(amount); //send funds back to the caller address

    }

    function withdrawAll() public {

    uint256 amount = _balance[msg.sender]; //store balance in amount variable so that we can use it after resetting the mapping value to 0 as part of withdrawAll process

    _balance[msg.sender] = 0; //reset the mapping value after storing current balance in temporary variable (amount)

    msg.sender.transfer(amount); // send entire balance back to the caller address by using transfer method on msg object which represents sender address (caller’s address)

    }


Векторы атаки​

Есть несколько способов, которыми вы можете использовать целочисленное недополнение/переполнение для получения желаемых математических результатов.
  • Вызовите функцию с большим количеством. Если вы дадите функции входное значение uint256(2)²⁵⁶ — 1, она вернет 0. Это простой способ «обнулить» баланс!
  • Вызовите функцию с отрицательной суммой несколько раз. Если вы вызовете функцию три раза с (uint256(-1)), она добавит 2⁸ — 3, в результате чего получится 2⁸ — 1, и если бы мы вызвали это снова, это привело бы к 0! Вы можете повторить это, чтобы создать любое число меньше 2⁸, используя всего 8 вызовов! Та же идея работает и для 256-битных чисел, если в вашем контракте достаточно газа.
  • Вызовите функцию с отрицательной суммой 101 раз или более. Вызов transfer(uint(-1)) 101 раз установит ваш баланс на MAX_UINT вместо MIN_UINT, поскольку добавление 101 * (-1) эквивалентно вычитанию 101 из вашего баланса, который переполняется при 255 и становится MAX_UINT.

Будьте осторожны при использовании целых чисел в коде смарт-контракта!​

Язык программирования Solidity был разработан для помощи в написании смарт-контрактов Ethereum. Сегодня это самый популярный выбор для написания смарт-контрактов.

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

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

Переведена вот статья

I like it!​
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Важное примечание:
В solidity начиная с 0.8.0 данная бага поправлена. транза фейлится если происходит overflow или underflow, но данное поведение можно отключить используя инструкцию unchecked
 
Важное примечание:
В solidity начиная с 0.8.0 данная бага поправлена. транза фейлится если происходит overflow или underflow, но данное поведение можно отключить используя инструкцию unchecked
только начал вникать в тему, думал как с web2 можно и скрипткиднуть и пойдет, а тут походу еще самое время влиться с головой, начал читать/смотреть ютуб. спасибо за исправления
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх