当前位置:  首页 →区块链技术 →正文

PoS 加密货币存致命安全隐患,详解最新“虚假权益”攻击

2019-01-29 12:12:23 华尔街之狼

权益证明(PoS)加密货币,特别是那些与比特币类似的 PoSv3(Proof-of-Stake version 3:权益证明版本3)加密货币,基本上都使用了UTXO(Unspent Transaction Output:未消费交易输出)模型和最长链共识规则。所谓 UTXO,是指关联比特币地址的比特币金额集合,由于比特币系统中没有账户的概念,只有遍布全网区块链的未消费交易输出,本质上是一个包含数据和可执行代码的数据结构。UTXO 的基本单位是“聪”,“聪”是比特币的最小计量单位,一个比特币等于10^8 聪。一个 UTXO 被创建后就无法被分割,只能当做交易的输入被花费掉,花费后会产生新的 UTXO,这样周而复始地实现货币的价值转移。因此我们在比特币钱包看到的账户余额实际上是未消费交易输出聚合计算后的结果。

相比于“工作量证明”,权益证明的确有一些潜在优势,比如能耗较少不会影响环境、针对 51% 攻击也有更好的安全性。实际上,如今市场上的很多加密货币都是比特币代码库的分叉(或者是比特币的派生品)再嫁接了权益证明共识机制,但由于一些设计理念并没有被安全地复制,导致出现了一些原代码库里没有的新漏洞。

我们将这些被发现的漏洞称为“虚假权益”攻击,从本质上来说,这些漏洞是因为 PoSv3(权益证明版本3)实施的时候,在提交宝贵资源(磁盘和 RAM)之前无法充分验证网络数据,结果会造成一些没有太多权益 (在某些情况下甚至根本就没有权益)的攻击者可以通过制造虚假数据填充磁盘或 RAM,这样就会导致节点崩溃。我们认为,所有基于 UTXO 和最长链权益证明模式的加密互补都很容易受到这种“虚假权益”的攻击,而且会把本次调研中涉及潜在影响的加密货币清单列在文末。

PoS

另外在本文的其他部分,我们将会详细解释漏洞和攻击,以及他们会产生什么样的微妙后果。虽然事后看起来这个漏洞本身可能并不复杂,但是想要完全解决这个问题其实很棘手,而且目前所采取的缓解措施还存在导致区块链分叉的风险(后面会详细介绍)。

在深入了解“虚假权益”漏洞的细节之前,我们先介绍一下权益证明的运作方式。

 

权益证明挖矿

与工作量证明挖矿类似,权益证明挖矿业包括了区块头哈希值和难度目标(注:难度目标是使整个网络的计算力大致每 10 分钟产生一个区块所需要的难度数值)。权益证明的高级目标是确保每个利益相关者挖掘下一个区块的机会,与他们持控制的加密货币数量成正比。为了实现这一点,在权益证明共识机制中,哈希值不仅取决于区块头,还取决于利益相关者在区块中插入的包含在一个特殊“coinstake”交易中的代币数量。

“Coinstake” 是权益证明创始人 Sunny King 专门设计的一种特殊交易,它借鉴了比特币创始人“中本聪”的 Coinbase 设计,本质上两者都是一笔“交易”,只是对各自的输入和输出做了一些硬性限制:

  • Coinbase 结构要求输入数量必须等于 1,且输入的 Prevout 字段(指定前一笔交易的输出)必须置空值,而输出数量必须大于等于 1;
  • Coinstake 结构要求输入数量大于等于 1,且第一个输入的 Prevout 字段不能为空,即要求 Kernel 必须存在,输出数量大于等于 2,且第一个输出必须置空值。

另外,这两种特殊交易对于在区块链中存放的位置也有特殊要求,中本聪规定每个区块的第一笔交易必须放置Coinbase,这也意味着 Coinbase 不能出现在区块的其他位置。Sunny King 显然不想破坏这个规则,但他增加了一条规则,对于“权益证明”区块第二笔交易必须放置 Coinstake,这么一来同样意味着 Coinstake 不能出现在区块链上的其他地方。换言之,只要第二笔交易是 Coinstake,那么这个区块就需要当做权益证明区块来处理。

