位置:芙蓉财经网 >> 区块链

Cobo 安全团队 - ETH 硬分叉中的隐藏风险和套利机会

2023年03月18日 21:55

Cobo 安全团队 - ETH 硬分叉中的隐藏风险和套利机会

本文由 Cobo 区块链安全团队提供。团队成员来自知名区块链安全厂商,具有丰富的智能合约审计经验。他们在多个 DeFi 项目中发现了高风险漏洞。团队目前专注于智能合约安全、DeFi安全等方向,研究和分享前沿的区块链安全技术。

我们也希望在加密***领域具有研究精神和科学方***的终身迭代学习者能够加入我们,向行业输出思维见解和研究观点!

这是Cobo的第16篇文章

前言

随着 ETH 升级为 PoS 共识系统,原 PoW 机制的 ETH 链在部分社区(以下简称 ETHW)的支持下成功硬分叉。但是,由于一些链上协议在设计之初没有为可能的硬分叉做好准备,相应的协议在ETHW分叉链中存在一定的安全风险,其中最严重的安全风险是。

硬分叉完成后,ETHW 主网上至少有 2 次使用重放机制的攻击,分别是重放攻击和重放攻击。本文将以这两个事件为例,分析重放攻击对分叉链的影响,以及协议应该如何防止此类攻击。

重播类型

首先,在开始分析之前,我们需要对重放攻击的类型有一个初步的了解。一般来说,我们将重放攻击分为两类,即交易重放和签名消息重放。接下来我们来说说这两种播放机制的区别。

交易重播

交易重放是指将原链中的交易原封不动地迁移到目标链的操作。它属于事务级别的重放。重放后可以正常执行交易分叉时间,完成交易验证。最著名的案例是平台上的攻击事件,直接导致了超过2000万个OP代币的损失。但在EIP 155实施后,由于交易本身的签名有(用于区分链本身与其他分叉链的标识符),如果重放的目标链不同,则交易本身无法重放。的。

签名消息重播

签名消息重放不同于交易重放。它用于重放使用私钥签名的消息(例如 Cobo 是最好的)。在签名消息重放中,

Cobo 安全团队 - ETH 硬分叉中的隐藏风险和套利机会

攻击者不需要重放整个交易,而只需重放签名消息。在消息签名中,最好以 Cobo 为例,由于消息不包含任何与链相关的特殊参数,因此消息在签名后理论上可以在任何分叉链中有效。可以检查。为了避免分叉上的消息重播,可以在消息内容中加上,比如Cobo最好+()。携带特定链标识后,不同分叉链上的消息内容不同,消息签名也不同,无法直接重放和重用。

和攻击原理

让我们来分析和攻击原理。首先得出结论,这两种攻击本身并不是事务重放攻击。原因是 ETHW 使用的和 ETH 主网不同,所以无法验证直接重放交易。那么剩下的唯一选择就是消息重放了,那么我们来一一分析一下它们各自在ETHW分叉链上是如何被消息重放攻击的。

它是xDAI与ETH主网之间进行资产转移的桥梁。它主要依靠桥提交的指定跨链消息来完成跨链资产的转移。中,提交的验证消息的逻辑是这样的

functionexecuteSignatures(bytes_data,bytes_signatures)pu***ic{

_allowMess***eExecution(_data,_signatures);

bytes32msgId;

addresssender;

addressexecutor;

uint32gasLimit;

uint8dataType;

uint256[2]memorychainIds;

bytesmemorydata;

(msgId,sender,executor,gasLimit,dataType,chainIds,data)=ArbitraryMess***e.un***ckData(_data);

_executeMess***e(msgId,sender,executor,gasLimit,dataType,chainIds,data);

}

在这个函数中,首先会根据#L2行的签名校验判断提交的签名是否被指定的签名,然后在#L11行对数据报文进行解码。从解码内容不难发现,返回的字段中包含字段,那么是不是表示签名的消息无法播放呢?我们继续分析。

