#crypto #链上漏洞 Aurora销毁逻辑错误导致代币窃取漏洞
跨链桥-RainBow Bridge
Rainbow Bridge 不要求用户信任任何东西,除了区块链本身,称之为无信任。任何在 NEAR 上加密可证明的信息都可用于以太坊合约,反之亦然。
例如以下信息:
• 将交易包含在区块中;• 执行具有特定结果的交易;• 合约的状态。
桥的设计
桥背后的核心思想是它实现了两个轻客户端:
1. 作为 NEAR 合约在 Rust 中实现的以太坊轻客户端
2. 作为以太坊合约在 Solidity 中实现的 NEAR 轻客户端
处理流程
https://near.org/blog/eth-near-rainbow-bridge/
1. 假设 Alice 想在 NEAR 区块链上将 X DAI 转给 Bob,她从 RainbowCLI/RainbowLib 发起转账;2. RainbowLib 首先设置允许将 X DAI 从 Alice 转移到 TokenLocker;3. 然后它调用 TokenLocker 获取那些令牌,导致 TokenLocker 发出事件“Alice locked X tokens in favor of Bob”;4. RainbowLib 然后等到 EthOnNearClient 收到包含此事件的以太坊标头,再加上 25 个区块进行确认;5. 然后 RainbowLib 计算这个事件的证明并提交给 MintableFungibleToken 合约;6. MintableFungibleToken 合约然后通过调用 EthOnNearProver 来验证这个证明是否正确; 6.1. EthOnNearProver 反过来验证证明的标头是否在 EthOnNearClient 的规范链上,并且它具有所需的确认次数。它还验证证明本身; 6.2. MintableFungibleToken 然后解包以太坊事件并为 Bob 铸造 X nearDAI,完成转账。
漏洞代码分析
根据这个漏洞的基本信息,错误提交是漏洞的核心,先来看一下EthCustodian的withdraw函数是如何实现的。
提取编码在’ proofData ‘中的适当数量的ETH,利用_parseAndConsumeProof对proofData进行解码。
https://etherscan.io/address/0x6BFaD42cFC4EfC96f529D786D643Ff4A8B89FA52#code#F1#L116
https://etherscan.io/address/0x6BFaD42cFC4EfC96f529D786D643Ff4A8B89FA52#code#F5#L45
1 | function _parseAndConsumeProof( |
从这里keccak256(fullOutcomeProof.outcome_proof.outcome_with_id.outcome.executor_id) == keccak256(nearProofProducerAccount_)可以看到会校验executor_id和nearProofProducerAccount_是否相等,也就是eth和near对应的合约是否一致。
从Aurora的代码里找到对应的部分看下如何实现的。
let mut executor = executor_params.make_executor(self);是这个漏洞的关键,可以看到Aurora将自己设置为了executor。
这时候我们模拟流程看一下会发生什么。
经过EthCustodian.sol初始处理后,会生成如下的数据包:
包含了要发送的ETH数量、ETH的接收账户、执行此操作的地址。
1 | require( |
在withdraw中验证result.ethCustodian是否等于BurnResult.ethCustodian,如果相等,则执行合约转账。
当ETH侧发起转账时,Aurora侧withdraw_eth_from_near的会进行处理。
同时重新定义了BurnResult数据结构如下:
在 withdraw函数中直接调用了withdraw_eth_from_near函数,如下
然后进一步跟踪withdraw_eth_from_near,最终在internal_withdraw_eth_from_near函数中实现了Near代币销毁。
以上就是Near向ETH跨链发送代币的流程。
那么如何利用漏洞来实现向ETH发送代币而不在Near链上销毁代币呢?
在上文中分析过,ETH侧会判断执行者id和Aurora 合约发起地址匹配,如果可以将Aurora 合约发起地址设置为Aurora合约本身,就可以不需要销毁代币从而窃取ETH了。
从Aurora的代码寻找会将自己设置为执行id的函数,在代码中我们找到三处,分别是deploy、call、view函数。
所以攻击链就有了:
0. 创建一个合约Evil进行跨链转币,进行数据封装0. 用view函数去调用Evil合约(理论上查看合约就可以触发)0. 这时候executor_id就是Aurora合约本身0. 自动化批量调用实现
当前的修复方式是验证Evil中的EthCustodian是否等于Evil自身的EthCustodian。
修复代码:
https://medium.com/immunefi/aurora-withdrawal-logic-error-bugfix-review-c5b4e30a9160
https://github.com/aurora-is-near/aurora-engine/commit/7109e30926ea33f67c6f702aa2b796b025cca96a
https://etherscan.io/address/0x6BFaD42cFC4EfC96f529D786D643Ff4A8B89FA52#code
还没有评论,来说两句吧...