Web3安全預警鏈上打新局中局交稅的狙擊機器人


《鏈上打新局中局,大規模RugPull方法揭秘》之前的文章揭示了一個自動化收割機地址0xdf1a對打新機器人的大規模退出騙局。該地址完成了200次以上RugPull,不只有一種手段。文章以「中華」代幣為例,解析了團體另一種RugPull手法。透過複雜的稅務功能邏輯隱藏邏輯功能,利用特定邏輯規避餘額校驗取消特權地址的代幣餘額增量上限。攻擊者透過RugPull獲利,專案方有意無視特權位址不需校驗餘額的後門代碼。比對MUMI代幣案例,中華代幣的RugPull手法更隱蔽,團隊透過相對座標讓分配地址擁有支配大量代幣權利。中華代幣案例揭示ERC20代幣標準潛在安全問題,強調安全防護視角不同。

背景

在CC之前的《鏈上打新局中局,大規模RugPull方法揭秘》中,揭示了一個針對打新機器人的大規模退出騙局自動化收割機地址0xdf1a,該地址在短短兩個月左右就完成了已經超過200次退出騙局(以下統稱RugPull),但這個團體並非只有一種RugPull手段。

先前的文章中以MUMI代幣為例,介紹了該地址背後團伙的RugPull手法:透過代碼後門直接描述了稅收地址的代幣餘額,但卻沒有修改代幣的總供應量,也沒有發送轉帳事件,從而使查看了etherscan的用戶也無法發現專案方偷偷鑄造代幣的行為。

今天的文章以代幣「中華」為例解析該團伙的另一種RugPull手法:用複雜的稅收功能邏輯,隱藏可用於RugPull的邏輯功能。接下來,我們透過「中華」代幣案例,分析地址0xdf1a的另一種RugPull技巧細節。

深入騙局

在這個案例中,專案方總共花了9,990億個中華消費成長了約5.884個WETH,消耗了礦池子的流動性。為了深入了解整個RugPull局,我們從頭梳理一下事件脈絡。

部署代幣

1月18日凌晨1點40分(UTC時間,下游同),攻擊者地址(😈0x74fc)部署了名為中華的ERC20代幣(🪙0x71d7),並預挖了10億個代幣發送給攻擊者地址(😈0x74fcfc)。

預挖代幣數量與合約原始碼內定義的數量一致。

Web3安全預警丨鏈上打新局中局,繳稅的狙擊機器人

增加流動性

1點50分(代幣創建10分鐘後),攻擊者地址(😈0x74fc)向Uniswap V2路由器授予中華代幣的批准權限,以準備添加流動性。

Web3安全預警丨鏈上打新局中局,繳稅的狙擊機器人

1分鐘後,攻擊者地址(😈0x74fc)調用Router中addLiquidityETH函數添加流動性以創建ZhongHua-WETH流動性礦池(🦄0x5c8b),將預挖的所有代幣和1.5個ETH添加到流動性礦池中,最後獲得約1.225個LP代幣。

Web3安全預警丨鏈上打新局中局,繳稅的狙擊機器人

從代幣轉帳記錄中我們可以看到,有一筆代幣是攻擊者(😈0x74fc)發送了0個代幣給了中華代幣合約本身。

下一趟不屬於添加流動性的往返,透過查看代幣合約原始碼發現,其中實現了_getAmount函數,該函數負責從轉帳的地址扣款併計算所要收取的手續費,然後將手續費發送至代幣地址,再觸發表示代幣地址收到手續費的轉帳事件。

Web3安全預警丨鏈上打新局中局,繳稅的狙擊機器人

_getAmount函數中會判斷轉帳的發送者不是_owner,如果_owner則將手續費設為0。 _owner在Ownable合約部署時由建構函式建構函式的輸入參數賦予。

Web3安全預警丨鏈上打新局中局,繳稅的狙擊機器人

而中華代幣合約繼承了Ownable合約,並在部署時將部署者msg.sender作為Ownable建構子的輸入參數。

因此攻擊者地址(😈0x74fc)就是代幣合約的_owner。而加入流動性的那筆0代幣轉帳就是透過_getAmount函數發出的,因為_getAmount會在transfer和transferFrom函數內被呼叫。

永久鎖定流動性

