如何在智能合約裡找BUG?你需要知道的7個技巧

尋找智能合約bug可能是一項高回報的工作,而且它也保護了生態系統免受黑客攻擊。我最近有幸採訪了一位開發人員,他發現了一個價值70 億美元的錯誤,並因報告該錯誤而獲得了220 萬美元的報酬。

在這篇文章中,我將詳細介紹該開發人員發現的bug 的過程,以及它如何有可能損害70 億美元的價值,然後再提供一些可幫助你查找錯誤的策略和工具。

讓我們開始吧。

Polygon 智能合約bug 案例

背景

2020 年5 月31 日,Matic 區塊鏈上線(Matic 後來更名為Polygon)。 Polygon 是一種與EVM 兼容的區塊鏈,以其低gas 費用和短塊時間而聞名。該鏈最近開始探索zk-rollup 技術。

如果你查看Polygon 的“創世”區塊,即區塊鏈的第一個區塊,你將看到10 筆交易。其中一筆交易創建了一個名為MRC20 的合約。

如何在智能合約裡找BUG?你需要知道的7個技巧

 Polygon 創世區塊

這個智能合約是什麼?

當我們發送原生區塊鏈通證時,我們必須花費gas。因此,Polygon 團隊部署了一個合約,允許你簽名一項交易以向某人發送ETH,而其他人則可以支付這筆交易的gas 費。這種功能被稱為“元交易”,隨著EIP-712的推出而普及。

你可以看到,該合約獲得了近100 億個MATIC 通證,以幫助促進這些無需gas 的交易。然而,這個設計精巧的合約卻包含一個bug ,而這個bug 可能會被利用來盜走全部餘額!

2021 年12 月3 日,故事的主人公、偽匿名開發者Leon Spacewalker向Immunefi bug 賞金計劃提交了一份報告,詳細介紹了這個函數的問題。第二位英雄,我們稱之為Whitehat2,也在一天后報告了該bug 。

在該鏈於2021 年12 月5 日最終分叉、回滾和修復之前,大約有800,000 個MATIC 被盜。

這次事件給我們拋出了很多問題: bug 是什麼?它是如何長期未被發現的?它是怎麼被發現的?

bug 利用

以下是發送無gas 交易的函數

如何在智能合約裡找BUG?你需要知道的7個技巧

乍一看,它似乎無害:它需要用戶的簽名、有多少通證、他們想將通證發送給誰、進一步的數據,以及交易的到期日期。

它也有一些限制,獲取數據哈希以發送元交易,確保數據哈希未被使用,並執行這個ecrecovery 函數。

這個函數本質上是Solidity ecrecover 函數的Wrapper。

如何在智能合約裡找BUG?你需要知道的7個技巧

 Solidity ecrecover 函數的wrapper

Here's the actual code: 我們這個函數驗證簽名交易的來源。你會注意到,即使在Solidity 文檔中,它也說它將“錯誤的返回值為零”。 ecrecovery 函數也一樣,如果有問題,它會返回0。正如許多開發人員所知,這可能是有風險的。如果它在出錯時返回零,那意味著我們應該檢查以確保返回的地址不為零,對嗎?

這是實際的代碼:

如何在智能合約裡找BUG?你需要知道的7個技巧

這是理想中的代碼:

如何在智能合約裡找BUG?你需要知道的7個技巧

我們其實沒有對地址執行檢查以確保它不會導致錯誤,好吧。 transferWithSig 函數中的最後一行代碼執行實際的轉賬,我們肯定要在那裡執行某種檢查,對吧?

如何在智能合約裡找BUG?你需要知道的7個技巧

_transferFrom 函數剛剛調用了我們的_transfer 函數,如上所示。你會注意到它不會檢查,以確保from 地址有足夠的餘額。

這意味著有人可以發送無效簽名,這將導致從ecrecovery 返回零地址,但MRC20 合約仍會向to 地址發送一定數量的通證。這就是9,999,993,000 MATIC 被盜走的方式,因為MRC20 合約直接從自身發送通證!

如果在合約中檢查,以確保發件人地址有足夠的餘額用於此簽名交易,就可以避免此問題。

為什麼智能合約bug 長期未被發現

令我感到奇怪的是,在該bug 潛伏了將近一年半之後,它在幾天之內就被另一位白帽子Leon 和一名黑客發現了。

好像有貓膩的樣子,但Immunefi 團隊告訴我,這種情況經常發生。某些bug 被利用可能會因一篇文章、文章或挑戰而變得流行,然後人們開始尋找該bug ,導致多個人同時找到它。

但更有可能的是,事實證明Polygon 在這段時間左右在Polygonscan 上驗證了合約——那也是人們真正開始關注它的時候。

也許還有更多的故事,但也許不是。

無論如何,讓我們把這個bug 作為一個教學案例,看看Leon 和其他bug hunter 用來發現bug 的一些技能,幫助保護Web3 生態系統。

7 個發現合約bug 的技巧

現在,我們將學習Leon 和其他bug hunter 用來發現這些bug 併申請bug 賞金的技能。此提示列表假定你已經了解智能合約的基礎知識,所以是的,學習Solidity是先決條件。

