ERC中的重入

所有重入的本质都是不可控的外部调用

注意:0.8.0 版本以后或使用了 SafeMath 的合约,重入时不能选择状态变量更改为 -= 的模式,否则会因为下溢而 revert

1
2
3
4
5
function withdraw(uint256 amount) public {
require(balanceOf[msg.sender] >= amount);
require(token.transfer(msg.sender, amount));
balanceOf[msg.sender] -= amount;
}

比如以上模式就不能重入,只能提取自己真正拥有的代币

ERC20

原理

ERC20 中的重入也就是最基础的重入,发生在 ETH 和 ERC20 代币的交换过程中,使用 call 低级调用,并未遵守检查-生效-交互模式,攻击者可以通过重写 fallback 或者 receive 函数来进行重入

详情见以前的博客

复现

reentrancy-exp/contracts/erc20

运行命令

1
npx hardhat test test/erc20_test

ERC223

原理

ERC223 相对于 ERC20,增加了 tokenReceived 函数,本意是防止意外发送的代币被合约接受(并卡在合约的余额中),但是增加了重入风险

黑客可以利用该函数调用原合约中的问题函数(如未遵守检查-生效-交互模式的函数),多次重入

复现

reentrancy-exp/contracts/erc223

运行命令

1
npx hardhat test test/erc223_test

相关事件

CTF-Tokenbank

[capture the ether - Token-bank](https://sissice.github.io/2022/04/02/capture the ether wp/#Token-bank)

ERC777中的重入

原理

ERC777 标准解析

ERC777 引入了“钩子”的概念,以解决 ERC20 的一些缺陷。使用挂钩让合约知道它正在接收或发送资金并允许它采取行动。

增加了两个需要用户自己实现的函数:tokensToSend 和 tokensReceived

image-20221122111656516

使用挂钩,接收联系人可以在收到令牌时执行操作,例如,如果向其发送了错误类型的令牌,则取消交易。所以 Tokenlon 似乎做出了正确的选择:所有 ERC20 的优点加上一些额外的很酷的功能。然而,正如他们沮丧地发现的那样,ERC777 钩子也为一些严重的攻击打开了大门!

如上所示,ERC777 挂钩允许合约在接收或发送资金时执行附加功能。然而,这个功能可能被滥用,允许恶意合约对毫无戒心的调用合约的问题函数,执行重入攻击。

image-20221122111744129

可以重入的场景:

  1. 在余额更新之前在转账功能中向收件人(或攻击者控制的任何其他帐户)进行外部调用。
  2. 在更新余额之前或之后在transferFrom函数中对令牌花费者(或攻击者控制的任何其他帐户)进行外部调用。重要的是要注意所有的transferFrom函数总是以交易所作为接收者来调用,因此在不同的 ERC20 扩展中常见的对接收者的回调并不危险。

复现

reentrancy-exp/contracts/erc777

运行命令

1
npx hardhat test test/erc777_test

相关事件

利用 Uniswap:从重入到实际盈利

imBTC

2020 年 4 月 18 日 imBTC Uniswap 池被黑客攻击并耗尽了价值 30 万的代币

image-20221125183759655

问题主要是在uniswap中ERC777会发生重入

攻击交易:0x32c83905db61047834f29385ff8ce8cb6f3d24f97e24e6101d8301619efee96e

image-20221125190825762

Cream Finance

2021 年 8 月 30 日, Cream Finance 遭遇闪电贷攻击,攻击者利用漏洞共计获利5890ETH(约合1880万美元)。

image-20221125192416343

由于 AMP 支持类似 ERC-777 的代币标准,而它的特性与某些协议不相兼容,此次 Cream.Finance 的重入攻击正是操纵了此漏洞。

这里在更新存储之前进行了转移贷款的操作

image-20221125200526963

官方解释

攻击交易:0xc90468d698700757f33543039c7cb10d4ca49d57b5417789e7656e73019de674

image-20221125193047131


ERC中的重入
http://sissice.github.io/2022/11/27/reentrancy-2/
作者
Sissice
发布于
2022年11月27日
许可协议