1點51分(流動性礦池創建的1分鐘內),攻擊者地址(😈0x74fc)將透過添加流動性獲取的全部1.225個LP代幣直接發送至0xdead地址,以完成對LP代幣的永久鎖定。

Web3安全預警丨鏈上打新局中局,繳稅的狙擊機器人

同MUMI代幣案例一樣,當LP被鎖定後,理論上攻擊者地址(😈0x74fc)便不再具備透過移除流動性進行RugPull的能力。而在由地址0xdf1a主導的針對打新機器人的RugPull騙局中,這一步驟主要是用來騙過打新機器人的反偽裝腳本。

至此,在使用者看來所有的預挖Token都是為了加入流動性礦池中,容易出現異常狀況。

地毯拉力

凌晨2點10分(中華代幣創建約30分鐘後),攻擊者地址2(👹0x5100)部署了專門用於RugPull的攻擊合約(🔪0xc403)。

Web3安全預警丨鏈上打新局中局,繳稅的狙擊機器人

同MUMI代幣的案例一樣,專案方沒有使用部署中華代幣合約的那個攻擊地址,且對於RugPull的攻擊合約不開源,目的都是為了提高技術人員溯源的難度,大部分RugPull騙局都有這樣的特點。

7點46分(代幣簽約創建約6小時後),攻擊者地址2(👹0x5100)上午進行了RugPull。

他透過調用攻擊合約(🔪0xc403)的「swapExactETHForTokens」方法,從攻擊合約中轉出9,990億個中華幣代幣增長約5.884個ETH,並取得了礦池子中大部分流動性。

Web3安全預警丨鏈上打新局中局,繳稅的狙擊機器人

由於攻擊合約(🔪0xc403)不開源,我們對此進行瞭如下字節碼進行了反編譯,結果:

https://app.dedaub.com/ethereum/address/0xc40343c5d0e9744a7dfd8eb7cd311e9cec49bd2e/decompiled

約定攻擊(🔪0xc403)的「swapExactETHForTokens」函數主要功能就是先用approve為UniswapV2 Router取得最大數量的中華代幣權限,再透過Router將呼叫者指定數量為「xt」的中華代幣(攻擊合約() 🔪0xc403)擁有的)兌換成ETH,人道主義運輸攻擊合約(🔪0xc403)中聲明的「_rescue」地址。

Web3安全預警丨鏈上打新局中局,繳稅的狙擊機器人

Web3安全預警丨鏈上打新局中局,繳稅的狙擊機器人

Web3安全預警丨鏈上打新局中局,繳稅的狙擊機器人

Web3安全預警丨鏈上打新局中局,繳稅的狙擊機器人

可以看到「_rescue」對應的位址就是攻擊合約(🔪0xc403)的部署者:攻擊者位址2(👹0x5100)。

此筆RugPull交易的輸入參數xt為999,000,000,000,000,000,000,對應9,990億個中華代幣(中華的小數為9)。

Web3安全預警丨鏈上打新局中局,繳稅的狙擊機器人

最終專案方用9,990億個中華將流動性礦池中的WETH消費乾,完成地毯拉動。

和先前文章的MUMI案例一樣,我們需要先確認攻擊合約(🔪0xc403)中華代幣的來源。從先前的文中我們得知中華代幣的總供應量為10億,而在RugPull結束後,我們在區塊瀏覽器中查詢到的中華代幣總供應量依然是10億,但攻擊合約(🔪 0xc403)出售的代幣數量卻是9,990億,是合約記錄的總供應量的999倍,這些遠超總供應量的代幣從何而來?

Web3安全預警丨鏈上打新局中局,繳稅的狙擊機器人

我們查看了合約的ERC20轉入事件歷史,發現和MUMI代幣的RugPull案例一樣,中華代幣案例中的攻擊合約(🔪0xc403)也沒有ERC20代幣的轉入事件。

Web3安全預警丨鏈上打新局中局,繳稅的狙擊機器人

在MUMI的案例中,稅收合約的代幣來自於代幣合約中直接對平衡的修改,使得稅收合約直接擁有遠超總供應量修改的代幣。由於MUMI代幣合約在平衡時不會修改對應代幣幣的總供應量,也沒有觸發轉移事件,我們因此無法看到MUMI案例中的代幣轉入,這一記錄中的標記為RugPull的代幣就像空出現一樣。

