【剖析】81个智能合约惊现同一漏洞,是巧合?还是另有玄机?

SECBIT实验室
SECBIT实验室 机构得得号

Jun 03, 2018 聚焦智能合约安全审计和形式化验证。

摘要: 本文分析了以太坊上出现的具有相同问题的81个智能合约及EOS映射过程中出现的213个公私钥对相同问题,解释了代码复制使用的风险,提出了智能合约审计的必要性。

前言

这是一个怎样的社交时代?

一个你不知道区块链、不知道智能合约就可能产生聊天障碍的时代;

这是一个怎样的商业时代?

一个公司没有利用区块链、没有使用智能合约就可能没办法实现业内突围的时代;

这是一个怎样的技术获取时代?

一个你有实力就自行开发,没实力也可以网络搜索的时代。

这个时代虽然几乎人人都在探讨区块链、几乎每个组织都试图引入智能合约,但并不是每个人都了解区块链,也不是每个组织都具备智能合约开发实力,那么如何获取该波技术红利?计算机技术特别是区块链及智能合约代码的开源使用为广大技术开发实力欠缺的个人和组织提供了接触并使用该技术的无限可能。

但是!同时这也为一些居心叵测之人提供了扰乱产业发展秩序、危害他人财产安全的可乘之机。特别是区块链这种生来自带金融属性的技术,一不小心使用了错误代码就会导致难以弥补的经济损失,近期屡次发生的智能合约漏洞导致的token市值蒸发就是典型的代表。

案例分析

今天SECBIT(安比)实验室和大家分享两个疑似复制使用公开代码导致出现高危风险问题的案例:一个是Ethereum上出现81个合约带有相同错误,另一个为EOS主网上线过程中钱包映射出现213个EOS 钱包地址使用了相同公私钥对的问题。

案例一

近期SECBIT(安比)实验室发现Ethereum上有81个智能合约出现了相同的问题,问题都是出现在ERC20 token合约中的transferFrom 函数上,该函数主要用于在限定token数量范围内两个地址之间的转账,该函数的基本功能和含义为:

  • 从转出地址 _from向转入地址 _to转一定数量_value的token
  • 转账的token数量上限由另一个approve函数设定,并可访问 allowed[_from][msg.sender]来获得 。
  • 只有转账数量_value值小于转出地址余额,并且小于限定的上限数量时,才能转账成功。
  • 在此过程中应该做overflow的检查

但是以太坊主网上的问题token合约代码如下:

乍一看,这段代码“谨慎”地进行了余额、授权限额以及整数溢出三种校验。仔细看红框中的问题代码。

  • 第一行表述为当转账数量_value值大于或等于转出账户余额fromBalance时将余额充足标记为true (正确写法应该是将小于号换成大于号);
  • 第二行当转账数量_value值大于或等于限定金额时将授权限额充足标记为true(正确写法应该是小于号换成大于号);
  • 第三行当转入账户原有余额加上转账数量大于或等于账户原有余额时将溢出判断标记为true(正确写法应该是将大于号换成小于号).

该段代码导致的后果为:三重校验形同虚设,当转账token数量大于转出账户余额和限定余额并且数量大到足以使函数出现溢出时才能转账成功。这样会攻击者可以将任意账户中的token全部转走,对整个合约的安全影响十分恶劣。

该问题主要是由于“不等号”写反导致的,当该问题出现在某一个合约中时,我们或许可以理解为由于程序员的笔误导致的,但是SECBIT(安比)实验室在以太坊主网上扫描,一次性发现了81个合约具有该问题,部分合约的地址(81个中的20个)如下:

数量如此之多的合约代码出现同一问题,无论是合约原始构建者无意错写代码后被他人复制使用了,还是有人蓄意创造问题合约并部署到主网上进行恶意传播,都值得我们思考“代码复制使用”这个问题的影响。当我们复制一段公开的代码时,往往出现在我们自身对该类型代码缺乏开发能力的情况下,该情况下复制者会缺乏对代码质量和正确性的辨别能力。智能合约目前最多的被用于token的发行,在以后极有可能会被用于大规模的资产管理,一旦部署后出现问题,将造成不可挽回的损失。

