BJDCTF2nd-区块链题目解析(题目2未完)
-
坚固性?!
这道题目给了我们solidity编写的智能合约源代码和合约地址,那么我们先来看代码
首先,题目有一个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
那么我们可用的函数只有一个Transferfunction 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来试验一下,我们将给我们的代码复制进去并部署到题目给的地址上
我们先来一下getBalance,然后用Transfer函数
在addr里你需要输入两个账户地址,
[“0x14723a09acff6d2a60dcdf7aa4aff308fddc160c”,“0x4b0897b0513fdc7c541b6d9d7e929c4e5364d2db”]一个是你的账户,另外一个可以随便找,然后在_value里输入57896044618658097711785492504343953926634992332820282019728792003956564819968(2^255)
转账后,你的余额就变成了
就可以得到flag了
第二道题未完待续...