KeyFrame內部研究專用

Differential Fuzzing of the Vyper Compiler

DeFi Security Summit - DSS·11月23日週日·21 min英文

三句話摘要

EVM 上 ABI 解碼器的記憶體越界漏洞發現過程,以及如何用帶偏置的差異模糊測試加以修復驗證。 對 ABI 解碼器這類以指標為核心風險的元件,用 Python 規格實作做差異基準、再以邊界值偏置毒指標做突變,是讓模糊測試真正有效的關鍵做法。 ABI 規範允許非連續指標:ABI 解碼分靜態區(存指標)與動態區(存實際資料),規範並未要求指標一定連續排列,允許多個欄位共享同一動態資料位置,這給了彈性但也留下安全隱患。

重點整理

重點
  • 1

    ABI 規範允許非連續指標:ABI 解碼分靜態區(存指標)與動態區(存實際資料),規範並未要求指標一定連續排列,允許多個欄位共享同一動態資料位置,這給了彈性但也留下安全隱患。

  • 2

    calldata 與記憶體緩衝區的風險差異:calldata 由使用者完全控制,即使讀到任意位置也只是讀回自己提供的資料;但 `abi.decode()` 作用於記憶體緩衝區,攻擊者若能構造特定 payload,就可能在解碼期間讀到緩衝區外的資料,造成真正的安全問題。

  • 3

    指標驗證是唯一真正困難的點:uint256 解碼只是複製 32 bytes,bytes 解碼也只是複製,幾乎不可能出錯;真正的風險集中在「指標是否仍在使用者提供的 payload 範圍內」這一個問題上。

  • 4

    偏置模糊測試優於純隨機:針對 payload 長度的邊界值(payload length、payload length × 2 附近)生成「毒指標」,能有效命中整數溢出與越界條件;純隨機在如此龐大的輸入空間中,實際上永遠找不到 bug。

實用技巧與重點

乾貨
  • 平台/工具:EVM(Ethereum 虛擬機)、Solidity、Python、Hypothesis(Python 模糊測試庫)、AFL(基於覆蓋率的模糊測試框架)
  • 數字:128 bytes 輸入空間 ≈ 8^128 種可能;單一指標為 uint256,空間極為龐大
  • 核心規則:修復後的規範允許指標指向 payload 內任意位置(可重疊、可非連續),但絕不得超出使用者提供的 payload 邊界
  • 高價值突變範圍:`payload_length` 到 `payload_length × 2` 之間的值,涵蓋越界與整數溢出場景
  • 差異測試做法:同一份輸入送進 Python 規格實作與 Solidity 編譯器,比對輸出是否一致
  • 突變操作:對有效 payload 做點突變(edit / add / delete 32-byte 區塊),並從高價值指標範圍取樣
  • 修復週期:在一個版本週期內完成,期間多次發現新問題後重新迭代

結論

結論

對 ABI 解碼器這類以指標為核心風險的元件,用 Python 規格實作做差異基準、再以邊界值偏置毒指標做突變,是讓模糊測試真正有效的關鍵做法。

完整解析

詳細

EVM 上的合約互呼時,資料的序列化與反序列化依賴一套稱為 ABI 的規範。ABI 將資料分成兩類:靜態資料(長度固定,如 uint256 固定佔 32 bytes)和動態資料(長度在執行期決定,如 bytes)。在編碼時,靜態區存放指向動態區的指標,動態區再存放實際資料及長度資訊。規範刻意允許「寬鬆解碼器」,也就是只要跟著指標走,不必驗證指標是否按照嚴格的連續順序排列,這讓多個欄位可以共享同一塊動態資料,是一種有意設計的彈性。

問題在於這個寬鬆特性與 `abi.decode()` 的組合。在 calldata 情境下,資料完全由使用者提供,即使解碼器跟隨了一個「奇怪的指標」,頂多也是讀回自己提供的資料,沒有實質危害。但 `abi.decode()` 是作用在記憶體緩衝區(y buffer)上的,若解碼器未驗證指標合法性,攻擊者就能構造特殊 payload,讓解碼器在解碼過程中讀到 y buffer 外的記憶體。這個問題最早由 Alex Wade 提報,當時以 calldata 無害為由關閉;等到 `abi.decode()` 實作後才真正成為安全漏洞。

