跳至正文
-
及時訂閱我們,以獲取第一手資訊
web3.0世界 web3.0世界

加密世界

web3.0世界 web3.0世界

加密世界

  • 首页
  • 首页
关

搜索

  • https://www.facebook.com/
  • https://twitter.com/
  • https://t.me/
  • https://www.instagram.com/
  • https://youtube.com/
訂閱

Liquid Network 快取鍵碰撞漏洞解析:近 4,000 枚 L-BTC 被憑空鑄造

3 分钟阅读

9 月 6 日 13:52:10 UTC,Liquid 的 4,050,335 號區塊裡出現兩筆結構相同的交易。一分鐘後,4,050,336 號區塊確認了第三筆,約 3,998.5 枚 L-BTC 進入 ​​UTXO 集,背後沒有任何一筆 peg-in。再過幾分鐘,這些並不存在的資產開始被歸攏、消費,隨後經聯邦 peg-out 通道兌成了比特幣主網上的真 BTC。

隔日,3,400 BTC 退回了聯邦 peg 錢包。剩下的 598.5 BTC 留在攻擊者手裡,到發稿時還在被反覆自我轉賬,每筆交易附帶一段 OP_RETURN 明文,向聯邦索要一成”賞金”。談判至今仍在鏈上公開進行。

我們把 4,050,335 前後的區塊逐筆核對了一遍,Bitcoin 側的資金流用 MistTrack 跟到了每一跳。這篇文章講兩件事,攻擊者在技術上做了什麼,以及一段 2016 年就進代碼庫的效能優化,為什麼十年後能兌走四千枚比特幣。

攻击概览

Liquid 的錢是怎麼管的

L-BTC 的發行只有一條正路。把 BTC 交進聯邦管理的多簽錢包,Liquid 側才鑄造等量的 L-BTC,反向走 peg-out 換回 BTC。這條一比一的錨定由機密交易機制看守。每個產出的金額不直接寫在鏈上,藏進一個 Pedersen 承諾裡;每個承諾必須附帶一張 rangeproof,證明金額非負、沒有越界。驗證交易時,節點把輸入和輸出的承諾點分別求和,兩邊對得上,這筆帳才算平。

只要有一個輸出能塞進假 rangeproof,承諾裡可以藏一個負數,或是一個天文數字,憑空造幣在數學上就成立了。所以 rangeproof 必須每次都真驗。

麻煩在於它貴。一張 rangeproof 通常四千多字節,驗證是實打實的橢圓曲線運算,每個輸出都要做一次。 2016 年 7 月 12 日,一筆標題為 Rangeproof caching 的提交(66ab07bd1b)進了 Elements 程式碼庫,思路沿用比特幣的簽名緩存。驗過的證明不再重驗,”驗證成功”這個結果存進一張快取表,下次同樣的輸入直接放行。

這類優化在密碼學程式碼裡很常見。這次的全部問題,也出在它身上。

快取鍵缺了什麼

先看 23.3.3 發布版裡的這段程式碼。

快取鍵就是 proof 和 commitment 裸拼進同一條 SHA-256 流。 proof 是變長字段,長的有四千多位元組。這條鍵裡沒有資產,沒有腳本,也沒有任何欄位邊界資訊。

今年 8 月 3 日的修復提交(c26d719)把資產承諾和鎖定腳本補了進去,變成四個欄位。方向沒錯,原先同一個證明確實可以配上不同的資產和腳本反覆”復用”。補丁仍然把四個字段裸拼進同一條流。 proof 和 scriptPubKey 都是變長字段,中間的邊界可以從這裡移到那裡。

9 月 8 日的加固提交(94000967f6)改用帶長度前綴的序列化雜湊。提交資料裡有一段話說得很直白。

This serializes each field with a length prefix, so distinct argument tuples with byte-identical raw concatenations no longer collide to the same cache key. A cache entry is a positive verification result; a collision wect let verby cat.

快取裡存的是”驗證通過”。鍵撞了,就等於替一個從沒驗過的東西作了保。同一筆提交還發現 surjection proof 的快取鍵裡連輸入資產標籤都沒綁,一併修掉了。

命中即免驗

放行發生在 CachingRangeProofChecker::VerifyRangeProof 的開頭。

命中直接傳回 true。後面的 secp256k1_rangeproof_verify、min_value 檢查,一行都不會執行。