function_executeMess***e(

bytes32msgId,

addresssender,

addressexecutor,

uint32gasLimit,

uint8dataType,

uint256[2]memorychainIds,

bytesmemorydata

)internal{

require(_***Mess***eVersionValid(msgId));

require(_***DestinationChainIdValid(chainIds[1]));

require(!relayedMess***es(msgId));

setRelayedMess***es(msgId,true);

processMess***e(sender,executor,msgId,gasLimit,dataType,chainIds[0],data);

}

通过跟踪函数,发现在#L11行检查了函数的合法性

function_***DestinationChainIdValid(uint256_chainId)internalreturns(boolres){

return_chainId==sourceChainId();

}

functionsourceChainId()pu***icviewreturns(uint256){

returnuintStor***e[SOURCE_CHAIN_ID];

}

通过继续分析后面的函数逻辑,不难发现,实际的校验并没有使用evm原生的来获取链本身,而是直接使用了变量中存储的值,那么这个值显然是由*** 所以可以认为消息本身没有链身份eth分叉时间,所以理论上可以重放签名的消息。

由于在硬分叉期间,分叉前的所有状态在两条链上都会保持不变,后续的 xDAI 团队没有额外的操作。分叉后,Omni 合约在 ETHW 和 ETH 主网上的状态不会改变,也就是说合约不会改变。基于这种情况,我们可以推断,主网上的签名也可以在 ETHW 上进行验证。然后,由于签名消息本身不包含它,攻击者可以使用签名重放在 ETHW 上提取同一合约的资产。

与 Omni 一样,它是往返于 ETH 主网的资产转移的桥梁。与 Omni 不同,它依赖区块证明来***。逻辑如下:

functionexit(bytescalldatainputData)externaloverride{

//...省略不重要逻辑

//verifyreceiptinclusion

require(

MerklePatriciaProof.verify(

receipt.toBytes(),

branchMaskBytes,

***yload.getReceiptProof(),

***yload.getReceiptRoot()

),

"RootChainMan***er:INVALID_PROOF"

);

//verifycheckpointinclusion

_checkBlockMembershipInCheckpoint(

***yload.getBlockNumber(),

***yload.getBlockTime(),

***yload.getTxRoot(),

***yload.getReceiptRoot(),

***yload.getHeaderNumber(),

***yload.getBlockProof()

);

ITokenPredicate(predicateAddress).exitTokens(

_msgSender(),

rootToken,

log.toRlpBytes()

);

}

通过函数逻辑不难发现,合约通过两个检查来确定消息的合法性,一个是检查总和,以确保交易实际发生在子链(Chain)中。第一次检查其实是可以绕过的,因为任何人都可以通过交易数据来构造自己的,但是第二次检查是不能绕过的,因为通过查看逻辑可以发现:

function_checkBlockMembershipInCheckpoint(

uint256***ockNumber,

uint256***ockTime,

bytes32txRoot,

bytes32receiptRoot,

uint256headerNumber,

bytesmemory***ockProof

)privateviewreturns(uint256){

(

bytes32headerRoot,

uint256startBlock,

,

uint256createdAt,

)=_checkpointMan***er.headerBlocks(headerNumber);

require(

keccak256(

abi.encodePacked(***ockNumber,***ockTime,txRoot,receiptRoot)

)

.checkMembership(

***ockNumber.sub(startBlock),

headerRoot,

***ockProof

),

"RootChainMan***er:INVALID_HEADER"

);

returncreatedAt;

}

从合同中提取相应的一项。按照这个逻辑,我们看一下设置