回到中華這個案例,攻擊合約(🔪0xc403)中的中華代幣也像去憑空出現的一樣,因此我們也中華代幣合約中搜尋「balance」這個關鍵字。

Web3安全預警丨鏈上打新局中局,繳稅的狙擊機器人

Web3安全預警丨鏈上打新局中局,繳稅的狙擊機器人

Web3安全預警丨鏈上打新局中局,繳稅的狙擊機器人

結果顯示整個代幣一致了三處對餘額變數的修改,分別在「_getAmount」、「_transferFrom」和「_transferBasic」函數中。

其中「_getAmount」用來處理回合轉帳的邏輯,「_transferFrom」和「_transferBasic」則在處理回合邏輯中,並沒有出現如下圖MUMI代幣一般明顯地直接修改balance的語句。

Web3安全預警丨鏈上打新局中局,繳稅的狙擊機器人

更關鍵的是,MUMI代幣合約直接改變了標籤代幣的平衡時並沒有觸發轉移事件,這也是我們無法在區塊瀏覽器中查詢到標籤代幣轉入事件,但標籤合約卻能擁有大量代幣幣的原因。

然而在中華代幣合約中,無論是「_getAmount」、「_transferFrom」或「_transferBasic」函數,它們在對balance進行修改後,都有觸發正確的轉帳事件,這與我們前面查詢與攻擊合約(🔪0xc403 )相關的轉帳事件時無法發現代幣轉入的轉帳事件的情況是衝突的。

難道與MUMI的案例不同,這次攻擊合約(🔪0xc403)中的代幣確實憑空出現的?

手法揭秘

攻擊契約的代幣從何來

在分析案例的過程中,當我們發現中華合約每次修改餘額都正確觸發了轉帳事件,卻又始終找不到與攻擊合約(🔪0xc403)相關的代幣轉入記錄或轉帳事件時,就需要找到新的分析思路。

我們查詢大量的周轉記錄,也一度把合約中的「performZhongSwap」函數設定為斷口,該函數負責將代幣出售合約中的代幣,在分析的其他RugPull事件中,存在明顯的以這類函數作為RugPull後門的案例。

儘管檢查了其他函數,結果還是一無所獲。於是我們開始將視野放到了「transfer」函數本身,無論攻擊者以什麼方式進行RugPull,「transfer」函數的實作邏輯一定都包含著最重要的資訊。

Web3安全預警丨鏈上打新局中局,繳稅的狙擊機器人

致命的轉會

代幣合約中的「transfer」函數直接呼叫了「_transferFrom」函數。

Web3安全預警丨鏈上打新局中局,繳稅的狙擊機器人

檢視「轉帳」函數進行代幣交易,轉帳完成後會觸發轉帳事件。

但在進行代幣轉帳前,「轉帳」函數會先用「_isNotTax」函數判斷轉帳的發送者是否為免稅地址:若不是則用「_getAmount」函數收稅;如果則不收稅,將代幣直接轉帳到收件人。而問題也正是出在這裡。

前文也提到,在「_getAmount」的實作中,代幣合約校驗了發送者的餘額,實體發送者進行了扣款,然後將手續費發送至代幣合約。

Web3安全預警丨鏈上打新局中局,繳稅的狙擊機器人

Web3安全預警丨鏈上打新局中局,繳稅的狙擊機器人

而問題在於,「_getAmount」僅在發送方不是稅務地址的時候被呼叫。當發送方是稅務地址時,則直接為接收方的餘額加上金額。

此時問題變得十分明確:當地址信貸作為發送者的輪流時,代幣合約並沒有去校驗發送者的餘額是否有足夠的時間,甚至都沒有從發送者的餘額中增加金額的操作。這意味著僅僅是代幣合約規定的地址物資,就可以向任何地址提供任何數量的代幣。這就是攻擊合約(🔪0xc403)能直接轉出999倍於總供應量的代幣的原因。

經檢查後發現,代幣合約僅在建構函式中將_taxReceipt設定為稅務地址,而_taxReceipt對應的地址正是攻擊合約(🔪0xc403)。