快取的寫入和清除各有一條規則,這是攻擊時序的關鍵。交易進記憶體池時按可寫入模式校驗,驗過的結果存進緩存,以供日後進塊時重複使用。區塊連接時則相反,只查詢、不寫入,查到一次就打上可回收的標記。 validation.cpp 第 2340 行的註解把後半條規則寫得很清楚,原文是 Don’t cache results if we’re actually connecting blocks (still consult the cache, though)。

快取條目是消耗品。攻擊者要保證的只有一件事,趁目標節點還留著這條”已驗證”記錄的窗口,把攜帶碰撞載荷的交易遞過去。

每個節點的快取鍵還帶一段啟動時產生的隨機鹽。鹽救不了它。鹽加在所有字段的最前面,兩條流本身就相同,加不加鹽都相同,碰撞於是在每個節點上獨立成立。

鏈上的八分鐘

攻擊從 13:52:10 開始,區塊 4,050,335,兩筆結構相同的 setup 交易被打進同一個區塊。每筆帶一個 OP_RETURN 輸出,這個輸出本身就乾乾淨淨。資產是明文 L-BTC(6f0279e9…),金額承諾 C0(09d6c615…)附帶一張誠實合法的 rangeproof P0,節點按正常流程驗過。載重藏在它的鎖定腳本裡。

0x43 是 67,剛好把後面 67 個位元組當作資料推入。 C1(

086f5d67…)是攻擊輸出準備使用的假金額承諾。 X(0a0a488de489…)是一種盲化形式的資產承諾,單看字節讀不出對應哪一種資產。我們用倉庫裡的 secp256k1 實算過 L-BTC 的明文產生元,是 0ab963d4 開頭,和 X 不是同一個點。這兩個值作為字面資料躺進腳本,驗證時只被當作普通資料。驗完,每個節點的快取裡多了一筆記錄,鍵是這四個欄位的裸拼接流。

中間還有一段 primer 的工夫。區塊連線會把快取條目用掉,攻擊者就拿同樣載重的交易在記憶體池裡重複播種,把各節點的快取重新填上。具體哪幾筆是 primer,從區塊資料反推不出來,它們可能根本沒進塊。兩筆 setup 擠在同一個區塊,大概也是為了條目被消耗後能馬上補一手。

13:53:10,區塊 4,050,336,鑄造交易出現。它有一個核心輸出,四個字段這樣填。 proof 放 P0 再跟 68 個位元組的尾巴,尾巴內容是 C0、A、6a43,A 是 setup 輸出自身的資產承諾。 commitment 放 C1。 asset_commitment 放 X。 scriptPubKey 只剩下一個位元組,6a。

四個欄位兩兩不同,把它們​​依序裸拼進 SHA-256,兩條流逐位元組相同。

節點驗到這個輸出,算鍵,命中,回傳 true。 secp256k1_rangeproof_verify 從未碰過這張證明。 C1 背後的金額要多大,再由負值承諾的輸出把 Pedersen 求和抵平,約 3,998.5 枚 L-BTC 就這樣進了 UTXO 集。

13:54:10 和 14:00:10,區塊 4,050,337 和 4,050,343,兩筆交易把相關 UTXO 歸攏花出。 peg-out 請求由聯邦照常授權,等值真 BTC 經 Bitcoin 主網付出,收款地址 bc1ql4mfu6aundtkksxklfajs2h3t9nzcd6gyqjlte。從第一筆 setup 落塊到資金開始歸攏,前後八分鐘。

返還與鏈上談判

第二天,3,400 BTC 被轉回聯邦 peg 錢包 bc1qdlld6antmv4xug242ed83q7k4rqw50cwfns38szx4qu2f4jwaxxsuhwxxr。剩下的 598.5 BTC 留在原地,9 月 8 日到 10 日在 966,052 至 966,199 號區塊間被反復自我花銷,每筆附帶 OP_RETURN 明文。其中一句寫著 “You SHALL pay 10% using your own money as bug bounty”,落款留了 Telegram 帳號 @MRBOND_1。留言里以白帽自居,要求聯邦自掏腰包,以 10% 支付一筆正式賞金。談判至今仍在鏈上公開進行。

MistTrack 資金追蹤

在明確事件基本上經過後,我們進一步對攻擊者在 Liquid 和 Bitcoin 主網上的資金流向進行了追踪,並使用 MistTrack 對 Bitcoin 側關鍵地址進行分析,再與鏈上數據交叉核驗。

