首页 > 世链号 > 【coinparking】币安被盗,再谈以太坊空账户 DoS 攻击事件
区块链日记  

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

摘要:近日来,币安被盗事件再次引发了大家对数字货币安全的关注。

01事件回顾:

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

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

02什么是空账户?

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

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

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

· 他们浪费存储空间

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

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

攻击方式:

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

(1)创建一个子合约

0000 PUSH32 0x6004600c60003960046000f3600035ff00000000000000000000000000000000

0021 PUSH1 0x00

0023 MSTORE

0024 PUSH1 0x20

0026 PUSH1 0x00

0028 PUSH1 0x00

002a CREATE

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

;; Child contract (in full)

PUSH1 0x00

CALLDATALOAD

SELFDESTRUCT

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

0000 PUSH32 0x6004600c60003960046000f3600035ff00000000000000000000000000000000

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

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

002b PUSH1 0x00

002d SLOAD

002e DUP1

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

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

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

0030 PUSH1 0x01

0032 ADD

0033 DUP1

0034 PUSH1 0x00

0036 MSTORE

0037 PUSH1 0x00

0039 DUP1

003a PUSH1 0x20

003c DUP2

003d DUP1

003e DUP8

003f PUSH1 0x06

0041 CALL

0042 POP

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

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

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

(4) 检查剩下的 Gas

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

0328 GAS

0329 PUSH2 0x6000

032c LT

032d PUSH3 0x00002f

0331 JUMPI

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

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

0332 PUSH1 0x00

0334 SSTORE

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

03谁会进行这种 DoS 攻击?

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

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

04以太坊的防御措施

阻止这样的攻击

调整 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 交易费的交易)

来源链接:mp.weixin.qq.com

免责声明
世链财经作为开放的信息发布平台,所有资讯仅代表作者个人观点,与世链财经无关。如文章、图片、音频或视频出现侵权、违规及其他不当言论,请提供相关材料,发送到:2785592653@qq.com。
风险提示:本站所提供的资讯不代表任何投资暗示。投资有风险,入市须谨慎。
世链粉丝群:提供最新热点新闻,空投糖果、红包等福利,微信:juu3644。