以太坊智能合约之溢出问题

区块链安全档案
区块链安全档案 机构得得号

2018年09月13日 隶属于曲速未来安全区,安全问题深度分析、一手威胁情报披露

摘要: 智能合约之所以“智能”,是由于合约代码一旦上链,其执行效果完全由可见且不可篡改。然而,通过分析溢出这一常见漏洞类型,发现管理员能够铸币烧币,背离合约白皮书的约定,这样的合约无法保证参与多方的公平性,更无谈智能。

 介绍:

以太坊Solidity设计之初就被定位为图灵完备性语言。在solidity的设计中,支持int/uint变长的有符号或无符号整型。变量支持的步长以8递增,支持从uint8到uint256,以及int8到int256。需要注意的是,uint和int默认代表的是uint256和int256。uint8的数值范围与C中的uchar相同,即取值范围是0到2^8-1,uint256支持的取值范围是0到2^256-1。而当对应变量值超出这个范围时,就会溢出至符号位,导致变量值发生巨大的变化。

(1)算数溢出

在Solidity智能合约代码中,在余额的检查中如果直接使用了加减乘除没做额外的判断时,就会存在算术溢出隐患

在上述代码中,由于没有校验_amount一定会小于balances[msg.sender],所以攻击者可以通过传入超大数字导致溢出绕过判断,这样就可以一口气转走巨额代币。

2018年4月24日,SMT/BEC合约被恶意攻击者转走了50,659,039,041,325,800,000,000,000,000,000,000,000,000,000,000,000,000,000,000个SMT代币。恶意攻击者就是利用了SMT/BEC合约的整数溢出漏洞导致了这样的结果。

2018年5月19日,以太坊Hexagon合约代币被公开存在整数溢出漏洞。

(2)铸币烧币溢出问题

作为一个合约代币的智能合约来说,除了有其他合约的功能以外,还需要有铸币和烧币功能。而更特殊的是,这两个函数一般都为乘法或者指数交易,很容易造成溢出问题。

上述代码未对代币总额做限制,会导致指数算数上溢。

漏洞实例:合约Playkey (PKT)

漏洞所在位置:红色标注的行L237

漏洞攻击效果:管理员可以篡改已发币总量(totalSupply)为任意值,并绕过合约中的铸币上限超额发行token;

漏洞原理:_value在函数调用时被设置为精心构造的极大值,使得totalSupply + _value计算结果溢出后小于tokenLimit,从而轻易绕过L237行的铸币上限检测。

影响:

截止2018年9月5日,总共发现了391个存在算数溢出问题的合约代码,其中332个仍处于交易状态,其中交易量最高的10个合约情况如下:

截止2018年9月5日,我们发现了1636个存在超额铸币销币问题的合约代码,其中1364个仍处于交易状态,其中交易量最高的10个合约情况如下:

修复方法

1)算术溢出问题

在调用加减乘除时,通常的修复方式都是使用openzeppelin-safeMath,但也可以通过对不同变量的判断来限制,但很难对乘法和指数做什么限制。

2)铸币烧币溢出问题

铸币函数中,应对totalSupply设置上限,避免因为算术溢出等漏洞导致恶意铸币增发。

在铸币烧币加上合理的权限限制可以有效减少该问题危害。

总结

智能合约之所以“智能”,是由于合约代码一旦上链,其执行效果完全由可见且不可篡改的代码来决定,而不用依赖于对任何参与方的信任。

然而,由上述漏洞分析可见,智能合约并没有预期的“智能”,存在相当多的安全风险,仅仅通过溢出这一常见漏洞类型,管理员便能够铸币烧币,背离合约白皮书的约定,这样的合约无法保证参与多方的公平性,更无谈智能。

而管理员利用整数溢出进行作恶早已有先例,2018年2月初,基于以太坊的Monero Gold(XMRG) Token在交易所的价格先猛涨787%,后迅速暴跌至崩盘,造成大量用户经济损失 ,其背后就是管理团队利用预留的整数溢出漏洞进行超额铸币,并在交易所抛售造成恶性通货膨胀,最后价值几乎归零。

在区块链上运行的智能合约,本意是利用区块链不可篡改的特性来构建可信的执行环境,然而安全漏洞的存在就像一个个隐藏的定时炸弹,对智能合约的可信任基础带来了巨大的挑战。

(作者:区块链安全档案,内容来自链得得内容开放平台“得得号”;本文仅代表作者观点,不代表链得得官方立场)

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

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

分享到:

相关推荐

    评论(0

    Oh! no

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

    分享到微信