希望螢幕前的你看到本文后可以傳播給更多人,避免更多人被盜。

作者:菠菜菠菜,Sivan,Beosin 安全研究員

*本文由 Beosin 特邀獨立研究員菠菜菠菜!(twitter@wzxznl)與 Beosin 安全研究員 Sivan 共同創作發佈。

駭客,這是一個讓 Web3 生態中每個人都聞風喪膽的存在,對於專案方來說,在全世界駭客都可能盯著你的情況下,代碼開源的特性使得專案方開發的時候生怕寫錯一行代碼留下漏洞,一旦出現安全事故後果難以承擔。

對於個人來說,如果你不懂得你正在做的操作意味著什麼,那麼你進行的每一個鏈上交互或簽名都有可能使你的資產被盜。 因此安全問題一直是加密世界中最頭疼的問題之一,並且由於區塊鏈的特性,一旦資產被盜幾乎是沒有辦法可以追回的,所以在加密世界中具備安全知識尤其重要。

就在最近,Beosin 的好朋友菠菜發現了一個近兩個月開始活躍的新釣魚手法,只要簽名就會被盜,手法極其隱蔽且難以防範,並且用過 Uniswap 交互的位址都有可能暴露在風險之下,本文 Beosin 聯合獨立研究員菠菜對這種簽名釣魚手法進行科普,盡量避免大家更多的資產損失。

圖片

以下為菠菜的親身經歷複述:

事件經過

最近,一位朋友(暫稱小 A)錢包裡的資產被盜后找到菠菜,與常見被盜方式不同的是,小 A 並沒有洩漏私鑰也沒有和釣魚網站的合約進行交互,於是菠菜開始調查起了這個資產被盜事件。

圖片

在区块链浏览器中可以看到小 A 钱包被盗的这笔 USDT 是通过 Transfer From 函数进行转移的,在这进行科普一下,当我们在以太坊上进行 Token 转账的时候,其实是调用了该 Token 智能合约的 Transfer 函数,这两者的区别简单来说 Transfer 是资产拥有者本人进行操作把 Token 转移给其他地址,而 Transfer From 是第三方将地址内的 Token 转移给其他地址。这也就意味着这笔被盗的资产是另外一个地址进行操作把 Token 转移走的,而非钱包私钥泄漏。

图片

通过查询交易细节,我们可以发现一些关键线索:

  • 尾号 fd51 的地址将小 A 的资产转移到了尾号 a0c8 的地址中
  • 这个操作是与 Uniswap 的 Permit2 合约进行交互的

那么疑点来了,尾号 fd51 的地址是如何拿到这笔资产的权限的?为什么会和 Uniswap 有关系?

图片

首先我们需要知道,要想成功调用 Transfer From 这个函数的前提是调用方需要拥有这个 Token 的额度权限,也就是 approve,相信大家有过链上操作的一定熟悉不过了,当我们去使用一些 Dapp 的时候,一旦涉及到资产的转移就需要我们先进行一个授权(approve)操作,这样 Dapp 的合约才有权限对我们的资产进行转移。

要解开这个谜题,我们需要继续挖掘,而答案就在尾号 fd51 的地址的交互记录中,在该地址进行 Transfer From 转走小 A 的资产之前,可以看到该地址还进行了一个 Permit 的操作,并且这两个操作的交互对象都是 Uniswap 的 Permit2 合约,那么这个 Permit 函数和 Uniswap Permit2 又是什么情况?

Uniswap Permit2 合约是 Uniswap 在 2022 年年底推出的新的智能合约,根据官方的说法,这是一个代币审批合约,允许代币授权在不同的应用程序中共享和管理,创造一个更统一、更具成本效益、更安全的用户体验。

并且未来随着越来越多的项目与 Permit2 集成,Permit2 可以在所有应用程序中实现标准化 Token 批准。Permit2 将通过降低交易成本来改善用户体验,同时提高智能合约的安全性。

图片

我们先要了解一下为什么 Uniswap 要推出 Permit2,我们来假设一个场景,当我们要在某 Dex 上进行 Swap 时,传统的交互方式是我们需要先授权 (approve) 给这个 Dex,然后再进行 Swap,这通常需要花费我们两笔 Gas 费,对于用户来说摩擦成本太大了,相信大家都有过这样的体验。

图片来源:https://github.com/dragonfly-xyz/useful-solidity-patterns/tree/main/patterns/permit2

而 Permit2 的推出将有可能改变整个 Dapp 生态的游戏规则,简单来说就是传统的方法是你每跟一个 Dapp 进行资产转移的交互你都需要进行一次授权,而 Permit2 可以把这个步骤给省去,这样可以非常有效的降低用户的交互成本,带来更好的用户体验。

