摘要:我们知道,很多PoS加密货币,其实是比特币代码库的分叉(或者至少是其后代),关键的区别在于,它们用币的所有权证明(PoS)取代了比特币的工作量证明(PoW)。然而,一些设计思想被不安全地复制,导致这些币种出现了一些新的漏洞,而它们在比特币父代码库中是不存在的。
权益证明(PoS)加密货币,尤其是基于PoSv3(第三版本PoS)的那些币种,它们和比特币是很相似的,因为它们使用的是UTXO模型和最长链共识规则。关键的区别在于,它们用币的所有权证明取代了工作量证明(PoW)。
PoS机制的潜在好处包括减少环境影响,以及更好地抵御51%攻击。事实上,很多PoS加密货币是比特币代码库的分叉(或者至少是其后代),然后植入了PoS机制。然而,一些设计思想被不安全地复制,导致这些币种出现了一些新的漏洞,而它们在比特币父代码库中是不存在的。
我们将这些漏洞称为“伪造权益”攻击。本质上,它们之所以起作用,是因为PoSv3实现在提交宝贵的资源(磁盘和RAM)之前没有充分验证网络数据。其结果是,没有太多权益(币)的攻击者(在某些情况下甚至不需要币)可通过伪造数据填充受害者的磁盘或RAM,来导致其节点崩溃。我们认为,所有基于UTXO和最长链PoS模型的加密货币都很容易受到这种“伪造权益”攻击。本文的最后,列出了经研究人员调查并被认为会受影响的加密货币列表。
背景
在深入研究这些漏洞的细节之前,我们先介绍一下基于PoS机制的链是如何工作的。
PoS挖矿:
与工作量证明(PoW)挖矿类似,PoS中的挖矿也包含比较区块头的哈希值和难度目标。PoS的高层次目标是确保每个利益相关者挖掘下一个区块的机会与他们持有的token数量成正比。为了实现这一点,在基于PoS的区块链中,哈希不仅取决于区块头,还取决于利益相关者插入区块中的特殊“CoinShare”交易中包含的币数量。关于PoS挖矿的完整细节,你可以在Earlz的博客文章中找到一个详尽的解释。对于这篇文章,重要的是检查PoS取决于1)coinstake交易,
2)以及被coinstake交易所使用的UTXO。
工作量证明(PoW)在保护区块验证资源方面的作用:
众所周知,PoW在比特币共识中起着至关重要的作用。但是,PoW也起到了第二个不太被重视的作用:即保护对节点有限资源(如磁盘、带宽、内存和CPU)的访问。在无许可的加密货币网络中,对等节点不需要信任。因此,为了防止资源耗尽攻击,比特币节点在提交更多资源(如将区块存储在RAM或磁盘上)之前,首先会检查PoW是否有任何接收到的区块。然而,事实证明,检查PoS比验证PoW要更复杂,其对环境也更加敏感。因此,很多基于PoS的链实现,忽略了适当的验证。
为了理解这是如何导致资源耗尽漏洞的,我们必须在验证之前提供一些关于如何存储区块的详细信息。一个节点不仅必须在当前时刻跟踪最长链,还必须跟踪链的分叉数(其中任何一个都可能会成为最长链,在这种情况下,节点需要“重新组合”才能切换到它)。这可能发生,例如,在一次拙劣升级、一次双花攻击(等51%攻击)或在一次临时网络分区期间。
验证这些脱离主链的区块是困难的。要完全验证这些区块,你需要前一区块时间的一组未用币(UTXO)。比特币将UTXO集保留在了最佳链的当前尖端,而不是在过去的其他区块。有两种主要方法可以完全验证分叉上的区块:1.“回滚”当前视图(UTXO集)到分叉开始前的点
2.或存储所有早期区块的UTXO集副本。
在将区块存储到磁盘之前,比特币代码库根据PoW执行一些初步验证(但忽略交易)。此初步检查仅依赖于前一个区块头和当前区块头,因此节点可以非常快速地执行此操作。这是一个有效的防御,因为其生成有效的POW,通过它是非常昂贵的。也就是说,虽然我们可欺骗比特币节点在磁盘上存储一个无效的区块,但进行这样的资源耗尽攻击,其代价是非常昂贵的。
PoS中类似的初步检查,是验证coinstake交易,并检查与当前一个区块的内核进行哈希时,它是否通过难度目标。计算coinstake交易的哈希是很容易的,而困难的部分是检查coinstake交易的输入UTXO是否有效和未使用,因为这需要检查UTXO集,正如前面提到的,该集对于过去的区块是不可用的。由于完全验证coinstake交易是困难的,大多数基于PoS机制的链提供了启发式或近似检查。结果表明,这些近似值往往不充分,可被加以利用。
漏洞1:不需要权益的攻击
当我们第一次调查这个问题时,我们发现有5种加密货币:Qtum(量子链)、Particl、Navcoin、HTMLcoin以及Emercoin表现出这一漏洞的相当轻微的形式:即在将区块提交到RAM或磁盘之前,它们根本没有检查任何coinshare交易。这五种加密货币的共同点是,它们采用了比特币的“区块头优先”功能,其中,区块传播被分成两条单独的消息,即区块和区块头。节点只有在区块头通过PoW检查才会请求区块,而它是最长(或更长)链。由于coinstake交易只存在于区块当中,而不存在区块头中,因此节点无法单独验证区块头。相反,它直接将区块头存储到内存中的数据结构(mapBlockIndex)。因此,任何网络攻击者,即使他们不持有币,也可以填满受害者节点的RAM。
这种攻击的第二种变体,可针对相同的代码库执行,尽管它的工作方式略有不同,且目标是不同的资源(即受害者的磁盘而非RAM)。有争议的是,涉及磁盘的攻击对受害者更有害:如果RAM已满,节点崩溃,则只需重新启动即可。但是,如果磁盘已满,则需要手动干预(例如,运行外部脚本以清除磁盘上的过时区块)。
当接收区块而不是接收区块头时,会执行不同的初步检查。理想情况下,由于区块确实包含coinstake交易,因此节点软件应在将区块提交到磁盘之前检查这个coinstake交易。但是,如前所述,如果区块位于分叉上,那么节点无法轻松地访问coinstake交易所使用的UTXO。也许正因为这个原因,这些代码库并不能验证coinstake交易。
这些漏洞中的任何一个,都可以在不持有币的情况下对加密货币进行攻击。RAM版本的攻击相对微不足道,但出于技术原因,磁盘版本的攻击需要稍微多加小心。这些细节将在2019年的《金融密码学》上发表的一篇短文中加以解释。
漏洞2:伪造权益攻击
通过跟踪这些代码库的“血统”,我们注意到,在将比特币的“区块头优先”功能合并到PoSv3代码库的情况下,漏洞1就会被引入。攻击不适用于早期版本的PoS币(例如点点币),因为在磁盘上存储区块之前,还需要进行两次额外的初步检查:1.检查正在使用的输出是否存在于主链当中;
2.检查PoS内核哈希是否满足难度目标;
基于问题A,我们也找到了一种欺骗这类检查的方法,我们将这种微妙的攻击方法称为“花费权益攻击”。为了绕过检查1,我们使用了一个输出,该输出由节点看到,但已被占用。通常,为了绕过检查2,我们需要挖掘一个通过难度目标的有效区块,而这又需要大量的币。然而,事实证明,我们可利用不完全验证,使用我们称之为“权益放大”的技术生成任意数量的表观权益。
权益放大(StakeAmplification)技术
为了通过少量的权益实施攻击,攻击者必须放大其表观权益。表观权益是指总的候选权益输出,甚至是已花费的权益输出。如果攻击者以数量为k的UTXO开始,那么攻击者可以创建多笔交易,将币花回攻击者,如下图所示。只有UTXO(n+1)才允许进行权益增值(staking),但是由于上面的检查2,我们可以从1到n+1的所有UTXO进行权益增值,从而使表观权益增加为n*k。这增加了找到PoS区块的机会,因为攻击者可以继续这样做来增加其表观权益。具体过程如下图左侧的“权益放大步骤”所示。

权益放大和花费权益攻击
例如,即使在系统中只拥有0.01%的权益,攻击者也只需要通过5000笔交易来挖掘具有50%的表观权益权力的区块。在攻击者收集了大量表观权益之后,他可使用新收集的表观权益输出继续挖掘PoS区块,最后,攻击者用无效区块填充受害者对等节点的磁盘,如上图右侧所示。例如,攻击者可以从交易所购买一些PoS币,如我们所描述的那样通过自我花费扩大表观权益,然后将这些币卖给交易所,并在之后的任何时候执行攻击。攻击者唯一要付出的代价就是交易费用。
协调漏洞披露
我们首先在Particl和Qtum加密货币的背景下调查了漏洞代码库。