所以SECBIT(安比)实验室作为一个聚焦于智能合约安全的组织建议大家切莫随意复制非官网资源的智能合约代码,谨慎开发。在部署智能合约之前最好找专业的第三方审计机构对智能合约做专业的审计,确保合约的正确性。

案例二

EOS在以太坊上进行了长达一年的众筹,众筹参与者在以太坊平台获得一定数量的ERC20 Token作为回报。 而EOS主网上线后,发行在以太坊平台上的EOS Token便将作废。这需要众筹参与者在主网上线快照前进行映射操作。

映射具体指,EOS Token持有者利用工具生一对公私钥,其中私钥必须私密保存,不能让任何其他人知道。持有者再调用以太坊上EOS Token智能合约的register函数,传入之前生成的公钥,发起交易打包确认,从而完成映射操作。EOS主网上线前会根据以太坊区块快照中的结果,将原有EOS ERC20 Token持仓情况映射至EOS主网区块链中,并需要之前生成的私钥来授权转账等操作。

2018年5月30日,EOS超级节点候选人在对EOS网络快照进行数据分析时,发现213个钱包地址共享相同的EOS公钥。造成这种情况的原因有两种可能,一种是同一个用户拥有213个不同的地址,还有一种可能是不同的用户使用了同一对公开的EOS公私钥对。

经过仔细分析后证实,实际情况是这些用户使用了同一对在网上公布的EOS公私钥进行映射操作。这对公私钥最早出现于EOS GitHub代码仓库中的一个配置文件,并且被大量EOS相关教程作为示例参数而广泛使用。

按目前的价格计算,这些钱包的金额超过了1000万美元。每个钱包平均约有3,866个EOS总共823000 EOS。共享的公钥为:

EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV

图片来自EOSAuthority.

该事件虽然现在并没有对EOS生态造成直接的影响,但是众多钱包共享一个公钥,且对应的私钥也不是某一个人专有的。当EOS部署成功后,这些钱包中的EOS可能会被恶意转移出EOS原有账户,造成经济损失。EOS平台自身具备的账号安全功能、时间延迟功能,仲裁流程等功能在这里并不适用,都不能保证这些资金的安全。

在密码学中,我们经常听到“公钥”和“私钥”两个词,公钥和私钥是成对存在的,公钥是私钥通过特定的函数派生出来的,通过私钥可以推测出公钥,但是通过公钥无法推测出私钥,所以在购买和交易加密货币时加密货币钱包会提醒用户保存好自己的私钥或是私钥种子,因为丢失或是泄露了私钥后自己钱包中的加密货币就会被窃取。

所以当众多人共享一对公私钥对,多个钱包用户拥有相同私钥时,恶意用户就可以转走其他用户钱包中的加密货币。所以多个EOS钱包复制使用公开公私钥对,而不是自己生成私有的公私钥对是一件极具风险的事情。错误使用了公开公私钥进行操作的用户,必须立即重新进行正确映射操作。

作为区块链行业从业者、智能合约使用者或是加密货币拥有者,应该学习、了解相应的密码学和智能合约编程知识,切不可随意复制使用涉及资金安全的合约和公私钥等的代码。如果恶意攻击者,将带有严重漏洞的代码公开在网络上进行传播,诱导技术开发能力欠缺的组织使用,将会给使用者造成毁灭性打击和不可挽回的损失。

SECBIT(安比)实验室作为一个聚焦智能合约安全的团队呼吁大家在使用网络开源代码,特别是智能合约代码时,最好交付专业审计机构,对合约进行审计和漏洞排查。

(以上观点由SECBIT(安比)实验室提供,SECBIT(安比)实验室专注于智能合约安全问题,全方位监控智能合约安全漏洞、提供专业合约安全审计服务。)

链得得仅提供相关信息展示,不构成任何投资建议
本文系作者 SECBIT实验室 授权链得得发表,并经链得得编辑,转载请注明出处、作者和本文链接

更多精彩内容,关注链得得微信号(ID:ChainDD),或者下载链得得App

分享到:

相关推荐

    评论(0

    Oh! no

    您是否确认要删除该条评论吗?

    分享到微信