核心在於攻擊者利用閃電貸中的特殊機制,操縱放大了空市場中累加器的數值。
作者:九九,Lisa
編輯: Liz
背景
根據慢霧安全團隊情報,2025 年 2 月 12 日,Starknet 鏈上的頭部借貸平台 zkLend 遭到攻擊,損失了價值近千萬美元的資產。慢霧安全團隊對此事件展開分析並將結果分享如下:

相關資訊
攻擊者網址: https://starkscan.co/contract/0x04d7191dc8eac499bac710dd368706e3ce76c9945da52535de770d06ce7d3b26
有漏洞的市場合約網址: https://starkscan.co/contract/0x04c0a5193d58f74fbace4b74dcf65481e734ed1714121bdc571da345540efa05
攻擊交易之一: https://starkscan.co/tx/0x0160a5841b3e99679691294d1f18904c557b28f7d5fe61577e75c8931f34a16f
根本原因
這次被駭事件的核心原因在於空市場中累加器的值可以透過閃電貸中的獨特機制來操控放大,並且市場合約採用的 SafeMath 庫在進行除法計算時使用直接相除的形式,導致攻擊者可以利用放大後的累加器造成向下舍入漏洞來獲利。
攻擊步驟分析
攻擊前置準備
1. 首先攻擊者調用市場合約的 deposit 函數往合約中存入數量為 1 wei 的 wstETH 代幣。

我們可以看到 wstETH 代幣的市場是處於一個空市場的狀態,市場合約中擁有的 wstETH 代幣的數量與鑄造的 zwstETH 的數量在該筆存款之前均為 0,這讓攻擊者可以用極低的成本進行下一步中的操縱。


此時 wstETH 市場中的 lending_accumulator 的值為 1e27。

交易雜湊:https://voyager.online/tx/0x039b6587b9d545cfde7c0f6646085ab0c39cc34e15c665613c30f148b569687
2. 接著攻擊者呼叫了市場合約的 flash_loan 函數進行閃電貸操作,借出了 1 wei 的 wstETH,而歸還了數量為 1000 wei 的 wstETH。

可以看到,在閃電貸之後,wstETH 市場中的 lending_accumulator 的值為 8.51e29, 與之前的值相比,竟然放大了 851 倍。

交易哈希:
https://voyager.online/tx/0x039b6587b9d545cfde7c0f6646085ab0c39cc34e15c665613c30f148b569687c
那麼是什麼原因導致 lending_accumulator 的值能被操控放大這麼多呢?讓我們跟進到市場合約的 flash_loan 函數中:

可以看到在使用者歸還閃電貸之後,呼叫了一個名為 settle_extra_reserve_balance 的函數。

此函數的功能主要是將合約中多餘的資金分配給存款人,而分配的方式是用合約中多餘的資金計算出一個新的 lending_accumulator,並更新保存到對應資產代幣的市場數據中。計算公式可以簡化為如下:
(reserve_balance + totaldebt - amount_to_treasury) * 1e27 / ztoken_supply
由於市場在之前是處於一個空市場的狀態,所以其中 reserve_balance 為用戶還款的閃電貸的數量,即 1000 wei,totaldebt 為 0,amount_to_treasury 計算出來為 149 wei,zwstETH 的供應量為上一步操作時鑄造的 1 wei,最終計算為新的
從歷史交易記錄中可以發現攻擊者進行了多次相同的閃電貸操作,透過每次都還款更多代幣的方法來迅速操控 wstETH 市場中 lending_accumulator 的值。

最終 lending_accumulator 被放大到了一個非常大的數值 4.069e45(406929790605164402000000000000000000000000000):

正式攻擊
交易雜湊:https://voyager.online/tx/0x0160a5841b3e99679691294d1f18904c557b28f7d5fe61577e75c8931f34a16f
1. 當有其他用戶往 wstETH 市場存款後,攻擊者開始正式的攻擊操作。首先攻擊者呼叫了市場合約的 deposit 函數,向合約存入約 4.069 枚 wstETH。

2. 接著呼叫 withdraw 函數,提取約 6.1039 枚 wstETH。

3. 透過重複上面兩步驟操作,攻擊者從市場中最終竊取了約 61 枚 wstETH。

那為什麼攻擊者只存入了 4.069 枚 wstETH,卻可以提領出 6.103 枚 wstETH 呢?
跟進到 deposit 函數中,當用戶轉入資產代幣 wstETH 後,會外部調用 zToken 合約來為用戶鑄造對應數量的 zwstETH 代幣。

用戶實際獲得的 zwstETH 數量是由傳入的資產代幣的數量與市場的 lending_accumulator 計算:


跟進到計算時所用到的 safe_decimal_math 函式庫中:

