Blast鏈9700萬美元爭奪戰某國黑客生疏了?

背景

Blast是由Blur的創辦人Pacman(Tieshun Roquerre、aka.鐵順)推出的Ethereum Layer2網絡,在2月29日啟動主網,目前約有19500 ETH和640000 stETH質押在Blast主網。

被攻擊的項目Munchables是Blast舉辦的Bigbang競賽獲勝的優質項目。

Blast官方對質押ETH在Blast主網的用戶會發放普通積分:

為了鼓勵用戶參與Blast生態上的DeFi項目,Blast官方會挑選出優質項目進行推薦,並鼓勵用戶將ETH二次質押到DeFi裡,可以獲得更快的積分增加速度以及黃金積分,因此有相當多的用戶將質押在Blast主網的ETH質押到了新創建的DeFi專案。

而這些DeFi計畫的成熟度、安全性仍有待考察,這些合約是否有足夠的安全考量來保管用戶的數千萬、甚至上億美元。

事件概述

Blast主網上線不到一個月,在2024年3月21日就發生了針對SSS Token(Super Sushi Samurai)的攻擊,Token合約中存在一個轉帳邏輯錯誤,導致攻擊者可以憑空增加指定帳戶的SSS Token餘額,最終項目損失了超過1310 ETH(約460萬美元)。

而在SSS Token攻擊事件過去不到一週的時間,Blast上又發生了一起更大的攻擊事件,Munchables專案被攻擊者一把捲走了17413.96 ETH,共約6250萬美元。

在這筆攻擊交易發生的半小時後,專案方合約裡的73.49 WETH也被駭客竊取的另一個地址。

此時專案方的合約地址上,還存著7276個WETH、7758267個USDB、4個ETH,隨時會落入駭客手裡,而駭客擁有拿走整個專案的所有資金的權限,共計約9700萬美元暴露於風險之中。

在事件後發生的第一時間,X(Twitter)的知名鏈上偵探zachXBT指出這次攻擊的根本原因是因為僱用了某國駭客所致。

讓我們深入看看,「某國駭客」是如何完成一次接近一億美元的攻擊。

現場還原

  • 受害者發聲

[UTC+0]2024年3月26日21點37分(攻擊發生5分鐘後),Munchables官方在X(Twitter)發文表示遭到攻擊。

按鏈上偵探ZachXBT的調查,是因為他們有一位開發者是“某國黑客”,aavegotchi的創始人coderdannn也在X(Twitter)上表示:“Aavegotchi的開發團隊Pixelcraft Studios在2022時曾短期僱用過Munchables攻擊者來進行一些遊戲開發工作,他技術很糙,感覺確實像某國駭客,我們在一個月內解雇了他。他還試圖讓我們僱用他的一位朋友,那個人很可能也是一名駭客.”

由於這次攻擊讓社群的用戶損失巨大,我們立即啟動了鏈上調查,讓我們深入看看這個「某國駭客」的攻擊細節。

  • 第一現場

[UTC+0]2024年3月26日21點32分,涉及17413.96 ETH的攻擊發生了。

透過Blastscan我們可以看到這筆攻擊交易:https://blastscan.io/tx/0x9a7e4d16ed15b0367b8ad677eaf1db6a2a54663610696d69e1b4aa1a08f55c95

受損合約(0x29..1F)是一個代理合約,存放了用戶質押的資金,我們可以看到,攻擊者調用了質押合約的unlock函數,並通過了所有的權限校驗,轉走了合約中所有的ETH到攻擊者位址1(0x6E..c5)。

看起來攻擊者呼叫了一個類似withdraw行為的unlock函數,取走了受損合約(0x29..1F)上大部分ETH。

是專案方的金庫忘了上鎖嗎?

受損合約(0x29..1F)中的unlock存在兩個相關校驗,我們一個一個來看。

首先,我們發現在校驗權限的流程中,調用了合約(0x16..A0)的isRegistered方法來查看當前的msg.sender,也即是黑客地址1(0x6E..c5)是否已經被註冊過:

答案是:通過了驗證。

這裡涉及到了合約(0x16..A0)以及其對應的最新的邏輯合約(0xe7..f1)

[UTC+0]2024年3月24日08點39分(攻擊發生的2天前),合約(0x16..A0)對應的邏輯合約被升級了。

