http://www.jyshunbo.com

药物与性健德堂“冰封”合约背后的老牌劲敌拒绝服务漏洞 | 漏洞解析连载之二


药物与性健德堂“冰封”合约背后的老牌劲敌拒绝服务漏洞 | 漏洞解析连载之二

安全,区块链领域举足轻重的话题,为什么一行代码能瞬间蒸发几十亿市值?合约底层函数的使用不当会引起哪些漏洞?在合约中发送以太币存在哪些风险?服务攻击DOS有哪些类型?

「区块链大本营」携手「链安科技」团队重磅推出「合约安全漏洞解析连载」,以讲故事的方式,带你回顾区块链安全走过的历程;分析漏洞背后的玄机。让开发者在趣味中学习,写出更加牢固的合约,且防患于未然。

当然,这些文章并不是专为开发者而作的,即使你不是开发者,当你读完本连载,相信再有安全问题爆出时,你会有全新的理解。

引子:秦人不暇自哀,而后人哀之;后人哀之而不鉴之,亦使后人而复哀后人也。

——《阿房宫赋》

DoS攻击重现区块链江湖 缜密防范助阵安全区阵营 

眼观目前区块链发展的步伐越来越急促,似乎我们已无暇回首当初那些辉煌与挫败,只能低着头继续跟从与追赶。

回首2016年的战场,似乎一切都已冰封,少有人记得这里发生过什么。

我们将当时的「拒绝服务攻击事件」挖掘出来,并将原理分析和漏洞修复技巧与大家分享,提醒要时刻牢记过去的教训。

事件回顾

2016年2月6日至8日The King of the Ether Throne(以下简称KotET)“纷争时代”(Turbulent Age)期间,许多游戏中的退位君王的补偿和未接受款项无法退回用户玩家的钱包[1] 。

具有讽刺意味的是同年6月,连庞氏骗局GovernMental的合约也遭遇DoS攻击,当时1100以太币是通过使用250万gas交易获得[2],这笔交易超出了合约能负荷的gas上限,带来交易活动的暂停。


药物与性健德堂“冰封”合约背后的老牌劲敌拒绝服务漏洞 | 漏洞解析连载之二

无论是蓄意破坏交易正常流程还是阻塞交易通道,都用到了一个互联网时代已经盛行已久的攻击方式——DoS,也就是我们所说的拒绝服务攻击。

这种攻击方式可以让合约执行的正常的交易操作被扰乱,中止,冻结,更严重的是让合约本身的逻辑无法运行。

何为DoS

DoS 是DenialOfService,拒绝服务的缩写[3],从字面上来理解,就是用户所需要的服务请求无法被系统处理。


药物与性健德堂“冰封”合约背后的老牌劲敌拒绝服务漏洞 | 漏洞解析连载之二

打个比方来形容DoS,火车站是为大家提供乘车服务的,如果想要DoS火车站的话,方法有很多,可以占用过道不上车,堵住售票点不付钱,阻挠列车员或者司机不让开车,甚至用破坏铁轨等更加极端的手段来影响车站服务的正常运营。

过去针对互联网的DoS有很多种方法,但基本分为三大类:利用软件实现的缺陷,利用协议的漏洞,利用资源压制[3]。

此外,还有DDoS,称为分布式DoS,其区别就是攻击者利用远程操控的计算机同时向目标发起进攻,在上面的比喻中可以理解为雇佣了几百个地痞流氓来做同样的事影响车站的运作。


药物与性健德堂“冰封”合约背后的老牌劲敌拒绝服务漏洞 | 漏洞解析连载之二

智能合约DoS攻击原理分析及其漏洞修复

无处不在的DoS当然也会对基于Solidity语言的以太坊合约产生威胁。

针对智能合约的DoS攻击属于利用协议漏洞进行的手段,具体的攻击方法有三种[4],其目的是使合约在一段时间或者永久无法正常运行。通过DoS攻击,可以使合约中的Ether永远无法提取出来,区块成为“冰冻废土”。


药物与性健德堂“冰封”合约背后的老牌劲敌拒绝服务漏洞 | 漏洞解析连载之二

在对原始代码进行分析后,我们发现KotET事件中对君王称号进行锁定的DoS攻击属于以下三种范畴。

1. 通过(Unexpected) Revert发动DoS

如果智能合约的状态改变依赖于外部函数执行的结果,又未对执行一直失败的情况做出防护,那么该智能合约就可能遭受DOS攻击[5]。

我们使用案例合约还原KotET的竞拍机制,进行模拟分析:


药物与性健德堂“冰封”合约背后的老牌劲敌拒绝服务漏洞 | 漏洞解析连载之二

以上案列合约是一个简化版的KotET的竞拍争夺王位的合约,如果当前交易的携带的Ether大于目前highestBid,那么highestBid所对应的Ether就退回给currentLeader,然后设置当前竞拍者为currentLeader,currentLeader改为msg.value。

但是,当恶意攻击者部署如下图所示的合约,并通过合约来竞拍,就会出现问题。


药物与性健德堂“冰封”合约背后的老牌劲敌拒绝服务漏洞 | 漏洞解析连载之二

攻击者先通过攻击合约向案例合约转账成为currentLeader,然后新的bider竞标的时候,执行到

require(currentLeader.send(highestBid))

会因为攻击合约的fallback()函数

(这里指function()external payable函数)

无法接收Ether而一直为false,最后攻击合约以较低的Ether赢得竞标。

漏洞修复

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