首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

关于“溢出”看这一篇就够了!

关于智能合约的溢出攻击,我遇到了多次这样的诘问:没有用SafeMath,难道你不怕溢出攻击吗?每次面对这样的问题,我的内心是这样的:

先来看一下以太坊官方文档是如何介绍TOKEN的智能合约:

地址:https://ethereum.org/token

截图如下:

关于铸造token的智能合约代码,有兴趣的同学可以去官方文档仔细阅读几遍,深入理解之后再来认真研究如何溢出攻击。我想告诉大家的是,溢出攻击和SafeMath的逻辑关系:用了不一定没问题,不用不一定有问题,因为问题的关键不是SafeMath,而是很多编程语言都会面临的问题:数值表达范围的溢出问题。这个问题不单是以太坊的智能合约才会有的。下面我给大家展示一下object-C语言里面的数值溢出:

通过以上2个例子(以太坊官方文档没有用所谓的SafeMath,Object-C编写同样的逻辑一样会溢出)已经充分证明,那些大肆渲染所谓以太坊智能合约存在致命缺陷的同学,请认清楚,同样的逻辑在其他语言一样存在,其实是某些基本功不扎实同学写的代码有bug,和以太坊的智能合约的设计没有一毛钱的关系,结果以讹传讹,很多非计算机专业的自媒体同学把他理解成了以太坊本身设计的缺陷问题。

那么我们来介绍一下攻击原理,我们以BEC代码为例,给大家详细的讲解一下:

首先要理解任何类型的数值都已自己的表达范围,这个是计算机本科的基本知识,不再展开讲,非计算及专业的同学参考下面的链接:

https://baike.baidu.com/item/%E6%97%A0%E7%AC%A6%E5%8F%B7%E6%95%B4%E6%95%B0/9203544?fr=aladdin

这里以我们的自己的例子讲解一下:一个short 型的数值能表示的数值的范围是:-32768~32767,有负数有正数,这种是有符号数的表达范围,无符号数的表达范围是0~65535。你会发现这2种情况下都有65536个数字,这是2的16次方,也就是说short类型的数字是16位比特位表示的。

好的,基本知识就普及这么多,那么当一种操作,使得操作结果最终超出了类型能够表达的范围,计算机会如何处理呢,如上图所示,65535加1之后变成了0,加2变成了1,这就是所谓的数值反转,所谓的溢出就是超出了数值的表达范围。

下面我们说明一下BEC是如何被攻击的,这里的数据类型不再是无符号的short类型,而是换成了uint256,不管什么类型,只要是固定长度都有其表达范围,上面已经解释过,不多说明。

当cnt 与_value的乘法运算超出了uint256的表达范围,那么amount得到值会远远小于预期的值,就像上面的例子中65535这么大的数字加上1结果变成了0.那么当amount的数值很小,但是cnt和_value很大的时候,签名红色箭头表示的检查就会全部通过,但是,最后转账的时候,不是使用的amount,而是使用的_value,看最后Transfer转账用的是_value。

这个例子充分说明所谓的溢出攻击和用不用SafeMath有什么关系呢?最后附上计算机数值类型表示的基本知识为非计算机专业的朋友降低理解难度:

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180503G0TWDF00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券