技術詳解:鏈上打新局中局,大規模Rug Pull手法解密

avatar
CertiK
6個月前
本文約4103字,閱讀全文需要約6分鐘
近期CertiK監測到超過200個退出騙局,可能預示著一個大規模自動化+透過「退出騙局」方式進行資產收割的駭客團隊。

技術詳解:鏈上打新局中局,大規模Rug Pull手法解密

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

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

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

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

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

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

深入騙局

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

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

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

部署代幣

3 月6 日上午7 點52 分(UTC 時間,下文同),攻擊者地址(0x 8 AF 8)Rug Pull 部署了名為MUMI(全名為MultiMixer AI)的ERC 20 代幣(地址為0x 4894 ),並預挖了420, 690, 000 (約4.2 億)個代幣且全部分配給合約部署者。技術詳解:鏈上打新局中局,大規模Rug Pull手法解密

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

技術詳解:鏈上打新局中局,大規模Rug Pull手法解密

添加流動性

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

攻擊者位址(0x 8 AF 8)調用代幣合約中的openTrading 函數,透過uniswap v2 factory 創建MUMI-WETH 流動性池,將預挖的所有代幣和3 個ETH 添加到流動性池中,最後獲得約1.036 個LP 代幣。技術詳解:鏈上打新局中局,大規模Rug Pull手法解密

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

技術詳解:鏈上打新局中局,大規模Rug Pull手法解密

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

技術詳解:鏈上打新局中局,大規模Rug Pull手法解密

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

鎖定流動性

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

技術詳解:鏈上打新局中局,大規模Rug Pull手法解密

LP 被鎖定後,理論上攻擊者地址(0x 8 AF 8)擁有的所有的MUMI 代幣便被鎖定在流動性池內(除開作為手續費的那部分),因此攻擊者地址(0x 8 AF 8 )也不具備透過移除流動性進行Rug Pull 的能力。為了讓用戶放心購買新推出的代幣,許多項目方都是將LP 進行鎖定,意思是項目方在說:“我不會跑路的,大家放心買吧!”,然而事實真的是這樣嗎?顯然不是,這個案例就是如此,讓我們繼續分析。

Rug Pull

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

技術詳解:鏈上打新局中局,大規模Rug Pull手法解密

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

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

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

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

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

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

技術詳解:鏈上打新局中局,大規模Rug Pull手法解密

由於稅收合約(0x 77 fb)不開源,我們對其字節碼進行反編譯,反編結果如下:https://app.dedaub.com/decompile?md5=01e2888c7691219bb7ea8c6b6befe11c查看完稅合約(0x 77 fb)的「swapExactETHForTokens」方法反編譯代碼後,我們發現實際上該函數實現的主要功能是透過uniswap V2 router 將數量為「xt」(呼叫者指定)的稅收合約(0x 77)擁有的MUMI 代幣兌換成ETH,並發送給稅收地址中聲明的“_manualSwap”地址。

技術詳解:鏈上打新局中局,大規模Rug Pull手法解密

技術詳解:鏈上打新局中局,大規模Rug Pull手法解密

技術詳解:鏈上打新局中局,大規模Rug Pull手法解密

_manualSwap 地址所處的storage 位址為0x 0 ,用json-rpc 的getStorageAt 指令查詢後發現_manualSwap 對應的地址正是稅合約(0x 77)的部署者:攻擊者②(0x 9 DF 4) 。技術詳解:鏈上打新局中局,大規模Rug Pull手法解密

此筆RugPull 交易的輸入參數xt 為420, 690, 000, 000, 000, 000, 000, 000 ,對應420, 690, 000, 000, 000 (約420 萬代幣的個為MUMI decimal 9)。技術詳解:鏈上打新局中局,大規模Rug Pull手法解密也就是說,最終專案方用420, 690, 000, 000, 000 (約420 兆)個MUMI 將流動性池中的WETH 耗幹,完成整個退出騙局。

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

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

技術詳解:鏈上打新局中局,大規模Rug Pull手法解密

手法揭秘

  • 稅收合約哪來的代幣

為了探討稅收合約(0x 7 ffb)的代幣來源,我們檢視了它的ERC 20 轉帳事件歷史。

技術詳解:鏈上打新局中局,大規模Rug Pull手法解密

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

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

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

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

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

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

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

技術詳解:鏈上打新局中局,大規模Rug Pull手法解密

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

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

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

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

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

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

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

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

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

  • 如何獲利

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

技術詳解:鏈上打新局中局,大規模Rug Pull手法解密

稅收合約(0x 77 fb)中的ETH 可以被其合約內實現的「rescue」函數取出。

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

技術詳解:鏈上打新局中局,大規模Rug Pull手法解密

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

技術詳解:鏈上打新局中局,大規模Rug Pull手法解密

而第一次兌換對應的,則是在第二次兌換過程中,當代幣從稅收合約(0x 7 ffb)發送至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 代幣的疑惑行為,都可以理解成是攻擊者為了試圖騙過鏈上各類打新機器人的反詐騙程序而做的偽裝。

我們透過追蹤資金流後發現,攻擊所獲得的收益最後全被攻擊地址②(0x 9 dF 4)送到了地址資金沉澱地址(0x DF 1 a)。技術詳解:鏈上打新局中局,大規模Rug Pull手法解密而實際上我們最近檢測到的多起退出騙局最初的資金來源以及最後的資金去向都指向這個地址,因此我們對這個地址的交易進行了大致的分析和統計。

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

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

其中部分代幣(名煙中華)的部署交易如下:https://etherscan.io/tx/0x324d7c133f079a2318c892ee49a2bcf1cbe9b20a2f5a1f36948641a902a83e17

技術詳解:鏈上打新局中局,大規模Rug Pull手法解密https://etherscan.io/tx/0x 0 ca 86151 3d c 68 eaef 3017 e 7118 e 7538 d 999 f 9 b 4 a 53 e 1 b 477 f 1 f 1 ce 07 d 98 2d c 3 f技術詳解:鏈上打新局中局,大規模Rug Pull手法解密因此我們可以認定,該位址其實就是大規模的自動化「退出騙局」收割機,收割的物件就是鏈上的打新機器人。

該地址現在仍在活躍。

寫在最後

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

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

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

  • 本文使用工具

查看交易基本資訊:https://etherscan.io/

合約反編譯:app.dedaub.com/decompilejson-rpc:

https://www.quicknode.com/docs/ethereum/eth_getStorageAt

原創文章,作者:CertiK。轉載/內容合作/尋求報導請聯系 report@odaily.email;違規轉載法律必究。

ODAILY提醒,請廣大讀者樹立正確的貨幣觀念和投資理念,理性看待區塊鏈,切實提高風險意識; 對發現的違法犯罪線索,可積極向有關部門舉報反映。

推薦閱讀
星球精選