BEC合约整数溢出解析—Solidity合约中的整数安全问题

当前位置:首页 > 币圈百科 > BEC合约整数溢出解析—Solidity合约中的整数安全问题

BEC合约整数溢出解析—Solidity合约中的整数安全问题

2022-11-26币圈百科459

1整数安全回顾

1.1整数安全介绍

?在传统的桌面windows攻防对抗领域,随着微软及其合作伙伴对软件开发流程实施SDL规范,加大安全投入,单个超长数据包和超长文件特定领域内容导致的溢出漏洞在一些大型软件中几乎已经消失。剩下的漏洞包括浏览器中的UAF(隔离堆和延迟释放用于缓解关键类),弱类型语言类型混乱,零星留下一些整数类漏洞。类漏洞,最近的是去年的nginx cve-2017-7529。

区块链方向。更早的整数溢出漏洞可以追溯到2010年的比特币大整数溢出,CVE-2010-5139。黑客通过整数溢出构造了约922372427039个比特币。最近的SMT/BEC的整数安全场景与之前的比特币类似。

?在传统安全领域,整数安全与数据模型和整数运算支持的运算符有关,其中数据模型与处理器架构和操作系统平台有关。如下图。

1

图1

C中容易引起整数安全问题的运算符简述如下。

2

图2

solidity契约中的整数安全场景类似。

?1.2 solidity中的整数安全场景

SMT和BEC都是以太坊令牌生态中常见的ERC-20令牌。转移和流通都是通过以太坊的实体契约来实现的。区块链1.0的

比特币也有脚本语言,但是为了安全,已经阉割了循环、递归等图灵完备性语言的功能。以太坊坚固性在设计之初就被定位为图灵完备性语言。Solidity的图灵完备性也为后续的契约漏洞埋下了伏笔。比如Dao漏洞事件直接导致以太坊硬分叉成eth和老链等。

Solidity语言暂时不支持C中类似float double的浮点数据类型。支持int/uint可变长度的有符号或无符号整数。支持的可变步长增加了8,从uint8增加到uint256,从int8增加到int256。注意,默认情况下,uint和int表示uint256和int256。uint8的数值范围与C中的uchar相同,即取值范围为0到2 ^ 8-1,uint256支持的取值范围为0到2 ^ 256-1,其余数据类型类似。

Solidity语言对运算符的支持如下。

比较:=,

=,返回值为bool类型。位运算符:|,(XOR),(~ NOT)。数学:一元运算,*,/,(%为余数),(* *平方)。【Solidity契约代码的逻辑比较简单,大部分运算符都是加减乘除。<,==,!=,>

以太坊提供了Solidity语言的在线编译和测试工具。3358remix.ethereum.org/# optimize=false version=sol JSON-v 0 . 4 . 23 commit . 124 ca 40d . js我们以加法和减法为例,简要说明Solidity语言中整数溢出的一般情况。

编写下面的可靠性测试代码。

