THORChain 官方公布了2022年Q1财报,在 2022 年初期持续性低迷的市场行情和高度不稳定的地缘政治双重因素影响下,THORChain 营收实现了正增长。从公开数据显示 THORChain 一季度收入 2.17 亿美元。被誉为「跨链版 Uniswap」的 THORChain 凭藉自身的产品独特性成功跻身跨链交易市场,受到投资者的青睐。

看似光鲜的背后,THORChain 也饱受骇客盗币之苦。自 THORChain 在以太坊发行以来,安全事件频发引起市场对 THORChain 安全性的质疑。4月11日,THORChain 官方推特发布一则注意网络钓鱼攻击的贴文,警告用户不要与DeTHOR或其他未知代币进行互动,再次引发用户对 THORChain 安全问题的担忧。

CoinEx 安全团队在专注自身产品的安全体系建设以外,同时保持对区块链行业安全事件持续性关注,希望从技术安全的视角帮助用户更好地瞭解不同项目的安全性,减轻项目投资风险。出于促进行业安全规范的角度出发,CoinEx 安全团队对近期关注度较高的项目 – THORChain(RUNE) 进行了安全风险剖析。期望能够引起项目方重视并进行合约代码的优化,同时警醒用户增强资产安全意识,规避资金损失风险。

THORChain(RUNE)的安全性如何

CoinEx 安全团队经过对 THORChain (RUNE) 合约代码及逻辑进行分析,总结 THORChain (RUNE) 可能存在的风险:

首先,透过查看 THORChain (RUNE) 的合约代码:

https://etherscan.io/address/0x3155ba85d5f96b2d030a4966af206230e46849cb#code

我们可以看到这是一个相对标准的 ERC-20 代币。值得注意的是,除了标准的 ERC-20 标准接口,THORChain (RUNE) 还额外提供了一个接口:

如上图所示,在 tranferTo 我们可以看到 THORChain (RUNE) 使用了 tx.origin,这是导致THORChain(RUNE)风险存在的因素之一。在这里,我们需要解释下 tx.origin 与 msg.sender 的区别:

下图是普通地址直接调用合约的情况:

这种情况下,智能合约里:msg.sender = account.address, tx.origin = account.address。 msg.sender 和 tx.origin 是一样的。

接下来,我们再观察下地址调用合约,合约再调用合约的情况如何:

如上图所示,在合约再调用合约的情况下,我们看到对于合约 contractA, 其 msg.sender 和 tx.origin 没有区别都是 account.address。

但是对于 contract B,结果显示 msg.sender 等于合约 A 的地址,而 tx.origin 则为 account.address。因此,tx.origin 相当于一个全局变量,它遍历整个调用栈并返回最初发送交易的帐户地址。这就是问题的关键所在,截至目前为止,THORChain (RUNE) 已知的黑客攻击事件几乎都是因为 tx.origin。

接下来,让我们看看攻击者是如何通过 tx.origin 的特性盗取用户的 RUNE 代币:

第一种方式:「顺手牵羊」

以太坊上地址分为:外部地址和合约地址。通过外部地址给两种类型的地址转帐 ETH 有着本质的区别。通过查看 solidity 的官方文档,我们知道要给合约地址转帐,合约地址必须实现 receive 方法。

结合 tx.origin 的特性,攻击者可以构造一个 Attack 合约:

通过 Attack 合约,只要用户给该合约转帐 ETH,在转帐过程中,Attack 合约就会顺手牵羊,把用户的帐上持有的 RUNE 同步顺走。

第二种方式:珠联币合

「珠联币合」则相对比较特殊,攻击者若通过本方式盗取用户的 RUNE 不仅需要一个媒介代币,还需要该代币有机会调用第三方合约。通过观察以太坊上 RUNE 的转帐记录,发现有攻击者通过 AMP 代币的转帐盗取用户 RUNE 的记录。

AMP 代币使用 erc1820 协议进行 hook 注册管理,每次 transfer 时都会有检测是否有注册 hook。如有,则调用对应的 hook 回调。

透过查看 AMP 代币的合约代码,我们发现 transfer 最终执行的是:_transferByPartition,其中有两处涉及 transferhook 的回调。一个是转帐之前:_callPreTransferhooks,一个是转帐之后:_callPostTransferhooks。_callPreTransferhooks 是针对 from 地址,而 _callPostTransferhooks 则针对的是 to 地址,即接收代币的地址。

对普通用户而言,薅自己的代币并没有任何意义。因此,对攻击者而言,可以操作的是 _callPostTransferhooks。让我们来查看 _callPostTransferhooks 的代码:

注意看,唯一可能被利用的回调 IAmptokensRecipient(recipientImplementation).tokensReceived()

下面将详细介绍如何利用该回调在转帐 AMP 代币的同时转走用户的 RUNE。

第一步:需要一个回调合约,如下所示:

第二步:部署第一步的合约得到地址 Attack Address

第三步:调用 erc1820 合约接口 setInterfaceImplementer 注册接口

erc1820 地址:0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24

合约接口:setInterfaceImplementer(address toAddr, bytes32 interfaceHash, address implementer)

其中:toAddr为转走AMP的接收地址,interfaceHash 为 Amp 代币 sRecipient 的 hash:

0xfa352d6368bbc643bcf9d528ffaba5dd3e826137bc42f935045c6c227bd4c72a

Implementer:为第二步部署得到的 attack address

第四步:引诱用户向 toAddr 转 AMP 触发回调,同时转帐用户的 RUNE。

第三种方式:「投怀送抱」

「投怀送抱」顾明思议是攻击者通过赠送用户一些可观的福利从而引诱用户进行合约操作。下面将介绍一种常见的方式。

第一步:攻击者发行一个ERC-20 代币,他可以写入任何涉及到签名的合约接口中;

第二步:在 Uniswap 或者其他 swap 创建交易对;

第三步:给所有持有 RUNE 代币的用户地址进行空投;

通过以上三步骤,前期的「投怀送抱」工作基本完成,接下来只需等待用户去 swap 交易,用户只要进行 approve、transfer 等操作都有 RUNE 丢失的风险。

此外,为进一步核实 THORChain 合约代码的安全风险问题,CoinEx 安全团队与行业两家知名安全机构慢雾安全团队及派盾安全团队进行了讨论,经慢雾安全团队和派盾安全团队验证后,认为以上提到的安全风险确实存在。

那么,项目方该如何优化合约代码以提高项目的安全性,确保用户资产安全呢

无他,唯有慎用 tx.origin。

另一方面,作为普通用户面对防不胜防的盗币方式时,该如何规避风险保护自我资产。对此,CoinEx 安全团队建议:

1. 针对第一种盗币方式:在转帐时需要注意预估的 gas 消耗。普通的ETH转帐,21000 的 Gas 消耗足矣,若发现 Gas 消耗远超于 21000,则需要加强警惕。

2. 针对第二种盗币方式:建议进行钱包隔离。不同的代币存放在不同的钱包地址,尤其是交易所的热钱包地址,更应多加小心。

3、针对第三种盗币方式:贪婪是万恶之源,切勿盲目参与空投活动。

安全是区块链行业亘古不变的话题,无论是项目方、交易所还是所有的行业参与者都应当将安全作为项目运营的重中之重,承担起保护用户资产安全的责任,共同推动行业良性发展。