专栏首页区块链大本营继承变量覆盖及构造函数失配,竟然会导致这些漏洞

继承变量覆盖及构造函数失配,竟然会导致这些漏洞

安全,区块链领域举足轻重的话题。本期咱们聊聊,由于名称书写、声明语句、继承中变量覆盖等细节问题引起的巨大安全隐患。 「区块链大本营」携手「成都链安科技」团队重磅推出「合约安全漏洞解析连载」,以讲故事的方式,带你回顾区块链安全走过的历程;分析漏洞背后的玄机。让开发者在趣味中学习,写出更加牢固的合约,且防患于未然。 当然,这些文章并不是专为开发者而作的,即使你不是开发者,当你读完本连载,相信再有安全问题爆出时,你会有全新的理解。

引子: 《易》曰:‘君子慎始,差若毫厘,缪以千里。’ - 《礼记·经解》

上回讲到:

机制依赖参数主导

矿工操纵投机取巧

区块参数作为区块属性的数据,对于挖掘区块的矿工来说,并不具有完全的随机性,因此将其作为随机数生成的依据是有局限性和危险性的。而以太坊本身又没有提供类似于传统语言的rand()函数,所以随机数生成的来源,尽量来源于区块链外部或者利用新的信任模型RanDAO来完成。随机数生成作为目前以太坊游戏的核心,在原理的定制上直接决定了项目质量和项目寿命。

本回咱们来聊聊:

继承变量名同实不同

构造函数名异失其义

广义的名字,指明了一个特定的人或物,将其与相似的其他人或物区别开来。我们把名字作为对一个人或物的称呼,初次了解人或物,我们都会先尝试记住他们的名字。

计算机也是如此,在区块链开发,合约的编写当中,我们给予不同函数、不同变量以不同的名字,程序才能按照编写的意愿调用和执行。正确书写名称、正确声明函数自然就成为智能合约安全开发的基础。

然而,这样的问题在区块链发展到近期依然屡次出现,导致安全事件的发生,例如Morphtoken, B2X, DoubleOrNothinglmpl等多个合约中出现的Owned合约构造函数Owned大小写问题。

本期咱们就来聊聊由于名称书写,声明语句,继承中变量覆盖等细节问题引起的巨大安全隐患。

01

基础知识

Solidity中的构造函数

Solidity的使用与面向对象编程语言非常相似。构造函数(constructor)用于初始化合约对象。一个合约的构造函数的方法名与合约的名字相同,在合约创建时,对于状态变量的数据初始化操作是通过调用构造函数完成的,一般包括:设置代币名称、标识符、发币、将所有代币发送给owner,注意此调用仅存在于合约部署时。此外,合约的所有者(owner)的设置一般也放在构造函数当中。因此,构造函数相当于合约启动的引擎

以太坊solidity0.4.22引入了新的构造函数声明形式constructor(),该函数引入的目的是避免编程人员在编写构造函数时的命名错误。

Solidity中的继承

Solidity支持多继承和多态,其原理是代码拷贝。换句话说,继承的写法总是能够写成一个单独的合约。当一个合约从多个合约继承时,只有一个合约(子类)会被部署到链上,而其他的代码都会被拷贝到这个单一的合约当中去。

02

因小失大

MorphToken出现的安全漏洞只是因为在构造函数中Owned大小写没有注意Owned写成的owned,使owned函数失去构造函数仅在部署时才能调用的特殊性,导致任何账户都能调用,来实现更改owner变量,转移合约所有权的恶性事件。攻击者在初次刺探时可能以为要黑构造函数可能相当于打李逵,结果细看之后发现对方不过是个李鬼。

继承的情况有许多种,在合约继承中出现的漏洞是因为:子类重新定义的变量继承父类的函数,而且还取了同样的名字来方便理解,而其实调用父类函数并不会操作子类的这个变量。开发者认为函数操作的是子合约的变量,没想到操作的父合约的变量。这个失误还曾被当作蜜罐手段伪装成漏洞吸引想要改变合约权限、偷取合约内资金的玩家上钩。

03

构造函数失配漏洞

上面讲到如果构造函数在声明时出错,变成了一个普通函数,那么,合约将存在重大安全风险。我们构造函数失配的情况分为两大类:

一、构造函数名和合约名不一致

  • 案例合约:

在这个合约中,ownerWallet和合约的函数名不一致,变成了普通的函数,导致用户可以执行此函数,变成合约的owner,然后取出合约地址下的Ether。

  • 漏洞修复

Solidity 0.4.22提出了构造函数的新的写法constructor() public {},如果可能,推荐这种写法,如果版本低于0.4.22,那么一定要着重检测构造函数的名称是否和合约名相同

二、constructor声明形式错误

  • 案例合约

其中,owned合约的function constructor()函数的功能是将创建者地址赋予owner,用于后续的身份验证。但是,在使用constructor声明构造函数时,开发者错误的在其前面添加了一个function关键字,导致其变成一个名为constructor普通的函数。任意账户地址都可以调用constructor()函数,并修改owner的值,导致合约管理权限被盗用。

  • 漏洞修复

Solidity 0.4.22 提出的新的构造函数的完整声明形式如下,注意:constructor前无function

04

合约继承中的变量覆盖漏洞

这里我们拿Owned合约做一个简单的例子。

