写点什么

智能合约中的那些后门漏洞

2020 年 9 月 07 日

智能合约中的那些后门漏洞

智能合约的概念可以追溯到 1994 年,由 Nick Szabo 提出,但直到 2008 年才出现采用智能合约所需的区块链技术,而最终于 2013 年,作为以太坊智能合约系统的一部分,智能合约首次出现。


智能合约包含了有关交易的所有信息,只有在满足要求后才会执行结果操作,智能合约和传统纸质合约的区别在于智能合约是由计算机生成的,因此,代码本身解释了参与方的相关义务,与此同时,用户可以根据规则开发自己想要的智能合约。


而随着智能合约普及,合约的安全问题也引起众多合约开发者和安全研究人员的关注,比较典型的就是随之建立的DASP Top10


近期,笔者在对一些智能合约进行代码审计时发现有很多合约存在可疑的后门漏洞,具备特殊权限的地址用户(合约的 owner)或合约账号具备控制用户资产的权限,可对任意用户的资产进行销毁操作,本文将对此进行简要分析。


函数漏洞

1.burn()

合约地址:


https://etherscan.io/address/0x705051bbfd9f287869a412cba8bc7d112de48e69#code


利用条件:合约的 owner 权限


漏洞代码:



漏洞分析:如上图所示,在智能合约中提供了burn函数,该函数主要用于销毁其它地址的 token,当要销毁的 token 数量小于目标账户所拥有的 token 值时就可以成功销毁目标账户的 token,且这里的地址能指定为任意用户的地址,所以只要我们能够调用该函数即可通过赋予_ from为任意地址账户,_ unitAmout为任意数量(不超过 from 账户拥有的数量)就可以销毁_from账户的代币,下面我们再来看一下此处对于函数调用者身份限定的修饰器—onlyOwner。



由以上代码可知,当函数的调用者为合约的 owner 地址账户时可以销毁任意地址用户的代币,甚至将其归 0。


2.burnFrom()

合约地址:


https://etherscan.io/address/0x365542df3c8c9d096c5f0de24a0d8cf33c19c8fd#code


利用条件:合约的 owner,同时mintingFinished为"False"


漏洞代码:



漏洞分析:如上图所示,合约中的burnFrom函数用于销毁代币,但是该函数只能被合约的 owner 调用,而且由于地址参数可控,故合约的 owner 可以操控任意地址用户的代币,销毁任意地址用户任意数量的代币(数量小于等于用户代币总量),由于该函数被canMint修饰,所以查看一下该修饰器。



之后,通过"Read Contract"来查看当前mintingFinished的值:



从图可以看到mintingFinished为"False",即满足canMint修饰器条件,所以,此时的burnFrom函数可被合约的 owner 调用来操控任意用户的代币。


3.burnTokens

合约地址:


https://etherscan.io/address/0x662abcad0b7f345ab7ffb1b1fbb9df7894f18e66#code


利用条件:合约的 owner 权限


漏洞代码:



漏洞分析:如上图所示,burnTokens用于销毁用户的代币,由于销毁的地址参数、销毁的代币数量都可控,所以合约的调用者可以销毁任意用户的代币,但是该函数只能被合约的 ICO 地址用户调用,下面跟踪一下该账户看看其实现上是否可以。



从上面可以看到,合约在初始化是对icoContract进行了赋值,下面通过 etherscan.io 中的readcontract溯源一下:



之后,再次进入icoContract中跟踪是否可以成功调用:



从代码中可以看到burnTokens(关于修饰器的跟踪分析与之前类似,这里不再赘述):



这里的cartaxiToken即为之前的合约地址:



同时,发现存在调用的历史记录:


https://etherscan.io/tx/0xf5d125c945e697966703894a400a311dc189d480e625aec1e317abb2434131f4



4.destory()

合约地址:


https://etherscan.io/address/0x27695e09149adc738a978e9a678f99e4c39e9eb9#code


利用条件:合约的 owner 权限


漏洞代码:



如上图所示,在智能合约当中提供了destory函数,用于销毁目标账户的代币,在该函数当中增加了对msg.senderaccountBalance的判断,从整个逻辑上可以看到主要有两种销毁途径:


  • 途径一:合约的 owner 赋予allowManuallyBurnTokens为"true"的条件下,地址账户自我销毁自己的代币;

  • 途径二:无需allowManuallyBurnTokens为"true"的条件,合约的 owner 销毁任意地址用户的代币。


