Web3安全警示丨鏈上打新局中局,大規模Rug Pull手法解密

近日,CertiK安全專家團隊頻繁地偵測到多起手法相同的“退出騙局”,也就是我們俗稱的Rug Pull。

在我們進行深入挖掘後發現,多起相同手法的事件都指向同一個團夥,最終關聯到超過200個Token退出騙局。這預示著我們可能發現了一個大規模自動化的,透過「退出騙局」方式進行資產收割的駭客團隊。

在這些退出騙局中,攻擊者會創建一個新的ERC20代幣,並用創建時預挖的代幣加上一定數量的WETH創建一個Uniswap V2的流動性池。

當鏈上的打新機器人或使用者在該流動性池購買一定次數的新代幣後,攻擊者則會透過憑空產生的代幣,將流動性池中的WETH全部耗盡。

由於攻擊者在憑空獲取的代幣沒有反映在總供應量(totalSupply),也不觸發Transfer事件,在etherscan是看不到的,因此外界難以感知。

攻擊者不僅考慮了隱蔽性,還設計了一個局中局,用來麻痺擁有初級技術能力,會看etherscan的用戶,用一個小的問題來掩蓋他們真正的目的…

深入騙局

我們以其中一個案例為例,詳解一下該退出騙局的細節。

被我們偵測到的實際上是攻擊者用巨量代幣(偷偷mint的)耗乾流動性池並獲利的交易,在該交易中,項目方共計用416,483,104,164,831(約416萬億)個MUMI兌換出了約9.736個WETH,耗乾了池子的流動性。

然而該交易只是整個騙局的最後一環,我們要了解整個騙局,就需要繼續往前追溯。

部署代幣

3月6日上午7點52分(UTC時間,下文同),攻擊者地址(0x8AF8)Rug Pull部署了名為MUMI(全名為MultiMixer AI)的ERC20代幣(地址為0x4894),並預挖了420,690,000(約4.2億)個代幣且全部分配給合約部署者。

預挖代幣數量與合約原始碼相對應。

Web3安全警示丨鏈上打新局中局,大規模Rug Pull手法解密

添加流動性

8點整(代幣創建8分鐘後),攻擊者地址(0x8AF8)開始增加流動性。

攻擊者地址(0x8AF8)調用代幣合約中的openTrading函數,透過uniswap v2 factory創建MUMI-WETH流動性池,將預挖的所有代幣和3個ETH添加到流動性池中,最後獲得約1.036個LP代幣。

Web3安全警示丨鏈上打新局中局,大規模Rug Pull手法解密

Web3安全警示丨鏈上打新局中局,大規模Rug Pull手法解密

從交易細節可以看出,原本用於添加流動性的420,690,000(約4.2億)個代幣中,有63,103,500(約6300萬)約個代幣又被發送回代幣合約(地址0x4894),透過查看合約原始碼發現,代幣合約為每筆轉帳收取一定的手續費,而收取手續費的地址正是代幣合約本身(具體實現在「_transfer函數中」)。

Web3安全警示丨鏈上打新局中局,大規模Rug Pull手法解密

奇怪的是,合約中已經設定了稅務地址0x7ffb(收取轉帳手續費的地址),最後手續費卻被發到代幣合約本身。

Web3安全警示丨鏈上打新局中局,大規模Rug Pull手法解密

因此最後被添加到流動性池的MUMI代幣數量為扣完稅的357,586,500(約3.5億),而不是420,690,000(約4.3億)。

鎖定流動性

8點1分(流動性池創建1分鐘後),攻擊者地址(0x8AF8)鎖定了透過添加流動性所獲得的全部1.036個LP代幣。

Web3安全警示丨鏈上打新局中局,大規模Rug Pull手法解密

LP被鎖定後,理論上攻擊者地址(0x8AF8)擁有的所有的MUMI代幣便被鎖定在流動性池內(除開作為手續費的那部分),因此攻擊者地址(0x8AF8)也不具備通過移除流動性進行Rug Pull的能力。

為了讓用戶放心購買新推出的代幣,許多專案方都是將LP進行鎖定,意思是專案方在說:“我不會跑路的,大家放心買吧!”,然而事實真的是這樣嗎?顯然不是,這個案例就是如此,讓我們繼續分析。