调用useEmergencyCode函数,只会更改TestBank合约中的owner,并不会更改Owned中的owner,onlyOwner中的owner仍是合约的部署者地址。

换句话说,TestBank合约中的owner与Owned中的owner是不一样的两个变量。根据上面提到的Solidity原理的解释:对于EVM来说,每个Storage 变量都会有一个唯一标识的slot id。在这里,虽然都叫做owner,但是从bytecode的角度来看,他们都是由不同的slot id来确定的,因此也和变量的名字没有什么关系。

关于Storage变量以及slot的相关知识我们也曾在漏洞连载分析第七期存储器局部变量未初始化中讲到过,在此就不赘述。

05

失之毫厘,差之千里

正确记住对方的名字,在社交礼仪中是非常重要的一点,代表着对他人的尊重。

在合约编写的过程中,规范书写,正确声明,辨析不同变量也是对代码的尊重,更是对工作的尊重。在做到这份尊重的同时,也能带来项目质量和资金安全的提升,当大部分开发者都做到这一点,这个产业的良性循环也就慢慢启动。

本回结语

蔺相如,司马相如,名相如,实不相如;

魏无忌,长孙无忌,人无忌,尔勿无忌。

引用:

[1]: Solidity原理(一):继承(Inheritance):

https://blog.csdn.net/Programmer_CJC/article/details/80042261

[2]: 以太坊蜜罐智能合约分析:

https://paper.seebug.org/631/

[3]: Solidity语法---以太坊智能合约生命周期:

https://www.jianshu.com/p/61e2d9e31aab

[4]: 深入理解Solidity:

https://solidity-cn.readthedocs.io/zh/develop/solidity-in-depth.html

[5]: 注意!3份合约又存在Owner权限被盗问题——低级错误不容忽视:

https://mp.weixin.qq.com/s/xPwhanev-cjHhc104Wmpug

相关阅读:

杨霞 成都链安科技CEO,创始人。电子科技大学副教授,最早研究区块链形式化验证的专家。一直为航空航天、军事领域提供形式化验证服务。主持国家核高基、装发重大软件课题等近10项国家课题。CC国际安全标准成员、CCF区块链专委会委员。发表学术论文30多篇,申请20多项专利。是成都链安科技有限公司创始人之一,该公司专注于区块链安全领域,其核心技术为形式化验证。

本文分享自微信公众号 - 区块链大本营(blockchain_camp),作者:链安科技

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-10-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 快讯 | 新型constructor函数使用漏洞,可致合约权限丢失、代币增发

    据悉,Solidity 0.4.22版本在更新后,引入一种新的构造函数声明形式:constructor()public {},通过这种写法,可以避免在合约开发过...

    区块链大本营
  • 偷天换日合约易主,地址变脸移花接木——底层函数误用漏洞 | 漏洞分析连载之四

    引子:阵有纵横,天衡为梁,地轴为柱。梁柱以精兵为之,故观其阵,则知精兵之所有。共战他敌时,频更其阵,暗中抽换其精兵,或竟代其为梁柱,势成阵塌,遂兼其兵。并此敌以...

    区块链大本营
  • 智能合约编写之 Solidity 的设计模式

    区块链所具有的独特优势,例如,数据公开透明、不可篡改,可以为业务带来便利。但与此同时,也存在一些隐患。数据的公开透明,意味着任何人都可以读取;不可篡改,意味着信...

    区块链大本营
  • 韩顺平_linux_随堂笔记

    这还是自己3年前(2011年)整理的笔记,记得当时那会儿自己对Linux还特别的憧憬,也很喜欢韩老师的讲课风格,边看边做笔记乐此不彼,现在开通了技术博客,所以把...

    Alfred Zhao
  • dotnet 在 Linux 下的 GDI 库对 EMF 图片格式的支持

    我想要在 UOS 上支持上古的图片格式,也就是差不多废弃了 20 年的 EMF 和 WMF 增强图形格式,这两个格式十分古老,而在 Windows 下也存在一些...

    林德熙
  • 定时器有几种实现方式?

    在开始正题之前,先闲聊几句。有人说,计算机科学这个学科,软件方向研究到头就是数学,硬件方向研究到头就是物理,最轻松的是中间这批使用者,可以不太懂物理,不太懂数学...

    kirito-moe
  • Java基础:六、访问权限修饰词 (2)

    访问权限控制的等级,从最大权限到最小权限依次为:public、protected、包访问权限(没有关键词)和private

    桑鱼
  • 深入理解计算机系统(3.5)------特殊的算术操作指令

      在上一篇博客 算术和逻辑操作 我们介绍了如下图几种常用的算术逻辑指令,但是大家发现没,这几种指令如果在 IA32 上只能操作32位寄存器,比如我用乘法指令I...

    IT可乐
  • 深入理解计算机系统(3.4)------算术和逻辑操作

      上一篇博客  我们介绍了几种数据传送指令,包括MOV,MOVS,MOVZ,PUSH和POP等,理解起来也不算难。本篇博客我们来接着看汇编语言的算术与逻辑运算...

    IT可乐
  • 2018最后一战:25天编程PK赛!

    2018 年余额已不足一个月!是惊喜还是惊恐?这一年是充实有意义的一年,还是觉得略有失望?最后这三十天,我们还能学些什么?获得哪些成长?如何为 2019 年准备...

    AI科技大本营

扫码关注云+社区

领取腾讯云代金券