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

avatar
CertiK
5個月前
本文約3349字,閱讀全文需要約5分鐘
Blast主網上線不到一個月,就發生了兩起攻擊事件,導致損失近億美元。起因竟是曾經用過「北韓駭客」? CertiK 透過對事件時間線的還原對本次攻擊進行了分析推斷。詳情可見本文。

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

背景

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

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

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

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

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

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

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

事件概述

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

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

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

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

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

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

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

現場還原

受害者發聲

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

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

按鏈上偵探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

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

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

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

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

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

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

首先,我們發現在校驗權限的流程中,呼叫了合約(0x 16..A 0)的isRegistered 方法來查看目前的msg.sender,也即是黑客地址1 (0x 6 E..c 5 )是否已經註冊過:

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

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

答案是:通過了驗證。

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

這裡涉及了合約(0x 16..A 0)以及其對應的最新的邏輯合約(0x e 7..f 1)

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

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

邏輯合約升級交易:

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

邏輯合約被更新至0x e 7..f 1 。

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

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

複盤Blast鏈9700萬美元爭奪戰,某國黑客生疏了?此時,我們懷疑駭客是更新代理合約的邏輯實現合約,將為0x 9 e..CD 變成惡意的0x e 7..f 1 ,完成了驗證權限的繞過。

真的是這樣嗎?

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

我們透過比較兩份合約(未開源合約),最初的0x 9 e..CD 合約與更新後0x e 7..f 1 存在一些明顯的差異:

0x e 7..f 1 的initialize 函數部分實作如下:

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

0x 9 e..CD 的initialize 函數部分實現如下:

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

可以看到,攻擊者在最初的邏輯合約(0x 9 e..CD)中,將攻擊者地址(0x 6 e..c 5)設為register,同時還有其他兩個攻擊者地址0x c 5 ..0 d、0x bf..87 也被register 了,而且它們的field 0 被設定為初始化時的區塊時間,field 0 後面會解釋用處。

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

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

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

我們來驗證一下:

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

可以看到,合約(0x 16.....A 0)中對應的slot 是有數值的。

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

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

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

另外,在unlock 的流程中,也涉及第二個校驗:

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

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

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

這一部分校驗就涉及到受損合約(0x 29..1 F)以及對應的邏輯合約0x f 5..cd。

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

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

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

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

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

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

被升級為了0x f 5..cd。

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

0x f 5..cd 的initialize 函數部分實現:

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

0x 91..11 的initialize 函數部分實現:

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

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

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

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

0x 6 e..c 5 (攻擊者地址1)

0x c 5..0 d(攻擊者地址2)

0x bf..87 (攻擊者地址3)

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

第二現場

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

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

並且攻擊gas 的來源位址(0x 97..de),同時給0x c 5..0 d(攻擊者地址2)和0x bf..87 (攻擊者地址3)都提供了手續費。

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

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

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

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

救援交易:

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

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

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

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

這裡的_dodoApproveAddress 為0x000000000000000000000000430000000000000000000000000000000000003

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

為usdb 的address

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

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

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

這裡的_uniswap V3 Factory 為0x000000000000000000000000430000000000000000000000000000000000004

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

為weth 的address

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

而0x 6 e..c 5 (攻擊者地址1)負責盜取的是address( 0),即是原生資產ETH。

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

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

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

問題

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

攻擊後的事件發展

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

https://twitter.com/Nearisbuilding/status/1772812190673756548

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

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

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

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

推薦閱讀
星球精選