自然,途径一自我销毁代币合情合理,但是途径二却导致合约的 owner 可以操控任意地址用户的代币,例如:销毁地址用户的所有代币,导致任意地址用户的代币为他人所操控,这自然不是地址用户所期望的。


5.destroyTokens()

合约地址:


https://etherscan.io/address/0xf7920b0768ecb20a123fac32311d07d193381d6f#code


利用条件:Controller 地址账户


漏洞代码:



如上图所示,destroyTokens函数用于销毁代币,其中地址参数可控,在函数中只校验了销毁地址账户的代币是否大于要销毁的数量以及当前总发行量是否大于要销毁的数量,之后进行更新代币总量和地址账户的代币数量,不过该函数有onlyController修饰器进行修饰,下面看以下该修饰器的具体内容:



之后,通过 ReadContract 可以看到该 controller 的地址:



之后在 Etherscan 中可以查看到该地址对应的为一个地址账户,故而该地址账户可以操控原合约中的任意地址用户的代币:



6.destroyIBTCToken

合约地址:


https://etherscan.io/address/0xb7c4a82936194fee52a4e3d4cec3415f74507532#code


利用条件:合约的 owner


漏洞代码:



如上图所示,合约中的destroyIBTCToken是用于销毁 IBTCToken 的,但是由于该函数只能被合约的 owner 调用,而且要销毁的地址参数 to 可控,所以合约的 owner 可以传入任意用户的地址作为参数 to,之后销毁任意地址账户的代币,onlyOwner 修饰器如下所示:



7.melt()

合约地址:


https://etherscan.io/address/0xabc1280a0187a2020cc675437aed400185f86db6#code


利用条件:合约的 owner


漏洞代码:



漏洞分析:如上图所示,合约中的 melt 函数用于销毁代币的 token,且该函数只能被合约的 CFO 调用,同时由于地址参数 dst 可控,故合约的 CFO 可以销毁任意地址用户的代币,onlyCFO 修饰器代码如下所示:



onlyCFO 修饰器中的_cfo由构造函数初始化:



8.Sweep()

合约地址:


https://etherscan.io/address/0x4bd70556ae3f8a6ec6c4080a0c327b24325438f3#code


利用条件:合约的 owner,同时mintingFinished为"False"


漏洞代码:



如上图所示,合约中的 sweep 函数用于转发代币,该函数只能被合约的 owner 调用,在 L167 行优先通过 allowance 进行授权操作代币的操作,之后调用transferFrom函数,并在transferFrom函数中做了相关的减法操作,由此抵消授权操作代币:



之后,紧接着又调用了_transfer函数:



在 transfer 函数中,判断转账地址是否为空、进行转账防溢出检查、进行转账操作,通过以上逻辑可以发现由于 sweep 中的地址参数 _ from_to可控,而且该函数只能被合约的 owner 调用,所以合约的 owner 可以通过该函数操控任意用户的 balance,并且将其转向任意用户的地址或者自己的地址。


9.zero_fee_transaction

合约地址:


https://etherscan.io/address/0xD65960FAcb8E4a2dFcb2C2212cb2e44a02e2a57E#code


利用条件:合约的 owner


漏洞代码:



漏洞分析:在智能合约中常见的转账方式大致有两种:一种是直接转账,例如常见的Transfer函数,该函数有两个参数,一个指定代币接受的地址,另一个为转账的额度,例如:



另一种为授权其他用户代为转账,这里的其他用户类似于一个中介/媒介的作用,其他用户可以对授权用户授予的资金额度进行操作,常见的也是Transfer函数,不过参数个数不同而已,其中有三个参数,一个为代为转账的地址,一个为接受代币的地址,一个为接受代币的数量,例如:



了解了常见的两种转账方式,下面我们回过头来看一下漏洞代码:



可以看到在函数zero_fee_transaction中进行了以下判断:


  1. 判断当前代为转账的额度是否大于当前转账的数量

  2. 判断当前转账的数量是否大于 0

  3. 防溢出检查


可以发现这里未对当前函数调用者是否具备授权转账进行检查(暂时忽略onlycentralAccount修饰器)以及授权额度进行检查,只对转账额度以及是否溢出进行了检查,显然这里是存在问题的,而且该函数没有修饰词进行修饰,故默认为public,这样一来所有人都可以调用该函数,在这里我们能看到在不管修饰器onlycentralAccount的情况下,我们可以传递任意地址账户为 from、任意地址账户为 to、以及任意数量(需要小于 from 地址账户的代币数量),之后即可无限制的从 from 地址账户转代币到 to 账户,直到 from 地址的代币数量归 0。