請有道德地去使用這些技巧,請記住負責任地披露你發現的任何bug 。

許多查找bug 的工作來自於查看代碼和運行諸如slither之類的工具。對於這筆220 萬美元的收穫,Leon 表示他能夠通過逐行查看智能合約代碼來找到bug ,所以請記住,發現bug 通常需要大量的人工手動操作!

除了下面的實用技巧外,Leon 最大的收穫是讓智能合約bug hunter “找到你的優勢”,什麼意思?通常,這意味著找到讓你有別於其他人的東西。作為一個社區,我們需要覆蓋智能合約空間的每一個角落,所以找到你特別擅長和擅長的部分。

這裡有七個策略和技巧可以幫助你找到優勢,讓你變成成功的智能合約的bug hunter。

1. 找到一個項目然後搜索bug

找到錯誤的第一種方法是詳細地了解協議工作原理。這是每個智能合約bug hunter 需要學習的首要技能之一:端到端理解協議的能力。

瀏覽文檔,嘗試自己重新實現協議,並在區塊瀏覽器上通過該協議查看交易。

Leon 說這個策略對其他bug hunter 有效,但對他無效。他專注於接下來的三個,但對於每個bug hunter 來說,能夠做到這一點很重要。

2. 找到bug 然後搜索項目

尋找bug 的一種更簡單的方法是:找到一個鮮為人知的bug,然後嘗試查看哪些協議的實現中包含這個bug。這種策略需要大量研究,因為有很多人致力於向公眾公開bug:https://swcregistry.io/

你首先需要了解所有基本的智能合約bug ,然後是它們的高級版本。你需要了解最佳實踐並查看是否有未遵循的協議。

一旦發現智能合約bug,你認為很多項目可能無法防範,就開始搜索該bug。直到真正熟悉這個新的bug 以及如何找到它。一定寫博客或某種帖子來幫助遇到此bug 的其他智能合約開發人員。

3.要快

希望bug hunter 查看其智能合約的項目需要註冊像Immunefi這樣的漏洞賞金計劃。你會想成為第一批發現新賞金的開發者之一。如果你比其他獵人先開始查看合約,你將有更多時間找到漏洞。

有幾種方法可以加快速度——Leon 能夠在其他人之前找到智能合約漏洞的方法之一是通過Immunifi Discord 頻道的通知。每當有新項目進入或項目更新時,他都會收到通知。像這樣的工具可以幫助你搶在其他人之前深入研究代碼。

4. 要有創意

Leon 獲得優勢的另一種方式是查看大量的社區論壇,發現他們正在考慮提交bug。然後他甚至在賞金獲得批准之前就開始查看智能合約。這讓他比其他開發人員有更多時間查看合約,因為別人會等待項目方bug 賞金提交成功。

5. 了解你的工具

Bug hunter 要使用VSCode Solidity 的extension、Hardhat、Foundry、Brownie、Dune、Etherscan 以及許多其他工具。

一種的bug 查找策略可能是加載VSCode,使用Solidity extension 將代碼添加到VSCode,然後逐行查找常見錯誤或有漏洞的代碼實現。

找到潛在漏洞後,設置測試環境以對合約運行測試。你通常可以重用協議開發人員最初使用的大量測試。

6. 不要放棄審計過的項目

這裡就不多說了。審計公司會犯錯誤。 Leon 發現漏洞的許多項目都已經過頂級公司的審計。

使用我們在此博客中討論的技巧可以幫助你找到這些問題!

7. 行業特定知識

你最大優勢之一可能就是專注於特定的細分市場。如果你非常了解一個領域,那麼你將擁有了解所有函數如何相互調用的知識。相反,如果你是一個厲害的智能合約漏洞專家,但對DeFi 一無所知,那麼很難找到DeFi 合約中的漏洞。例如,許多開發人員了解代碼,但不了解財務術語。

你可能非常擅長理解去中心化交易所、借貸協議,或者只是NFT!

如果你能成為安全專家和Web3 中某個垂直領域的專家,你將處於有利地位,在其他尋找漏洞的人面前佔據優勢。

總結

我希望這篇文章在你的智能合約bug 搜索之旅中幫助到你。如果你想在編寫智能合約時了解更多有關安全的信息,請務必查看十大DeFi 安全最佳實踐。

而且,一如既往,我希望看到你在那裡建設並保持生態系統更安全。

相關鏈接:

? MRC20 contract:

https://polygonscan.com/address/0x0000000000000000000000000000000000001010#code

?Immunefi writeup:

https://medium.com/immunefi/polygon-lack-of-balance-check-bugfix-postmortem-2-2m-bounty-64ec66c24c7d

?Change to Polygon contracts:

https://github.com/maticnetwork/contracts/commit/55e8118ad406c9cb0e9b457ca4f275c5977809e4#diff-cc4ed03464edad9d87d48cff647eb6940dfe9a4c419f63e3994bdc91b01bfecb

?Previous Polygon contracts:

https://github.com/maticnetwork/contracts/blob/56ec7eb257ce10a9f70621f56f6e3f37eb8e0c57/contracts/child/MRC20.sol

?Ecrecovery challenge:

https://github.com/code-423n4/2021-09-swivel-findings/issues/61