BJDCTF2nd-区块链题目解析(题目2未完)



  • 坚固性?!

    这道题目给了我们solidity编写的智能合约源代码和合约地址,那么我们先来看代码
    92362e7a-3d06-423a-be96-5f72b5aeea6e-image.png
    首先,题目有一个

    function getBalance() public returns (bool){
            balances[msg.sender] = 100;
            return true;
    }
    

    来给用户100的初始余额

    function getFlag() public view returns (string){
            require(balances[msg.sender] > 9999999);
            return flag;
        }
    

    getFlag函数是用来获取flag的,我们可以看到条件是余额大于9999999
    那么我们可用的函数只有一个Transfer

    function Transfer(address[] _addr, uint256 _value) public returns (bool){
            uint times = _addr.length;
            uint256 amount = uint256(times) * _value;
            require(_value > 0 && balances[msg.sender] >= amount);
            require(times > 0 && times < 10);
            balances[msg.sender] -= amount;
            for(uint i = 0; i < times; i++){
                balances[_addr[i]] += _value;
            }
            return true;
        }
    

    这里就要用到整数溢出漏洞了
    首先,根据函数,我们可以控制的量有times和_value
    然后这两个量相乘会得到一个amount,amount变量的类型是uint256,上限是2^255
    那么我们让times=2,_value=2^255,2*(2^255)就会超出变量的上限,从而amount会变成一个极小值
    我们就绕过了下面的判断
    好,使用remix来试验一下,我们将给我们的代码复制进去并部署到题目给的地址上
    913bcefe-5e20-46ba-bace-e1f90f6fa26b-image.png
    我们先来一下getBalance,然后用Transfer函数
    在addr里你需要输入两个账户地址,
    [“0x14723a09acff6d2a60dcdf7aa4aff308fddc160c”,“0x4b0897b0513fdc7c541b6d9d7e929c4e5364d2db”]一个是你的账户,另外一个可以随便找,然后在_value里输入57896044618658097711785492504343953926634992332820282019728792003956564819968(2^255)
    转账后,你的余额就变成了
    cbc1527a-0dca-48b6-aaf1-1661b12a85ab-image.png
    就可以得到flag了
    第二道题未完待续...


Log in to reply