修復過程極為複雜,涉及指標算術溢出、零長度遞迴優化的邊界條件等多個細節。團隊在反覆修補、反覆發現新問題後意識到:必須先有一份明確的規範,再用規範去驗證實作。他們用 Python 寫了一個儘可能簡單的規格實作,目標是讓它成為「可讀的規範」而非「最佳化過的程式碼」。接著,他們將同一份輸入分別送入 Python 規格實作與 Solidity 編譯器,比對結果是否一致,這就是差異模糊測試的核心。

然而,純隨機輸入完全失效。原因很直觀:ABI 解碼器中唯一真正困難的部分是指標驗證,其他操作(複製 32 bytes、複製位元組資料)幾乎不可能出錯。但指標是 uint256,空間龐大到隨機命中邊界的機率趨近於零。團隊因此引入了「偏置突變」策略:從有效 payload 出發,再針對 `payload_length` 到 `payload_length × 2` 之間的範圍生成毒指標,這個範圍能系統性地覆蓋越界讀取與整數溢出兩類場景。實際使用 Python 的 Hypothesis 函式庫,將不同突變策略組合成複合策略,最終成功找到潛在問題。關鍵心得是:模糊測試不能完全隨機,要理解「哪些值對程式有害」,再對模糊器施加適度偏置,同時保留足夠的隨機性來發現未知錯誤。

關鍵時刻

Pipeline v2

帶時間戳的重點,會在逐字稿層級分析上線後產生。目前請先透過原始影片觀看。

事實查核

Pipeline v2

說法查證是下一次管線升級的一部分。KeyFrame 只會顯示它真正能驗證的內容。

更多「Web3 安全」的內容

IF YOU OWN XRP YOU NEED TO SEE THIS PRICE MANIPULATION! ⚠️
8 min
Web3 安全英文8月14日

IF YOU OWN XRP YOU NEED TO SEE THIS PRICE MANIPULATION! ⚠️

Zach Humphries

  • 機構支撐的積極意義:價格操縱常被視為負面,但Ripple掌握大量XRP供應與escrow,在熊市期間提高價格下限,實際上替零售投資者鎖定了低風險的積累區間,這不是剝削而是市場穩定機制。
  • 歷史模式驗證:2024年7月至11月XRP在50美分附近橫盤整理,低點觸及42美分(wick),高點65美分;隨後11月5日至12月5日單月上漲456%,年底到2025年初累計漲幅534%,這個歷史周期正在1美元價位重演。
  • 比特幣聯動邏輯:講者在4-5月就預測「如果比特幣跌至60k以下,XRP會跌至1美元或更低」,此預測精準應驗,反映出熊市中兩者的明確連動關係。
Minimmit, Multimmit and the New Consensus Frontier with Patrick O'Grady
72 min
Web3 安全英文PODCAST8月5日

Minimmit, Multimmit and the New Consensus Frontier with Patrick O'Grady

Zero Knowledge

  • 反向 Linux 架構:Commonware 刻意暴露棧各層級控制,讓開發者自訂執行環境、共識機制、密碼學實現,而非像 Cosmos SDK 只允許應用層以上定制。2-3 個月能組裝一條定製鏈,代價是額外深度但回報是長期維護成本降低及效能優化彈性。
  • 容錯假設的典範轉移:Alpine Glow(Solana 2025)實現單輪投票定終的關鍵是將容錯預算分離為獨立的 Byzantine 和 Crash 容限。傳統系統把 33% 當一個整體預算;新模型允許 20% 惡意加 20% 崩潰,打破了 PBFT 理論界線,釋放單輪設計空間。
  • Minimet 與 Multimet 的遞進:Minimet 是 5F+1 設定下的乾淨構造,實現更短視圖延遲;Multimet(剛發布)進一步允許並行 mini-commits 且驗證者可推翻領導者審查,使用者交易在全球分布式網路達到 200-300 毫秒端到端定終。
Private Information Retrieval (PIR) with Alex Hoover
64 min
Web3 安全英文PODCAST7月29日

Private Information Retrieval (PIR) with Alex Hoover

Zero Knowledge

  • PIR 保護的是訪問模式,不是資料本身
  • PIR 與加密不同,它關注的是隱藏「客戶端查詢了什麼」,而非「資料是否加密」。在公開資料庫(如區塊鏈)上,客戶端可以在不洩露查詢對象給伺服器的情況下檢索特定條目,解決了輕量級客戶端的隱私和防審查問題。
  • 客戶端預處理方案是突破瓶頸的關鍵