Cover photo

什么,签名也能盗走钱包资产?

缘起

昨晚有个 NFT 项目开放白名单 mint,一会之后朋友就说钱包被盗了。再然后被盗钱包的人越来越多,项目方也随即关闭了 twiiter 和 DC,这是一次有组织有预谋的诈骗行为。

一般而言,链上操作的老韭菜都会知道,一定要保存好自己的密钥或者助记词,这样能防范钱包被盗的情况。进阶一点知道不能乱点不明来历的网站,不要随便授权一些链接,这块的诈骗会在大项目之后特别多,比如年中的 moonbird 和猴地发售之后,也发生过多起 NFT holder 被盗的情况。

简单预防的手段就是 Mac 电脑 + 硬件钱包,对于来历不明的网站,使用空币钱包去链接,也可以租一个服务器,丢服务器去查看,一旦有问题,重装服务器系统即可。

那这次事件是如何发生的呢?在打开项目的网站后,也没有做过任何链上的确认动作,钱就被项目方从口袋里给掏空了。这其实是 Metamask 的签名在搞鬼。

技术分析

post image

ETH RPC

上面的 ETH RPC 是用户和以太坊网络交互的入口,节点执行的是 JSON-RPC 协议,简单理解就是统一规范发送网络请求,这一块东西是很底层的了,大致就是下面这个样子。对很多 dev 来说都不友好,更别提普通人了。基于此,有了需求就有了产品

post image

ETH SDK

即封装了 ETH RPC 中的功能,面向更多的程序员和开发者使用,这块不展开说了。

钱包

以Metamask 为代表的钱包,在封装了 ETH RPC 功能后,做成了 GUI 的可视化模式,能让所有人都能更方便的与以太坊网络交互。

然后再来阐述下交互的流程,一笔交易的完成分为三个步骤,构建交易 —> 签名交易 —> 发送交易。由于 RPC 是底层的,因此它的权限非常大。本次事件就是因为项目方作恶,伪造一笔交易,然后使用了 eth_sign 这个函数,让用户签名后,项目方就能提交这笔交易,实现盗取钱包的手段,完成了交易操作。

由此可见,关键的步骤就是作恶的人,会调用 RPC 交互,从而达到目的。对于钱包和 sdk 而言,禁止了很多 eth_sign 的操作,保障了安全。现在的 Metamask 钱包,对于签名操作,也做了风险提示。

post image

然后再看下源码,但凡出现 eth_sign 这种,就要特别小心了。还好 Metamask 最近的升级,对这种危险签名都有红字警告。

  ethSign.onclick = async () => {
    try {
      // const msg = 'Sample message to hash for signature'
      // const msgHash = keccak256(msg)
      const msg =
        '0x879a053d4800c6354e76c7985a865d2922c82fb5b3f4577b2fe08b998954f2e0';
      const ethResult = await ethereum.request({
        method: 'eth_sign',
        params: [accounts[0], msg],
      });
      ethSignResult.innerHTML = JSON.stringify(ethResult);
    } catch (err) {
      console.error(err);
      ethSign.innerHTML = `Error: ${err.message}`;
    }
  };

总结

今年熊市真的是 hacker summer 了,总之技术傍身多学习,下一个牛市就是丰收的季节了。