干货分享:Qtum量子链开发者公开经典PoS协议的一个DoS攻击向量

2017-05-17 18:04 来源:巴比特资讯 阅读:7503
最近在Qtum量子链的开发过程中,我发现SCRIPT_VERIFY_ALLOW_EMPTY_SIG中的标识符字段并不是必填选项,这个漏洞可能会导致拒绝服务(DoS)攻击。

编者注:本文由Qtum联合创始人、核心开发者Jordan earlz撰写。Jordan earlz从13岁开始学习编程,具有18年开发经验,作为一名Coin Reviewer,他曾Review过社区100多种虚拟货币的设计。同时他也是一名安全专家,北美比特币社区最有名的开发者之一。以下观点仅代表Qtum量子链Jordan eaelz个人观点。

炸弹

最近在Qtum量子链的开发过程中,我发现SCRIPT_VERIFY_ALLOW_EMPTY_SIG中的标识符字段并不是必填选项,这个漏洞可能会导致拒绝服务(DoS)攻击。由于这个字段是非必填字段,因此用户可以创建一个无效交易而不会触发DoS禁令。利用这个漏洞,攻击者可以创建一个昂贵的交易并提交验证,然后提交empty push和checksigverify操作,从而验证一个空的签名。这样系统返回一个错误信息,该交易也被认定为无效交易,以此同时该区块也是无效区块。此外,代码结构会导致对昂贵的交易进行两次评估验证。

方法:

创建不含vout的non-standard交易

[pubkey]

DUP

TOALTSTACK

OVER

TOALTSTACK

CHECKSIG -should be valid and return true

DROP –drop result

FROMALTSTACK

FROMALTSTACK

SWAP

— 无限重复这个过程,直至达到sigop的上限值

[empty push]

[pubkey]

CHECKSIG

1- 将1推入栈,是交易输出变为可花费的

Mine into a block (non-standard so you would have to do it yourself probably)

更改源代码,使CHECKSIG返回真值,但不进行编码验证等

Finally, mine/stake a block which spends the previous vout (vin should be valid signature for pubkey)

最后,当前区块使用上一个区块的输出值(vin应该是pubkey的有效签名)

由于最后的empty push签名,因此该区块将被认为是无效区块,而这会触发main.cpp:1328的代码

// Verify signature

if (!VerifySignature(txPrev, *this, i, flags, 0))

{

if (flags & STANDARD_NOT_MANDATORY_VERIFY_FLAGS) {

// Check whether the failure was caused by a

// non-mandatory script verification check, such as

// non-null dummy arguments;

// if so, don’t trigger DoS protection to

// avoid splitting the network between upgraded and

// non-upgraded nodes.

if (VerifySignature(txPrev, *this, i, flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, 0))

return error(“ConnectInputs() : %s non-mandatory VerifySignature failed”, GetHash().ToString());

}

我认为script.cpp应该返回不同的操作结果:

case OP_CHECKSIG:

case OP_CHECKSIGVERIFY:

{

// (sig pubkey — bool)

if (stack.size() < 2)

return false;

valtype& vchSig    = stacktop(-2);

valtype& vchPubKey = stacktop(-1);

// Subset of script starting at the most recent codeseparator

CScript scriptCode(pbegincodehash, pend);

// Drop the signature, since there’s no way for a signature to sign itself

scriptCode.FindAndDelete(CScript(vchSig));

if ((flags & SCRIPT_VERIFY_STRICTENC) && (!CheckSignatureEncoding(vchSig, flags) || !CheckPubKeyEncoding(vchPubKey)))

return false; //HERE, it fails the script in the first execution, but not in the second

bool fSuccess = CheckSignatureEncoding(vchSig, flags) && CheckPubKeyEncoding(vchPubKey) &&

CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType, flags);针对共识机制的常见攻击向量:

图

 在本节中,我们总结了共识机制可能会面临的各种攻击向量。通常来说,常见的针对网络层和共识协议层面的攻击有拒绝服务攻击(DoS女巫攻击(Sybil Attack。拒绝服务攻击通过向节点发送大量的数据(比如发送大量的小额交易请求从而导致系统无法处理正常的交易)导致节点无法处理正常的数据。女巫攻击则是通过控制网络中大部分节点来削弱正确数据冗余备份的作用。

在PoW共识机制中,矿工会立即向全网播报新发现的区块。而在Selfish Mining攻击中,行为不端的矿工会通过以下方式浪费计算资源:当其发现新的有效区块时,并不立即向全网播报,而是继续进行挖矿,并尝试在其他矿工挖到新区块之前挖到更多的区块;当其他矿工挖到有效区块时,攻击者便立即向全网播报之前持有的有效区块。但一些研究人员认为,在实际操作中实现这种攻击并非易事。

Short-range攻击中,攻击者通过控制一定比例的、保障系统安全性的各种资源(如计算资源、加密货币资源等)从而实现在执行交易(如花费代币或执行智能合约)后将其回滚(从而进行双花攻击,也就是将一个加密货币进行多次花费)。当攻击者发起short-range攻击时,首先向全网提交一个待回滚的交易,并在上一个区块的分叉上(不包含待回滚交易的分叉)继续进行挖矿,直到该交易得到n个区块确认信息。若分叉上的区块数多于n,则攻击者公布包含有待回滚交易的区块。这样,由于分叉链的长度大于原本的主链,则全网节点将分叉链视为主链。此时,交易得到回滚。

Long-range攻击中,攻击者通过控制一定比例的系统资源,在历史区块、甚至是创始区块上对区块链主链进行分叉,旨在获取更多的区块奖励和/或者达到回滚交易的目的。这种攻击更多的是针对基于权益证明共识机制的系统。即使攻击者可能在分叉出现时仅持有一小部分的代币,但他可以在分叉上自由地进行代币的交易,从而导致攻击者能够更加容易地进行造币并快速的形成一条更长的区块链。

反观基于PoS共识机制的系统中,攻击者可以利用币龄计算节点权益,并通过总消耗的币龄确定有效的区块链。未花费交易输出(UTXO)的币龄是根据币龄乘以该区块之前的历史区块的数量得出(比如后面章节会介绍的点点币)。在币龄累计攻击中,攻击者将其持有的代币分散至不同的UTXO中,并等待直至其所占权益远大于节点平均值。这样,攻击者有极大的可能性连续进行造币,从而达到对主链的分叉或交易回滚(如实施双花攻击)的目的。

在PoS共识机制中,解谜当前区块取决于前一个区块的哈希值。拥有足够算力和权益的攻击者可以在第h个区块的虚拟挖矿过程中,通过随机试错法对该区块的哈希值进行干涉,直至攻击者可以对第h+1个区块进行挖矿。这就是所谓的pre-computation攻击。接此方法,攻击者可以连续的进行造币,并获取相对应的区块奖励或者发起双花攻击。

声明:此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。本网站所提供的信息,只供参考之用。

点击阅读全文