作者: @korpi87

編譯:Kxp,BlockBeats

你可能很難想像,Metamask 中一個簡單的簽名就能掏空你的錢包。但這樣的事卻發生在了一名資深用戶身上,今天他因一個漏洞損失了近50 萬USDC 。如果不多加小心的話,你可能就是下一個他。所以,今天我想和大家講講這件事的來龍去脈,告訴大家以後如何注意此類問題。

那是在一個安靜的午後時分,Joe(化名)突然發現自己的錢包被轉走了46.9 萬USDC。這次轉賬並不簡單,肯定不是攻擊者能做出的行為,因為他們根本不可能得到Joe 錢包的權限。那就說明,轉走他所有USDC 的應該是某個惡意合約。

50萬美元的血淚教訓:一個簡單的簽名如何導致資產被盜?

在講述今天的故事之前,我需要先向大家解釋一些術語。 USDC 是以太坊上的一個具有多種功能的合約,規定了我們可以如何使用USDC。

在眾多功能當中,我們需要特別關注下面兩項功能:

轉賬(transfer)

代轉(transferFrom)

50萬美元的血淚教訓:一個簡單的簽名如何導致資產被盜?

當你需要在錢包之間轉移USDC,或其他ERC20s 時,就需要用到轉賬功能。它可以將Token 從調用者(調用該功能的地址)轉移到其他地址。如果有人能以你的名義惡意使用該功能,那麼他一定得先掌握了你錢包的全部權限才行。

50萬美元的血淚教訓:一個簡單的簽名如何導致資產被盜?

當你與合約產生互動時,它們會通過代轉功能來轉移你的Token,具體金額由你提前預設好的比例決定。因此,如果你允許一項合約轉移無限量的USDC,那麼理論上它就可以拿走你所有的USDC。

現在讓我們回到Joe 的故事當中,轉走他全部USDC 的確實就是transferFrom 功能。然而,只有當Joe 批准合約使用他的USDC 時,transferFrom 才能發揮作用。但事實上,Joe 堅信自己沒有批准任何事項。

50萬美元的血淚教訓:一個簡單的簽名如何導致資產被盜?

可是,DeBank 的交易記錄清楚地顯示,在漏洞發生前10 分鐘,該惡意合約可以無限使用賬戶中的USDC。那麼問題就在於,如果不是Joe 本人的話,究竟是誰給了該合約這一項批准呢?我只能說,Joe 確實批准了這一操作,但卻是在他不知情的情況下完成的。

50萬美元的血淚教訓:一個簡單的簽名如何導致資產被盜?

Etherscan 上的信息顯示,Joe 本人確實沒有調用該功能,真正批准了這一額度的是其他地址,這才讓惡意合約得以花光Joe 全部的USDC。

我們不禁疑問,別人怎麼能代替我給予合約許可呢?

50萬美元的血淚教訓:一個簡單的簽名如何導致資產被盜?

許可功能的引入原本是為了改善以太坊的用戶體驗,它只需一個簽名就可以讓用戶在不提交交易的情況下修改批准金額。也就是說,只要有了你的簽名,任何人都可以調用許可功能,並更新你對合約的批准額度。

50萬美元的血淚教訓:一個簡單的簽名如何導致資產被盜?

當你使用1inch dApp 時,你就可以體驗到這一功能。如果你想在上面出售USDC,那你並不需要事先批准,只需要籤上你的名字就夠了。有了這個簽名,1inch 便獲取了你全部USDC 的使用權限。雖然1inch 不會無緣無故花光你所有的USDC,但這卻給了惡意合約機會。

50萬美元的血淚教訓:一個簡單的簽名如何導致資產被盜?

Joe 一定是不小心在一個惡意網站上簽署了這樣的信息。不幸的是,那一次他用的是熱錢包,簽名只是隨手點擊一下就完成了。如果他用的是硬件錢包的話,就需要在外部設備上簽署信息,那麼還會有一個思考的時間。

有了Joe 的簽名,其他地址便可以提交一個帶有許可功能的交易,這樣惡意合約就獲取了Joe 錢包全部USDC 的使用權限。然後,只要它調用transferFrom 功能,就可以轉走全部這些資金了。

50萬美元的血淚教訓:一個簡單的簽名如何導致資產被盜?

所以說,一個看似小小的簽名卻可以引來巨大的災難。在某些情況下,Metamask 會在你準備簽名是對你發出警告,告知你其中的危險性。簽署一個信息可能是危險的。但一些技術層面上的批准簽名卻不會收到預警,但這些一旦濫用往往會造成巨額的損失。

如何避免今後遇到類似的問題?

1. 不要在Metamask 中籤署一切內容;

2. 花點時間了解你所簽署的內容;

3. 對傳統的批准事項要格外小心。