权益证明挖矿涉及的细节问题很多,在此就不一一赘述了,我们暂时把重点研究放在了以下两方面:

1、Coinstake 交易

2、Coinstake 交易所花费的 UTXO(未消费交易输出)。

 

在保护区块验证资源中工作量证明所扮演的角色

众所周知,虽然工作量证明在比特币共识中起到了至关重要的作用,但与磁盘、带宽、内存和CPU相关的一系列问题也导致了它并不是非常受欢迎。在去中心化的加密货币网路中,交易的前提其实并不是基于信任的,因此为了防止资源耗尽攻击(resource exhaustion attacks),比特币节点在提交更多资源(比如将区块存储在 RAM 或磁盘上)之前首先要用工作量证明机制检查所有交易接收区块。然而事实证明,使用权益证明检查区块要比工作量证明复杂得多,而且这种共识机制对语义环境敏感(context-sensitive,或上下文敏感),因此很多权益证明在实施验证的时候其实是非常“吝啬”的。

在了解如何导致资源耗尽漏洞之前,我们必须先详细解释一下区块在验证之前是如何被存储的。事实上,区块链节点不仅要追踪当前时刻的最长链,还要追踪一整个分叉链树(a tree of fork chains),因为它们中的任何一个都有可能成为最长链,此时区块链节点需要进行“重组”才能切换到最长链上,例如在没有准备充分的升级、双重支出攻击(比如以太坊经典遭受51%攻击)、或是临时网络分区的时候,区块链“重组”这种情况就有可能发生。

在这种情况下,验证这些“非主链”上的区块是非常困难的一件事。如果你想要完全验证区块,就需要获得前一区块当前时间点的所有未消费交易输出(UTXO)的集合。比特币会将未消费交易输出集合保持在最佳链的当前装顶端(tip),但是分叉区块链上的区块可能并不会这么按照比特币这种做法。一个分叉上的区块想要得到完全验证,有两个主要方法:

1、“回滚”当前视图(未消费交易输出集合)到分叉之前的点;或者,

2、存储所有早期区块的未消费交易数据集合副本。

比特币代码库不支持第二种方法,即使能这么做也会增加额外的存储成本(比特币节点性能依赖于不断“修剪”不需要的数据)。而第一种方式正是比特币代码库当前处理重组的方式,但这种处理方法的成本可能非常昂贵,因此当分叉链中的工作量证明量大于当前主区块链时,回滚和完全验证就会被推迟到最后时刻执行。因此,当节点第一次接收到不属于最长链的区块或标头时,就会跳过完整验证并将区块保存到本地存储。

再将区块存储到磁盘之前,比特币代码库会基于工作量证明执行一些初步验证,但此时会忽略交易。这个初步检查仅取决于前一个区块的区块头和当前区块的区块头,因此节点可以非常快速地执行此操作。这其实也是一种非常有效的防御,因为要完全执行一个有效的工作量证明通常非常昂贵,比如即便你欺骗比特币节点并在磁盘上存储了无效区块,但想用这种方式实现资源耗尽攻击的代价是非常昂贵的。

在权益证明中,类似的初步检查时验证 coinstake 交易,并检查它是否通过了前一个区块内核的难度目标。计算 coinstake 交易的算力很容易,真正困难的检查 coinstake 交易中输入的未消费交易数据是否有效,而且还是没有消费过的。如前所述,由于这个操作需要检查未消费交易数据集合,因此不适用于此前的区块。正是由于完全验证 coinstake 交易非常困难,所以大多数基于权益证明的区块链只是使用了“启发式”或是“近似”检查,结果显示,这些近似检查通常是不充分、并且可以被利用的。

 

漏洞一:“我不相信它不是权益”

当我们第一次调查这个问题的时候,就发现 Qtum、Particl、Navcoin、HTMLcoin 和 Emercoin 这五个加密货币存在相当简单的漏洞形式——即,在区块被提交到 RAM 或磁盘之前,这些加密货币很可能根本就没有检查任何 coinstake 交易。这五种加密货币的共同之处在于它们采用了比特币的“区块头为先”(headers first)功能,其中区块传播被分成了两个独立的消息,一个是区块,另一个是区块头。当区块头通过了工作量证明之后,节点仅询问区块是否是最长链。由于 coinstake 交易仅出现在区块、而不是区块头中,因此节点无法靠自己来验证区块头。相反,它会将一个区块头存储在一个内存数据结构(mapBlockIndex)。因此,任何网络攻击者,甚至是没有任何权益的攻击者,都可以填满潜在受攻击节点的 RAM。

