本文爲 Decentralized Systems Lab 發表的討論使用最長鏈規則的 PoS 系統安全性的文章。按照某種劃分方法,PoS 系統可以分爲鏈式結構型(chain-based)和拜占庭容錯型(BFT-Style);文章所闡述的漏洞是鏈式結構型系統中出現的,因此跟 Cosmos 的 Tendermint 這樣的拜占庭容錯型 PoS 共識算法無關;Casper 不使用最長鏈規則,而是 Latest Message Driven Ghost,因此也跟這裏講的漏洞無關。

原文標題:《乾貨 對鏈式結構型 PoS 系統的 「虛假權益」 攻擊,Part-1》
原文作者 :Decentralized Systems Lab
翻譯 & 校對 :TrumanW、閔敏

本文由伊利諾伊大學厄巴納-香檳分校(@ UIUC)的分佈式系統實驗室(Decentralized Systems Lab)發佈。由 Sanket Kanjalkar、Yuqi Li、Yuguang Chen、Joseph Kuo 組成的學生研究團隊在 Andrew Miller 導師的帶領下發現了一些會造成資源耗竭的漏洞,特撰此文作公開披露。這些漏洞已經影響了超過 26 類 PoS 型加密貨幣。通過這些漏洞,一個攻擊者只需使用少量權益就能摧毀任何運行相關軟件的網絡節點。在這次公開披露之前,我們從 2018 年 10 月開始有規劃地通知受影響的加密貨幣開發團隊。大部分團隊(根據市值計算)已經部署了應對措施。

權益證明(PoS)類加密貨幣,特別是那些基於鏈上 PoSv3(第三版權益證明)的加密貨幣,它們與比特幣很相似,都使用未花費的交易輸出(UTXO)模型和最長鏈共識規則。主要的區別在於前者用代幣的所有權證明替代了工作量證明(PoW)。PoS 的潛在優點包括能夠降低對環境的影響以及增強對 51% 攻擊的抵抗性。很多加密貨幣實際上是比特幣代碼庫的分叉(至少是衍生物)並且加入了 PoS 的功能。但是,由於它們盲目複製了比特幣的一些設計理念,留下了安全隱患,因此出現了一些在原先代碼庫中並不存在的新漏洞。

我們將這些漏洞稱爲「虛假權益」攻擊。從本質上講,該攻擊之所以有效是因爲 PoSv3 的程序在簽發珍貴資源(硬盤和內存)之前對網絡數據驗證不足。因此,一個攻擊者只需使用很少的權益份額(在某些情況下甚至是零份額),就能用虛假數據填滿某個節點的硬盤和內存,致使其崩潰。我們認爲所有基於 UTXO 和最長鏈原則的權益證明模型都容易受到這類「虛假權益」攻擊的影響。經過調查研究,我們已經發現了一批存在漏洞的加密貨幣,並在文末附上了列表。

接下來,我們將詳細解釋這些漏洞和攻擊手法,因爲它們會產生一些不易察覺的後果。雖然事後看來這些漏洞本身很簡單,但是想要一勞永逸地解決它們還是很困難,而且現有的解決方案可能會導致分叉(後文會給出解釋)。

背景

在深入瞭解這些漏洞的細節之前,我們將簡要介紹一些關於鏈上 PoS 機制原理的背景知識。

權益證明挖礦

與 PoW 挖礦類似,PoS 挖礦也要將區塊頭的哈希值(hash)與難度目標進行比較。PoS 的目標是確保每個權益者挖出下一個區塊的概率與他們質押的代幣量成正比。爲了達成這一目標,鏈式結構型 PoS 機制的哈希值不僅取決於區塊頭,還取決於權益所有者通過區塊中一筆特殊的 「coinstake」 交易所質押的代幣數量。本文會涉及一些關於 PoS 挖礦的具體細節,更詳細的解釋可以在 Earlz 的博客中找到。本文重點從 1) coinstake 交易和 2) coinstake 交易所花費的 UTXO 這兩方面來闡述 PoS 機制。

工作量證明在節約區塊驗證資源方面起到的作用

衆所周知,PoW 在比特幣共識機制中扮演至關重要的作用,不過它還有一個不那麼受重視的作用,就是控制對節點有限資源的訪問,例如磁盤、帶寬、內存和 CPU。在免許可型公鏈網絡中,一個節點是不能信任其它對等節點的。因此,爲了防止資源耗竭型攻擊,比特幣節點要先檢查區塊的工作量證明,再決定是否花費更多硬盤或內存資源存儲這個區塊。但是,事實表明,檢查權益證明比起驗證工作量證明要複雜的多,對環境也更爲敏感。因此,許多鏈式結構 PoS 機制在有效驗證上投入的資源嚴重不足。

爲了理解資源耗竭型漏洞產生的原因,我們必須詳細說明一下區塊在被驗證之前是如何存儲的。一個節點不僅要追蹤當前時刻最長的鏈,還要追蹤一整棵分叉鏈樹(因爲任何一條分叉鏈都有可能成爲最長鏈,在這種情況下,節點需要 「重組」才能切換到新的最長鏈上)。舉例來說,不當升級、雙花攻擊(例如:遭受 51% 攻擊的 ETC ),或者臨時網絡分區都有可能引發這種情況。

