慢霧安全團隊建議在關鍵函數採用重入鎖來防止重入問題。

作者: Victory

據慢霧安全團隊情報,2022 年 7 月 10 號,OmniX NFT 平台遭受閃電貸攻擊。慢霧安全團隊現將簡要復盤分析分享如下。

相關信息

攻擊交易

0x05d65e0adddc5d9ccfe6cd65be4a7899ebcb6e5ec7a39787971bcc3d6ba73996

攻擊者地址

0x627a22ff70cb84e74c9c70e2d5b0b75af5a1dcb9

攻擊者部署的攻擊合約地址

0x23f8770bd80effa7f09dffdc12a35b7221d5cad3

0x5992f10a5b284be845947a1ae1694f8560a89fa8

0x948d6fe8a7e9ebbb672508e7e93d58c6cfbd3d3f

攻擊分析

1、攻擊者先從 Balancer: Vault 閃電貸借出 1000 個 WETH,然後花費 16.505 WETH 買了一個 BeaconProxy 的 DOODLE 憑證。

2、接著攻擊者又從 BeaconProxy 閃電貸借出 20 個 DOODLE 的憑證,之後通過 redeem 函數取出對應的 20 個 DoodleNFT,至此攻擊者的準備工作完成。

3、攻擊者創建了一個合約

0x23F8770bd80EFFA7F09dFfdc12A35B7221d5cad3 把 20 個 DoodleNFT 轉給新創建的合約後,由合約去調用 supplyERC721 抵押 NFT,獲得質押的憑證 NToken, 隨後調用 borrow 函數借出 12.15 個 WETH。

4、攻擊者調用 withdrawERC721 取走質押的 NFT。

接著就是此次攻擊的核心,由於在 executeWithdrawERC721 中需要 burn 質押憑證的 NToken。

但是 NToken 中 burn 使用的是帶有回調特性的轉賬函數。

圖片

所以在進行 burn 的過程中,攻擊者利用這一特性重入了合約的 liquidationERC721 函數。

圖片

5、隨後攻擊者在清算邏輯這邊償還了前面借出的 12.15 個 WETH 並且拿到了對應的 NFT,此時在清算邏輯中。

在回調中攻擊者繼續把所有 NFT 質押進去,並且重新借出 81 個 WETH,如果按照正常的借款邏輯合約會調用

userConfig.setBorrowing(reserve.id, true); 記錄用戶存在藉貸狀態。

但是攻擊者在重入調用結束後會繼續走回 executeERC721LiquidationCall 剩餘的邏輯,由於在重入之前是全額還款所以可以通過

vars.userTotalDebt == vars.actualDebtToLiquidate,之後會執行

userConfig.setBorrowing(liquidationAssetReserve.id, false); 把用戶的借貸狀態設置為 false。

圖片

隨後攻擊者單獨發起了一次 withdrawERC721 的操作,在提現的判斷中會先檢查是否有借貸的標誌位再去判斷負債多少,由於在之前的攻擊中藉貸狀態已經被設置為 false,所以攻擊者可以在不清理負債的情況下取出質押的 NFT。

圖片
圖片

6、最終,攻擊者又創建了一個新的合約執行了一次相同手法的攻擊,歸還了閃電貸的 WETH 和 NFT 獲利離場。

總結

本次事件中是由於 NToken 的 burn 函數是一個帶有回調的函數,導致攻擊者可以多次重入合約,從而導致合約的記賬出現了錯誤。即使重入後再藉款,但用戶的狀態標識被設置為未借款導致無需還款。慢霧安全團隊建議在關鍵函數採用重入鎖來防止重入問題。

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