Paid Twice, Lost Everything ($3M Vulnerability)
三句話摘要
智能合約的重入攻擊漏洞原理、實戰演示與防護方法。 始終在進行外部呼叫前完成狀態更新,遵循「檢查、效果、交互」的原則,才能根本防止重入攻擊。 重入攻擊的核心機制在於執行順序缺陷:金庫先發送資金再清零餘額,當資金轉入攻擊者合約時自動觸發 receive 函數,此時餘額尚未更新,使攻擊者能在同一交易內反覆調用 withdraw 並多次領取資金。
重點整理
重點- 1
重入攻擊的核心機制在於執行順序缺陷:金庫先發送資金再清零餘額,當資金轉入攻擊者合約時自動觸發 receive 函數,此時餘額尚未更新,使攻擊者能在同一交易內反覆調用 withdraw 並多次領取資金。
- 2
攻擊流程看似複雜但執行極簡:使用者只需點擊一次「steal」按鈕,receive 函數會自動迴圈調用 withdraw,直至資金池被完全掏空,整個過程由單一交易完成。
- 3
修復方案遵循「檢查、效果、交互」(checks, effects, interactions)原則:改為先清零餘額(效果)再發送資金(交互),當攻擊者重入時餘額已為零,require 檢查會立即失敗並回滾交易。
- 4
完整驗證跨越三層:Remix 手動演示展示具體流程、Foundry 測試框架用程式碼固化漏洞的可重現性、Sepolia 測試網上的真實交易記錄通過 Etherscan 公開驗證易受攻擊版本失敗和修復版本成功。
實用技巧與重點
乾貨- 攻擊前金庫餘額:3 ether(其他使用者存款)
- 攻擊者自己存入:1 ether
- 攻擊後攻擊者獲得:4 ether
- 原始漏洞代碼順序:call 發送 eth → set balance to zero
- 修復後代碼順序:set balance to zero → call 發送 eth
- 安全設計模式:checks, effects, interactions
- 替代防護方案:re-entrance guard(重入鎖)
- 使用工具:Remix IDE、Foundry 測試框架、Etherscan 區塊瀏覽器
- 驗證網路:Sepolia testnet
結論
結論“始終在進行外部呼叫前完成狀態更新,遵循「檢查、效果、交互」的原則,才能根本防止重入攻擊。”
完整解析
詳細智能合約中最著名且最危險的漏洞莫過於重入攻擊(reentrancy)。這種攻擊的根源看起來很簡單,但它曾在真實場景中造成過鉅額損失。金庫合約的基本邏輯是:使用者存入資金時記錄其餘額,取款時發送對應資金並清零帳戶。然而,這三個動作的執行順序決定了系統的安全性。
在易受攻擊的版本中,金庫採用「先發送資金,後更新餘額」的順序。這看似無關緊要,卻給了攻擊者可乘之機。當金庫向攻擊者合約轉移資金時,以太坊的機制會自動呼叫該合約的 receive 函數。攻擊者在 receive 函數中巧妙插入再次呼叫 withdraw 的邏輯。由於金庫尚未清零攻擊者的餘額,系統仍認為他有權取款,於是再次支付。這個迴圈會持續進行,直到金庫被徹底掏空。值得注意的是,整個攻擊過程只需攻擊者點擊一次「steal」按鈕,之後 receive 函數會自動處理所有重複呼叫。
修復方案優雅而簡潔,只需移動一行程式碼。改為「先清零餘額,再發送資金」的順序,遵循智能合約設計的黃金法則:checks(檢查)、effects(效果/狀態更新)、interactions(交互/外部呼叫)。現在當攻擊者試圖重新進入 withdraw 時,其餘額已為零,require 檢查會立即拒絕並回滾整個交易。
影片通過三個遞進的驗證層級證明了漏洞的真實性和修復的有效性。首先在 Remix 中手動演示每一步——金庫初始 3 ether,攻擊者存入 1 ether 變成 4 ether,單次 steal 呼叫將餘額清空至零,攻擊者最終獲得 4 ether。其次用 Foundry 框架編寫單元測試,用程式碼固化漏洞的可重現性與修復的有效性。最後在真實的 Sepolia 測試網部署相同合約,通過 Etherscan 展示完整交易記錄——易受攻擊版本的 steal 交易成功執行且資金被清空,修復版本的相同交易失敗回滾且資金安全。
關鍵時刻
Pipeline v2帶時間戳的重點,會在逐字稿層級分析上線後產生。目前請先透過原始影片觀看。
事實查核
Pipeline v2說法查證是下一次管線升級的一部分。KeyFrame 只會顯示它真正能驗證的內容。

