3

慢雾:空白支票 eth_sign 钓鱼分析

 1 year ago
source link: https://www.ccvalue.cn/article/1404551.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

慢雾:空白支票 eth_sign 钓鱼分析

 •  22 小时前
“你”的点击,“我”的 NFT。

By:Lisa & Kong

近期,我们发现多起关于 eth_sign 签名的钓鱼事件。

钓鱼网站 1:https://moonbirds-exclusive.com/

a09d14a42a664300bc245e950c76b9e5.jpg

当我们连接钱包后并点击 Claim 后,弹出一个签名申请框,同时 MetaMask 显示了一个红色提醒警告,而光从这个弹窗上无法辨别要求签名的到底是什么内容。

其实这是一种非常危险的签名类型,基本上就是以太坊的“空白支票”。通过这个钓鱼,骗子可以使用您的私钥签署任何交易。

除此之外,还有一种钓鱼:在你拒绝上述的 sign 后,它会在你的 MetaMask 自动显示另一个签名框,趁你没注意就骗到你的签名。而看看签名内容,使用了 SetApprovalForAll 方法,同时 Approved asset 的目标显示为 All of your NFT,也就是说,一旦你签名,骗子就可以毫无节制地盗走你的所有 NFT。如下:

钓鱼网站 2:https://dooooodles.org/

ddb0496a6a9713992b0bde83e5933c07.gif

我们使用 MistTrack 来分析下骗子地址:

0xa594f48e80ffc8240f2f28d375fe4ca5379babc7

2c311e1f92bc0644ba7247548c44294b.jpg
ceff5617705a0d8a0559ecc53e3a6a82.jpg

通过分析,骗子多次调用 SetApprovalForAll 盗取用户资产,骗子地址目前已收到 33 个 NFT,售出部分后获得超 4 ETH。

回到正题,我们来研究下这种钓鱼方法。首先,我们看看 MetaMask 官方是如何说明的:

3cb613ad38abc4400ef8568f6dfaafe7.jpg

也就是说,MetaMask 目前有六种签名方法(例如 personal_sign),只有一种方式会出现 MetaMask 警告,发生在 eth_sign 的签名情况下,原因是 eth_sign 方法是一种开放式签名方法,它允许对任意 Hash 进行签名,这意味着它可用于对交易或任何其他数据进行签名,从而构成危险的网络钓鱼风险。

根据 MetaMask 官方文档说明,eth_sign 方法是可以对任意哈希进行签名的,而我们在签署一笔交易时本质上也是对一串哈希进行签名,只不过这中间的编码过程都由 MetaMask 替我们处理了。我们可以再简单回顾下从编码到交易广播的过程:

a2473d84ae15fbd76e195505a9af88a9.png

在进行交易广播前,MetaMask 会获取我们转账的对象(to)、转账的金额(value)、附带的数据(data),以及 MetaMask 自动帮我们获取并计算的 nonce、gasPrice、gasLimit 参数进行 RLP 编码得到原始交易内容(rawTransaction)。如果是合约调用,那么 to 即为合约地址,data 即为调用数据。

rlp = require('rlp');// Use non-EIP115 standardconst transaction = { nonce: '', gasPrice: '', gasLimit: '', to: '0x', value: '', data: '0x'};// RLP encodeconst rawTransaction = rlp.encode([transaction.nonce, transaction.gasPrice, transaction.gasLimit, transaction.to, transaction.value, transaction.data]);

随后再对此内容进行 keccak256 哈希后得到一串 bytes32 的数据就是所需要我们签名的数据了。

// keccak256 encodeconst msgHex = rawTransaction.toString('hex');const msgHash = Web3.utils.keccak256('0x'+ msgHex);

我们使用 MetaMask 对这串数据签名后就会得到 r, s, v 值,用这三个值再与 nonce/gasPrice/gasLimit/to/value/data 进行一次 RLP 编码即可得到签名后的原始交易内容了,这时候就可以广播发出交易了。

rlp = require('rlp');const transaction = { nonce: '', gasPrice: '', gasLimit: '', to: '', value: '', data: '', v: '', r: '', s: ''};// RLP encodeconst signedRawTransaction = rlp.encode([transaction.nonce, transaction.gasPrice, transaction.gasLimit, transaction.to, transaction.value, transaction.data, transaction.v, transaction.r, transaction.s]);

而如上所述,eth_sign 方法可以对任意哈希进行签名,那么自然可以对我们签名后的 bytes32 数据进行签名。因此攻击者只需要在我们连接 DApp 后获取我们的地址对我们账户进行分析查询,即可构造出任意数据(如:native 代币转账,合约调用)让我们通过 eth_sign 进行签名。

这种钓鱼方式对用户会有很强的迷惑性,以往我们碰到的授权类钓鱼在 MetaMask 会给我直观的展示出攻击者所要我们签名的数据。如下所示,MetaMask 展示出了此钓鱼网站诱导用户将 NFT 授权给恶意地址。

a76bd059fb9ebc9b70bbc04ba43bbf23.jpg

而当攻击者使用 eth_sign 方法让用户签名时,如下所示,MetaMask 展示的只是一串 bytes32 的哈希。

92de958ee1afd5dc2557354646d55f81.jpg

总结

本文主要介绍 eth_sign 签名方式的钓鱼手法。虽然在签名时 MetaMask 会有风险提示,但若结合钓鱼话术干扰,没有技术背景的普通用户很难防范此类钓鱼。建议用户在遇到此类钓鱼时提高警惕, 认准域名,仔细检查签名数据,必要时可以安装安全插件,如:RevokeCash、ScamSniffer 等,同时注意插件提醒。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK