以太坊再爆高危漏洞!黑客增发ATN 1100万枚token事件始末

编者按:5月11日,ATN Token遭受恶意攻击,攻击者利用DSAuth库与ERC223搭配使用具有的混合漏洞,窃取了ATN的所有权。之后,攻击者进行了窃取代币操作。 这是一起严重的黑客攻击事件,可以导致Token的供应总量发生变化。 归根结底,黑客这次又是冲着智能合约的编写漏洞来的。我们今天就来给大家从技术上揭底这次事件,并透过这次事件,奉上实用的合约编写建议。在此鸣谢成都链安科技CEO杨霞提供的独家资料。

事情发生在5月中旬,ATN技术人员发现Token合约由于存在漏洞受到攻击。不过ATN基金会随后透露,将销毁1100万个ATN,并恢复ATN总量,同时将在主链上线映射时对黑客地址内的资产予以剔除,确保原固定总量不变。

以下是事件还原。

事件回顾

2018年5月11日中午,ATN技术人员收到异常监控报告,显示ATN Token供应量出现异常,迅速介入后发现Token合约由于存在漏洞受到攻击。以下是黑客的攻击操作以及利用合约漏洞的全过程。

攻击

这次攻击主要分为4步。首先,黑客利用ERC223方法漏洞,获得提权,将自己的地址设为owner:

第二,黑客在获得owner权限后,发行1100w ATN到自己的攻击主地址:

第三,黑客将owner设置恢复,企图隐藏踪迹:

最后,黑客从主地址将偷来的黑币分散到14个地址中:

利用合约漏洞

ATN Token合约采用的是在传统ERC20Token合约基础上的扩展版本ERC223 ,并在其中使用了dapphub/ds-auth库。采用这样的设计是为了实现以下几个能力:

  1. 天然支持Token互换协议,即ERC20Token与ERC20Token之间的直接互换。本质上是发送ATN时,通过回调函数执行额外指令,比如发回其他Token。
  2. 可扩展的、结构化的权限控制能力。
  3. Token合约可升级,在出现意外状况时可进行治理。

单独使用ERC223或者ds-auth库时,

并没有什么问题,但是两者结合时,

黑客利用了回调函数回调了setOwner方法,

从而获得高级权限。

ERC223转账代 码如下:

当黑客转账时在方法中输入以下参数:

  • from: 0x2eca25e9e19b31633db106341a1ba78accba7d0f——黑客地址;
  • to: 0x461733c17b0755ca5649b6db08b3e213fcf22546——ATN合约地址;
  • amount: 0
  • data: 0x0
  • custom_fallback: setOwner(address)

该交易执行的时候,

receiver会被_to(ATN合约地址)赋值,

ATN 合约会调用_custom_fallback

DSAuth中的setOwner(adddress)方法,

而此时的msg.sender变为ATN合约地址,

owner_参数为_from(黑客地址)

ds-auth库中setOwner代码如下:

此时setOwner会先验证auth合法性的,而msg.sender就是ATN的合约地址。

setOwnermodifier auth代码如下:

通过利用这个ERC223方法与DS-AUTH库的混合漏洞,黑客将ATN Token合约的owner变更为自己控制的地址。获取owner权限后,黑客发起另外一笔交易对ATN合约进行攻击,调用mint方法给另外一个地址发行1100w ATN。

最后,黑客调用setOwner方法将权限复原 。

PS. 截至发稿前,ATN官方已声称:黑客将黑币分散在14个不同的新地址中,而这些地址中并没有ETH,暂时不存在立即转账到交易所销赃的风险。

漏洞是怎么造成的?

这次事件主要是利用了开发者对以太坊底层函数call、callcode、delegatecall的不当使用造成的。

call、callcode、delegatecall是以太坊智能合约编写语言Solidity提供的底层函数,用来与外部合约或者库进行交互。不当的使用会造成很严重的后果。

例如,以下情况:

上述例子中,call函数的调用地址(如上图中的_spender参数)是可以由用户控制的,攻击者可以将其设置为合约自身的地址,同时call函数调用的参数(如上图中的_extraData参数)也是可以由用户任意输入的,攻击者可以调用任意函数。

攻击者利用上述操作,伪造成合约账户进行恶意操作,可能造成如下影响:

  1. 绕过权限检查,调用敏感函数,例如setOwer;
  2. 窃取合约地址持有的代币;
  3. 伪装成合约地址与其他合约进行交互;

因此,在编写合约时,此类函数使用时需要对调用参数的安全性进行判定,建议谨慎使用。

怎样避免此类漏洞

为了避免此类漏洞,我们提醒开发者应注意以下几点。

  1. 谨慎使用call、delegatecall等底层函数。此类函数使用时需要对调用参数进行限定,应对用户输入的call调用发起地址、调用参数做出严格限定。比如,call调用的地址不能是合约自身的账户地址,call调用的参数由合约预先限定方法选择器字符串,避免直接注入bytes可能导致的恶意call调用。
  2. 对于一些敏感函数,不要将合约自身的账户地址作为可信地址
  3. 准备修复措施,增加Guard合约禁止回调函数向ATN合约本身回调
  4. 增加黑名单合约,随时冻结黑客地址。

合约无小事

综合上文的分析,我们认为,call函数的使用一定要小心,在智能合约开发中尽量避免call函数的使用,如果使用需要对其相关参数进行严格的限定。另一方面,智能合约在部署之前应进行安全审计,比如代码的形式化验证等。

合约的安全审计,仅依靠开发者的经验和能力总有隐患,过去业内的几次合约漏洞事件也说明了这个问题,开发者务必要引起重视。

关于作者:

杨霞,成都链安科技CEO,创始人。电子科技大学副教授,最早研究区块链形式化验证的专家。一直为航空航天、军事领域提供形式化验证服务。主持国家核高基、装发重大软件课题等近10项国家课题。CC国际安全标准成员、CCF区块链专委会委员。发表学术论文30多篇,申请20多项专利。

原文发布于微信公众号 - 区块链大本营(blockchain_camp)

原文发表时间:2018-06-25

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏专注研发

区块链关键字的解析

目前大多数区块链先驱都喜欢将区块链分为三层:应用服务层、服务平台层、底层区块链核心层

23520
来自专栏区块链入门

第二十一课 如何通过Solidity的智能合约函数把长文章记录到以太坊区块链上?

辉哥的文章《第十六课 不用编程,如何把长文章记录到以太坊区块链上?》 是通过MetaMask的交易形式把数据写到链上。 本文提供另外一个方式,通过智能合约函数...

10620
来自专栏区块链大本营

“危机四伏”的以太转账操作|以太转账安全风险——漏洞分析连载之八期

Solidity语言的默认存储规则和引用未初始化变量带来的特殊性共同导致了未初始化变量将原有状态变量覆盖,占用了状态变量在Storage中的位置,重演了最近“高...

10720
来自专栏mathor

第六届蓝桥杯决赛B组C/C++——关联账户

8230
来自专栏申龙斌的程序人生

区块链上存证,只需这四步

区块链里的信息具有不可篡改性,比如中本聪在创世区块中写的一段话:“The Times 03/Jan/2009 Chancellor on brink of se...

81210
来自专栏友弟技术工作室

以太坊ERC20协议以及发行自己代币

ERC-20 标准是在2015年11月份推出的,使用这种规则的代币,表现出一种通用的和可预测的方式。

13910
来自专栏区块链入门

【 链安科技】constructor函数使用漏洞

2018年7月12日,成都链安科技(LianAn Technology)智能合约审计小组使用自主研发的VaaS平台对以太坊链上智能合约进行安全审计的过程中,发现...

11130
来自专栏区块链中本聪

区块链技术分布式数据库解决隐私

​ 主链侧链开发数字货币交易所白皮书区块链浏览器跨境支付场内场外宠物挖矿游戏基金会牌照 181-4069-6008 微信电话同号

15830
来自专栏Seebug漏洞平台

以太坊智能合约 Owner 相关 CVE 漏洞分析

最近学习了下以太坊的智能合约,而且也看到挺多厂家pr智能合约相关的漏洞,其中《ERC20智能合约整数溢出系列漏洞披露》文章中披露了6个CVE编号的漏洞,而这些漏...

18930
来自专栏区块链入门

【链安】智能合约DoS攻击原理分析及相应漏洞修复

DoS 是DenialOfService,拒绝服务的缩写[3],从字面上来理解,就是用户所需要的服务请求无法被系统处理。 打个比方来形容DoS,火车站是为大家...

14740

扫码关注云+社区

领取腾讯云代金券