【漏洞分析】DoughFina 攻擊事件分析:不做任何參數檢查的去杠桿合約
背景介紹
2024 年 7 月 12 日,DoughFina 協議遭受了黑客攻擊,造成本次攻擊的主要原因是 ConnectorDeleverageParaswap 合約沒有對輸入參數進行檢查,且該合約為 DSA 合約的 owner。攻擊者可以構造惡意參數竊取 DSA 合約的資金。
相關合約
- DSA(被攻擊地址):0x534a
在 AAVE V3 上質押了 596 WETH,借出了 938566 USDC - 攻擊合約:0x11a8
- ConnectorDeleverageParaswap:0x9f54e8eaa9658316bb8006e03fff1cb191aafbe6
通過閃電貸協助 DSA 降低在 AAVE V3 上的杠桿。
攻擊交易分析
這個章節我們先嘗試從 trace 來定位漏洞的位置。
通過對這筆交易進行一個大概的觀察,如下圖所示,攻擊者在發起攻擊之前,先利用閃電貸的資金幫 0x534a 歸還了他的借款 938566 USDC,其他部分都是常規的操作,其中需要深入調查的就是 0x11a8 調用 ConnectorDeleverageParaswap.flashloanReq 函數的過程。

ConnectorDeleverageParaswap.flashloanReq 函數

我們看到在 ConnectorDeleverageParaswap.flashloanReq 函數中,會調用 POOL.flashLoan
POOL.flashLoan 執行一個常規的閃電貸流程
- ConnectorDeleverageParaswap 合約從閃電貸獲取 5 USDC
- 調用 ConnectorDeleverageParaswap.executeOperation 函數
- 歸還 5.025 USDC
- handleRepayment

繼續跟進到 ConnectorDeleverageParaswap.executeOperation 函數,可以看到它對傳入的參數進行解析后直接調用 deloopInOneOrMultipleTransactions 函數

對 deloopInOneOrMultipleTransactions 函數進行分析
function deloopInOneOrMultipleTransactions(bool opt, address _dsaAddress, address[] memory assets, uint256[] memory amounts, uint256[] memory premiums, address[] memory collateralTokens, uint256[] memory collateralAmounts, bytes[] memory multiTokenSwapData) private {
// Repay all flashloan assets or withdraw all collaterals
// 使用閃電貸獲得的資金來償還用戶在 Aave 上的債務。
repayAllDebtAssetsWithFlashLoan(opt, _dsaAddress, assets, amounts);
// Extract all collaterals
// 從用戶的 DSA 中提取指定數量的抵押品。
extractAllCollaterals(_dsaAddress, collateralTokens, collateralAmounts);
// Deloop all collaterals
// 使用 Paraswap 將提取的抵押品換成債務代幣
deloopAllCollaterals(multiTokenSwapData);
// Repay all flashloan assets or withdraw all collaterals
// 償還閃電貸,然后將剩余的資金存回 Aave 或轉移到金庫
repayFlashloansAndTransferToTreasury(opt, _dsaAddress, assets, amounts, premiums);
}
不過在查看 ConnectorDeleverageParaswap.executeOperation 函數的執行 trace 時,發現 Phalcon 把調用的四個函數混在一起了不好分辨。

根據轉移的金額確定攻擊發生的位置,猜測這筆 WETH 的轉賬與漏洞的利用有關。

所以通過單步調試的方式來檢查發生了什么。
執行到 ConnectorDeleverageParaswap.deloopAllCollaterals 函數中時,對傳入的 multiTokenSwapData 參數進行解析,得到對應的參數: flashloanVars.srcToken, flashloanVars.destToken, flashloanVars.srcAmount, flashloanVars.destAmount, flashloanVars.paraSwapContract, flashloanVars.tokenTransferProxy, flashloanVars.paraswapCallData
其中 paraSwapContract(out4)對應的地址為 WETH 的合約地址(0xc02a),而不是進行 swap 的合約地址。

當執行到 paraSwapContract.call 部分的函數時,由于 paraSwapContract 的地址已被替換為 WETH9 的地址,且 paraswapCallData 為攻擊者構造的轉賬 calldata,所以實際執行的是 WETH 的轉賬操作
function deloopAllCollaterals(bytes[] memory multiTokenSwapData) private {
FlashloanVars memory flashloanVars;
for (uint i = 0; i < multiTokenSwapData.length;) {
// Deloop
(flashloanVars.srcToken, flashloanVars.destToken, flashloanVars.srcAmount, flashloanVars.destAmount, flashloanVars.paraSwapContract, flashloanVars.tokenTransferProxy, flashloanVars.paraswapCallData) = _getParaswapData(multiTokenSwapData[i]);
// using ParaSwap
IERC20(flashloanVars.srcToken).safeIncreaseAllowance(flashloanVars.tokenTransferProxy, flashloanVars.srcAmount);
(flashloanVars.sent, ) = flashloanVars.paraSwapContract.call(flashloanVars.paraswapCallData);
if (!flashloanVars.sent) revert CustomError("ParaSwap deloop failed");
unchecked { i++; }
}
}
deloopInOneOrMultipleTransactions 函數分析
已經定位到了漏洞發生的位置,接下來就根據 trace 分析 deloopInOneOrMultipleTransactions 函數對四個函數的調用情況
-
repayAllDebtAssetsWithFlashLoan
替 0x11a8 賬戶歸還 5 USDC 的借款

-
extractAllCollaterals
傳入空數組,跳過這函數的邏輯

-
deloopAllCollaterals
由于沒有進行參數檢查,攻擊者在這個函數中構造了兩個惡意的調用來獲利。

-
第一個 for 循環:調用 0x534a.executeAction 把 5 USDC 兌換成 596 WETH,并且 approve 給 ConnectorDeleverageParaswap 合約

-
第二個 for 循環:把 596 WETH 轉移到攻擊者控制的 0x11a8 地址

-
-
repayFlashloansAndTransferToTreasury
提供 0.9 USDC 給 0x11a8 的 AAVE 賬戶

攻擊流程分析
本次攻擊是圍繞降低 0x11a8 賬戶在 AAVE V3 上的杠桿而展開的,由于這個函數沒有對傳入的參數進行檢查,所以攻擊者構造了惡意的 multiTokenSwapData 參數在 deloopAllCollaterals 函數中對 0x534a 的 AVVE 資金進行轉移。
攻擊者構造惡意的 data 參數,解析出惡意的 multiTokenSwapData 參數

惡意的 multiTokenSwapData 參數傳入到 deloopAllCollaterals 函數中

惡意的 multiTokenSwapData 參數解析出惡意的 paraSwapContract 和 paraswapCallData,導致了任意執行。

后記
第一次分析這個類型的攻擊事件,感覺攻擊事件還是得多分析,多積累積累經驗,擴展自己的視野。好好看好好學吧,之前對項目類型的接觸和理解上都有很大的局限,還是需要多接觸一下目前經典的、熱門的項目有利于提高自己的水平,跟上市場的步伐。繼續干唄,這事兒只能靠慢慢積累起來的。

浙公網安備 33010602011771號