邏輯合約升級交易:

https://blastscan.io/tx/0x9c431e09a80d2942319853ccfdaae24c5de23cedfcef0022815fdae42a7e2ab6

邏輯合約被更新至0xe7..f1。

最初的邏輯合約地址在這裡能看到,為0x9e..CD。

https://blastscan.io/tx/0x7ad050d84c89833aa1398fb8e5d179ddfae6d48e8ce964f6d5b71484cc06d003

此時,我們懷疑駭客是更新代理合約的邏輯實現合約,將為0x9e..CD變成惡意的0xe7..f1,完成了驗證權限的繞過。

真的是這樣嗎?

在Web3.0從來不需要猜測和聽信別人,你只需要掌握技術就能自己得到答案。

我們透過比較兩份合約(未開源合約),最初的0x9e..CD合約與更新後0xe7..f1存在一些明顯的區別:

0xe7..f1的initialize函數部分實作如下:

0x9e..CD的initialize函數部分實作如下:

可以看到,攻擊者在最初的邏輯合約(0x9e..CD)中,將攻擊者位址(0x6e..c5)設為register,同時還有其他兩個攻擊者位址0xc5..0d、0xbf.. 87也被register了,並且它們的field0被設定為初始化時的區塊時間,field0後面會解釋用處。

實際上,和我們猜測的恰好相反,真正的藏有後門的邏輯合約,反而是最初就存在,而後面更新的反而是正常的!

等等,這個更新出現在[UTC+0]2024年3月24日08點39分(攻擊發生的2天前),也就是在這個事件之前,邏輯合約已經變成沒有後門的合約了,為什麼後面攻擊者還可以完成攻擊?

這是因為delegatecall的原因,所以實際的狀態儲存更新是在合約(0x16..A0)中,這也就導致了即使之後邏輯合約被更新至沒有後門的邏輯合約0xe7..f1,合約(0x16. .A0)中被更改的slot依然不會恢復。

我們來驗證一下:

可以看到,合約(0x16…..A0)中對應的slot是有數值的。

這使得攻擊者能夠通過isRegistered方法的校驗:

攻擊者之後再將後門合約更換為正常合約掩人耳目,其實此時後門早已種下。

另外,在unlock的流程中,還牽涉到第二個校驗:

對於lock時間的檢查,這一部分是保證鎖定的資產不會在未到期就被轉走。

攻擊者需要保證當unlock被呼叫時的區塊時間大於要求的鎖定過期時間(field3)。

這一部分校驗就涉及受損合約(0x29..1F)以及對應的邏輯合約0xf5..cd。

在[UTC+0]2024年3月21日11點54分(攻擊發生的5天前)的交易中,

https://blastscan.io/tx/0x3d08f2fcfe51cf5758f4e9ba057c51543b0ff386ba53e0b4f267850871b88170

我們可以看到受損合約(0x29..1F)合約最初的邏輯合約是0x91..11,而在僅僅四分鐘後,就在

https://blastscan.io/tx/0xea1d9c0d8de4280b538b6fe6dbc3636602075184651dfeb837cb03f8a19ffc4f

被升級為了0xf5..cd。

我們同樣來比較兩份合約,可以發現攻擊者和之前一樣,也在initialize函數做了手腳,

0xf5..cd的initialize函數部分實作:

0x91..11的initialize函數部分實作:

可以看到,很明顯的,又是運用了同樣的手法,將自己持有的ETH數量&解鎖時間都進行了篡改,之後再替換回正常合約掩人耳目,當項目方和安全研究人員在Debug的時候,看到的邏輯合約全是正常的,而且由於合約均為未開源合約,更難以看清問題的核心。

至此,我們了解了這筆涉及17413 ETH的交易,攻擊者是如何做到的,但是這個事件背後的信息,只有這麼多嗎?

我們上面的分析中,其實看到駭客在合約內部內建了3個位址:

0x6e..c5(攻擊者位址1)

0xc5..0d(攻擊者位址2)

0xbf..87(攻擊者地址3)

而我們上面發現的攻擊交易只看到0x6e..c5,其他兩個位址都做了什麼?而且裡面的address(0)、_dodoApproveAddress、_uniswapV3Factorty到底還隱藏著什麼秘密?

  • 第二現場

我們先來看看攻擊者地址3(0xbf..87),透過同樣的手法盜取了73.49 WETH:

