币安被盗,再谈以太坊空账户DoS攻击事件

事件回顾

近日来,币安被盗事件再次引发了大家对数字货币安全的关注。其实网络盗窃事件很普遍,并且引发了技术的不断升级。以太坊作为区块链2.0的代表,自从诞生以来就一直遭受各种攻击。为此,本文就以太坊空账户DoS攻击事件,来谈一谈以太坊如何在技术上保障安全。

以太坊在2016年9月份和10月份遭受一连串的DoS攻击,攻击者在以太坊网络内以非常低的成本创建了1900万个空账户。空帐户会浪费硬盘空间,增加同步时间并减慢处理时间,这导致了2016年10月的“EIP-150 Hard Fork”硬分叉。以及,11月的“Spurious Dragon”分叉对此攻击所造成的影响进行了进一步修复。

币安被盗,再谈以太坊空账户DoS攻击事件

什么是空账户?

空帐户是具有零余额,零常数和空代码的帐户(以太坊中每个账户都有一个常数,常数等于和这个帐号所相关的交易数)。空账户在功能上等同于不存在的账户,唯一的实际区别是,空账户需要存储在以太坊状态树中。空账户很容易产生,只需要你向一个不存在的账户发0个或者任意个以太坊,那个不存在的账户就会变成空账户。从理论上讲,如果矿工接受0交易手续费,甚至可以从空账户或者不存在的账户发送交易。

币安被盗,再谈以太坊空账户DoS攻击事件

在以太坊树中拥有1900万个空帐户有什么问题?

空账户会存储在以太坊状态树中

· 他们浪费存储空间

· 它们会增加同步时间,尤其是fast sync 和 warp sync.

· 它们减慢了事务处理速度,因为在RAM中存储大部分或全部状态变得更加困难,因此需要更多的磁盘访问。

攻击方式:

攻击者建立了一个母合约,这个智能合约被调用了4750次。这个母合约方法如下:

(1)创建一个子合约

0000 PUSH32 0x6004600c60003960046000f3600035ff00000000000000000000000000000000

0021 PUSH1 0×00

0023 MSTORE

0024 PUSH1 0×20

0026 PUSH1 0×00

0028 PUSH1 0×00

002a CREATE

这会在一个新地址上创建一个子合约。

;; Child contract (in full)

PUSH1 0×00

CALLDATALOAD

SELFDESTRUCT

子合约的代码在PUSH32里,即:

0000 PUSH32 0x6004600c60003960046000f3600035ff00000000000000000000000000000000

前面的12 bytes是构造子合约的函数,接下来的4 bytes是子合约的代码。

(2)在存储中加载一个计数器

002b PUSH1 0×00

002d SLOAD

002e DUP1

这将跟踪正在创建的空帐户,并允许后续调用母合约,从前一个停止的位置继续生成空账户。

(3)循环调用子合约的”自毁函数“40次

(以下代码会被循环40次)

0030 PUSH1 0×01

0032 ADD

0033 DUP1

0034 PUSH1 0×00

0036 MSTORE

0037 PUSH1 0×00

0039 DUP1

003a PUSH1 0×20

003c DUP2

003d DUP1

003e DUP8

003f PUSH1 0×06

0041 CALL

0042 POP

首先向计数器添加一,复制它,将一个副本放回内存,然后用计数器作为调用数据调用子合约。子合约将它发送的数据(计数器)解释为一个地址,当它自毁时,它将其(零)值发送到该地址,从而创建了一个空的帐户。

selfdestruct(address)“自毁函数“会将合约的余额转到指定地址address,”自毁函数“函数的Gas数很少,这个设计是为了鼓励人对不再使用的智能合约进行销毁,销毁后合约的状态会从状态存储中消失。当你不再使用一个合约,你调用“自毁函数“,比起调用Transfer将合约中的钱转出要更划算。

币安被盗,再谈以太坊空账户DoS攻击事件

这里的关键点是子合约在当前交易执行结束之前实际上不会自毁,因此可以在一个交易中多次调用它。 子合约在当前交易终止时被删除。 每次调用母合同时,会重新创建子合约,然后可以从内部多次调用它的”自毁函数“,最后被销毁。

(4) 检查剩下的Gas

如果有足够的Gas话, 再返回并重新遍历所有40个调用,并继续增加地址计数器。

0328 GAS

0329 PUSH2 0×6000

032c LT

