ERC223及ERC827实现代码欠缺安全考虑 —— ATN Token中的CUSTOM_CALL漏洞深入分析

本文部分内容基于安比(SECBIT)实验室团队与吴玉会(轻信科技)的讨论

本文结论: ERC223, ERC827的部分实现代码引入了任意函数调用缺陷,可能会对使用这部分代码的合约带来安全漏洞。如果需要实现上述规范接口,请仔细检查实现代码。这种合约本身允许用户自定义call() 任意地址上任意函数的设计,十分危险。攻击者可以很容易地借用当前合约的身份来进行任何操作,比如盗取Token或者绕开权限检查等。

影响范围:截止目前检测到以太坊上部署的受影响的ERC20合约数量:146

最新更新:

  • 火币网已经暂停了已经上线交易的相关问题Token[9][10]
  • ATN团队已经修复漏洞[1]

CUSTOM_CALL 滥用事件回顾与分析

2018 年 6 月 20 日,AI Technology Network (ATN) 和慢雾团队披露了一起针对 ATN 智能合约的攻击事件,黑客于 2018 年 5 月 11 日利用 ATN Token 合约存在的漏洞,将自己地址设为 owner 并增发获利 1100 万 ATN。ATN 技术团队迅速发现问题、定位攻击方法并完成合约的升级修复 [1]。黑客利用了 ERC223 合约可传入自定义的接收调用函数与 ds-auth 权限校验等特征,在 ERC223 合约调用这个自定义函数时,合约调用自身函数从而造成内部权限控制失效。随后,百度安全的“隐形人真忙”也在先知安全大会上进行了“以太坊智能合约 call 注入攻击”的主题分享 [2]。这个漏洞源于一个较为常见的做法:在调用合约函数之后,可以再次调用一次另一个合约的任意函数,并且这个任意函数可以由合约调用发起者指定。但是 ATN 的合约漏洞恰恰暴露了这一常见做法非常危险的一面:合约调用者可能通过该功能绕开权限检查,或者以合约的身份发起对其它合约的攻击等等。

有安全隐患代码链接:
https://github.com/Dexaran/ERC223-token-standard/blob/16d350ec85d5b14b9dc857468c8e0eb4a10572d3/ERC223_Token.sol#L70
https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC827/ERC827Token.sol

ATN 事件漏洞分析

ERC223 是由 Dexaran 于 2017 年 3 月 5 日提出的一个 Token 标准草案 [3],用于改进 ERC20,解决其无法处理发往合约自身 Token 的这一问题。ERC20 有两套代币转账机制,一套为直接调用transfer()函数,另一套为调用 approve() + transferFrom()先授权再转账。当转账对象为智能合约时,这种情况必须使用第二套方法,否则转往合约地址的 Token 将永远无法再次转出。

下面代码为 ERC223 草案中的一段* 正确示例*,调用 transfer()函数时,合约判断目标地址 to 是否是合约,如果是合约,则调用目标合约的tokenFallback()方法,从而实现合约对转入 Token 的处理。这段代码并没有 CUSTOM_CALL 滥用的问题。

// 提案中的正确示例代码
contract ERC223 {
  function transfer(address to, uint value, bytes data) {
        uint codeLength;
        assembly {
            codeLength := extcodesize(_to)
        }
        balances[msg.sender] = balances[msg.sender].sub(_value);
        balances[_to] = balances[_to].add(_value);
        if(codeLength>0) {
            // Require proper transaction handling.
            ERC223Receiver receiver = ERC223Receiver(_to);
            receiver.tokenFallback(msg.sender, _value, _data);
        }
    }
}

ERC223 合约是 ERC20 合约的超集,目标为取代 ERC20 合约,成为新的 Token 合约标准。但提出以来至今一年多的时间仍未得到广泛接受,仅有少数项目采用了该提案。

下面是 ERC223 错误实现代码,ATN Token不幸地采用了这一段代码。用户被允许传入任意自定义的_custom_fallback,从而任意调用目标_to地址上的任意方法!

// 此代码有 CUSTOM_CALL 滥用问题
function transferFrom(
    address _from, 
    address _to, 
    uint256 _amount, 
    bytes _data, 
    string _custom_fallback
    ) 
    public returns (bool success)
{
    ...
    ERC223ReceivingContract receiver = ERC223ReceivingContract(_to);
    receiving.call.value(0)(byte4(keccak256(_custom_fallback)), _from
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值