https://blastscan.io/tx/0xfc7bfbc38662b659bf6af032bf20ef224de0ef20a4fd8418db87f78f9370f233

並且攻擊gas的來源位址(0x97..de),同時給0xc5..0d(攻擊者位址2)和0xbf..87(攻擊者位址3)都提供了手續費。

而攻擊gas來源位址(0x97..de)的0.1 ETH的資金源頭則來自owlto.finance(跨鏈橋)。

0xc5..0d(攻擊者地址2)收到手續費後,並未進行任何攻擊,但它其實肩負了一個隱藏的計劃,我們繼續看下去。

實際上,根據官方的事後救援交易,原來受損合約(0x29..1F)地址上並不止73.49枚weth,直到攻擊結束,也仍有7276.5 WETH & 7758267 USDB。

救援交易:

https://blastscan.io/tx/0x1969f10af9d0d8f80ee3e3c88d358a6f668a7bf4da6e598e5be7a3407dc6d5bb

原本攻擊者是打算竊取這些資產的,可以看到0xc5..0d(攻擊者位址2)這個位址原本是用來偷取USDB的。

這裡的_dodoApproveAddress為0x0000000000000000000000004300000000000000000000000000000000000003

為usdb的address

0xbf..87(攻擊者地址3)這個地址是用來偷取weth的:

這裡的_uniswapV3Factory為0x0000000000000000000000004300000000000000000000000000000000000004

為weth的address

而0x6e..c5(攻擊者地址1)負責盜用的是address(0),即是原生資產ETH。

攻擊者透過設定field0,即可透過以下邏輯對對應資產進行竊取:

問題

  • 為什麼攻擊者沒有盜走所有資產?

理論上他可以盜取所有的資產,也就是剩下的WETH和USDB。

0xbf..87(攻擊者地址3)只盜取了73.49 WETH,0xbf..87(攻擊者地址3)其實完全可以把所有的7350 WETH拿走,也可以藉助0xc5..0d(攻擊者地址2 )把7758267 USDB全部拿走,為什麼只拿了一點點WETH就停下來了,我們不得而知,可能需要知名鏈上偵探深入內部的調查了。

https://blastscan.io/tx/0xfc7bfbc38662b659bf6af032bf20ef224de0ef20a4fd8418db87f78f9370f233

  • 為什麼攻擊者沒有把17413ETH轉到Ethereum主網?

眾所周知,Blast主網是有可能透過中心化的方式攔截這些ETH,讓它永久停留在這裡,從而不會造成實質上的用戶損失,但是一旦這些ETH進入Ethereum主網,就沒有辦法攔截了。

我們評估了目前Blast的跨鏈橋,官方跨鏈橋沒有限制數量,但需要14天的退出時間,因此足以讓Blast官方來準備攔截的計劃。

而第三方的跨鏈橋是可以接近即時到帳的,就像攻擊者的手續費來源一樣,很快完成跨鏈,為什麼攻擊者沒有第一時間進行跨鏈?

實際上攻擊者在第一時間(攻擊的2分鐘內)進行了跨鏈:

https://blastscan.io/tx/0x10cf2f2b884549979a3a1dd912287256229458ef40d56df61738d6ea7d9d198f

而且資金花了20秒就在Ethereum主網到賬了,理論上攻擊者可以持續不斷進行跨鏈,可以在跨鏈橋人工幹預之前,將大量ETH跨鏈轉走。

至於為什麼只能每次3 ETH,原因是跨鏈橋的流動性限制,從Blast上跨到ETH上:

另一個支援Blast的跨鏈橋則支援的更少:

而在這一筆跨鏈交易後,攻擊者沒有繼續其他的跨鏈操作,原因我們不得而知,看上去“某國黑客”似乎是沒有為資金退出Blast進行充足的準備。

攻擊後的事件發展

根據社群使用者Nearisbuilding的回饋,他找到了更多攻擊者的身分訊息,並想辦法促使攻擊者歸還資金。

最終,在加密社群的關注和努力下,「某國駭客」也許因為害怕暴露身份,向專案方提供了以上3個攻擊者地址的私鑰,並歸還了所有資金,專案方也進行了救援交易,將受損合約的資金全部轉到多簽合約進行保管。

Total
0
Shares
Related Posts