032d PUSH3 0x00002f

0331 JUMPI

因此,每次对母合同的调用都能够创建数千个空账户,具体取决于最初供应的Gas量。

(5)存储计数器,为下一次调用中做准备

0332 PUSH1 0×00

0334 SSTORE

使用”自毁函数“创建账户,成本极低。

谁会进行这种DoS攻击?

网络协议存在着攻击机会,这是很常见的,现实世界中并没有人会去做,因为他们没有动力去利用这些攻击漏洞。可悲的是,我们担心会有人针对以太坊发动这样的攻击。

币安被盗,再谈以太坊空账户DoS攻击事件

最危险的群体是“griefers”,他们可能为了做空以太币,从而发动一次DoS攻击,为的就是让以太币的价格在短期内能够下跌。同样的,极端分子认为加密货币是一种零和游戏,他们也可能会参与破坏。当然,那些想要攻击以太坊矿工的人也可能会参与进来。因为在目前,这种攻击还没有什么成本,这些群体很可能会发动攻击。

以太坊的防御措施

  • 阻止这样的攻击

调整Gas用量,使“自毁函数”成本变高。以太坊进行了一次“EIP-150 Hard Fork”硬分叉。在2016年10月18日 23:19:31 2463000号块。除了其他的Gas量的调整以外,“自毁函数”调整成了5000 Gas(原本是0 Gas)。

  • 清除以前建立的空账户

随后,以太坊做了叫做“Spurious Dragon”的分叉。在2016年11月23日 01:15:44 2675000号块,这次分叉的相关改动是EIP 161 状态清扫, 为了清除以前建立的空账户。真正的清除账户的操作实际是在分叉之后进行的,空账号会在被某个交易“触碰”时自动删除。以太坊基金会会系统性的开始”CALL“这些因为攻击而生成的空账号以逐步完成清扫。

概括:当一笔交易“触及”一个“空账户”时,这个“空账户”会被删除。

  • 解释:

· “空账户”:如果帐户没有代码且常数为0和余额为0,则该帐户被视为空。(以太坊中每个账户都有一个常数,常数等于和这个帐号所相关的交易数)

· “触及”:当一个账户涉及到“状态改变”的操作时,被认为是被“触及”。这包括但不限于,被转入0个以太坊。

· 账户的“状态改变”:

o 当它是”SUICIDE”操作的目标或者退款地址时。(”SUICIDE”即后来的”selfdestruct”,因为自杀是一个沉重的主题,所以改成了自毁)

o 当它是”CALL”操作或 message-call的目标或者源时。

o 当它是”CREATE”操作或者合约创建操作的目标或者源时。

o 作为矿工,是区块奖励或者交易费的接受方时。

· 一个交易会在产生交易收据之前,立即执行自杀列表。因此,如果出现触及空账户的情况,空账户会被自杀掉。

事实上,目前的实现只需要跟踪四种情境:

· 一个空帐户,存在通过CALL传递给它的零值的交易;

· 一个空账户,存在通过SUICIDE传输给零值的交易;

· 一个空帐户,存在通过message-call交易传递给它的值为零;

· 一个空账户通过zero-gas-price fees 转账将零值转移给它。 (一般Gas Price设置为零的交易,矿工不会去挖,但矿工可能挖自己发送的0交易费的交易)



版权声明:

币安被盗,再谈以太坊空账户DoS攻击事件币安被盗,再谈以太坊空账户DoS攻击事件币安被盗,再谈以太坊空账户DoS攻击事件

作者保留权利。文章为作者独立观点,不代表巴比特立场。



发文时比特币价格

¥42880.15


本文来源于互联网:币安被盗,再谈以太坊空账户DoS攻击事件

原创文章,作者:酷毙编辑,如若转载,请注明出处:https://www.dailybtc.cn/%e5%b8%81%e5%ae%89%e8%a2%ab%e7%9b%97%ef%bc%8c%e5%86%8d%e8%b0%88%e4%bb%a5%e5%a4%aa%e5%9d%8a%e7%a9%ba%e8%b4%a6%e6%88%b7dos%e6%94%bb%e5%87%bb%e4%ba%8b%e4%bb%b6/

发表评论

电子邮件地址不会被公开。 必填项已用*标注

联系我们

在线咨询:点击这里给我发消息

邮件:[email protected]

工作时间:周一至周五,9:30-18:30,节假日休息

QR code