pragma solidity ^0.4.0;契约C {//(2 * * 256-1)1=0 function overflow()returns(uint 256 _ overflow){?马鞭马鞭uint 256 max=2 * * 256-1;马鞭马鞭马鞭return max 1;马鞭马鞭马鞭}?//0-1=2 * * 256-1函数下溢()返回(uint256 _下溢){?马鞭马鞭uint 256min=0;马鞭马鞭马鞭返回min-1;马鞭马鞭马鞭}}

在线测试工具中编译运行的结果如下。

3图3

图4

4可以看出,uint256取最大整数值时,溢出后直接返回值0,uint256取0下溢时返回值2。这是solidity中整数溢出场景的一般情况。

?1.3 solidity中的整数溢出缓解和SafeMath库

为了减少solidity契约开发中的安全问题,以太坊官方开发博客陆续发布了一些与solidity开发安全相关的博文。2017年8月6日,发表了一篇关于使用SafeMath库进行整数安全操作的独立文章

。 详见链接

?https://ethereumdev . io/safe math-protect-overflow/

<>?

/**?* @title SafeMath?* @dev带有安全检查的数学运算会引发错误?*/库SafeMath {?函数mul(uint256 a,uint256 b)内部常量返回(uint256) {?马鞭马鞭uint 256 c=a * b;马鞭马鞭马鞭断言(a==0 | | c/a==b);马鞭马鞭马鞭回归c;马鞭}?function div(uint256 a,uint256 b)内部常量返回(uint256) {?马鞭马鞭//assert(B0);//Solidity除以0时自动抛出?马鞭马鞭uint 256 c=a/b;马鞭马鞭马鞭//assert(a==b * c a % b);//不存在这个不成立的情况?马鞭马鞭回归c;马鞭}?function sub(uint256 a,uint256 b)内部常量returns (uint256) {?马鞭马鞭断言(b=a);马鞭马鞭马鞭回归c;骑乘作物}}可以看出,将可能引起溢出的相关操作单独封装到函数中,并加入assert断言进行判断,避免溢出。调用SafeMath库的方法如下。

图5

2。SMT合约中整数安全问题分析51

与大型软件或操作系统频繁使用数百行甚至数千万行代码不同,智能合约通常代码很少,功能也不是很复杂。我们来看看SMT合同的相关代码。

SMT的合同地址为https://ethers can . io/address/0x 55 f 93985431 fc 9304077687 a 35 a1 ba 103 dc1 e 081 # code

。问题在于transferProxy()函数代码下面的

。_feeSmt参数和_value参数都可以被外界控制。_feeSmt和value为uint256无符号整数,相加后最高位被截断,结果为0。

61图7

直接溢出绕过了代码检查,导致可以构造和转移的smt令牌数量巨大。

图87 (2)

攻击者的恶意转账记录可以从下面的链接中看到。

3359 ethers can . io/tx/0x 1 abab 48 db 9 a 30 e 703114528 e 31 de 129 a3 a 758 f 7 F8 ABC 3b 6494 aad 3d 304 e 43 f

图98BEC合同地址为0 C5 d 105 e 63711398 a F9 BFF 092d 4b 6769 c 82 f 793d,合同代码可在以下地址查看ether代码是299行。

问题函数如下所示。

图10

蓑衣网小编20229可以看到,在batchTransfer函数中,在语句balances[msg . sender]=balances[msg . sender]中,sub(金额)和余额[_ receivers [I]]=余额[_ receivers [I]]。add (_ value),调用Safemath库中的safe函数完成加减运算,但是在第三行代码中,uint 256 amount=uint 256(CNT)* _ value直接使用乘法运算符。

变量cnt是要传输的地址数,可以通过外部用户输入_receivers来控制,_value是单个地址传输的量,也可以直接控制。乘法溢出,产生意外的amount值,外界可以通过调整_receivers和_value的值来操纵它。紧接着下面,有一个代码require(_ value 0 balances[msg . sender]=amount)检查金额的条件;其中balances[msg.sender]表示当前用户的余额。Amount表示要转移的资金总额。该代码意味着确保当前用户拥有的代币余额大于或等于在后续转移之前转移的货币总量。很容易绕过balances[msg.sender]=amount的校验码,因为通过增加单个地址的transfer amount _value的值,金额可以是一个很小的数,或者溢出后为0。导致巨额金额被恶意转移。

攻击者的恶意转账记录可以从以下链接中看到:https://ethers can . io/TX/0 xad 89 F6 f1 D1 EB 3a 0a 7 cf 4 ed 282302 c 06626 C1 af 蓑衣网小编2022 33221 EB 0d 3 a 470 a 4 a 660 f。

图11

10从代码totalSupply中可以看出,bec令牌的总数只有7,000,000,000。

图12

但是攻击者通过溢出金额来绕过后续require中的判断条件,恶意将钱转移到两个地址?789604461865810000000000000000000000000000000004 . 400000005

4。合约整数漏洞事件总结

11从技术上来说,smt和bec的这个合约中的漏洞的成因和利用并不复杂,都是通过构造恶意整数溢出来绕过条件检查。相信以太坊生态中其他数千个代币的合约也不同程度存在类似的整数漏洞。由于solidity合同直接与金钱打交道,安全开发和合同审计需要ico项目方和solidity开发商投入更多的时间和精力,以确保合同的安全性。

参考链接:

https://ether eum . io/safe math-protect-overflow/

蓑衣网小编2022

3359juanlan.zhihu.com/p/35989258? UTM _ medium=social UTM _ member=zjzlymq 1 mgzkmjzjzmjknte 4 mgmmmexzja 5 ntm 0 NME=UTM _ source=we chat _ session wechatshare=1 from=timelineisappinstalled=012

BEC合约整数溢出解析—Solidity合约中的整数安全问题 | 分享给朋友: