慢霧安全團隊建議專案方在健康因子計算過程中,確保資產狀態的即時更新。

作者:慢霧安全團隊,慢霧科技

背景

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,20027, 20222200025, 20002757252562562200025, 200027575622020202 隨後,攻擊者轉移 LP Token,為後續贖回資金作準備。

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

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

  • USDC 借出份額:150237398 + 45070847435535 = 45070997672933
  • stETH 借貸共享: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 尚未從池中轉出,導致健康因子計算結果高於實際情況,系統錯誤地認為用戶的借貸狀態是安全的。攻擊者因此能夠繞過健康因子的正確校驗,非法取得目標資產。慢霧安全團隊建議專案方在健康因子計算過程中,確保資產狀態的即時更新,以避免類似情況的發生。

免責聲明:作為區塊鏈資訊平台,本站所發布文章僅代表作者及來賓個人觀點,與 Web3Caff 立場無關。文章內的資訊僅供參考,均不構成任何投資建議及要約,並請您遵守所在國家或地區的相關法律法規。