同一个钓鱼链接,为什么他丢了12个ETH,我只丢了0.3个

· 钱包对比

2023年3月,我朋友老陈在Discord上点了一个“Collab Land验证”链接。钱包里12个ETH,3分钟内被转走。我当时在同一台电脑上,也点了那个链接,只丢了0.3个ETH的gas费。

差别不在运气,在钱包设置。

老陈的钱包,问题出在哪

老陈用的是MetaMask,助记词抄在手机备忘录里。他点完链接,签名弹窗看都没看就确认了。那是个setApprovalForAll请求,授权了对方操作他所有NFT。他钱包里正好有3个BAYC,加上ETH,一起没了。

我后来帮他查链上记录。攻击者地址在收到授权后,用脚本在同一个区块里批量转走了他的资产。整个过程不到15秒。

他的问题有三个:助记词存手机、签名不看内容、所有资产放一个钱包。

我的钱包设置,多花了20分钟

我点那个链接之前,其实也差点中招。但我的MetaMask弹窗显示的是“授权所有NFT”,我停了一下。因为我提前做了几件事:

第一,热钱包只放零钱。 我日常交互的钱包里面永远不超过0.5个ETH。大额资产在Ledger里,那个钱包从不点任何链接。

第二,签名前必看请求类型。 MetaMask的签名弹窗,如果是eth_sign,我直接拒绝。这个签名方法可以签任何哈希,等于把私钥控制权交出去。正规DApp不会用这个。personal_sign和eth_signTypedData相对安全,但也要看内容。

第三,用Rabby钱包做交互。 Rabby有个功能,签名前会模拟交易结果,直接告诉你“这个操作会转走你的NFT”。MetaMask后来也加了类似功能,但Rabby的模拟更细。老陈出事那会儿,MetaMask还没有这个。

助记词和私钥,别存手机

老陈的助记词在手机备忘录里。他的手机没丢,但iCloud账号被盗了。攻击者登录他的Apple ID,直接看到了备忘录。

我自己的做法:助记词抄在金属板上,两块,放在不同地方。一块在老家书柜,一块在办公室保险柜。不拍照、不存云盘、不发微信。

私钥同理。如果你用私钥导入钱包,那个私钥一旦联网就永远不安全。正确做法是用硬件钱包生成地址,私钥永远不触网。

多签钱包,不是大户专属

老陈出事之后,我帮他把剩下的资产转到了Safe多签钱包。Safe是以太坊上最成熟的多签方案,现在管理着超过800亿美元的资产。

多签的逻辑很简单:一个钱包需要2个或3个私钥中的2个签名才能转账。我用的是2/3配置,一个Ledger、一个Trezor、一个手机上的MetaMask作为备用。攻击者要偷,得同时控制两个设备。

设置步骤不复杂:

  1. 打开app.safe.global,连接一个钱包作为创建者
  2. 添加其他所有者地址,设置签名阈值
  3. 部署合约,大概花0.1 ETH的gas
  4. 之后每笔交易,其他所有者需要在Safe界面确认

小资金用不着多签,但超过1万美元的资产,多签是底线。

授权管理,每月清一次

老陈的12个ETH里,有一部分是通过之前的授权被转走的。他半年前在一个不知名DEX上授权过USDC,那个合约后来被攻击了,攻击者用他的授权转走了他的USDC。

我现在每月1号做一件事:打开revoke.cash,连接钱包,看所有授权。不用的DApp,直接取消。取消授权要花gas,大概0.5到2美元一笔。但比被偷强。

有个细节:取消授权时,把gas limit调高一点,比如100000。有些恶意合约会故意消耗更多gas,gas limit不够交易就失败,授权还在。

硬件钱包,别只买一个

我见过有人买了一个Ledger,助记词抄了一份,放在同一个抽屉里。这等于没做隔离。硬件钱包的意义是私钥不触网,但如果助记词和设备在一起,攻击者物理访问就能全拿。

我的配置:两个不同品牌的硬件钱包,助记词分开存。一个Ledger放BTC和ETH,一个Trezor放其他链。这样做还有个好处:如果一个品牌的固件出问题,另一个不受影响。

Ledger 2023年5月那个Ledger Recover功能争议,很多人担心助记词泄露。我用Trezor做备份,就是因为不想把所有信任押在一个品牌上。

最后说个真实的坑

去年有个读者找我,说他按教程设置了多签,但还是被偷了。我让他把Safe地址发我。一看,他的多签阈值是1/3。三个所有者,只需要一个签名就能转账。攻击者控制了他其中一个热钱包,直接转走了。

多签的阈值设置,2/3是底线。1/3等于没设。

还有个坑:有人用多签钱包去点钓鱼链接。Safe钱包本身不能直接交互DApp,但有人用WalletConnect连。连的时候,Safe会弹签名请求。如果你签了setApprovalForAll,多签也救不了你。多签防的是私钥泄露,不防你主动签名。

钱包安全没有一劳永逸。老陈现在每次签名前会截图发给我看,我帮他确认。这有点麻烦,但比丢12个ETH强。