漏洞描述

burnFrom函数的作用是供被授权用户操作授权用户的资产,而在操作授权用户授权的资产时需要同步更新授权用户的资产数量,即销毁授权用户特定数量的资产,同时需要更新代币总量以及授权转账的额度,同时burnFrom函数应该具备溢出检查逻辑设计或者使用SafeMath函数进行溢出防御,而不少合约中缺乏allowance更新操作,甚至存在下溢问题、特权后门等。

漏洞示例

下图所示burnfrom函数在销毁代币时只做了授权数量的检查,而在授权转账之后未更新授权转账的额度导致被授权用户可以无限制的销毁授权账户的资产

漏洞复现

Step 1:下载合约源代码到本地并使用Remix进行部署调试
https://cn.etherscan.com/address/0x49aec0752e68d0282db544c677f6ba407ba17ed7#code

部署合约:

Step 2:查询当前合约owner所持资产数量

  • Owner地址:0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2
  • 所持资产:3333333000000000000000000
  • 数值精度:18

Step 3:使用合约的owner地址向用户A和用户B分别转账,为后期测试做准备

  • 用户A地址:0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db
  • 转账数量:1000000000000000000000

  • 用户B地址:0x78731D3Ca6b7E34aC0F824c42a7cC18A495cabaB
  • 转账数量:1000000000000000000000

Step 4:使用A账户地址给B账户授权转账数量200000000000000000000

Step 5:由于合约中的burnFrom函数存在设计缺陷,在销毁授权用户特定数量的资产时,未更新授权转账的额度,导致被授权账户可以无限制销毁授权账户的资产,下面我们使用B账户来销毁A账户的资产,销毁数量为之前A账户授权给B账户的额度——200000000000000000000
当下A账户(0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db)资产数量如下:

通过进行销毁操作:

检查授权额度:

之后检查A账户资产:1000000000000000000000——>800000000000000000000

由于授权额度未更新,所以此时B用户依旧可以销毁A用户的资产数量,下面我们再一次进行销毁:

再次查看授权额度——依旧未变:

查看A账户的资产数量:800000000000000000000——600000000000000000000

依次类推,可知授权用户B可以销毁被授权用户A所有的资产

安全建议:

采用OpenZeppelin官方标准
https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/extensions/ERC20Burnable.sol

点击收藏 | 0 关注 | 1
  • 动动手指,沙发就是你的了!
登录 后跟帖