解决方案是 Permit2 作为用户和 Dapp 之间的中间人,用户只需要把 Token 的权限授权给 Permit2 合约,所有集成 Permit2 合约的 Dapp 都可以共享这个授权额度,对于用户来说,减少了交互成本和提高了用户体验,对于 Dapp 来说,用户体验的提升带来更多的用户和资金,这本是一个双赢的局面,但同时这也可以是一个双刃剑,而问题就出在和 Permit2 交互方式上。

在传统的交互方式中,不管是授权还是进行资金的转移对于操作的用户来说都是链上的交互。而 Permit2 则将用户的操作变为了链下签名,而所有链上的操作都由中间角色(如 Permit2 合约和集成了 Permit2 的项目方等)来完成,这种方案带来的好处是由于链上交互的角色从用户转移为了中间角色,用户即使钱包里没有 ETH 也可以使用其他 Token 来支付 Gas 费或完全由中间角色报销,这取决于中间角色的选择。

图片来源:https://github.com/dragonfly-xyz/useful-solidity-patterns/tree/main/patterns/permit2

虽然 Permit2 的出现有可能改变未来 Dapp 的游戏规则,但是可以看出的是这是一把很强的双刃剑,对于用户来说,链下签名是最容易放下防备的环节,比如当我们用钱包登入某些 Dapp 的时候会需要签名进行连接,而绝大多数人并不会仔细检查签名的内容也并不理解签名的内容,而这就是最可怕的地方。

明白了 Permit2 合约,回到小 A 的事件中我们就明白了为什么资产被盗都是与 Permit2 合约进行交互了,那么就让菠菜来重现这个 Permit2 签名钓鱼手法,首先一个至关重要的前提条件是被钓鱼的钱包需要有 Token 授权给 Uniswap 的 Permit2 合约,菠菜发现目前只要在与 Permit2 集成的 Dapp 或 Uniswap 上进行 Swap 的话,都是需要授权给 Permit2 合约的(下图菠菜使用了安全插件)。

图片

另外一个很可怕的点是,不管你要 Swap 的金额是多少,Uniswap 的 Permit2 合约都会默认让你授权该 Token 全部余额的额度,虽然 MetaMask 会让你自定义输入金额,但我相信大部分人都会直接点击最大或默认值,而 Permit2 的默认值是无限的额度…….

图片
图片

这也就意味着,只要你在 2023 年之后与 Uniswap 有过交互并授权额度给 Permit2 合约,你就会暴露在这个钓鱼骗局的风险之下。

因为重点就在于之前在尾号 fd51 的地址中与 Permit2 合约交互的 Permit 函数上,这个函数简单来说就是利用你的钱包将你授权给 Permit2 合约的 Token 额度转移给别的地址,也就是说只要拿到了你的签名,黑客就可以拿到你钱包中 Token 的权限并把你的资产转移走。

事件详细分析

permit 函数:

你可以把 Permit 函数看作是一种在线签署合同的方式。这个函数让你 (PermitSingle) 可以提前签署一个” 合同”,允许其他人(spender)在未来的某个时间花费你的一些代币。

同时,你还需要提供一个签名(signature),就像在纸质合同上签名一样,用来证明这个” 合同” 真的是你签署的。

那么这个函数是怎么工作的呢?

  1. 首先,它会检查现在的时间是否超过了你的签名的有效期 (sigDeadline)。就像你签署的合同有个有效期一样,如果现在的时间超过了有效期,那么这个” 合同” 就不能再用了,程序会直接停止。
  2. 接着,它会检查你的签名是否真的是你签的。程序会用一个特殊的方法(signature.verify)来检查这个签名,确保这个签名真的是你签的,没有被别人伪造。
  3. 最后,如果检查都通过了,那么程序就会更新一下记录,记下你已经允许其他人使用你的一些代币。

重点则主要在于 verify 函数和_updateApproval 函数。

verify 函数:

图片

可以看到,verify 函数会从签名信息参数中获取出 v、r、s 三个数据,v、r、s 是交易签名的值,它们可以用来恢复交易签名的地址,上图代码中可以看到,合约恢复了交易签名的地址后,与传入的代币拥有者地址进行比较,如果相同,则验证通过,继续_updateApproval 函数的调用,如果不同,则回滚交易。

_updateApproval 函数:

图片

当通过了签名校验后,会调用_updateApproval 函数更新授权值,这也就意味着你的权限发生了转移。此时,被授权方便可以调用 transferfrom 函数将代币转移到制定地址,如下图代码。

好了,解释完 permit 函数,我们来看看链上真实交易,我们查看这个交互的细节可以发现:

owner 就是小 A 的钱包地址 (尾号 308a)

Details 中可以看到授权的 Token 合约地址 (USDT) 和金额等信息

Spender 就是尾号 fd51 的黑客地址

sigDeadline 是签名的有效时间,而 signature 就是小 A 的签名信息

图片

而往回翻小 A 的交互记录我们会发现,小 A 之前使用 Uniswap 的时候点击了默认的授权额度,也就是几乎无限的额度。

图片

简单复盘一下就是,小 A 在之前使用 Uniswap 的过程中授权给了 Uniswap Permit2 无限的 USDT 额度,而小 A 在进行钱包操作的时候不小心掉入了黑客设计的 Permit2 签名钓鱼陷阱,黑客拿到了小 A 的签名后利用小 A 的签名在 Permit2 合约中进行了 Permit 和 Transfer From 两个操作把小 A 的资产转移走了,而目前菠菜观察到的是 Uniswap 的 Permit2 合约已经沦为了钓鱼天堂,这个 Permit2 签名钓鱼似乎在两个月前才开始活跃。

來源:https://etherscan.io/address/0x000000000022d473030f116ddee9f6b43ac78ba3

並且在交互記錄中可以發現幾乎大部分都是被標記的釣魚位址(Fake_Phishing),不斷有人上當。

來源:https://etherscan.io/address/0x000000000022d473030f116ddee9f6b43ac78ba3

如何防範?

考慮到 Uniswap Permit2 合約可能會在未來更加普及,會有更多專案集成 Permit2 合約進行授權共用,菠菜能想到有效的防範手段有:

1 理解並識別簽名內容:

Permit 的簽名格式通常包含 Owner、Spender、value、nonce 和 deadline 這幾個關鍵格式,如果你想享受 Permit2 帶來的便利和低成本的話一定要學會識別這種簽名格式。(下載安全外掛程式是一個很好的選擇)

我們向各位讀者朋友推薦下面這款 Beosin Alert 反釣魚外掛程式,可以識別 Web3 領域的大部分釣魚網站,守護大家的錢包和資產安全。

圖片

反釣魚外掛程式下載:

https://chrome.google.com/webstore/detail/beosin-alert/lgbhcpagiobjacpmcgckfgodjeogceji?hl=en

2 放資產的錢包和交互的錢包分離使用:

如果你有大量資產的話,建議資產都放在一個冷錢包中,鏈上交互的錢包放少量資金,可以大幅減少遇到釣魚騙局時的損失。

3 不要授權過多額度給 Permit2 合約或取消授權:

當你在 Uniswap 上進行 Swap 的時候,只授權你要交互的金額數量,這樣雖然每次交互都需要重新授權會多出一些交互成本,但是可以免於遭受 Permit2 的簽名釣魚。 如果你已經授權了額度,可以找相應的安全外掛程式進行取消授權。

4 識別代幣性質,是否支援 permit 功能:

後續可能越來越多的 ERC20 代幣使用該擴展協議實現 permit 功能,對於你來說需要關注自己所持有的代幣是否支援該功能,如果支援,那麼對於該代幣的交易或操縱一定要格外小心,對於每條未知簽名也要嚴格檢查是否是對 permit 函數的簽名。

5 若被騙后還有代幣存在其他平臺,需制定完善的拯救計劃:

當你發現自己被詐騙,代幣被駭客轉移出去后,但自己還有代幣通過例如質押等方式存在其他平臺上,需要提取出來轉移到安全位址上,這時需要知道駭客可能時刻監控著你的位址代幣餘額,因為他擁有你的簽名,只要你的被盜位址上出現了代幣,那麼駭客可以直接轉移出去。 這時需要制定完善的代幣拯救過程,在提取代幣和轉移代幣兩個過程需要一起執行,不能讓駭客交易插入其中,可以使用 MEV 轉移,這需要一些區塊鏈知識以及代碼功底,也可以尋找專業的安全公司比如 Beosin 團隊利用交易搶跑腳本來實現。

案例閱讀:加密大 V 遭遇「清道夫」攻擊,Beosin 安全團隊如何幫其追回資金?

相信在未來基於 Permit2 的釣魚可能會越來越多,這種簽名釣魚方式極其隱蔽且難防,並且隨著 Permit2 的應用範圍越來越廣,暴露在風險下的位址也會越來越多,希望螢幕前的你看到本文後可以傳播給更多人,避免更多人被盜。

免責聲明:作為區塊鏈資訊平臺,本站所發佈文章僅代表作者及嘉賓個人觀點,與 Web3Caff 立場無關。 本文內容僅用於資訊分享,均不構成任何投資建議及要約,並請您遵守所在國家或地區的相關法律法規。