Liquid 側,攻擊者使用位址 ex1q7kgx4ptje7px48tn0nsmc6se5pngdp3smpqa2w 完成相關資產的歸攏和消費。該地址共涉及 91 筆交易、247 個輸出,目前已全部花費。由於 MistTrack 目前尚未涵蓋 Liquid 鏈,因此 Liquid 側從 L-BTC 鑄造、UTXO 消費到後續 peg-out 的資金流,主要以區塊瀏覽器數據逐筆核驗。

在 Bitcoin 主網一側,約 3,998.5 BTC 的 peg-out 資金最終進入地址 bc1ql4mfu6aundtkksxklfajs2h3t9nzcd6gyqjlte。 MistTrack 對該地址的風險評分為 100/100,評級為 Severe,標籤包括 Malicious Address / Involved Theft Activity,並與 Theft 類非法活動實體一跳直連,關聯度為 100%。

從資金來源來看,該地址收到的 BTC 並不存在對應的正常資金本金,其來源可以追溯至前述 L-BTC 的鑄造及後續 peg-out,攻擊者實際承擔的主要是相關交易手續費。

隨後,這筆資金分成兩部分。其中 3,400 BTC 於次日轉入聯邦 peg 錢包 bc1qdlld6antmv4xug242ed83q7k4rqw50cwfns38szx4qu2f4jwaxxsuhwxxr。透過 MistTrack 交易調查進行核驗時,該地址也是 bc1ql4mfu… 轉出目標中金額最高的地址,對應轉帳金額為 3,400 BTC,與鏈上資料一致。

剩餘約 598.5 BTC 仍由攻擊者控制。 9 月 8 日至 10 日期間,這部分資金在 Bitcoin 區塊 966,052 至 966,199 之間持續發生自我轉賬,並透過 OP_RETURN 留言與聯邦進行公開談判。其中一則留言寫有 “You SHALL pay 10% using your own money as bug bounty”,並留下 Telegram 帳號 @MRBOND_1。目前相關談判仍可在鏈上觀察到。

結語

這段程式碼在倉庫裡待了十年,被無數節點跑了無數遍。 8 月 3 日修過一次,9 月 6 日還是被打了。第一版補丁把缺少的字段補進了哈希,漏掉字段邊界,五週後邊界被精確利用。 9 月 8 日發布的 Elements 23.3.4 除了把鍵長度前綴化,還加了 -norangeproofcache 急停開關,維運可以不放行任何快取結果,直接關掉這張表。

這次的教訓可以壓得很短。密碼學驗證路徑上的正向結果緩存,命中即免驗,它的鍵必須按密碼學原語的標準對待。驗證函數讀進去的每個欄位、每個欄位的邊界,都要無歧義地進哈希,長度前綴就是乾這個的。快取、記憶化、平行化這類效能最佳化,只要落在驗證路徑上,稽核時就應與被最佳化的密碼學原語同等待遇。

慢霧安全團隊建議專案方在部署前做一次完整的外部安全審計。共識層的稽核清單裡,驗證快取的鍵完整性應列為必檢項。

Post Views: 1
作者

安全守护

关注我
其他文章
上一个

新幣擔保遭「雙重圍剿」:美國制裁疊加 Tether 凍結,東南亞最大非法擔保平台關閉

下一个

法國黃金儲備佔70%,中國僅3.8%:為什麼差距這麼大?

暂无评论!成为第一个。

发表回复 取消回复

您的邮箱地址不会被公开。 必填项已用 * 标注

加密世界

本站為所有區塊鏈愛好者提供最新第一手免費內容資訊,含蓋,政策,突發大事件,各地衝突等豐富內容

搜尋

近期文章

  • 錢包被盜怎麽辦?
  • Web3 安全指南:如何預防錢包被惡意多簽的風險
  • 21 家全球銀行巨頭聯手!銀行版穩定幣要來了
  • Symbiosis追回15枚比特幣,為何跨鏈橋漏洞為何總是能先鑄幣再追損
  • 3.2 億美元 Liquid 迷局:金鑰沒被攻破,錢怎麼就轉走了?

加密世界

本站為所有區塊鏈愛好者提供最新第一手免費內容資訊,含蓋,政策,突發大事件,各地衝突等豐富內容

版權所有 2026 — 加密世界。保留所有權利。