风险提示:理性看待区块链,提高风险意识!
从技术角度剖析针对THE DAO的攻击手法
首页 > 币界资讯 > 区块链知识 2016-06-18 23:24:00

本文内容并非原创,而是来自对于以下两篇博文的翻译和解读。

Blog 1: http://vessenes.com/more-ethereum-attacks-race-to-empty-is-the-real-deal/
Blog 2: http://vessenes.com/deconstructing-thedao-attack-a-brief-code-tour/

attack

一、攻击手法解密

由于攻击者是在创建childDAO并将Ether持续转入其中,这是目前唯一可行的提取Ether的机制,所以关注点从splitDAO函数开始。

splitDAO会创建childDAO(如果不存在的话),将分裂者拥有的Ether转入childDAO中,支付任何孽生的Reward(目前应该是0)然后返回。

根据白皮书的设计,splitDAO的本意是要保护投票中处于弱势地位的少数派防止他们被多数派通过投票的方式合法剥削。通过分裂出一个小规模的DAO,给予他们一个用脚投票的机制,同时仍然确保他们可以获取分裂前进行的对外资助产生的可能收益。

但通往地狱的道路就这样用鲜花铺就了。

根据BLOG 2,在DAO.sol中,function splitDAO函数有这样一行:

Snip20160618_137

合约中,为msg.sender记录的dao币余额归零、扣减dao币总量totalSupply等等都发生在将发回msg.sender之后,这里是博主在Blog 1中指出的一个典型“反模式”。

接下来看withdrawRewardFor函数。目前github中所见最新代码并非部署于Ethereum livenet的代码,出问题的代码博主说是这样:

Snip20160618_139

paidOut[_account] += reward 在原来代码里面放在payOut函数调用之后,最新github代码中被移到了payOut之前。
再看payOut函数调用。rewardAccount的类型是ManagedAccount,在ManagedAccount.sol中可以看到:

Snip20160618_140

注意标深的这一行:对_recipient发出call调用,转账_amount个Wei,call调用默认会使用当前剩余的所有gas,此时call调用所执行的代码步骤数可能很多,基本只受攻击者所发消息的可用的gas限制。
把这些拼起来,黑客的攻击手法就浮现了:
1) 准备工作

黑客创建自己的黑客合约HC,该合约带有一个匿名的fallback函数。根据solidity的规范,fallback函数将在HC收到Ether(不带data)时自动执行。此fallback函数将通过递归触发对THE DAO的splitDAO函数的多次调用(但不会次数太多以避免gas不够),过程中还应该需要记录当前调用深度以控制堆栈使用情况。

2) 开始攻击
黑客向THE DAO多次提交split proposal,并将每个proposal的recipient地址都设定为HC地址,同时设定适当的gasLimit。调用栈就会这样:

Snip20160618_140
提交split proposal
—> splitDAO函数(No. 1)
—> withdrawRewardFor函数 (No. 1,黑客的dao余额和dao总量此时没变!)
—> papOut 函数(No. 1,向HC发送以太第一次)
—> HC的fallback函数 (No. 1)
—->如果递归未达预设深度:调用split DAO函数(No. 2)
—> withdrawRewardFor函数(No. 2, 黑客dao余额等仍然没变!)
—> payOut函数(No. 2, 向HC发送以太第二次)
—> HC的fallback函数 (No. 2)
—> (继续递归)

3) 转款走人
转入childDAO的钱在一定时间后根据原合约可以提取,黑客收割韭菜的时候到了。

二、防范和思考

从代码看,本次攻击得逞的因素有二:一是dao余额扣减和Ether转账这两步操作的顺序有误,二是不受限制地执行未知代码。

应用代码顺序方面,应先扣减dao的余额再转账Ether,因为dao的余额检查作为转账Ether的先决条件,要求dao的余额状况必须能够及时反映最新状况。在问题代码实现中,尽管最深的递归返回并成功扣减黑客的dao余额,但此时对黑客dao余额的扣减已经无济于事,因为其上各层递归调用中余额检查都已成功告终,已经不会再有机会判断最新余额了。

