本文作者:小驹[1]
1. 重入漏洞简介
1.1 漏洞定义
重入,顾名思义是指重复进入,也就是“递归”
的含义,本质是循环调用缺陷
。重入漏洞(或者叫做重入攻击),是产生的根源是由于solidity智能合约
的特性,这就导致许多不熟悉 solidity 语言的混迹于安全圈多年的安全人员看到“重入漏洞”这 4 个字时也都会一脸蒙圈,重入漏洞本质是一种循环调用,类似于其他语言中的死循环调用代码缺陷。
1.2 危害和利用难度
重入漏洞多数可以绕过代码的正常逻辑的执行,危害的究竟是可以导致拒绝服务还是可以导致代币丢失不能一概而论,更多取决于代码的编写逻辑
相关,在区块链历史上,也产生过由于重入漏洞导致代币被盗的例子。
1.3 典型案例- The DAO 事件
DAO,英文全称是 Decentralized Autonomous Organization,翻译过来是“去中心化自治组织”,是 以太坊创始人 V 神提出的一个概念。它依靠智能合约在区块链上运行,代码表明一切的规则,code is god,可以简单理解为 web3 上的去中心化的公司。
The DAO 则是区块链公司 Slock.it[2] 发起的一个众筹项目,是当时的明星众筹项目。
在 2016 年 6 月 7 日,有黑客利用漏洞向一个匿名的地址转移走了项目众筹来的 360 万枚 ether ,不过幸运的是,当时 The DAO 有 28 日的锁定期,所以要到 7 月 4 日,黑客才能转移走盗来的 ether,这给了社区处理的时间。当时,Slock.it[3] 的首席技术官发表过一篇博文,他提出两点建议:
- 软分叉,即 V 神的提议。不过,这仅仅把 the DAO 的所有资产都冻结住,黑客与其它投资者均无法提现。
- 硬分叉。能把所有的资金都退回去,投资者不会有什么损失,而且不需要回滚。
对打硬分叉大家形城了分歧,主要有两种声音:
- 反对派:认为去中心化是以太坊网络的使命,神圣不可侵犯,硬分叉也就意味着人为操纵,违背了初衷。
- 支持派:要严厉惩戒黑客,其次通过硬分叉解决事件,不必借助外部的力量(比如监管机构)本身也是自治、去中心化的体现。
最终结果,两方谁都不服,形成两条链:一条为原链条 ETC,另一条为新的分叉链 ETH,各自代表不同的社区共识。
这个事件是以太坊历史上最大的事件。在这个事件里,黑客利用的漏洞就是重入攻击漏洞
。
2. 漏洞原理
为了更好地理解漏洞,需要有对 solidity 编程的基本的理解,主要关注下面两个前置知识:
- solidity 的转账函数
- fallback 回调
2.1 前置知识 1-solidity 的转账函数