Web3安全預警丨鏈上打新局中局,繳稅的狙擊機器人

Web3安全預警丨鏈上打新局中局,繳稅的狙擊機器人

Web3安全預警丨鏈上打新局中局,繳稅的狙擊機器人

由此確定了中華代幣的RugPull的手法:攻擊者利用特定的邏輯規避了對特權地址的餘額校驗,使得特權地址能夠憑藉空轉出代幣,首先完成RugPull。

如何獲利

Web3安全預警丨鏈上打新局中局,繳稅的狙擊機器人

利用上述的漏洞,攻擊者位址2(👹0x5100)直接呼叫擁有特權的攻擊契約(🔪0xc403)的「swapExactETHForTokens」完成RugPull。 「swapExactETHForTokens」函數中,攻擊契約(🔪0xc403)為Uniswap V2 Router取得了代幣流通權限,然後直接呼叫路由器的代幣兌換函數,用9,990億個中華代幣兌換成長礦池子中的5.88個ETH。

另外,除上述近期進行RugPull的交易之外,專案方還透過攻擊合約(🔪0xc403)在中途出售過11次代幣,累計獲得9.64ETH;加上最後一筆RugPull交易,共計獲得15.52ETH。而成本不過是用於添加流動性的1.5 個ETH、用於配置消耗的少量手續費以及用於誘導打新機器人而進行主動兌換所消耗的少量ETH。

甚至專案方中途還用不同的EOA地址去調用該攻擊合約(🔪0xc403)進行代幣出售,看待不同的發送者在出售代幣,以偽裝其不斷套現的真實含義。

Web3安全預警丨鏈上打新局中局,繳稅的狙擊機器人

總結

現在回過頭來思考整個中華代幣的RugPull案例,發現其手法本身很簡單,不過是取消特權地址的代幣餘額增量上限。但是為什麼在分析這個案例的時候卻沒有那麼順利?關鍵可能有2點:

1.安全防護和攻擊的視野不同。對於安全從業者來說,程式碼中的餘額校驗是完成安全保障的最基礎,因此大多數安全從業者都會下意識地認為「轉移」函數理應所地會完成對使用者餘額的校驗,緩解對此類漏洞的預警(或認為這類漏洞太基礎,攻擊者不會採用)。

然而站在攻擊者視角,最有效的攻擊方式往往是最樸素的:不校驗餘額作為一種既有效又容易被忽視的RugPull手段,沒有不使用的理由。事實也確實如此,至少從案例表徵來看,中華代幣案例的RugPull手法留下的痕跡是最少的,追蹤起來的難度遠大於其他類型的RugPull,最後仍需要透過人工審核程式碼定位程式碼後門。

2.專案方有意識地忽略特權位址現不需要校驗餘額的後門程式碼。專案方甚至單獨為非特權地址實現了一套完整的稅收分區計算邏輯、代幣地址提重複投的邏輯,使得代幣地址不再需要校驗餘額的後門代碼。幣實現了複雜的交易邏輯看來也合情合理。而其他普通地址進行交易時也與正常行為無異,在不仔細看代碼的前提下完全無法發現任何一端倪。

比較該團隊針對MUMI代幣和中華代幣的RugPull手法案例,兩者都是透過相對座標的方式使得分配地址擁有支配大量代幣的權利。

在MUMI代幣RugPull案例中,專案方直接修改餘額,且不修改totalSupply,也不觸發轉讓事件,使得用戶無法取得特權地址已經擁有巨額代幣。

而中華代幣案例盤點更徹底,透過直接不校驗特權地址的餘額,使得除看源碼之外的任何手段都無法發現特權地址已經擁有了無上限的代幣(用balanceOf查詢特權地址的餘額會)顯示為0,這可以轉出無限的代幣)。

中華代幣的RugPull案例首要代幣標準的潛在安全問題,ERC20代幣標準在安全性方面只能用於約束君子而無法防範小人。攻擊者往往會在實現符合標準的業務邏輯的前提下如果通過將代幣行為標準化,雖然減少了功能的靈活性,但隱藏了避免了後門的可能性,提供了更多的安全保障。

資訊來源:0x資訊編譯自網際網路。版權歸作者CertiK所有,未經許可,不得轉載

Total
0
Shares
Related Posts