Решение задачи Ethernaut Challenge #2 — Fallout

Это вторая часть серии «Играем в OpenZeppelin Ethernaut CTF», в которой я объясню, как решить каждую задачу.

Ethernaut — это варгейм на основе Web3/Solidity, созданный OpenZeppelin.
Каждый уровень представляет собой смарт-контракт, который необходимо «взломать». Игра выступает в качестве инструмента для тех, кто заинтересован в изучении ethereum, и как способ каталогизации исторических взломов уровней. Уровни могут быть бесконечными, и игра не требует соблюдения определенного порядка.

Задача №2: Fallout

Чтобы завершить этот уровень, заявите о владении контрактом, приведенным ниже.

Вещи, которые могут помочь

  • Solidity Remix IDE

Автор(ы) уровня: Алехандро Сантандер

Изучите контракты

Первое, что мы заметили, это используемая версия компилятора Solidity < 0.8.x. Это означает, что контракт будет подвержен ошибкам переполнения и недополнения математики.

Этот контракт импортирует и использует библиотеку OpenZeppelin SafeMath, поэтому проблемы переполнения/недополнения должны быть безопасны.

Проблема довольно уникальна, и если вы новичок в теме безопасности Solidity, вам, вероятно, будет трудно понять, как решить эту проблему, но только по одной причине: эта проблема существовала только до Solidity 0.4.22.

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

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

Если вы посмотрите на код, имя контракта Fallout, но функция конструктора называется Fal1out. Вы видите опечатку? Они использовали 1 вместо l.
Из-за этой опечатки, когда контракт развернут, функция конструктора никогда не выполняется во время создания, и переменная owner никогда не обновляется. Это происходит потому, что Fal1out теперь воспринимается как «обычная» функция.

Код решения

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

function exploitLevel() internal override {
    vm.startPrank(player);

    // Before Solidity 0.4.22 the only way to define a constructor for a contract was to define a function with the same name of the contract itself
    // After that version they introduced a new `constructor` keyword to avoid this kind of mistake
    // In this case the developer made the mistake to misstype the name of the constructor
    // Contract name -> Fallout
    // Constructor name -> Fal1out
    // The result of this is that the contract was never initialized, the owner was the address(0)
    // and we were able to call the `Fal1out` function that at this point is not a constructor (callable only once)
    // but a "normal" function. This also mean that anyone can call multiple time this function switching the owner of the contract.
    level.Fal1out();

    vm.stopPrank();
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Вы можете прочитать полное решение задачи, открыв Fallout.t.sol

Дальнейшее чтение

  • SWC-118 — Неправильное имя конструктора

Отказ от ответственности

Весь код Solidity, практики и паттерны в этом репозитории являются ЧЕРТОВСКИ ВУЛЬГЕРНЫМИ и предназначены только для образовательных целей.

Я не даю никаких гарантий и не несу ответственности за любые потери, понесенные в результате использования этой кодовой базы.

НЕ ИСПОЛЬЗУЙТЕ В ПРОИЗВОДСТВЕ.

Оцените статью
devanswers.ru
Добавить комментарий