functionsubmitCheckpoint(bytescalldatadata,uint[3][]calldatasigs)external{

(addressproposer,uint256start,uint256end,bytes32rootHash,bytes32accountHash,uint256_borChainID)=abi

.decode(data,(address,uint256,uint256,bytes32,bytes32,uint256));

require(CHAINID==_borChainID,"Invalidborchainid");

require(_buildHeaderBlock(proposer,start,end,rootHash),"INCORRECT_HEADER_DATA");

//checkifit******tertokeepitinlocalstor***einstead

IStakeMan***erstakeMan***er=IStakeMan***er(reg***try.getStakeMan***erAddress());

uint256_reward=stakeMan***er.checkSignatures(

end.sub(start).add(1),

/**

prefix01todata

01representspositivevoteondataand00***negativevote

maliciousvalidatorcantrytosend2/3onnegativevoteso01***appended

*/

keccak256(abi.encodePacked(bytes(hex"01"),data)),

accountHash,

proposer,

sigs

);

//....剩余逻辑省略

不难发现,在#L2这行代码中,只检查了签名数据,而没有检查链本身。由于消息是由合约签名的,理论上攻击者也可以分叉链。重放消息的签名是合法的,通过调用ETHW链中的exit函数并提交相应的交易证明,可以成功撤回并通过后续的校验。

以地址b9为例,该地址通过以下步骤成功完成了ETHW链上的套利

首先,依靠钞票能力在主网交易所提币。通过链上传递的功能存钱;通过ETH主网调用的exit函数取款;复制并提取提交的ETH主网;在 ETHW 中重放上一步提取的签名消息;在 ETHW 中调用 exit 提取货币

为什么会这样?

从上面分析的两个例子不难发现,这两个协议在ETHW上遭受重放攻击是因为协议本身没有做好防重放保护,导致协议对应的资产被掏空分叉的链。但是,由于这两个桥不支持ETHW分叉链,用户并没有遭受任何损失。但我们需要考虑的是,为什么这两座桥没有设计好重放保护措施?其实原因很简单,因为他们设计的应用场景很简单,只是用来将资产转移到自己指定的对应链上,没有多链部署的计划,所以没有保护。该协议本身没有安全隐患。

相比之下,ETHW 上的用户,由于这些桥接器本身不支持多链场景,如果用户在 ETHW 分叉链上操作,就会在 ETH 主网上受到消息重放攻击。

比如在当前的矿池合约中,有一个函数,这个函数中有变量,其中包含变量。

functionpermit(addressowner,addressspender,uintvalue,uintdeadline,uint8v,bytes32r,bytes32s)external{

require(deadline>=***ock.timestamp,'Un***wapV2:EXPIRED');

bytes32digest=keccak256(

abi.encodePacked(

'x19x01',

DOMAIN_SEPARATOR,

Cobo 安全团队 - ETH 硬分叉中的隐藏风险和套利机会

keccak256(abi.encode(PERMIT_TYPEHASH,owner,spender,value,nonces[owner]++,deadline))

)

);

addressrecoveredAddress=ecrecover(digest,v,r,s);

require(recoveredAddress!=address(0)&&recoveredAddress==owner,'Un***wapV2:INVALID_SIGNATURE');

_approve(owner,spender,value);

}

这个变量首先定义在 . 这个变量包含,在设计之初就包含了可能的多链场景的重放预防,但是根据矿池合约的逻辑,如下:

constructor()pu***ic{

uintchainId;

assem***y{

chainId:=chainid

}

DOMAIN_SEPARATOR=keccak256(

abi.encode(

keccak256('EIP712Domain(stringname,stringversion,uint256chainId,addressverifyingContract)'),

keccak256(bytes(name)),

keccak256(bytes('1')),

chainId,

address(th***)

)

);

}

已经在构造函数中定义了,也就是说,硬分叉后,即使链本身发生了变化,矿池合约也无法获取新的更新。如果用户将来授权了 ETHW,那么 ETHW 上的签名可以在 ETH 主网上重放。另外,类似的协议还有很多,比如特定版本下的yearn vault合约,也是采用固定的情况。用户在 ETHW 上进行交互时,还需要防范此类协议的重放风险。

协议设计之初的注意事项

对于开发者来说,在为协议本身定制消息签名机制时,应该考虑到后续可能出现的多链场景。如果路线图中存在多链部署的可能性,则应将其作为变量添加到签名消息中。同时,在验证签名时,由于硬分叉不会在分叉前改变任何状态,所以用于验证签名消息的合约变量不应设置为合约变量,而应在之前重新获取每次验证,然后对签名进行验证以确保安全。.

对用户的影响

一般情况下,如果协议不支持分叉链,应尽量不要对分叉链进行任何操作,以防止相应的签名消息在主网上重播,导致用户在主网上丢失资产。

对交易所和托管人的影响

由于很多交易所本身都支持ETHW代币,因此这些因攻击而提取的代币可能会被充值到交易所***。但是需要注意的是,这样的攻击并不是链共识本身的问题。交易所造成的恶意增发,因此对于交易所而言,此类攻击无需额外防范

总结

随着多链场景的发展,重放攻击从理论层面逐渐成为主流攻击手段。开发人员应仔细考虑协议设计。在设计消息签名机制时,尽量加入其他因素作为签名内容。遵循相关的最佳实践以防止用户资产丢失。

Cobo是亚太地区最大的加密货币托管机构。自成立以来,已为超过500家行业顶尖机构和高净值人士提供了优质服务。在保证加密资产安全存储的前提下,也实现了加密资产的稳定收益。深受世界各地用户的信赖。Cobo专注于构建可扩展的基础设施,为机构提供安全托管、资产增值、链上交互、多类型资产跨链跨层管理等多种解决方案,为机构向Web转型提供解决方案3.0 最强大的技术底层支持和赋能。Cobo 包括 Cobo、Cobo DaaS、Cobo MaaS、Cobo StaaS、Cobo、

原文源自微信公众号(Cobo):Cobo安全团队——ETH硬分叉中的隐患与套利机会

以上就是腾赚网小编为大家带来的全部内容,希望可以帮助到大家

推荐阅读

标签:

文章来源: 芙蓉财经网
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至405936398@qq.com 举报,一经查实,本站将立刻删除。
相关资讯
虚拟币交易平台app活动 正规的虚拟币交易平台有哪些?
虚拟币交易平台app活动 正规的虚拟币交易平台有哪些? 1970-01-01

本文由 Cobo 区块链安全团队提供。团队成员来自知名区块链安全厂商,具有丰富的智能合约审计经验。他们在多个 DeFi ...

虚拟快币充值平台官网入口,虚拟快币充值平台官网入口下载
虚拟快币充值平台官网入口,虚拟快币充值平台官网入口下载 1970-01-01

本文由 Cobo 区块链安全团队提供。团队成员来自知名区块链安全厂商,具有丰富的智能合约审计经验。他们在多个 DeFi ...

整治虚拟货币挖矿省份排名?欧美国家为什么没有禁止?
整治虚拟货币挖矿省份排名?欧美国家为什么没有禁止? 1970-01-01

本文由 Cobo 区块链安全团队提供。团队成员来自知名区块链安全厂商,具有丰富的智能合约审计经验。他们在多个 DeFi ...

虚拟货币与虚拟银行学?什么是虚拟币账户
虚拟货币与虚拟银行学?什么是虚拟币账户 1970-01-01

本文由 Cobo 区块链安全团队提供。团队成员来自知名区块链安全厂商,具有丰富的智能合约审计经验。他们在多个 DeFi ...

加强虚拟货币 关于进一步规范和处置虚拟货币交易
加强虚拟货币 关于进一步规范和处置虚拟货币交易 1970-01-01

本文由 Cobo 区块链安全团队提供。团队成员来自知名区块链安全厂商,具有丰富的智能合约审计经验。他们在多个 DeFi ...

虚拟币 平台?虚拟币平台
虚拟币 平台?虚拟币平台 1970-01-01

本文由 Cobo 区块链安全团队提供。团队成员来自知名区块链安全厂商,具有丰富的智能合约审计经验。他们在多个 DeFi ...