以小博大- UniLend 被駭事件分析

背景

2025 年1 月13 日,根據慢霧MistEye 安全監控系統監測,EVM 鏈上的UniLend 遭攻擊,損失約19.7 萬美元。慢霧安全團隊對此事件展開分析並將結果分享如下:

(https://x.com/SlowMist_Team/status/1878651772375572573)

相關資訊

攻擊者地址:0x55f5f8058816d5376df310770ca3a2e294089c33

存在漏洞的合約位址:0xc86d2555f8c360d3c5e8e4364f42c1f2d169330e

攻擊交易:0x44037ffc0993327176975e08789b71c1058318f48ddeff25890a577d6555b6ba

攻擊核心

本次攻擊的核心在於合約在贖回資產時,計算健康因子直接使用了池中舊的USDC 餘額。這導致健康因子的計算結果高於實際情況,使得系統錯誤地認為使用者的借貸狀態是安全的。攻擊者利用此漏洞,透過閃電貸借入大量資產,存入並贖回資產時繞過健康因子的正確校驗,從而無需承擔實際風險便獲取了目標資產。

攻擊流程

1. 事先質押資產:攻擊者透過前置交易(0xdaf42127499f878b62fc5ba2103135de1c36e1646487cee309c077296814f5ff) 提前質押20007cee309c077296814f5ff) 提前質押2000005,20077296814f5ff) 提前質押2000005,23275,0375,隨後,攻擊者轉移LP Token,為後續贖回資金作準備。

2. 利用閃電貸借入資產:攻擊者透過閃電貸借入60M USDC 和5 wstETH,並將wstETH 轉換為6 stETH。

3. 存入資產以獲取借貸份額:攻擊者分別兩次調用lend 函數,將USDC 和stETH 存入先前準備好的LP 中,從而獲得相應的份額。此時,攻擊者所持有的份額為:

  • USDC lendshare: 150237398 + 45070847435535 = 45070997672933

  • stETH lendshare: 6663517741687683225

4. 借入目標資產:由於攻擊者事先存入了大量的USDC,於是透過呼叫borrow 函數,可以正常藉入60 stETH。此時由於借貸,stETH borrowShare 增加至60239272000126842038。

5. 贖回質押的stETH:攻擊者呼叫redeemUnderlying 函數,贖回質押的全部stETH。由於攻擊者從未借貸USDC,USDC borrowShare 為0,因此可以直接贖回全部的stETH,stETH lendShare 歸零。

6. 贖回質押的USDC:攻擊者再次呼叫redeemUnderlying 函數,贖回質押的全部USDC。在redeemUnderlying 函數中,首先呼叫_burnLPposition 函數銷毀對應的USDC lendShare,此時的USDC lendShare 還剩下150237398。隨後,合約在checkHealthFactorLtv1 函數中檢查健康因子,最後將贖回的USDC 轉移給使用者。

理論上,攻擊者已經憑藉質押的USDC 借出了一部分stETH,當他想贖回全部的USDC時,健康因子檢查不應該通過。然而,實際情況並不是這樣,讓我們跟進checkHealthFactorLtv1 函數:

我們很容易從上圖發現,該函數先透過userBalanceOftoken0 和userBalanceOftoken1 函數獲得目前的USDC lendBalance 和stETH borrowBalance,再計算USDC 健康因子,並將其與安全閾值進行比較,以判斷是否允許贖回USDC。

繼續深入userBalanceOftoken0 函數進行檢查:

顯然,這就是問題的關鍵,合約直接使用了pool 目前的USDC 餘額以及USDC lendShare 來計算lendBalance。然而,這一部分餘額包含了用戶準備贖回的USDC 數量,USDC lendShare 卻已經在前面的_burnLPposition 函數中扣除了用戶準備贖回的份額。因此USDC lendBalance 由預期的150237398*(728895404+4829907565)/4175666009 = 200001650 變為150237398*(60000728895406 2158955960717,明顯偏大,導致健康因子的回傳值遠高於預期,能成功通過校驗。

7. 完成攻擊並獲利:最終,攻擊者返還閃電貸借入的USDC 和wstETH,獲利離場。由於漏洞,攻擊者僅質押了200 USDC 便可獲得60 stEth。

總結

這次攻擊的核心在於攻擊者利用redeemUnderlying 函數使用了池舊的token 餘額來計算健康因子,而此時用戶的token 尚未從池中轉出,導致健康因子計算結果高於實際情況,系統錯誤地認為用戶的借貸狀態是安全的。攻擊者因此能夠繞過健康因子的正確校驗,非法取得目標資產。慢霧安全團隊建議專案方在健康因子計算過程中,確保資產狀態的即時更新,以避免類似情況的發生。

Total
0
Shares
Related Posts