CARD:智能合约安全实践(二)| 练就“火眼金睛”,真假构造函数一眼看清

引子:“真行者珞珈山诉苦,假猴王水帘洞誊文。”?——《西游记·第五十八回》

在《西游记》中,六耳猕猴冒充猴王孙悟空,以假乱真,过了唐僧,过了众神,纵使是照妖镜也分不出真假。

现在,智能合约遇上了“六耳猕猴”,又会擦出怎样的火花?

在智能合约中,构造函数负责一些数据的初始化工作,owner值一般也会放在构造函数中进行初始化。

owner是智能合约拥有者的称呼,也常被用来作为该合约的超级管理员。对代币合约来说,owner可能被分配的权限有:铸造/销毁代币、冻结代币等。

如果开发者以错误的语法创建“构造函数”,造成构造函数缺失,致使“六耳猕猴”以假乱真,瞒过了开发者,最后使得攻击者成为合约的拥有者,那么攻击者便可依赖owner的权限,对代币进行增发或销毁等操作,进而可能造成整个代币的崩盘。

Cardano创始人:Cardano新功能应被称为“可编程验证器”而非“智能合约”:9月19日消息,Cardano创始人Charles Hoskinson最近在推特上表示,对于Cardano来说,“智能合约”这个词其实并不恰当,并建议社区将其新功能称为“可编程验证器”。Cardano开发者Matthias Benkort最先发现了语义上的错误。他声称由于其eUTXO交易模型,Cardano的可编程性与以太坊和Solana等竞争链截然不同。因此,智能合约不能实际部署在Cardano上:“与以太坊、Solana、Algorand等公链不同,Cardano上没有所谓的‘部署’智能合约(功能)。取而代之的是,验证器在使用前由哈希隐式引用,并在激活时公开。”(U.Today)[2021/9/19 23:37:05]

一、构造函数简介

在Solidity语言中,当函数名和合约名相同时,此函数就是合约的构造函数,在合约对象创建时,会先调用构造函数对相关的数据进行初始化。

ZenaPay钱包将允许用户创建高价物品交易智能合约:9月1日消息,基于云的软件公司Epazz Inc.宣布ZenaPay正在添加新功能。通过ZenaPay钱包,用户将能够创建购买汽车、船只、房屋和其他高价物品的智能合约,这需要支持使用加密货币购买的书面协议。ZenaPay钱包将管理买家和卖家之间的购买流程,同时扩大这些大型商品的市场。此外,买卖双方可以使用钱包管理高价项目的贷款支付,以及确定何时发放托管付款。

ZenaPay钱包App将继续添加新的加密货币。ZenaPay提供快速、简单和完整的交易,并将包括Epazz的其他区块链应用程序的功能。(DGAP.DE)[2021/9/1 22:52:25]

以太坊Solidity0.4.22版本中引入了关键字constructor,新的构造函数声明形式:constructor()public{},引入的目的是用以替代低版本中将合约名作为构造函数名的语法形式,从而避免开发者笔误造成构造函数命名错误的问题。

引入的这个关键字看似平淡无奇,实则意蕴深刻,且听我慢慢道来。

Charles Hoskinson:认证软件可以大幅降低智能合约遭受黑客攻击的概率:IOHK首席执行官Charles Hoskinson在最近的AMA中表示,智能合约并非不受潜在黑客攻击的影响,因为任何编写和构建的东西都可能被破坏。他进一步阐述了“认证软件”的概念,该概念使此类黑天鹅事件发生的几率指数级降低。“如果你有一个规范和一个特定的开发方法和工具,你或外部审计员可以做的就是证明其实现遵循该规范,并且该规范可以得到很好的测试和理解,如果你这样做,你遭受黑客攻击的机会将呈指数级下降。”Hoskinson进一步解释说,Cardano和其区块链智能合约平台Plutus旨在实现高保障。(U.Today)[2021/8/14 1:55:34]

二、Fallout“以假乱真?”

