原文:《以太坊系列(三) | “以太坊合并”之际,有哪些不可忽视的安全问题?》
*以下仅为安全技术研究,不构成投资建议,本文部分内容翻译自 jmcook.eth 发表在 mirror上的文章,详细内容可自行查阅。
今天是“以太坊大合并”系列的最后一篇,在前两篇,我们介绍了以太坊为什么会升级,以及以太坊会面临哪些监管问题和应用层问题。
本章节主要介绍以太坊合并使用 PoS 共识机制以后,可能面临的共识层面的攻击。
1、小型质押者的攻击
短程重组(Short range re-orgs)
这是一种针对信标链的攻击,该攻击通常由攻击者向其他验证者隐藏部分信息,然后在某个特定时刻发布,从而实现双花或通过 front-running 大额交易来提取MEV。这种攻击还可以扩展到多个区块,但成功的可能性会随着重组长度的增加而降低。
这种攻击本质上是一种区块重组,区块重组分为事前重组(ex ante reorg)和事后重组(ex post reorg)两种。其中,事前重组指的是在区块尚未被创建时,攻击者从主链中将其替换;事后重组则指的是攻击者删除主链中已经验证的区块。在PoS以太坊中,如果要进行事后重组必须拥有其超过2/3 的权益。同时有研究表明,即使攻击者拥有了以太坊65%的权益,攻击成功的机率也小于0.05%。
短程重组攻击是通过事前重组实现的,攻击者不需要控制以太坊中大多数质押的 ETH 就可以实现,且成功的机会会随着控制质押比例的增加而增加。
弹跳攻击和平衡攻击(Bouncing and Balancing)
平衡攻击(Bouncing and Balancing)攻击指的是攻击者采取特定手段,将诚实的验证者集合拆分为对区块持不同意见的离散小组。
具体地说,攻击者等待机会提出一个区块,当它到达时,他们会在同一个 slot 中提出两个区块。他们将一个区块发送给诚实验证者集的一半,将另一个区块发送给另一半。分叉选择算法将检测到这种冲突的情况,并且区块提议者会被罚没并从网络中弹出。但上述两个区块仍然存在,并且将有大约一半的验证者集证明其中的每一个分叉。
在花费单个验证者罚没成本的情况下,攻击者成功地将区块链一分为二。与此同时,其余的恶意验证者扣留了他们的证明。然后,在执行分叉选择算法时有选择地将有利于一个或另一个分叉的证明发布给足够的验证者,这使得他们能够生成任何一个具有最多累积证明的分叉。这可以无限期地继续下去,攻击者在两个分叉上保持验证者的平均分配。由于两个分叉都无法吸引 2/3 的绝对多数,所以信标链无法最终达成共识并出块。
这种攻击方式中,攻击验证者控制的质押权益比例越大,在任何给定 epoch 时间段进行攻击的可能性就越大,因为他们越有可能选择验证者在每个 slot 中提议一个区块。即使只控制 1% 的质押权益,发动平衡攻击的机会平均每 100 个 epoch 时期就会出现一次,这并不需要等待太久。
一种名为弹跳攻击(bouncing attack)的类似攻击方式,也只需要控制一小部分质押权益。在这种情况下,攻击者的验证者将拒绝投票。该方式中,攻击者没有发布投票来保持两个分叉之间的平均分配,而是在适当的时候使用他们的投票来证明在分叉 A 和分叉 B 之间交替的检查点的合理性。两个分叉之间的这种翻转,可停止最终确定性。
雪崩攻击(avalanche attacks)
2022 年 3 月的一篇论文描述了另一种称为雪崩攻击(avalanche attacks)的攻击类型。这篇论文的作者认为,提议者权重提升(proposer-weight boosting)方案无法防止雪崩攻击的某些变体。然而,论文作者也只展示了对以太坊分叉选择算法的高度理想化版本的攻击(他们使用了没有 LMD 的 GHOST)。其中,GHOST分叉选择算法会将第一个分叉区块和其对应的所有子孙区块所得票数累加,并选择其中得票数最多的分叉作为主链。
假设要发动一次雪崩攻击,前提条件是攻击者能够控制多个连续区块的提议者。当提议者针对 slot提议时,攻击者将扣留并收集他们的区块,直到扣留区块达到和主链区块相等的累加权重。然后,攻击者将释放被扣留的全部区块,此时由于主链和子链拥有相同的权重,使得区块链产生分叉,造成后续区块顺序混乱。例如,攻击者 扣留6个区块,第一个诚实区块n与第一个敌对区块n同时竞争,此时在系统中产生了一个分叉。然后攻击者将剩余的 5 个敌对区块全部都并行连接在第一个敌对区块后的 n+1 处。
具体如下图所示,由于GHOST分叉选择算法的特性,此时敌对区块n和其后的所有5个分叉和原链中6个区块累加的权重相等,这意味着系统中第7个区块有一定概率会选择连接在攻击者制造的分叉后。在这种情况下,攻击者可以对剩余的扣留区块重复此操作,阻止诚实的验证者继续跟随在证实主链后,直至攻击者用尽所有预留区块。如果攻击者在攻击过程中有更多机会提出区块,他们可以使用这些区块来扩展攻击,这样,越多的验证者参与共谋攻击,攻击持续的时间就越长,并且可以将更多诚实的区块从主链中移出。
图源自《Two Attacks On Proof-of-Stake GHOST/Ethereum》
而 LMD-GHOST 分叉选择算法的 LMD 部分减轻了雪崩攻击,LMD, 即“最后一条消息驱动”,指的是每个验证者保存的一个表格,其中包含从其他验证者收到的最新消息。只有当新消息来自比特定验证者表中已存在的 slot 更晚的 slot 时,该字段才会更新。在实践中,这意味着在每个 slot 中,接收到的第一条消息就是它接受的消息,其他消息将会忽略。换句话说,共识客户端使用来自每个验证者最先到达的消息,并且相互矛盾的消息会被简单地丢弃,以防止雪崩攻击。
长程攻击(long range attacks)
长程攻击也是一种权益证明(PoS)共识机制下特定的攻击方式,主要包含以下两种情况:
第一种情况是,攻击者作为参与创始区块的验证者,在原本的区块链旁维护一个单独的区块链分叉,并最终说服诚实的验证者在很久以后的某个时间点切换过去。但是该攻击在信标链上无法实现,因为“finality gadget”可确保所有验证者定期就诚实链的状态(“检查点”)达成一致,此后检查点之后的区块将无法再进行重组。
第二种情况是,当新节点加入网络时,将从离其最近的节点处获取信息(称为弱主观性检查点)作为伪创始区块构建区块链。这将为加入网络的新节点创建一个“信任网关”,然后其才能开始自己验证区块。然而,从区块浏览器等客户端收集构建检查点所需的可信区块信息,并不能增加客户端本身的可信度,因此主观性是“弱的”。因为根据定义,检查点由网络上的所有节点共享,所以不诚实的检查点是共识失败的状态。
2、大型质押者的攻击
33%
质押的ETH数量为33% 是攻击者的一个基准,如果其 超过了这个数量,他们就有能力阻止信标链最终确定,而无需精细控制其他验证者的操作。这是因为要最终确定信标链,必须有 2/3 的质押 ETH 来证明检查点对(pairs of checkpoints)。
如果 1/3 或更多的质押 ETH 被恶意证明或未能证明,那么 2/3 的绝对多数就不可能存在。对此的防御措施是信标链的消极惩罚(inactivity leak)机制,这是一种紧急安全措施,它会在信标链 4 个 epoch 后仍未能 finalize 时被触发。消极惩罚标识了那些未能证明或证明与大多数人相反的验证者。这些非证明验证者拥有的质押 ETH 会逐渐流失,直到最终它们占总数的比例不到 1/3,这样区块链才能再次finalize。
50%和51%
理论上,在一个恶意验证者控制的质押 ETH 比例达到 50% 的情况下,他可以将以太坊区块链分裂成两个大小相等的分叉。与前面描述的平衡攻击类似,攻击者可通过为同一个 slot 提出两个区块,然后只需使用其全部 50% 的质押权益与诚实的验证者集进行相反的投票,从而维持两个分叉并防止最终确定性。
在四个 epoch 之后,两个分叉上的消减惩罚(inactivity leak)机制将激活,因为每个分叉都会看到其一半的验证者无法证明。每个分叉都会消减验证者集的另一半质押权益,最终导致两条链都无法达到 2/3 的绝大多数验证者验证。在这一点上,唯一的选择就是依靠社区恢复。
而当攻击者控制的质押权益占到 51% 以上,则可以控制分叉选择算法。在这种情况下,攻击者将能够以多数投票作证,让他们有足够的控制权来进行短期重组,而无需欺骗诚实的客户端。控制 51% 的质押权益不允许攻击者改变历史,但他们有能力通过将多数投票应用于对其有利的分叉,或将区块重组来影响未来。
诚实的验证者会效仿,因为它们的分叉选择算法也会将攻击者选择的链视为最重链,因此该攻击链可以最终确定。这使攻击者能够审查某些交易,进行短程重组,并通过重新排序对其有利的区块来提取最大 MEV。针对该问题的防御手段就是多数质押权益的巨大成本,这会让攻击者会面临巨大的风险,因为社交层可能会介入,并采用诚实的少数派分叉,从而使攻击者的质押权益大幅消减。
66%
控制 66% 或更多比例质押 ETH 的攻击者可以确定其首选链,而无需控制其他诚实的验证者。攻击者可以对他们想要选择的分叉进行简单的投票,然后最终确定它。作为绝对多数的质押者,攻击者将始终控制最终区块的内容,其拥有花费、回滚和再次花费的权力,他还能审查某些交易并随意重组区块链,此时攻击者实际上拥有了事后重组和最终性反转的能力(即改变过去并控制未来)。而唯一的防御措施,就是通过社交层介入来协调采用替代分叉。
总的来说,尽管存在这些潜在的攻击向量,但信标链的风险很低,甚至要低于工作量证明的等效链。这是因为攻击者为了用投票权压倒诚实的验证者,需要将质押 ETH 的巨大成本置于风险之中。内置的“胡萝卜加大棒”激励层可以防止大多数的恶意行为,尤其是对于低质押的攻击者。更微妙的弹跳攻击和平衡攻击也不太可能成功,因为真实的网络条件使得很难实现对特定验证者子集的消息传递进行精细控制,并且客户端团队已经用简单的补丁快速修复了已知的弹跳攻击、平衡攻击以及雪崩攻击问题。
但34%、51% 或 66% 攻击可能需要社区进行投票解决,所以社区的有效治理对攻击者来说是一个强大的抑制因素。对于攻击者来说,一次技术上成功实现的攻击仍然存在被社区阻止的风险,这降低了攻击者获利的可能性,足以起到有效的威慑作用。这也是维持一个价值观一致的有效社区对于投资而言如此重要的原因。
3、ETH PoW 安全性
自以太坊成立以来,矿工一直在以太坊中扮演着重要角色,但以太坊的合并将打破这一局面。据 Bitpro 估计,GPU 矿工要想在合并后的加密生态系统中保持盈利,需要关闭大约95%的GPU 。但是如此多的GPU不太可能在合并后立即关闭,所以矿工可能在合并后试图进行PoW 分叉。事实上,目前确实已有一些矿工明确表示了对 ETHPoW 分叉的支持。而如果同时再有部分交易所也支持分叉,那么分叉的寿命将会比预期的更长。
此外,目前以太坊分叉项目 Ethereum Pow 官网已成立,且已开始有所动作:
2022 年 8月 15 日,以太坊分叉项目 Ethereum Pow 发推文称,ETHW Core 的初始版本已在 GitHub 上发布,主要特点是:1、禁用难度炸弹;2、EIP-1559变更,基础费用改为矿工和社区共同管理的多签钱包;3、调整了ETHW的起始挖矿难度。
2022 年 8 月 26 日,以太坊分叉项目 EthereumPoW 发推称,ETHW第一个测试网“冰山”发布。随之而来的是区块链浏览器和RPC服务器。我们欢迎社区中所有潜在的合作伙伴(交易所、资金池、钱包供应商、桥梁、建设者等)加入我们,共同构建一个真正的PoW驱动的以太坊生态系统。
那么,在以太坊合并升级后,出现的硬分叉 ETHPoW 可能会面临哪些安全问题呢,我们下面来详细分析。
1、算力攻击
51% 算力攻击是针对区块链网络的潜在攻击,当系统中恶意的单个实体或组织能够控制大部分,即全网超过51%的算力时,由于PoW算法中的共识由算力决定,这使得攻击者可以利用算力篡改账本,导致系统遭受恶意攻击。而在以太坊合并之后,无法再通过挖矿获取收益的矿工会关闭矿机,这导致基于 PoW 的 ETH 分叉可能会丢失部分算力,比如目前最大的矿池 Ethermine 已发布公告,将停止支持 ETH PoW 挖矿。
图源自ethermine.org
而一旦支持 ETHPoW 的算力下降,就会降低攻击者发动算力攻击的成本。则攻击者可以通过租用大量矿池算力,使得其算力达到51%以上,此时可以利用算力优势更快地生成区块,当生成的区块成为系统中最长的链时,就可以回滚区块交易,实现数据篡改,造成巨大危害,比如:双花、控制任意地址的交易等。下面将分别进行介绍:
双花
双花攻击是指攻击者企图重复花费自己账户所拥有的同一笔数字代币的攻击行为。举个例子:
假设A拥有51%的算力,在区块高度1000时,A转给B一个ETH,该转账交易被矿工打包。
待交易被确认后,A依靠51%的算力优势在区块高度999后重新生成了一条“更长的链”,并在区块高度1000处重新将该ETH转给C且该交易记录被打包,即该链包含了A将一个ETH转给C的记录。
根据“最长链共识”,包含给C转账记录的链成为主链,则A转给B的一个ETH则为“无效支付“。
控制任意地址的交易
如果拥有了51%的算力,则攻击者可以任意打包或者不打包某个地址的交易,也可以阻止区块确认任意交易,甚至阻止部分矿工获得有效的记账权,从而达到控制任意地址交易的目的。
但是,拥有51%的算力也不是万能的,比如无法修改其他人的交易记录,也不能阻止交易的发出,更不能凭空产生ETH。
2、重放攻击
传统计算机术语中,重放攻击(Replay Attacks)又称重播攻击、回放攻击,是指攻击者发送一个目标主机已接收过的数据包,来达到欺骗系统的目的。而在区块链领域,重放攻击通常出现在区块链硬分叉的时候,指的是“一条链上的交易在另一条链上也往往是合法的”。
2016 年 7 月 20 日晚,以太坊在第192万个区块高度发生了硬分叉,产生了两条链,分别称为ETH chain和ETH Classic chain,对应的代币分别为ETH和ETC。
由于这两条链上的地址和私钥相同,交易格式也完全相同,因此其中一条链上的交易在另一条链上也是完全合法的。所以你在其中一条链上发起的交易,将其放到另一条链上去重放,可能也会得到确认。由于事先没有做好预案,很多人利用这个漏洞,不断在交易所进行ETH充提操作,获取额外的ETC。至此, “重放攻击”得以在区块链世界被重新定义。
本次以太坊合并升级,大概率出现的硬分叉ETHPoW,理论上也可能存在上述的问题。
针对重放攻击,应该如何防范呢?其实对于以升级为目的的分叉而言很容易就能达到,因为硬分叉升级将采用不同的客户端版本,交易的前缀中通常包含有发起交易客户端的版本信息。分叉后矿工为了避免打包旧客户端的“非法交易”(并非恶意交易,仅仅只是版本号过低不被其他节点所承认),通常会拒绝一定版本号以前的交易,保证恶意攻击者很难在硬分叉升级时通过重放攻击窃取资金。
而在 2022 年 8 月 23 日,以太坊分叉项目 EthereumPoW 官方发文称,ETHW Core 发布第二次代码更新,强制执行 EIP-155。此次更新后,所有交易都必须使用链 ID 进行签名。这将保护 ETHW 用户免受来自 ETHPoS 和其他分叉 Token 的重放攻击。
这里简单介绍下 EIP-155 :
该提案名为“简单的重放攻击保护”。提案中规定:如果block.number >= FORK_BLKNUM并且CHAIN_ID是可用的,那么在计算交易的哈希以进行签名时,不是仅对之前的六个 rlp 编码元素(nonce, gasprice, startgas, to, value, data)进行哈希处理,而是应该对九个 rlp 编码元素(nonce, gasprice, startgas, to, value, data, chainid, 0, 0)进行哈希处理。此时,签名中的v 值不再是 recid , 而是 recid+ chainID*2+ 35。
因此,简单来说,在交易签名时,需要提供一个签名器(Signer)和私钥(PrivateKey)。需要Singer是因为在 EIP-155 修复简单重复攻击漏洞后,需要保持旧区块链的签名方式不变,但又需要提供新版本的签名方式。因此通过接口实现新旧签名方式,根据区块高度创建不同的签名器。而 EIP-155 中实现的新哈希算法,主要目的是获取交易用于签名的哈希值 TxSignHash。和旧方式相比,哈希计算中混入了链ID和两个空值。注意这个哈希值 TxSignHash 在EIP155中并不等同于交易哈希值。
图源自《区块链技术与实现》
如此一来,一笔已签名的交易就只可能属于某唯一确定的区块链。
此外,为了保证项目安全,建议项目方在合约中进行离线签名校验时,签名数据中应包含Chain ID,避免因跨链签名重用导致资产损失。
3、应用层项目
事实上,常规性的分叉是需要用算力做选择,选择的主角是矿工,而这次以太坊升级如果真的有两条以太坊链同时出现,需要作出选择的,是以太坊的整体生态,是其中的项目方,是用户,是投资者。
如今的以太坊与2016年硬分叉时相比早已今非昔比了,DeFi 项目已经占了以太坊生态的半壁江山,但 DeFi 项目的基础是链上的资产,所以项目方主要是跟着资产方走的。所谓资产方,是如 USDT、USDC 这种链上稳定资产,DeFi 的抵押借贷生态基本都是基于资产方的。
对于这些稳定资产(这里主要指稳定币)的发行方而言,如果以太坊网络分叉,他们就会突然面临一个危险的问题:出现两个版本的稳定币。作为稳定币的发行者,每发行一个稳定币,就会突然有两个债务义务。
虽然大多数人认为,稳定币发行方会把新的PoS链视为“真正的”以太坊网络,但如果他们想要支持PoW链呢?毕竟他们有足够的经济动机去做。
例如,他们可以做空 PoS 以太坊代币,在 PoW 网络上宣布赎回,然后大捞数十亿美元。这可能会破坏新的以太坊网络,导致贷款被清算,协议、交易所以及相关的额DeFi项目等被关闭。这将造成一场巨大的混乱,并可能大范围地摧毁加密货币市场。
同样,以太坊分叉项目 EthereumPow 8 月 17 日发推文称,ETHW Core将引入流动性池冻结技术保护用户资产,即在以太坊PoW硬分叉之后,特别是最初的几个区块,用户存放在流动性池中的ETHW代币,如Uniswap、Susiswap、Aave、Compound,将被黑客和科学家使用弃用的或没有价值的方式交换或借出USDT、USDC、WBTC ,这将对整个网络和社区造成巨大的混乱。因此,ETHW Core暂时冻结某些LP合约以保护用户的ETHW代币,直到协议的控制器或社区找到更好的归还用户资产的方法。冻结将不适用于仅涉及单一资产的质押合约(例如ETH2.0存款合约和Wrapped Ether)。ETHW Core建议每个人在硬分叉之前从LP(例如DEX和借贷协议)中提取他们的ETH。
参考文献:
《Ethereum PoS Attack and Defense》
https://mirror.xyz/jmcook.eth/YqHargbVWVNRQqQpVpzrqEQ8IqwNUJDIpwRP7SS5FXs
《什么是区块链上的重放攻击》
https://zhuanlan.zhihu.com/p/163121813
《区块链技术与实现》
https://learnblockchain.cn/books/geth/part3/sign-and-valid.html