驗證這些非主鏈上的區塊是非常困難的。要完全驗證某個區塊,你需要上一個區塊中未花費的代幣(UTXOs)集合。比特幣保存的是最長鏈頂端區塊時候的 UTXO 集合,但是不會保存之前區塊時候的 UTXO 集合狀態(儘管在此前任何一個區塊上都有可能形成分叉)。在完全驗證分叉鏈上的區塊主要有兩種方法:

  • 將當前視圖(UTXO 集合)「回滾」 到分叉起始點之前;
  • 存儲之前每一區塊時候的 UTXO 狀態。

(校對注:(在 UTXO 模型的區塊鏈中)將一條鏈上的所有區塊所包含的交易都處理完之後就會形成一個 UTXO 的集合,這個集合就是該鏈的最新狀態。因此,哪怕在同一條鏈上, #100 區塊時候的狀態(UTXO 集合)與 #101 區塊時候的狀態也是不同的。上文的意思是,雖然每一個區塊上都有可能形成分叉,但比特幣軟件不會把每一個區塊時候的狀態都專門保存一個副本,而是隻保存最新的 UTXO 集合;若是每一個區塊時候的狀態都要專門保存,這會變成很大一筆存儲開銷。)

比特幣的代碼庫不支持第二個方法,即使它支持,這也會增加額外的存儲成本(比特幣的節點性能依賴於大幅裁減不必要的數據)。比特幣代碼庫目前正是採用第一種方法來處理重組的。然而,經常回滾的代價也是很昂貴的,因此,回滾和完全驗證不會在一有分叉的時候就發生,而是等到分叉鏈上的工作量證明真的超過當前主鏈的時候纔會進行。因此,當一個對等節點第一次接收到一個非最長鏈上的區塊或區塊頭時,我們將跳過完全驗證並將這個區塊保存在本地存儲區。

在將這個區塊存儲進磁盤之前,比特幣代碼庫會基於 PoW 機制執行一些初步驗證(不過會忽略區塊內的交易)。初步驗證僅針對之前的區塊頭以及當前的區塊頭,因此節點驗證起來非常快。而且這是一個非常有效的防禦手段,因爲生成一個有效的工作量證明來通過這個初步驗證成本很高。例如,雖然有可能欺騙一個比特幣節點將一個非法區塊存儲在硬盤內,但是以這種方式發起資源耗竭型攻擊是一個非常不經濟的行爲。

PoS 機制中也存在類似的初步驗證過程,就是對 coinstake 交易進行驗證,將它與上一個區塊的 kernel 值一起進行哈希運算,看最後得到的哈希值是否超過難度目標。計算 coinstake 交易的哈希值很容易,難的是驗證 coinstake 交易中輸入的 UTXO 是否合法並且未被花費;但是要檢查一筆 UTXO 是否沒有被花費,你就需要該筆交易發生前一個區塊時候的 UTXO 集合狀態;如我們上文所說,節點往往是沒有專門存儲這樣一個狀態的。因爲完全驗證 coinstake 交易是非常困難的,大多數鏈上 PoS 機制提供的是一個經驗式或者近似式的驗證方法作爲替代。事實證明這些替代性的驗證方法通常並不充分並且存在漏洞。

漏洞:「我簡直不敢相信還有非權益持有者可以攻擊的漏洞」

我們第一次研究這個漏洞的時候,發現 Qtum、Particl、Navcoin、HTMLcoin 和 Emercoin 這五種密碼學貨幣都存在這個漏洞,即,在將區塊提交至內存或硬盤之前,無法對 coinstake 交易進行驗證。這五種加密貨幣的共同之處是它們都採用了比特幣的「區塊頭優先」 規則,將區塊分成兩類獨立的信息——區塊體和區塊頭——進行傳播。只有當節點確認了某個區塊的區塊頭通過了 PoW 驗證、並且該區塊跟在最長鏈(或更長鏈)之後,纔會請求區塊體的信息。由於 coinstake 交易僅存在於區塊體而非區塊頭中,節點無法做到只驗證區塊頭,於是直接將區塊頭存儲在了內部數據結構(mapBlockIndex)裏。因此,任何網絡攻擊者,即使不持有任何權益,也可以惡意填滿一個節點的內存。

此種攻擊的還有另一個形式,可以針對相同的代碼庫實施,不過它採用的方式略微不同,而且攻擊目標也從節點的內存資源轉向了硬盤資源。可以說,針對節點硬盤的攻擊危害更大:如果節點因內存被填滿而崩潰,只需簡單重啓即可恢復。但是,如果硬盤被填滿了,則需要手動干預才能恢復(例如,運行一個外部腳本來清除硬盤中的過時區塊)。

如果接收的不是區塊頭而是區塊體,需要執行初步驗證也會不同。理想情況下,因爲 coinstake 交易就包含在區塊體中,節點軟件應該先對其進行驗證,再將區塊體提交至硬盤。但是,如上所述,如果這個區塊是在一條分叉鏈上,節點要訪問 coinstake 交易所花費的 UTXO 會難得多。也許是出於這個原因,這些代碼庫並沒有驗證 coinstake 交易。

對於存在上述任意一個漏洞的加密貨幣來說,即使是不持有任何權益的人也能對它們發動攻擊。針對內存的資源耗竭型攻擊微不足道,從技術的角度來看,我們更需要堤防的是針對硬盤的資源耗竭型攻擊(儘管二者都是不需要持有任何權益就能發動的攻擊)。

來源鏈接:medium.com