2025 年 3 月 5 日,一個整合了 1inch Fusion V1 協議的第三方解析器(resolver)合約遭到協同攻擊,導致了總計超過 500 萬美元的損失。根本原因是結算流程中存在不安全的調用數據(calldata)重構,攻擊者控制的交互長度在後綴組裝過程中觸發了指標下溢(pointer underflow),從而允許注入偽造的結算數據。此次攻擊因信任邊界處理不當而進一步擴大:解析器合約僅基於 msg.sender 而隱式信任結算合約轉發的所有調用數據,導致攻擊者控制的數據儘管通過了所有存取控制檢查,卻繼承了結算級別的操作權限。
這起事件成為 2025 年最複雜的 DeFi 攻擊之一,這並非因為使用了某種創新的金融原語,而是因為它利用了低層級的 ABI 和記憶體佈局假設,模糊了智能合約漏洞與經典二進制漏洞利用技術之間的界線。
背景
1inch 的 Fusion V1 協議
1inch 是一個去中心化交易所(DEX)聚合器,透過匯集來自多個 DEX 的流動性,為用戶提供優化的兌換執行體驗。基於聚合器的限價單基礎設施,1inch Fusion 引入了一種基於荷蘭拍賣的訂單撮合模型,允許用戶指定靈活的執行參數,如價格區間和兌換時間窗口。
在 Fusion 模型中,用戶訂單並非由協議本身直接處理,而是由專門的參與者(即解析器)執行。解析器可以被視為具備特權的白名單參與者:為了獲得資格,他們必須質押代幣以獲取足夠的 Unicorn Power,這是一種經濟門檻機制。
在運作上,解析器運行自己的鏈下基礎設施,與 1inch 的後端 API 交互以發現用戶訂單,並確定是否以及何時進行撮合。一旦解析器決定執行訂單,它會通過專用帳戶將鏈上交易提交給“結算合約”(Settlement contract),由後者執行實際的交換。(雖然 Fusion 涉及解析器之間的競爭性荷蘭拍賣,但此機制對於理解攻擊並非必要,因此在此省略;為簡化起見,我們假設解析器可以直接滿足用戶的訂單條件。)
在執行兌換時,解析器可以選擇從外部市場獲取流動性,以提供比用戶最低要求更好的執行結果,或者直接使用自己的資產進行結算。在此過程中產生的任何剩餘價值將作為利潤歸解析器所有。本部落格討論的攻擊即針對此類解析器合約。具體來說,該合約用於鏈上做市,持有資產並已向結算合約授予授權,最終導致了這些資產的損失。
訂單處理與完成
1inch Fusion 中的訂單執行由結算合約協調,並遵循由交互數據驅動的遞歸結算模型,而非線性執行流程。
流程在解析器調用 settleOrders() 函數時啟動,並傳入編碼了第一個訂單及其交互負載(interaction payload)的調用數據。結算合約並不嘗試一次性結算所有訂單,而是通過重複調用內部的 _settleOrder() 函數來逐步處理。
對於每個訂單,_settleOrder() 函數會在記憶體中重構對限價單協議(AggregationRouterV5.fillOrderTo())的調用。在此重構過程中,結算合約會將與解析器相關的其他上下文以**動態後綴(dynamic suffix)**的形式附加到交互數據中。該後綴包含執行元數據(如解析器身分、累計費用等),對於限價單協議而言,它是透明的。該數據會被原封不動地轉發,並在後續的交互回調中由結算合約本身解碼。
訂單完成後,控制權通過 fillOrderInteraction() 函數返回給結算合約。根據交互數據,結算合約要麼通過遞歸調用 _settleOrder() 使用剩餘的交互負載來繼續結算,要麼轉向完成階段。在最後階段,結算合約通過調用解析器合約的 resolveOrders() 函數將控制權轉移給解析器,並傳入累積的執行上下文。
這種設計允許在單筆交易中順序結算多個訂單,同時將解析器特定的邏輯延後至所有協議級執行步驟完成後再處理。
漏洞分析
漏洞源於內部 _settleOrder() 函數中不安全的調用數據重構邏輯,特別是在於附加到交互數據的動態後綴的放置位置。
解析器合約受到明確的存取控制保護:它們要求調用必須源自結算合約,並且在解析過程中提供的解析器位址必須與解析器合約本身相匹配。這些檢查假設通過結算流程傳播的解析器身分構建正確且保持完整。此假設取決於在調用數據重構過程中,解析器相關數據的編碼和附加方式是否正確。
具體而言,解析器的 resolveOrders() 強制執行兩個守衛(guards):
require(msg.sender == _settlement, OnlySettlement());
require(this == resolver, NotTaker());
第一個檢查確認調用源自結算合約。第二個檢查確認 resolver 參數(從後綴中解碼得出)與解析器合約自身的位址相符。在正常操作下,這兩個欄位均由 _settleOrder() 正確設定。在攻擊過程中,這兩個檢查仍然都會通過:攻擊者在結算流程「內部」(而非外部)操作,因此 msg.sender 的確是結算合約;而 resolver 欄位則是從偽造的後綴中解碼出來的,攻擊者已在其中寫入了受害者解析器的位址。
在結算過程中,_settleOrder() 在記憶體中重構調用數據,並附加一個包含特定執行上下文的動態後綴。該後綴不僅包含解析器位址,還包含了解析器判斷結算是否合法所依賴的訂單相關資訊。後綴寫入的記憶體位置計算方式為 ptr + interactionOffset + interactionLength,其中 interactionLength 是直接從調用數據中讀取的 32 位元組數值。
由於此偏移量計算未進行邊界檢查,攻擊者可以控制 interactionLength 來引發算術溢位,並操縱後綴在記憶體中的寫入位置。透過這種方式,攻擊者可以用偽造的後綴替換原始後綴,從而提供任意的解析器位址以及攻擊者控制的訂單上下文。
結果,當結算流程隨後解碼該後綴時,它可能會錯誤地認為執行源自合法的解析器並涉及有效的訂單數據,儘管這兩項假設均不成立。攻擊者實際上能夠注入自己版本的訂單後綴,同時偽裝成解析器,最終以極小的代價(幾 wei)換取價值數百萬的資產。
攻擊分析
以交易 0x74bc 為例。攻擊始於創建五個有效的訂單,這些訂單將極少量的代幣(幾個 wei)兌換為不成比例的巨額輸出。這些訂單在語法上是有效的,並通過了協議級別的檢查。
隨後,攻擊者在訂單調用數據中填充了大量的空位元組(null bytes)。此填充區作為受控記憶體區域,稍後會因為後綴放置錯誤而被覆蓋。
關鍵在於,攻擊者為最後一個訂單指定了一個無效的 interactionLength 值。該值被選擇為 0xffff…fe00,作為有符號整數解釋時對應 -512。由於 interactionLength 被視為無符號 256 位元值並直接用於指標運算,這在計算後綴寫入偏移量時導致了算術溢位。
下方的惡意交互結構將被視為後綴:
從偽造後綴到資產提取
當結算合約處理最後一個訂單時,溢位導致合法的後綴被寫入到空填充區域,無害地覆蓋了零。而攻擊者放置在真正讀取位置的偽造後綴隨即被解釋為合法的結算上下文。
偽造的後綴設定了完成旗標(finalize flag),導致結算合約從遞歸訂單處理轉向完成階段。結算合約調用了從後綴解碼出的位址的 resolveOrders(),即受害解析器位址。如漏洞分析中所述,兩項存取控制檢查均通過:msg.sender 是結算合約(調用流經合法的結算路徑),且 resolver 與受害者位址相符(由攻擊者寫入偽造後綴中)。
受害解析器隨後處理 tokensAndAmounts 陣列,其中包含了攻擊者選擇的代幣位址和金額。由於解析器之前為了正常運作已向結算合約授予了代幣授權,轉帳得以執行。解析器將其持有的資產發送出去,以完成僅需少量 wei 輸入的虛假訂單,從而導致超過 500 萬美元的損失。
總結
此事件針對整合了 1inch 已棄用的 Fusion V1 協議的第三方解析器合約,造成了鉅額損失,重點突出了幾個重要的教訓:
- 不安全的數據假設:依賴動態構建輸入數據的系統,絕不能在任何部分受到用戶影響的情況下,假設長度、偏移量或結構的完整性。
- 隱式信任鏈:當合約依賴上游組件來保存關鍵上下文,而不是在每個邊界自行驗證時,安全檢查可能會被繞過。
- 遺留攻擊面:支援過時的組件會增加攻擊面,使協議更容易受到新型攻擊技術的影響。
- 跨領域攻擊模式:當涉及到底層記憶體或數據佈局邏輯時,傳統軟體中常見的漏洞可能會重新出現在鏈上。
參考資料
-
https://blog.decurity.io/yul-calldata-corruption-1inch-postmortem-a7ea7a53bfd9
-
https://paragraph.com/@cookies-research/1inch-fusion-cost-efficient-mev-resistant-swaps
-
https://blog-zh.1inch.com/fusion-swap-resolving-onchain-component/#steps-5-6
關於 BlockSec
BlockSec 是一家全方位的區塊鏈安全與加密合規服務提供商。我們構建各類產品和服務,協助客戶在協議與平台的生命週期中執行代碼審計(包括智能合約、區塊鏈和錢包)、即時攔截攻擊、分析資安事件、追蹤非法資金,並滿足反洗錢 (AML) 與打擊資助恐怖主義 (CFT) 的義務。
BlockSec 已在知名學術會議上發表多篇區塊鏈安全論文,通報了多項 DeFi 應用程式的零日攻擊,攔截了多次駭客攻擊並挽回超過 2,000 萬美元的資產,保護了價值數十億美元的加密貨幣安全。
-
官方 Twitter 帳號:https://twitter.com/BlockSecTeam
-
🔗 BlockSec 審計服務 : 提交請求



