我们在前面进行了两讲公式机制(参考链接如下),在前文的讲述中,我们讲解了部分共识的具体流程以及优缺点。本文中,我们补充剩下的共识理念并分析其对应的优缺点。除此之外,我们针对相关的共识漏洞进行分析,为安全爱好者提供更多攻击的参考模型。
区块链安全—详谈共识攻击(一)
区块链安全—详谈共识攻击(二)
在介绍协议前,我们简单的介绍下瑞波的由来。简单来说,瑞波是一个基于互联网的全球开放的支付网络,人们可以通过该支付网络转账任意一种货币,交易确认时间很短,一般只需要几秒钟就能完成。所以此支付网络非常简便与快捷,所以交易费用接近于零。
瑞波共识协议(Ripple Consensus Protocol,RCP)中包括了特殊节点列表并基于此使一组节点达成共识。初始特殊节点列表就像一个俱乐部,如果俱乐部要接纳新成员,必须由俱乐部会员进行投票,一定比例的会员通过才允许接纳新会员。要接纳一个新成员需要该俱乐部51%的会员投票通过,并且外部成员对此没有任何影响力。由于该俱乐部有“中心化”特性,如果其开始腐化那么股东们则无法做任何事情。所以瑞波系统将股东们与其投票权利分隔开,并因此比其他系统更中心化。
在Ripple的共识算法中,参与投票节点的身份是事先知道的,因此,算法的效率比PoW等匿名共识算法要高效,交易的确认时间只需几秒钟。当然,这点也决定了该共识算法适用场景有限的缺陷。
在介绍协议前,我们先交代下其中的节点类型:瑞波共识包括以下几种节点类型:活跃信任节点、不活跃信任节点、验证节点。
下面我们具体的介绍一下RCP协议的具体内容:
①验证节点保存未经验证的交易。
在系统运行的过程中,验证节点会接受系统中发起的交易请求,并保存其在本地,之后等待共识。而在本轮共识过程中新到的交易需要等待,在下次共识时再确认。
②活跃信任节点将合法交易发送至验证节点。
根据我们上面的内容可知,RCP协议中存在“信任节点列表”的概念。而其是验证池中的一部分,其列表中的节点均来自验证池。而跟大多数协议相同,RCP共识机制要求参与共识的信任节点必须处于活跃的状态(否则无法进行下一步的操作)。而那些不活跃的节点将会被踢出列表。
在这里,信任列表中的节点也会收到系统中的各个TXs(交易),包括交易双方额度、交易历史等。之后会对交易进行判断,判定其交易是否合法,并将合法的交易打包成提议发送给验证节点。
③验证节点检验提议来源。
验证节点检查接收到的提议是否来自信任节点列表中的合法信任节点,如果是,则存储;如果不是,则丢弃。
在这里我们类似于将权利下放,将判定工作下放给员工(信任节点)来做。
④验证节点根据收到的提议确定出交易清单。
开始的时候,我们需要规定信任列表中的信任节点数量,例如M个。而我们需要规定交易的认可比例N。由此,验证节点就有其依据来判断交易是否可以被认可。当每一个超过M*N个信任节点认可的交易将会被验证节点认可。
例如M为10个节点,我们可以规定超过百分之60就可以添加为合法,即10×60%=6个节点
在验证节点本地需要生成认可交易列表。系统为验证节点设置一个计数器,当计数器时间到了之后验证节点就要向信任节点索要交易认可列表。
⑤账本共识达成。
验证节点接受信任节点的各种提议,并计算信任节点针对某个交易所提供的正确与否的消息。在此过程中,节点会持续更新认可交易列表。而
其次,验证节点认可列表的生成并不代表最终账本的形成以及共识的达成,账本共识只有在每笔交易都获得至少超过一定比例(例如 N%)的信任节点列表认可才能达成。
如果账本中每笔交易都获得超过比例N的信任节点认可,则共识达成,交易验证结束,否则继续上述过程。
⑥共识过程结束,形成最新账本。
共识过程结束后,已经形成最新的账本,将上轮剩余的待确认交易以及新交易纳入待确认交易列表,开始新一轮共识过程。
之后将账本发布,供系统中所有节点下载使用。
总结来说,协议分为以下几个过程:①系统中客户端进行交易、②验证节点接收并存储交易、③信任节点发送提议于验证节点、④验证节点验证列表、⑤达成账本共识并关闭账本
根据我们对协议具体内容的分析,我们知道瑞波协议就是易于遭受攻击,黑客可以伪造node,甚至可以大量扩散潜伏,并在某个时间突然攻击所有网络。
我们知道,应用此协议的系统能够做到将交易账本几秒钟部署应用到所有节点,效率十分高。所以用此来维护整个网络的有效性以及一致性十分合适。并且这点也决定了该共识算法只适合于权限链(Permissioned chain)的场景。Ripple共识算法的拜占庭容错(BFT)能力为(n-1)/5,即可以容忍整个网络中20%的节点出现拜占庭错误而不影响正确的共识。
而在整个社区中,共识一旦达成,当前的账本将会保存记录在此之前的所有交易信息,然后关闭成为最后的账本。在这个关闭的账本中所有网络节点维护都是相同的。
此算法在芯片制造商英特尔(Intel)创立之初就被拿来进行使用,由于其耗能十分低,所以乔布斯也曾将其应用于产品。它是一种算法,通常用于被许可的区块链网络来决定采矿权或网络上的块赢家。它是由英特尔构建在可信执行环境的一种彩票协议。核心是用intel支持SGX技术的CPU硬件,在受控安全环境(TEE)下随机产生一些延时,同时CPU从硬件级别证明延时的可信性,类似于彩票算法,谁的延时最低,谁将获取记账权。
而投票机制是基于CPU的数量,也就是说一个CPU只能进行一次投票。所以增加记账权的唯一方法就是多增加CPU的数量,具备了当初中本聪设想的一个CPU一票的可能,同时增加的CPU会提升整个系统的资源,变相实现了记账权与提供资源之间的正比例关系。
该算法要求网络中的每个参与节点在定时器上等待一个随机的时间量,第一个完成指定等待时间的节点为新块的赢家。网络上的每个节点基本上都是在随机产生的一段时间内进入睡眠状态,而第一个醒来的节点,也就是睡眠时间最短的节点,醒来时向区块链提交一个新的块。
下面我们详细介绍下此共识的大致思路:
1每一个节点均需要从enclave(代表一个可信操作)中获得一个随机的等待时间。
2拥有最短时间的备选人将被选为leader并率先发布块。
3enclave是通过新型的安全CPU指令来实现的。其包括两个函数“CreateTimer”、“CheckTimer”。第三步中使用CreateTimer
从enclave中产生一个timer。
4之后使用验证函数CheckTimer
去检验这个timer是不是由enclave产生、是否已经过期。
5如果满足了上述条件就会生成一个attestation凭证。其中包含的信息可以用来校验certificate是否由该encalve产生并已经等待了timer规定的时间。成为leader的概率与捐献的资源成正比。因为是通用处理器而不需要定制的矿机,所以参与门槛较低并且节点较多,整个共识机制更为健壮。
根据我们前文提及的知识,Pow由于其浪费资源的原因导致越来越多的区块链项目转变共识为Pos,所以在权益证明已经越来越受关注。而我们这次提及的攻击就是主要针对Pos共识的一种非常巨大的威胁攻击。由于其具有弱主观性并且能进行无代价模拟的特点,所以这种攻击带来的危害更大。
我们知道在区块链系统中,除了主链之外还存在许多与主链并行的其他分支链。而长程攻击就是攻击者创建了一条从创世区块开始的长区块链分支,并试图替换掉当前的合法主链。该分支上可能存有和主链不同的交易和区块,所以这种攻击又被称替换历史攻击或历史覆写攻击。而当保证金被解除绑定,激励不从某个高度区块前进行长距离投票就被取消了。换句话说就是当用户可以不受制裁的进行分叉链的创建时,就有可能导致分叉链超过主链从而代替主链的地位。
这里的弱主观性是针对新加入的节点而言。我们知道在系统中总会存在长期不在线或者新加入的节点。当这些节点回归系统或者加入系统后,我们需要为其提供创世区块。这个区块是独一无二被大家共识为首区块的区块。设置好创世区块后,节点接着就会收到当前区块链上所有公开的分支。然而此时问题就来了,作为萌新,新区块并不知道哪个是主链,哪个是分支。而对于离线很久的节点,它也并不知道在它离线的这些日子里主链成为了何模样。对于在线的节点而言,这种情况则不会出现。持在线状态的节点则总能及时地监控并同步主链。除非其它分支链篡位成功成为了合法主链,否则保持在线状态的节点不可能接受其他分支作为主链。
而我们为什么说Pos中存在这种类似的攻击而Pow中很少出现呢?
上图中红色为创世区块,而绿色为主链,其他颜色为分叉。
而整个区块链上的确有许多不同的分支,并且长度不一,主链可能是他们中任意的一支。
但是我们能发现,图中主链却十分好认。我们只需寻找最长链即可。
而对于Pow共识,由于在工作量证明区块链中需要现实的算力资源来生产区块,因此链长度可以有效地反映出分支上凝聚的工作量,最长链原则也就是说凝聚了最多工作量的分支便是主链。
也就是说,倘若系统使用的时Pow算法,那么除非遭受了51%攻击,否则不可能有其它从创世区块开始并与当前主链存在潜在竞争关系的分支链。那些攻击者倘若要想替换掉主链,那么它需要使自己的分支链达到相应的长度,这也是十分耗费算力的。所以对采取工作量证明协议的区块链,最长链原则已经足够解决弱主观性问题了。
由于Pos中依据的是无代价模拟的模式,所以最长链原则并不能成为判断主链的依据。
由于在权益证明区块链网络中没有矿工,所以也就不需要消耗算力来进行计算与挖矿。并且其系统基于对验证人进行信任,相信他们会诚实的对主链进行持续的投资、记账。
在Pos中,验证者仅仅是从交易池中取交易,打包到区块中,然后广播出去,仅此而已。所以说,无代价模拟就是几乎不消耗算力资源来创建一条从创世区块开始的长分支链的能力。
在任何区块链中,新加入的节点会收到许多条分支。在Pos系统中,其中大部分的分支长度是相同的。所以我们仅仅依凭最长链原则不足以判断哪一条是主链。长程攻击恰恰利用了权益证明协议区块链的这两个特点。
开始的时候我们先简单的介绍一下长城攻击中的简单攻击:在本例中,整个验证池中有三个验证者,A,B,C。简单起见,设定他们的初始持权数额均为 33.3% 。
权益证明协议区块链的简版,在这种场景下,节点不会去检查区块时间戳。
在权益证明协议正常的一轮周期内,每一个验证者都有机会验证区块(即出块)。
而创世区块中记录了验证者和它们各自的持权信息。A决定实施一次长程攻击,并且创建了一条分支链。她回溯到创世区块,开始生成她的分支链。
由于创世区块中保存了验证者的信息,所以攻击者就不能比主链更新的更快,所以最好的情况就是支链出块速度与主链一致。所以A只能提前产生区块。
上图中,下方为主链,而上方为A伪造的分支,此时分支与主链长度相同,也就是说成为主链的概率与主链一致。
之后A进行时间戳的伪造,并且由于A是这条分支链的唯一活跃持权验证人,这样做并没有什么风险。在不验证时间戳的权益证明协议区块链中,所有的分支链都是有效的。
我们假设时间戳已经无法被篡改,所以A需要在相同的时间内生成比主链更多的区块数量。但是这如何做到呢?
所以A想到利用B来帮助他生成。这时候就该引入一个名为验证者轮换的概念。
我们知道在权益证明系统中为了保证系统公平,验证者必须是轮换更替的。
验证者应当可以选择退出,并且区块链系统在某些情况下能轮换更替验证者或是把验证者移除出系统。
在这里,我们假设B在出块999个后选择退出了区块链系统。此时他的私钥也就没有往日那么重要了(因为他已经成为了一个平民)。
然而我们知道,虽然B退出了验证者这个位置,但是他的私钥仍然可以为999区块之前的区块签名,并且具有合法效应。
既然 Bob 在系统中没有任何质押的权益,他就没有任何负向激励不对区块链发动攻击。于是A可以盗取B的私钥,或者贿赂B,迫使B加入到攻击中。
当A得到了B的私钥,他就可以像B一样为区块进行签名,也就是说B帮助A更快速的生成了区块数量,用以赶超主链出块速度。我们称这样的攻击为变节攻击。
长程攻击的第三种类型被称为权益流损。
与上文中提到的内容一样,A作为主链的验证者同时他边记账边密谋从创始区块开始构建自己的分支链。由于验证者的初始信息在创世区块中早已经写好。所以在分支链没有超过主链长度之前,A不会讲分支链广播出去。
为了增加攻击的成功率,A开始主动拖延主链的正常运行速度。也就是说,倘若A的权益占比足够多,这种行为可能会演变为一次活性冻结攻击。每当 A 被选举为主链上的区块验证者时,她都会跳过该块,放弃自己的区块验证的身份。然而这并不会有其他验证者代替其工作,反而在该区块位置不会有新的区块加入到主链中。
然而这样会导致A不能从系统中获得区块验证奖励。但是A会不断从从主链上复制交易并在自己的分支链上广播出去。这样会增加其权益占比。
通过采用这样的策略,一方面拖延主链的出块速度,一方面在分支链上尽可能广播更多的区块,Malory最终可以在自己的分支链上获得绝大部分的权益,并且比主链更快地产生区块。一旦他的分支链长度超过了主链,他就将发布最后一笔交易,将自己的权益交易给其他的验证者,并且紧接着广播发布自己的分支链。
Prodigal Contracts 浪子合约是指交易资金因为漏洞返还给所有者、交易者过去发送给以太网的地址,以及特定地址。这种漏洞就像是空手套白狼,买家得到商品,而卖家无法得到加密货币。
合约可向攻击者指定地址发送以太币,而员工地址变量由于调用消息赋值的工资分发函数缺乏对调用者的检验而导致了资金返还,但是交易却产生了。
对于此漏洞的防御措施如下: 1. 消息发送者地址不在合约存储中且在合约中没有Ether。 2. 调用了CALL(且发生了Ether交换), DELEGATECALL或SUICIDE。所以要对此类函数进行严格的过滤措施。
智能合约的拥有者可以在以太坊发生故障时选择退回,类似于微信中的撤回选项。但是这个指令也可以被其他人执行,使得交易失败。
而引起此类漏洞的关键就是suicide函数,suicide函数可被攻击者调用 eg: 调用suicide前未检查调用者身份/授权用户列表可被修改。 如攻击函数库,可导致大量依赖合约异常。
而此类攻击的特征如下:执行代码中包含suicide,且消息发送者不在合约存储中。
本稿为原创稿件,转载请标明出处。谢谢。