曲速未来 :智能合约攻击分析之SafeMath使用不当区块链

区块链安全档案 2018-09-05 23:39
分享到:
导读

智能合约安全咨询公司曲速未来提醒:在编写智能合约的时候需要注意的一个主要的安全特性:防止溢出和下溢。为了防止这些情况,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”进行基线检查外,还需要实施更深入细致的审计。

SafeMath 合约 代码 溢出 使用
分享到:

1.TMT观察网遵循行业规范,任何转载的稿件都会明确标注作者和来源;
2.TMT观察网的原创文章,请转载时务必注明文章作者和"来源:TMT观察网",不尊重原创的行为TMT观察网或将追究责任;
3.作者投稿可能会经TMT观察网编辑修改或补充。