不受限制地执行未知代码方面,虽然黑客当前是利用了solidity提供的匿名fallback函数,但这种对未知代码的执行原则上可以发生在更多场景下,因为合约之间的消息传递完全类似于面向对象程序开发中的方法调用,而提供接口等待回调是设计模式中常见的手法,所以完全有可能执行一个未知的普通函数。

类似黑客事件不限于以太坊,很可能未来会在rootstock等平台上重演。这是因为本次漏洞属于应用层面,并不是以太坊本身的问题,甚至都不能归咎于“图灵完备”,因为这种攻击即使在一个非图灵完备的平台上也可以奏效。总的来说,应用越复杂,应用出现安全问题的概率就越高。

本次黑客事件带给我们很多思考:在TRUST MACHINE上是否应该信任未知代码?去中心化系统是否应该在设计之初就加入应急干预代码以备“临时停牌”?出现问题后在舆情掌控、信息公开等方面是否应该存在预案?项目在上线之前是否应该经过更长时间的社区审视和测试?

本次黑客事件不意味着以太坊乃至去中心化、区块链的终结。虽然教训深刻,但如果能够汲取教训,那么从中获益的不仅仅是THE DAO, 以太坊,整个区块链社区都将从中获益。

上一篇: 永恒之链:用微信在区块链上刻字项目技术详解
下一篇: 详解最近大热的闪电网络、雷电网络和CORDA
推荐专栏
web3首席知识博主
一位相信价值投资的币圈KOL。稳定盈利的缠论野生交易员 #BTC行情分析师 #价值投资 #链上数据分析
爱Web 3,爱生活,爱科技,爱炒币的老韭菜
热门币种
更多
币种
价格
24H涨跌幅
BTC比特币
¥264,810.46
37,103.37 USDT
+0.1%
ETH以太坊
¥14,413.37
2,019.50 USDT
0%
USDT泰达币
¥7.20
1.01 USDT
0%
BNB币安币
¥1,629.54
228.32 USDT
+0.63%
XRP瑞波币
¥4.32
0.60480 USDT
+0.45%
USDC
¥7.14
1.00 USDT
+0.04%
SOLSolana
¥400.45
56.11 USDT
+1.59%
OKBOK币
¥399.37
55.96 USDT
-1.23%
ADA艾达币
¥2.67
0.37480 USDT
-1.32%
DOGE狗狗币
¥0.55330
0.07753 USDT
-1.01%
热搜币种
更多
币种
价格
24H涨跌幅
Terra Classic
¥0.00
9.481E-5 USDT
-18.15%
Gala
¥0.18
0.025383 USDT
-4.86%
dYdX
¥22.63
3.1984 USDT
-0.73%
比特股
¥0.05
0.006569 USDT
-1.93%
PancakeSwap
¥15.60
2.2054 USDT
-2.16%
Conflux
¥1.08
0.1531 USDT
-2.36%
Filecoin
¥31.55
4.4597 USDT
-0.5%
FTX Token
¥29.65
4.1911 USDT
+15.24%
Yield Guild Games
¥2.56
0.3615 USDT
-0.55%
Shiba Inu
¥0.00
8.15E-6 USDT
-2.16%
比特币
¥262,467.38
37103.37 USDT
+0.1%
比原链
¥0.07
0.010022 USDT
-4.68%
最新快讯
更多
汇丰、恒生、渣打、富邦华一四家外资银行入围首批“数字人民币”业务试点名单
2023-11-28 19:06:57
摩根大通和Apollo计划建立代币化“企业主网”
2023-11-28 19:03:57
Nansen2公测版本上线,新增链上数据异动、智能搜索等功能
2023-11-28 18:59:52
西班牙公民需在明年3月底前申报其海外平台上加密货币持仓
2023-11-28 18:53:43
Nansen2已公开测试
2023-11-28 18:53:38
dYdX基金会:主网启动以来超过1645万DYDX被质押
2023-11-28 18:52:07
NicCarter等比特币倡导者发文:比特币挖矿是清洁能源和平衡电网的关键工具
2023-11-28 18:47:58
下载币界网APP