智能合约攻击分析之SafeMath使用不当

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

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

摘要: 在编写智能合约的时候需要注意的一个主要的安全特性:防止溢出和下溢。为了防止这些情况,OpenZeppelin建立了一个叫做SafeMath的库(library),默认情况下可以防止这些问题。

 智能合约安全咨询公司 曲速未来 提醒:在编写智能合约的时候需要注意的一个主要的安全特性:防止溢出和下溢。为了防止这些情况,OpenZeppelin建立了一个叫做SafeMath的库(library),默认情况下可以防止这些问题。

什么是溢出(overflow)?

假设我们有一个uint8, 只能存储8 bit数据。这意味着我们能存储的最大数字就是二进制11111111(或者说十进制的2^8-1 =255).

来看看下面的代码。最后 number 将会是什么值?

在这个例子中,我们导致了溢出—虽然我们加了1,但是number出乎意料地等于0了。

下溢(underflow)也类似,如果你从一个等于0的uint8减去1, 它将变成255 (因为uint是无符号的,其不能等于负数)。

使用 SafeMath

不过在我们使用之前……什么叫做库?

一个库是Solidity中一种特殊的合约。其中一个有用的功能是给原始数据类型增加一些方法。

比如,使用SafeMath库的时候,我们将使用using SafeMath for uint256这样的语法。SafeMath库有四个方法—add,sub,mul,以及 div。

以太坊虚拟机EVM定义无符号整数为uint256,可以表示一个256位的大整数,但并没有提供溢出的检测机制。OpenZeppline是一个第三方智能合约库,实现了一套SafeMath库来检测溢出。其代码如下:

SafeMath使用内建的require或assert来检查运算是否发生溢出,如果发生了溢出,require和assert中包含的代码会使该事务回滚。但有些开发者不能完全理解SafeMath模版代码,导致合约代码中仍然存在漏洞。

1.攻击案例:UCN (0x6EF5B9ae723Fe059Cac71aD620495575d19dAc42)

UCN是一个智能合约DApp应用。合约代码在SafeMath库中注释assert语句,因此SafeMath函数等同于直接进行算术运算,没有任何安全检查。并且在transferFrom函数中,注释中声明sub函数是安全的,不知道这是开发人员的疏忽还是故意留下的后门。

由于sub函数等同于算术运算,balances[_from] = balances[_from].sub(_value); 存在整数下溢漏洞,可以使得账户余额变成一个极大值。

2.攻击案例:EMVC(0xd3F5056D9a112cA81B0e6f9f47F3285AA44c6AAA)

EMVC合约代码在SafeMath库中使用了一个自定义的assert来代替内建的assert。在assert函数中,如果参数assertion为false则直接return,并没有进行异常处理。因此SafeMath函数等同于直接进行算术运算,没有任何安全检查。

攻击者可以使用transfer函数设置任意账户余额为任意值。

总结

智能合约安全咨询公司 曲速未来 提醒:当智能合约要实现更多功能时,代码会相应变得更加复杂,与ERC20标准代码的差异也越来越大,因而潜在的漏洞面貌更加多样。为了保证智能合约的安全,除遵循安全开发原则、按照“Check Lists”进行基线检查外,还需要实施更深入细致的审计。

本文内容由 曲速未来 (WarpFuture.com) 安全咨询公司独家编译,转载请注明。 曲速未来提供包括主链安全、交易所安全、交易所钱包安全、DAPP开发安全、智能合约开发安全等相关区块链安全咨询服务。

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

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

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

分享到:

相关推荐

    评论(0

    Oh! no

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

    分享到微信