这种攻击的第二种变体主要针对代码库,虽然它是以稍微不同的方式进行,而且针对的也是不同资源,但其攻击目标并不是 RAM,而是磁盘。可以说,涉及磁盘的攻击对受害节点的危害更大,如果 RAM 被填满并导致节点崩溃,只需简单重新启动即可;但是,如果磁盘已满,则需要手动干预,比如运行外部脚本以清除磁盘中的过时区块。

接收区块和接收区块头,需要执行不同的初步检查。理想情况下,由于区块确实包含了 coinstake 交易,因此节点软件应该在区块被提交给磁盘之前检查 coinstake 交易。但是如前文所述,如果区块在分叉链上,那么节点可能无法轻松访问 coinstake 交易所花费的未消费交易输出,也许出于这个原因,这些节点代码库可能不会去验证 coinstake 交易。

利用这些漏洞中的任何一个,都可以在没有任何权益的情况下影响加密货币。相比之下,对 RAM 的攻击可能影响程度较低一些,而从技术角度来看,攻击磁盘则需要稍微小心一点,而且也都没有任何权益要求。

 

漏洞二:消费权益攻击(Spent Stake Attack)

通过追踪这些代码库的谱系,我们注意到漏洞一最初是将比特币“区块头优先”功能合并到 PoSv3 代码库中。不过,该攻击不适用于早期版本(比如 Peercoin),因此在磁盘上存储区块之前还需要进行两个额外的初步检查:

1、检查所有的输出是否存在于主链中;

2、检查权益证明 Kernel Hash 是否符合难度目标要求。

第一个检查工作是通过交易数据库(TxDB)中查找完成的,该数据库可以追踪当前主链中到目前为止的所有交易。换句话说,初步验证总比完全不验证要好,但完全验证仍然无法做到,只能做到“启发式”和“近似”验证。如果延续这一思路进行解释的话,可能会衍生出另外两个问题:

  • 关注 A:第一个检查工作确保了代币是存在的,但无法确定这些代币是否是未消费的。这种情况会立即导致接下来讨论的另一个漏洞;
  • 关注 B:即使我们在主链的一个分叉链上验证一个区块,也会针对主链本身的交易数据库验证 coinstake 交易。

基于关注 A,我们找到了一种欺骗这些检查的手段,这种手段使用了一种更微妙的攻击,我们称之为“消费权益攻击”(spent stake attack)。为了绕过第一个检查,我们让节点看到一个输出,但其实该输出已经被消费(spent)了;而为了绕过第二个检查,我们需要先挖掘一个通过难度目标的有效区块,这么做可能需要你拥有很大数量的权益。然而事实证明,我们可以利用一些不完整的验证交易,然后采取一种被称为“权益放大”的技术就能生成任意数量的明显权益(apparent stake)。

 

权益放大

攻击者通常会从少量权益开始实施攻击,之后会不断扩大明显权益的数量,攻击规模也会因此不断扩大。明显权益是指网络候选人的总投入,甚至包括已经消费的权益。如果一个攻击者以数量为“k”的 UTXO(未消费交易输出)开始,之后该攻击者可以创建多个消费了该代币交易,如下图所示。理论上,只有 UTXO(n+1) 应该被允许用于权益证明,但现在我们能够把从 UTXO(1) 到 UTXO(n+1)都放置到,也就是说明显权益被放大了n*k倍。这么一来,就能让攻击者增加找到权益证明区块的机会,因为攻击者可以不断地采用上述手段增加自己的明显权益,下图左展示了“权益放大的步骤”。

权益放大的步骤

你会发现,即使你只有系统 0.01% 的权益,攻击者也只需要 5000 笔交易就能挖掘50%的明显权益区块。在攻击者收集了大量明显权益之后,就开始使用新收集的明显权益输出继续挖掘权益证明区块。最后,攻击者使用无效区块填充到受害节点的磁盘,如上图右所示。实际上,攻击者可以从加密货币交易所购买一些代币,然后通过上述手段扩大权益,接着再把这些代币卖回给交易所,并在之后执行攻击,他们唯一承担的成本就是一点点交易费用而已。

 