Rug Pull

8點10分,出現了新的攻擊者地址②(0x9DF4),Ta部署了代幣合約中聲明的稅收地址0x7ffb。

Web3安全警示丨鏈上打新局中局,大規模Rug Pull手法解密

這裡有三個值得一提的點:

1.部署稅收地址的地址和部署代幣的地址並不是同一個,這可能說明項目方在有意減少各個操作之間與地址的關聯性,提高行為溯源的難度

2.稅收地址的合約不開源,也就是說稅務地址中可能隱藏有不想暴露的操作

3.稅收合約比代幣合約晚部署,而代幣合約中稅收地址已被寫死,這意味著專案方可以預知稅收合約的地址,由於CREATE指令在確定創建者地址和nonce的情況下,部署合約地址是確定的,因此專案方提前就使用創建者地址模擬計算出了合約地址

其實有不少退出騙局都是透過稅收地址進行,且稅收地址的部署模式特徵符合上述的1、2點。

上午11點(代幣創建3小時後),攻擊者地址②(0x9DF4)進行了Rug Pull。他透過調用稅收合約(0x77fb)的「swapExactETHForTokens」方法,用稅收地址中的416,483,104,164,831(約416萬億)個MUMI代幣兌換了約9.736個ETH,並耗盡了池子中流動性。

Web3安全警示丨鏈上打新局中局,大規模Rug Pull手法解密

由於稅收合約(0x77fb)不開源,我們對其字節碼進行反編譯,反編結果如下:

https://app.dedaub.com/decompile?md5=01e2888c7691219bb7ea8c6b6befe11c

檢視完稅收合約(0x77fb)的「swapExactETHForTokens」方法反編譯程式碼後,我們發現實際上該函數實現的主要功能就是透過uniswapV2 router將數量為「xt」(呼叫者指定)的稅收合約(0x77fb)擁有的MUMI代幣兌換成ETH,並發送給稅務地址中聲明的「_manualSwap」地址。

Web3安全警示丨鏈上打新局中局,大規模Rug Pull手法解密

Web3安全警示丨鏈上打新局中局,大規模Rug Pull手法解密

Web3安全警示丨鏈上打新局中局,大規模Rug Pull手法解密

_manualSwap位址所處的storage位址為0x0,以json-rpc的getStorageAt指令查詢後發現_manualSwap對應的位址正是稅務合約(0x77fb)的部署者:攻擊者②(0x9DF4)。

Web3安全警示丨鏈上打新局中局,大規模Rug Pull手法解密

此筆Rug Pull交易的輸入參數xt為420,690,000,000,000,000,000,000,對應420,690,000,000,000(約420兆)個MUMI代幣(MUMI代幣的decimal為9)。

Web3安全警示丨鏈上打新局中局,大規模Rug Pull手法解密

也就是說,最終專案方用420,690,000,000,000(約420兆)個MUMI將流動性池中的WETH耗幹,完成整個退出騙局。

然而這裡有一個至關重要的問題,就是稅收合約(0x77fb)哪來的這麼多MUMI代幣?