所以可以得出實際得到的 zwstETH 數量的計算公式為:
zToken_amount = amount * 1e27 / lending_accumulator
其中 amount 的值為:4069297906051644021,lending_accumulator 為攻擊者操縱之後的值:4069297906051644020000000000000000000000000000000000。最後計算出來所得的 zwstETH 的數量為 1。
當使用者呼叫 withdraw 函數提取 6.103 枚 wstETH 時,會呼叫 zToken 合約的 burn 函數來燃燒先前存款獲得的 zwstETH。


在 zToken 合約的 burn 函數中,我們可以發現實際所需燃燒的 zwstETH 數量的計算方式與鑄造時一樣:

其中 amount 傳入的數量為 6103946859077466029,但由於所使用的 safe_math 函式庫中的 div 函數在進行除法時是直接相除的形式,所以會截斷結果中的小數部分。並且因為 lending_accumulator 被攻擊者在先前的操作中放大,最後計算出來實際應該燃燒的 zwstETH 代幣的數量會因為向下舍入取整的問題也等於 1,剛好滿足用戶存款時實際獲得的 zwstETH 數量。
6103946859077466029 * 1e27 / 4069297906051644020000000000000000000000000000 = 1

所以提款時燃燒 zwstETH 代幣的邏輯可以正常通過,這也就是為什麼攻擊者可以只存入 4.069 枚 wstETH,卻可以成功提領出 6.103 枚 wstETH 的根本原因。
而在正常的市場情況下,lending_accumulator 的值應該是精度為 1e27 的數,相除時由於分子遠大於分母好幾個數量級,所以並不會受到影響。
MistTrack 分析
根據鏈上追蹤工具 MistTrack 的分析,攻擊者從 zkLend 盜取了約 950 萬美元。隨後將獲利代幣兌換為 ETH 後使用 LayerSwap, Orbiter Bridge, Rhino.fi, StarkGate ETH Bridge 等跨鏈橋跨鏈到各種網絡,大部分資金被跨鏈到以下以太坊地址:
- 0xcd1c290198e12c4c1809271e683572fbf977bb63
- 0x0b7d061d91018aab823a755020e625ffe8b93074
- 0x645c77833833A6654F7EdaA977eBEaBc680a9109

其中,地址 0x645c77833833A6654F7EdaA977eBEaBc680a9109 有許多歷史交易,首筆交易出現在 2024 年 6 月 22 日。

該地址在以太坊、BSC 和 Base 網路上都有與 Binance 互動的記錄,也可能是嵌套 Binance 帳號介面的第三方交易平台。該位址在以太坊網路上也存在與 ChangeNOW 和 Hitbtc 互動的痕跡。

進一步分析駭客在 Starknet 上的相關地址:0x04d7191dc8eac499bac710dd368706e3ce76c9945da52535de770d06ce7d3b26,發現該位址在攻擊前與以下關聯 L1 位址有強烈關係:
- 0xd95b3c1e638ce3cdc070ad6d4f385c61e2ee8662
- 0x93920786e0fda8496248c4447e2e082da69b6c40
- 0x34e5dc779cb705200e951239b6a89aaf5c7dbfc1

根據 MistTrack 的擴展分析,地址 0x93920786e0fda8496248c4447e2e082da69b6c40 和
0x34e5dc779cb705200e951239b6a89aaf5c7dbfc1 都與 2023 年 7 月 25 日 EraLend 被駭事件的攻擊者位址有關聯。此外,根據慢霧 InMist Lab 威脅情報合作網路訊息,0x93920786e0fda8496248c4447e2e082da69b6c40 是攻擊者用於接收 EraLend 被盜資金的地址。


當時 EraLend 被盜約 276 萬美金,攻擊者也使用多個橋樑將被盜的資金分散到各個鏈上的多個錢包。
綜上,我們可以推論 zkLend 和 EraLend 攻擊事件是同一攻擊者所為。
總結
這次攻擊的核心在於攻擊者利用閃電貸中的特殊機制,操縱放大了空市場中累加器的值,從而在提款時可以利用舍入漏洞來獲得超出預期的資產。慢霧安全團隊建議專案方設計合理安全的閃電貸邏輯模型,將影響存款憑證代幣的數量計算的情況考慮進去,並在數學運算中實現安全的捨入機制,以防止精度損失。此外,對於涉及存取款等核心的業務邏輯,應加強審計與安全測試,從而避免類似情況的發生。
免責聲明:作為區塊鏈資訊平台,本站所發布文章僅代表作者及來賓個人觀點,與 Web3Caff 立場無關。文章內的資訊僅供參考,均不構成任何投資建議及要約,並請您遵守所在國家或地區的相關法律法規。