攻击描述
- 被黑目标:EDU Token / BAI Token
- 事件描述:智能合约存在严重漏洞,可将任意账户中的 Token 转出。
- 攻击损失:新发代币对智能合约进行升级,对异常账户出现前的资产地址进行快照,智能合约升级后根据快照按比例空投至原有代币地址。原代币将作废。
- 攻击方式:业务逻辑漏洞
合约描述
EDU
- 合约地址: 0xa0872eE815B8dd0F6937386Fd77134720d953581
- 合约代码: https://etherscan.io/token/0xa0872eE815B8dd0F6937386Fd77134720d953581#code
BAI
- 合约地址: 0x14d9779b6585f3a7d4f768383b3cb030705dad2e
- 合约代码: https://etherscan.io/token/0x14d9779b6585f3a7d4f768383b3cb030705dad2e#code
攻击过程技术分析
transferFrom 没有校验 allowed[_from][msg.sender] >= _value
,并且函数内 allowed[_from][msg.sender] -= _value;
没有使用 SafeMath,导致无法抛出异常来回滚交易。
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
/// same as above
require(_to != 0x0);
require(balances[_from] >= _value);
require(balances[_to] + _value > balances[_to]);
uint previousBalances = balances[_from] + balances[_to];
balances[_from] -= _value;
balances[_to] += _value;
allowed[_from][msg.sender] -= _value;
Transfer(_from, _to, _value);
assert(balances[_from] + balances[_to] == previousBalances);
return true;
}
漏洞发现时已存在大量洗劫行为,攻击者不需私钥即可转走账户中的代币。而由于合约没有 Pause 设计,导致无法止损。
解决办法
- 权限判断,使用 SafeMath 库。
require(allowed[_from][msg.sender] >= _value)
- 合约尽量增加 Pause 设计。可以由管理员进行限制。