從前面的內容我們得知,MUMI代幣在部署時的代幣合約時的總供應量為420,690,000(約4.2億),而在退出騙局結束後,我們在MUMI代幣合約中查詢到的總供應量依舊為420,690,000(下圖中顯示為420,690,000,000,000,000,需要減去decimal對應位數的0,decimal為9),稅收合約(0x77fb)中的遠超總供應量的代幣(420,690,000,000,000 億就彷彿憑空出現的一樣,要知道,如上文所提,0x77fb作為稅收地址甚至沒有被用於接收MUMI代幣轉賬過程中產生的手續費,稅收被代幣合約接收了。

Web3安全警示丨鏈上打新局中局,大規模Rug Pull手法解密

手法揭秘

  • 稅收合約哪來的代幣

為了探討稅收合約(0x7ffb)的代幣來源,我們查看了它的ERC20轉帳事件歷史。

Web3安全警示丨鏈上打新局中局,大規模Rug Pull手法解密

結果發現在全部6筆關於0x77fb的轉帳事件中,只有從稅收合約(0x7ffb)轉出的事件,而沒有任何MUMI代幣轉入的事件,乍一看,稅收合約(0x7ffb)的代幣還真是憑空出現的。

所以稅收合約(0x7ffb)地址中憑空出現的巨額MUMI代幣有兩個特點:

1.沒有對MUMI合約的totalSupply產生影響

2.代幣的增加沒有觸發Transfer事件

那麼想法就很明確了,即MUMI代幣合約中一定存在後門,這個後門直接對balance變數進行修改,且在修改balabce的同時不對應修改totalSupply,也不觸發Transfer事件。

也就是說,這是一個不標準的、或者說是惡意的ERC20代幣實現,用戶無法從總供應量的變化和事件中感知到專案方在偷偷mint代幣。

接著就是驗證上面的想法,我們直接在MUMI代幣合約原始碼中搜尋關鍵字「balance」。

Web3安全警示丨鏈上打新局中局,大規模Rug Pull手法解密

結果我們發現傳入參數為uint256類型的tokenAmount,在該函數的第5行,項目方直接將_taxWallet,也就是稅收合約(0x7ffb)的MUMI餘額修改為tokenAmount * 10**_decimals,也就是tokenAmount的1,000,000,000(約10億)倍,然後再從流動性池中將tokenAmount數量的MUMI兌換為ETH並存在代幣合約(0x4894)中。

再接著搜尋關鍵字“swapTokenForEth“。

Web3安全警示丨鏈上打新局中局,大規模Rug Pull手法解密

「swapTokenForEth」函數在「_transfer」函數中被調用,再細看調用條件,會發現:

1.當轉帳的接收位址to位址為MUMI-WETH流動性池。

2.當有其他地址在流動性池中購買MUMI代幣的數量超過_preventSwapBefore(5次)時,“swapTokenForEth”函數才會被調用

3.傳入的tokenAmount為代幣地址所擁有的MUMI代幣餘額和_maxTaxSwap之間的較小值

Web3安全警示丨鏈上打新局中局,大規模Rug Pull手法解密

Web3安全警示丨鏈上打新局中局,大規模Rug Pull手法解密

也就是說當合約偵測到用戶在池子中用WETH兌換成MUMI代幣超過5次後,便會為稅收地址偷偷mint巨量代幣,並將一部分代幣兌換成ETH儲存在代幣合約中。

一方面,專案方表面上進行收稅並定期自動換成少量ETH放到代幣合約,這是給用戶看的,讓大家以為這就是專案方的利潤來源。

另一方面,專案方真正在做的,則是在用戶交易次數達到5次後,直接修改帳戶餘額,把流動性池全部抽乾。

  • 如何獲利

執行完「swapTokenForEth」函數後,「_transfer」函數也會執行sendETHToFee將代幣地址中收稅所獲得的ETH傳送到稅務合約(0x77fb)。

Web3安全警示丨鏈上打新局中局,大規模Rug Pull手法解密

稅收合約(0x77fb)中的ETH可以被其合約內實現的“rescue”函數取出。

Web3安全警示丨鏈上打新局中局,大規模Rug Pull手法解密

現在再回看整個退出騙局中最後一筆獲利交易的兌換記錄。

Web3安全警示丨鏈上打新局中局,大規模Rug Pull手法解密

獲利交易中共進行了兩次兌換,第一次是4,164,831(約416萬)個MUMI代幣換0.349個ETH,第二次是416,483,100,000,000(約416兆)個MUMI代幣換9.368個ETH。其中第二次兌換即為稅收合約(0x7ffb)中「swapExactETHForTokens」函數內發起的兌換,之所以數量與輸入參數代表的420,690,000,000,000(約420兆)個代幣不符,是因為有部分代幣作為稅收發送給了代幣合約(0x4894),如下圖所示:

Web3安全警示丨鏈上打新局中局,大規模Rug Pull手法解密

而第一次兌換對應的,則是在第二次兌換過程中,當代幣從稅收合約(0x7ffb)發送至router合約時,由因為滿足代幣合約內的後門函數觸發條件,導致觸發“swapTokensForEth”函數所發起的兌換,並非關鍵操作。

  • 背後的大鐮刀

從上文可以看出,MUMI代幣從部署,到創建流動性池,再到Rug Pull,整個退出騙局週期才約3個小時,但是卻以不到約6.5個ETH的成本(3 ETH用於添加流動性,3 ETH用於從流動性池中兌換MUMI以作誘導,不到0.5 ETH用於部署合約和發起交易)獲得了9.7個ETH,利潤超過50%。

攻擊者用ETH換MUMI的交易有5筆,前文並沒有提到,交易資訊如下:

  • https://etherscan.io/tx/0x62a59ba219e9b2b6ac14a1c35cb99a5683538379235a68b3a607182d7c814817
  • https://etherscan.io/tx/0x0c9af78f983aba6fef85bf2ecccd6cd68a5a5d4e5ef3a4b1e94fb10898fa597e
  • https://etherscan.io/tx/0xc0a048e993409d0d68450db6ff3fdc1f13474314c49b734bac3f1b3e0ef39525
  • https://etherscan.io/tx/0x9874c19cedafec351939a570ef392140c46a7f7da89b8d125cabc14dc54e7306
  • https://etherscan.io/tx/0x9ee3928dc782e54eb99f907fcdddc9fe6232b969a080bc79caa53ca143736f75

透過分析在流動性中進行操作的eoa地址後發現,相當一部分的地址為鏈上的“打新機器人”,結合整個騙局快進快出的特點,我們有理由認為,這整個騙局針對的對象正是鏈上十分活躍的各種打新機器人、打新腳本。

因此無論是代幣看似沒必要但是複雜的合約設計、合約部署、流動性鎖定流程,還是中途攻擊者相關地址主動用ETH換取MUMI代幣的疑惑行為,都可以理解成是攻擊者為了試圖騙過鏈上各類打新機器人的反詐騙程式而做的偽裝。

我們透過追蹤資金流後發現,攻擊所獲得的收益最後全被攻擊地址②(0x9dF4)送到了地址資金沉澱地址(0xDF1a)。

Web3安全警示丨鏈上打新局中局,大規模Rug Pull手法解密

而實際上我們最近檢測到的多起退出騙局最初的資金來源以及最後的資金去向都指向這個地址,因此我們對這個地址的交易進行了大致的分析和統計。

最終發現,該地址在約2個月前開始活躍,到今天為止已經發起了超過7,000筆交易,並且該地址已經和超過200個代幣進行過交互。

我們對其中的約40個代幣交易記錄進行分析,然後發現我們查看的幾乎所有代幣對應的流動性池中,最後都會有一筆輸入數量遠大於代幣總供應量的兌換交易將流動性池中的ETH耗盡,且整個退出騙局的週期都較短。

其中部分代幣(名煙中華)的部署交易如下:

https://etherscan.io/tx/0x324d7c133f079a2318c892ee49a2bcf1cbe9b20a2f5a1f36948641a902a83e17

Web3安全警示丨鏈上打新局中局,大規模Rug Pull手法解密

https://etherscan.io/tx/0x0ca861513dc68eaef3017e7118e7538d999f9b4a53e1b477f1f1ce07d982dc3f

Web3安全警示丨鏈上打新局中局,大規模Rug Pull手法解密

因此我們可以認定,該地址其實就是一個大規模的自動化「退出騙局」收割機,收割的物件就是鏈上的打新機器人。

該地址現在仍在活躍。

寫在最後

如果一個代幣在mint時不對應修改totalSupply,也不觸發Transfer事件,那麼我們是很難感知專案方是否有在偷偷mint代幣的,這也將加劇「代幣是否安全,完全依賴於專案方是否自覺」的現狀。

因此我們可能需要考慮改進現有的代幣機製或引入一種有效的代幣總量檢測方案,來保障代幣數量變更的公開透明,現在憑藉event來捕獲代幣狀態變更是不夠的。

而我們需要警醒的是,儘管現在大家的防騙意識在提高,但是攻擊者的反防騙手段也在提高,這是一場永不停息的博弈,我們需要保持不斷學習和思考,才能在這樣的博弈中保全自身。

Total
0
Shares
Related Posts