下面,我们看一下onlycentralAccount修饰器对于函数调用者的身份限定:



之后,搜索central_account发现central_account由函数set_centralAccount进行赋值操作,此处的修饰器为 onlyOwner:



之后查看 onlyOwner 修饰器可以看到此处需要msg.sender为 owner,即合约的 owner,在构造函数中进行初始化:



小结

智能合约主要依托于公链(例如:以太坊)来发行代币并提供代币的转账、销毁、增发等其它逻辑功能,但用户的代币理应由用户自我进行控制(通过交易增加或减少),并由用户自我决定是否销毁持币数量,而不是由合约的 owner 或其他特殊的地址账户进行操控。


本文转自 Seebug,原文地址:https://paper.seebug.org/1300/


2020 年 9 月 07 日 14:582610

评论

发布
暂无评论
发现更多内容

“用友 • 华为云杯”第三届企业云服务开发者大赛

ToB行业头条

开发者 低代码 用友

接任务时一定要锁定需求啊!(转自小明同学)

CloudQuery社区

数据库 dba 国产数据库 运维开发

CDH 的安装(四)

大数据技术指南

CDH 7月日更

【Redis】数据结构

awen

redis 数据结构

模块七 - 王者荣耀商城异地多活架构设计

华仔架构训练营

被boss直聘转发过多而“封杀”的2021年全套Java高级面试题有多牛

Java领路人

Java 编程 程序员 面试 架构师

5分钟学会本地Pypi源搭建

Python测试和开发

Python

编程模式:信息隐藏

Medivh Yang

编程模式

相约山城重庆!HarmonyOS Connect伙伴峰会将于7月16日举办

科技汇

Clickhouse Projection 特性探索

GrowingIO技术专栏

数据库 大数据 数据分析 OLAP Clickhouse

底层技术支撑智慧出行,汽车智能化发展下区块链大放异彩

CECBC区块链专委会

技术干货 | 录屏采集实现教程 —— Android端

ZEGO即构

前端 音视频开发 录屏采集 Android端

3分钟评估 你的运维监控系统是“救命稻草”还是“鸡肋”

鹿小U

运维自动化 监控系统 运维平台

5分钟速读之Rust权威指南(三十八)模板语法

码生笔谈

rust

区块链时代下,企业如何打造数据要素的“新竞争力”?

CECBC区块链专委会

【架构实战营】第 7 模块作业

swordman

架构实战营

百度搜索稳定性问题分析的故事(上)

百度开发者中心

百度搜索

北鲲云助力生命科学,高性能计算突破屏障

北鲲云

每天学习10个实用Javascript代码片段(三)

devpoint

JavaScript JSON格式化 7月日更

网络攻防学习笔记 Day68

穿过生命散发芬芳

网络攻防 7月日更

云南智慧公安研判分析系统搭建,重点人员研判分析平台

13823153121

“京东商城”亿级高并发秒杀系统到底是怎么设计的?自己做该如何下手?

Java架构师迁哥

MindSpore教程免费学,还有入门奖品

Geek_6cdeb6

人工智能 机器学习 深度学习 自我提升 羊毛

构筑智能制造时代“四重护城河”,联想中国开创产业新格局

科技大数据

我是如何从设计师转到软件行业的? | 可怜巴巴的程序猿

Python测试和开发

随笔 话题讨论

正式发布!中国首个LF Edge捐赠项目Baetyl 2.2发布

百度开发者中心

物联网 开源技术

香帅:2021年财富格局新变化

石云升

读书笔记 7月日更

爆款阿里P5到P7晋升之路,九大源码文档助我超神果然努力幸运并存

Java 白

Java BAT

阿里P8手抄本惨遭泄露,并出现病毒式传播,致28人斩获大厂offer

Java架构师迁哥

聊聊事务与分布式系统-从零讲到通透

刘绍

sql 分布式 事务 2PC XA

Flink进入大厂面试准备,收藏这一篇就够了

五分钟学大数据

flink 7月日更

低代码的认知误区与落地实践

低代码的认知误区与落地实践

智能合约中的那些后门漏洞-InfoQ