协调漏洞披露

我们首先调查了 Particl 和 Qtum 两个加密货币是否存在“漏洞一”,即这些加密货币在区块被提交到 RAM 或磁盘之前,到底有没有检查任何 coinstake 交易。为了确定该漏洞的影响程度,我们在 2018 年 8 月 9 日从 CoinMarketCap.com 上收集了按市值排序的已知加密货币列表,并且通过基于区块链权益证明共识类型进行了筛选。需要说明的是,我们只研究了代码库从比特币衍生分叉出的加密货币,一共检查了 26 个加密货币,发现有五个加密货币受到了漏洞影响,分别是 Qtum、Navcoin、HTMLcoin、Emercoin 和 Partickl,但我们的攻击似乎并不适用于其他的加密货币。

为了进一步确认漏洞,我们又在五个受影响的代码库中实施了攻击。我们利用比特币软件中现有的测试套件——特别是“ regtest ”模式,该模式支持模拟时间戳,而且很容易就能创建区块。此外,我们还基于比特币 TestFramework 构建了一个基于 Python 开发语言的测试节点,并允许它可以通过攻击者行为进行扩展。我们使用了 Docker 容器进行测试,同时还把之间的依存关系和受影响的特定提交算力(commit hash)打包到了一个可多次使用的工具包中,作为漏洞披露的一部分,我们可以轻松地把这些信息与所有五个受影响的开发团队共享。

然后我们进行了深入挖掘,以了解为什么没有受影响的加密货币不太容易受到第一个漏洞攻击的影响。此时我们发现,“漏洞二”问题同样严重,而且更为普遍。在规划协调披露漏洞的时候,我们发现,如果简单地告知一些经济活动较低、且不活跃的加密货币及其开发团队,效果可能会适得其反,因为如果漏洞被泄露出去,而相关加密货币开发团队部署解决措施的效率又比较低,那么这些加密货币就会受到攻击。最终,我们决定将注意力集中在最有可能受到攻击的加密货币身上——即市值前 200 名的加密货币中的 15 个,并与相关联的开发团队进行了沟通,让他们及时作出响应(包括 2018 年期间的一些提交活动)。

然而,这里还存在了一个比较“麻烦”的问题,就是大多数代码库没有使用“regtest”模式,因此我们无法直观地演示攻击、或是为每个代码库提供一个可多次使用的工具包。因此,我们只提供了 stratisX 的 C++ 代码库演示。基于代码库中的相似性,我们告知所有 15 个潜在受影响的加密货币开发团队——我们认为,他们的代币会收到漏洞攻击影响。其中,有 5 个加密货币开发团队承认了这个漏洞,3 个加密货币开发团队仍在调查,另外 3 个团队并不承认该漏洞(并指出如果实施一些升级改变可以缓解问题),4 个团队还没有给予任何回应。对于没有给予回复的 4 个团队,我们通过他们的网站找到了联系方式,并且在 GitHub 代码库里放了检查漏洞的可重复性工具包。

 

缓解措施

目前,我们已经看到一些加密货币开发团队开始针对本文中披露的漏洞实施一系列缓解措施了。那些实施了缓解措施的加密货币,不仅可以检测到漏洞攻击,而且还能断开违规的分叉链。简单来说,节点可以监视异常行为,比如某个分叉链上发送了大量区块头。

不过,这里依然存在一个难以解决的问题,即如何将实际攻击的“虚假权益”和合法重组的诚实节点区分开,因为某些缓解措施很可能存在错误地将诚实节点给禁止的风险。到目前为止,我们看到的一些缓解措施实施还是很合理的,但这还需要进一步调查分析,并观察后续效果。

还有一些加密货币的缓解措施是在一定长度内天井部分验证功能。如果一个分叉区块收到了超过主链上规定的长度,那么该区块就会被丢弃。举个例子,Bitcoin Cash ABC 代码库就采用了这个方法,他们每十个区块就会设置一个滚动检查点。但是这种方法也存在其他缺点,即存在“区块链分裂”的可能性。因为当越来越多诚实节点出现在区块链不同的分叉上的时候,就会发生区块链分裂。特别是当网络连接不良导致节点不同步,也没有足够长的时间来创建冲突检查点,也会导致出现“区块链分裂”的情况。即使节点重新获得连接,它们也无法达到区块链的公共视图(a common view of the chain)。