波场与WAVES达成战略合作 将利用Gravity连接区块链智能合约语言:据官方消息,波场已与WAVES达成战略合作,Waves和TRON将一起利用Gravity来连接各自区块链的智能合约语言,即Ride和Solidity。Gravity是一个无基础代币的预言机,具有跨链通信网络。TRON和Waves正在通过Gravity建立一座桥梁,这将允许两个生态系统为两个用户群提供更多的服务。波场和Waves的生态系统计划将这一趋势扩展到其他区块链生态系统并以此为链间DeFi行业带来革命性改变。波场 TRON 以推动互联网去中心化为己任,致力于为去中心化互联网搭建基础设施。旗下的 TRON 协议是基于区块链的去中心化应用操作系统协议之一,为协议上的去中心化应用运行提供高吞吐,高扩展,高可靠性的底层公链支持。波场 TRON 还通过创新的可插拔智能合约平台为以太坊智能合约提供更好的兼容性。[2020/8/14]

–漏洞分析

下面以ethernaut靶场的Fallout题目为例进行分析。

声音 | Circle首席执行官:通证资产和智能合同将为加密行业带来资金流入:据AMBcrypto报道,Circle的首席执行官兼创始人Jeremy Allaire近日在接受媒体采访时表示,虽然目前由于监管机构和决策机构对该行业的审查力度加大和绝大多数公司的融资和估值下降,ICO数量正在成比例的减少,市场的波动期正在下降,但通证资产和智能合同将帮助该行业发展到一个新的水平。我很确定随着时间的推移,会有许多百万级的资金流入。[2018/10/11]

一眼看去,这似乎是一个正常没有漏洞的合约代码,但经过仔细观察发现,该合约存在一个致命错误——构造函数名称与合约名称不一致,Fallout合约的构造函数被写错成了Fal1out。

这样的错误使其成为了一个被public修饰的普通函数,失去了构造函数仅在合约部署时被调用的特性,使得任何人都可以调用。该题目源码如下图所示:

图1

在Fal1out函数中直接指定了函数调用者的地址即为owner,所以只需要调用Fal1out函数即可实现对合约owner的更改。

如下图所示:

图2

“假猴王”Fal1out想借着一些字体类型的相似字符的视觉差异混淆视听,可最终还是没能逃过我们的“火眼金睛”。

三、前车之覆

MorphToken事件分析

在过去也曾发生过类似的安全事件,包含着假构造函数的合约被成功发布到主链上,其中比较出名的是“MorphToken事件”,其因为一个看似很小的问题而造成了数千万市值的代币被增发。

合约代码地址:https://etherscan.io/address/0x2ef27bf41236bd859a95209e17a43fbd26851f92#code

在Owned合约中,由于首字母大小写的错误,导致本该成为构造函数的Owned成为了普通函数owned,且被public修饰,可供任何人调用。

如下图所示:

图3

MorphToken合约继承了Owned合约,并在自己的构造函数内进行了owner的初始化,但是父合约Owned的owned函数是可供任何人调用的,攻击者便可通过调用owned函数更改合约的所有者owner。

owner的初始化代码如下图所示:

图4

由上述可知,任何人都可以通过调用合约的owned函数,成为合约的拥有者(owner)。

如下图所示:

图5

失之毫厘,差之千里,一个小小的字母错误,却导致了合约的代币的崩盘。代币也被恶意增发。

如下图所示:

图6

四、后车之鉴

开发者应如何正确使用构造函数

建议更换Solidity0.4.22及以上版本,并使用正确的constructor()语法。

如下图所示:

图7

切记:constructor()前并无function,functionconstructor()public{}为错误的构造函数形式。

如果要使用低于0.4.22的版本,则一定要着重检查函数名是否和合约名一致。

如下图所示:

图8

五、安全建议

在智能合约中因开发者粗心,而造成安全漏洞的事件层出不穷,“千里之堤,溃于蚁穴”,成都链安-安全实验室在此给出如下建议:

1、开发者在编写智能合约敏感函数时,应严格

按照官方要求的代码书写规范,注意不要出现字符错误等情况。

2、在某些情况下,编译器会对constructor的错误使用发出警告,开发者应予以正确对待,不可认为其只是警告信息而忽略不处理。

3、在合约正式上线前一定要找专业可信的机构做好合约代码的审计工作。

郑重声明: 本文版权归原作者所有, 转载文章仅为传播更多信息之目的, 如作者信息标记有误, 请第一时间联系我们修改或删除, 多谢。

金星链

[0:0ms0-1:12ms