但关键是,我们注意到即使实施了这种缓解措施也存在“区块链分裂”的风险,因为如果使用当前链中的交易输出验证了 coinstake 交易,此时一个节点临时发现自己在一个分叉链上,很可能无法切换到真正的主链上。

“区块链分裂”风险还会为敌对矿工引入新的攻击媒介,攻击者可能会尝试秘密挖掘长链,然后将其发布到节点子集(a subset of the nodes)以导致区块链断裂。初始区块下载(Initial Block Download)中的节点、以及长时间离线刚刚重新启动的节点特别容易受到此类攻击,而且该攻击还可以和eclipse攻击相结合,将诚实节点“引入”到攻击者控制的区块链上。

因此你会发现,所有这些缓解措施只是让攻击难以执行,但却无法真正替代完全验证。据悉,包括 Qtum 在内的一些加密货币正计划在未来版本中对非主区块链上的区块进行完全验证。

当务之急,应该建议以下受影响的加密货币用户尽快在自己节点上更新最新的修补软件。此外,对于那些没有得到及时修补的加密货币节点,一定要注意本文提到的漏洞可能会导致 RAM 或磁盘消耗增加,最终导致崩溃。

下表是我们认为受到上述两个漏洞影响的加密货币列表,现阶段,我们尚未对全部加密货币(可能有上千个)验证相关漏洞,而且还没有检查那些声称不受漏洞影响的权益认证加密货币为何不受影响。

加密货币列表

最后的想法

虽然“虚假权益”攻击理论上看非常简单,但是它揭示了权益证明加密货币在设计上可能存在问题:一些在工作量证明中有意义的想法并没有被安全地转化为权益证明。鉴于比特币核心代码共享高度是 PoSv3 加密货币的“上一级分支”(upstream),我们认为这些权益证明加密货币应该受到更多审查。在调查这些漏洞的同事,我们还在不同代码库进行的工作和注释掉的代码中找了几个示例。对我们而言,这表明一些权益证明加密货币开发人员在设计加密货币的时候并没有完全理解这一共识机制。

一方面,我们希望尽快拒绝无效区块,提高区块链处理效率;但另一方面,我们又不希望在分叉的区块链上遭遇阻塞,继而影响、延迟主链上的实际交易,处理这个问题的系统解决方案仍然是当前工作组一个悬而未决的问题。

虽然我们已经看到这个漏洞最近已经至少影响了两个代码库(比如比特币中的 CVE 2018-17144),但据我们所知,就在我们首次协调、披露该安全漏洞的时候就发现有超过 20 个加密货币受到了影响,这个数字其实并不少。考虑到加密货币中普遍存在复制设计想法和代码重用的现象,我们预计未来会有更多这样的漏洞。

最后,我们发现大多数加密货币项目都没有安排专门负责项目安全的联系人,因此即便我们发现了安全漏洞也无法联系到他们。所以,我们在此呼吁建立一个协调披露的机制,这也可以使整个加密货币生态系统受益。

 

本文是由伊利诺伊大学厄巴纳-香槟分校(UIUC)旗下去中心化系统实验室(Decentralized Systems Lab)调研团队所撰写的“资源枯竭漏洞”(resource exhaustion vulnerabilities)研究报告,该团队成员包括 Sanket Kanjalkar、Yunqi Li、Yuguang Chen、Joseph Kuo、以及顾问 Andrew Miller。据悉,这些漏洞总共影响了超过 26 个基于权益证明的加密货币,网络攻击者只需要利用非常少的的“权益”(stake)就能让运行相应软件的任何一个网络节点崩溃。该研究团队从2018年10月开始启动调研工作的信息披露,旨在让潜在受影响的加密货币开发人员了解此事,其中大部分加密货币现在已经部署了缓解措施。

BB财经|BBcaijing.com原创,作者华尔街之狼,转载请注明出处:http://www.bbcaijing.cn/geek/48986.html