加密貨幣交易所 加密貨幣交易所
Ctrl+D 加密貨幣交易所
ads

崩潰的RPC:內存安全區塊鏈RPC節點新型漏洞解析_RPC:NIC

Author:

Time:1900/1/1 0:00:00

CertiK的Skyfall團隊最近在Aptos、StarCoin和Sui等多個區塊鏈中發現了基于Rust的RPC節點的多個漏洞。由于RPC節點是連接dApp和底層區塊鏈的關鍵基礎設施組件,其穩健性對于無縫操作至關重要。區塊鏈設計者都知道穩定RPC服務的重要性,因此他們采用Rust等內存安全語言來規避可能破壞RPC節點的常見漏洞。

采用內存安全語言(如Rust)有助于RPC節點避免許多基于內存破壞漏洞的攻擊。然而,通過最近的審計,我們發現即使是內存安全的Rust實現,如果沒有經過精心設計和審查,也很容易受到某些安全威脅的影響,從而破壞RPC服務的可用性。

本文我們將通過實際案例介紹我們對一系列漏洞的發現。

區塊鏈RPC節點作用

區塊鏈的遠程過程調用(RPC)服務是Layer 1區塊鏈的核心基礎設施組件。它為用戶提供重要的API前端,并作為通向后端區塊鏈網絡的網關。然而,區塊鏈RPC服務與傳統的RPC服務不同,它方便用戶交互無需身份驗證。服務的持續可用性至關重要,任何服務中斷都會嚴重影響底層區塊鏈的可用性。

審計角度:傳統RPC服務器 VS 區塊鏈RPC服務器

對傳統RPC服務器的審計主要集中在輸入驗證、授權/認證、跨站請求偽造/服務器端請求偽造(CSRF/SSRF)、注入漏洞(如SQL注入、命令注入)和信息泄露等方面進檢查。

然而,區塊鏈RPC服務器的情況有所不同。只要交易是簽名的,就不需要在RPC層對發起請求的客戶端進行身份驗證。作為區塊鏈的前端,RPC服務的一個主要目標是保證其可用性。如果它失效,用戶就無法與區塊鏈交互,從而阻礙查詢鏈上數據、提交交易或發布合約功能。

因此,區塊鏈RPC服務器最脆弱的方面是“可用性”。如果服務器宕機,用戶就失去了與區塊鏈交互的能力。更嚴重的是,一些攻擊會在鏈上擴散,影響大量節點,甚至導致整個網絡癱瘓。

為何新區塊鏈會采用內存安全的RPC

一些著名的Layer 1區塊鏈,如Aptos和Sui,使用內存安全編程語言Rust實現其RPC服務。得益于其強大的安全性和編譯時嚴格的檢查,Rust幾乎可以使程序免受內存破壞漏洞的影響,如堆棧溢出、和空指針解引用和釋放后重引用等漏洞。

BlockFi債權人:在FTX崩潰后的幾天,BlockF將約2.4億美元的加密貨幣轉換為法幣:金色財經報道,BlockFi 債權人將 BlockFi 說成是 FTX 和 Alameda 受害者的說法稱為虛假陳述,并將該公司的失敗歸咎于管理決策不善以及重組代理人。債權人委員會指出,在 FTX 崩潰后的幾天里,當加密貨幣市場暴跌時,BlockFi 將大約 2.4 億美元的加密貨幣轉換為法幣,給客戶造成了重大的財務損失和潛在的稅務問題,BlockFi 隨后將收益和額外的 1000 萬美元存入硅谷銀行(SVB),該銀行之后倒閉。

債權人委員會表示,SVB 的存款機構實力不足以滿足《破產法》的保護要求,這促使美國受托人反對將遺產資金存放在那里。最終達成了一項安排,如果銀行倒閉,SVB 將提供足夠的抵押品(以債券的形式)。但 BlockFi 的任何人(包括重組團隊)都懶得跟進,也沒有人支付任何保證金。

此外,BlockFi 還花費 2250 萬美元的客戶資金為其董事和高管購買價值 3000 萬美元的保險。[2023/5/16 15:05:50]

為了進一步確保代碼庫的安全,開發人員需嚴格遵循最佳實踐,例如不引入不安全代碼。在源代碼中使用#![forbid(unsafe_code)]確保阻攔過濾不安全的代碼。

區塊鏈開發者執行Rust編程實踐的例子

為了防止整數溢出,開發人員通常使用checked_add、checked_sub、saturating_add、saturating_sub等函數,而不是簡單的加法和減法(+、-)。通過設置適當的超時、請求大小限制和請求項數限制來緩解資源耗盡。

Layer 1區塊鏈中內存安全RPC威脅

盡管不存在傳統意義上內存不安全的漏洞,但RPC節點會暴露在攻擊者容易操縱的輸入中。在內存安全RPC實現中,有幾種情況會導致拒絕服務。例如,內存放大可能會耗盡服務的內存,而邏輯問題可能會引入無限循環。此外,競態條件也可能構成威脅,并發操作可能會出現意外的事件序列,從而使系統處于未定義的狀態。此外,管理不當的依賴關系和第三方庫可能會給系統帶來未知漏洞。

觀點:FTX崩潰可能加快推動加密立法:金色財經報道,位于華盛頓的加密行業游說團體區塊鏈協會執行董事Kristin Smith表示,加密貨幣交易所FTX倒閉后行業信譽受損,要修復聲譽將需要繼續與美國政策制定者接觸。她表示,該行業可以“擺脫當前的危機”,需要的是與有興趣為加密找到正確的監管框架的兩黨政策制定者合作,不僅要保護消費者,還要推動創新。

Smith說,“我們將看到提出的一些兩黨立法提案,這些提案將在國會的多個委員會中得到非常嚴格的審查和辯論,而且我們確實可以看到一些立法加快完成的勢頭”。[2022/12/14 21:43:20]

在這篇文章中,我們的目的是讓人們關注可以觸發 Rust 運行時保護的更直接的方式,從而導致服務自行中止。

顯式的Rust Panic:一種直接終止RPC 服務的方法

開發人員可以有意或無意地引入顯式panic代碼。這些代碼主要用于處理意外或異常情況。一些常見的例子包括:

assert!():當必須滿足一個條件時使用該macro。如果斷言的條件失敗,程序將 panic,表明代碼中存在嚴重錯誤。

panic!():當程序遇到無法恢復的錯誤且無法繼續執行時調用該函數。

unreachable!():當一段代碼不應該被執行時使用該macro。如果該macro被調用,則表示存在嚴重的邏輯錯誤。

unimplemented!()和todo!():這些宏是尚未實現功能的占位符。如果達到該值,程序將崩潰。

unwrap():該方法用于Option或Result類型,當遇到Err變量或None時會導致程序宕機。

漏洞一:觸發Move Verifier中的assert!

Aptos區塊鏈采用Move字節碼驗證器,通過對字節碼的抽象解釋進行引用安全分析。execute()函數是TransferFunctions trait實現的一部分,模擬基本塊中字節碼指令的執行。

羅伯特清崎:史上最大的經濟崩潰將至,多買黃金白銀和比特幣:《富爸爸窮爸爸》作者羅伯特清崎(Robert Kiyosaki)今日表示,世界歷史上最大的經濟崩潰即將來臨。好消息是,致富的最佳時機是在崩盤期間。壞消息是,下一次危機將持續很長時間。趁你還有機會,多買些黃金、白銀和比特幣。(U.today)[2021/6/28 0:11:32]

函數execute_inner()的任務是解釋當前字節碼指令并相應地更新狀態。如果我們已經執行到基本塊中的最后一條指令,如index == last_index所示,函數將調用assert!(self.stack.is_empty())以確保棧為空。此行為背后的意圖是保證所有操作都是平衡的,這也意味著每次入棧都有相應的出棧。

在正常的執行流程中,棧在抽象解釋過程中始終是平衡的。堆棧平衡檢查器(Stack Balance Checker)保證了這一點,它在解釋之前對字節碼進行了驗證。然而,一旦我們將視角擴展到抽象解釋器的范圍,就會發現堆棧平衡假設并不總是有效的。

AbstractInterpreter中analyze_function漏洞的補丁程序

抽象解釋器的核心是在基本塊級別中模擬字節碼。在其最初的實現中,在execute_block過程中,遇到錯誤會提示分析過程記錄錯誤,并繼續執行控制流圖中的下一個塊。這可能會造成一種情況:執行塊中的錯誤會導致堆棧不平衡。如果在這種情況下繼續執行,就會在堆棧不為空的情況下進行assert!檢查,從而引發panic。

這就使得攻擊者有機可趁。攻擊者可通過在execute_block()中設計特定的字節碼來觸發錯誤,隨后execute()有可能在堆棧不為空的情況下執行assert,從而導致assert檢查失敗。這將進一步導致panic并終止RPC服務,從而影響其可用性。

超過6000人試圖加入Skybridge比特幣基金導致其網絡系統崩潰:1月10日消息,超過6000人試圖加入天橋資本的Skybridge比特幣基金導致其網絡系統崩潰而失敗。對此,天橋資本將于1月12日召開第二次電話會議。此前消息,天橋資本已正式推出Skybridge比特幣基金。(Decrypt)[2021/1/10 15:46:20]

為防止出現這種情況,已實施的修復中,確保了在execute_block函數首次出現錯誤時會停止整個分析過程,進而避免了因錯誤導致堆棧不平衡而繼續分析時可能發生的后續崩潰風險。這一修改消除了可能引起panic的情況,并有助于提高抽象解釋器的健壯性和安全性。

漏洞二:觸發StarCoin中的panic!

Starcoin區塊鏈有自己的Move實現分叉。在這個Move repo中,Struct類型的構造函數中存在一個panic! 如果提供的StructDefinition擁有 Native 字段信息,就會顯式觸發這個panic!。

規范化例程中初始化結構體的顯式panic

這種潛在風險存在于重新發布模塊的過程中。如果被發布的模塊已經存在于數據存儲中,則需要對現有模塊和攻擊者控制的輸入模塊進行模塊規范化處理。在這個過程中,"normalized::Module::new "函數會從攻擊者控制的輸入模塊中構建模塊結構,從而觸發 "panic!"。

規范化例程的前提條件

通過從客戶端提交特制的有效載荷,可以觸發該panic。因此,惡意行為者可以破壞RPC服務的可用性。

聲音 | 彭博:加密貸款市場擴張過快,并正走向崩潰:彭博社發文稱,金融法則仍然適用于加密貨幣的平行宇宙。一群正在尋求數字資產財富的前華爾街交易員表示,加密信貸擴張過快,并正走向崩潰。據區塊鏈數據公司Graychain Ltd.稱,就在兩年前,一個價值近50億美元的行業從無到有,貸款平臺的數量正在迅速激增。[2019/10/29]

結構初始化panic補丁

Starcoin的補丁引入了一個新的行為來處理Native情況。現在,它不會引起panic,而是返回一個空的ec。這減少了用戶提交數據引起panic的可能性。

隱式 Rust Panic: 一種容易被忽視的終止RPC服務的方法

顯式 panic 在源代碼中很容易識別,而隱式panic則更可能被開發人員忽略。隱式panic通常發生在使用標準或第三方庫提供的API時。開發人員需要徹底閱讀和理解API文檔,否則他們的Rust程序可能會意外停止。

BTreeMap 中的隱式 panic

讓我們以Rust STD中的BTreeMap為例。BTreeMap是一種常用的數據結構,它以排序的二叉樹形式組織鍵值對。BTreeMap提供了兩種通過鍵值檢索值的方法:get(&self, key: &Q)和index(&self, key: &Q)。

方法get(&self, key: &Q)使用鍵檢索值并返回一個Option。Option可以是Some(&V),如果key存在,則返回值的引用,如果在BTreeMap中沒有找到key,則返回None。

另一方面,index(&self, key: &Q)直接返回鍵對應的值的引用。然而,它有一個很大的風險:如果鍵不存在于BTreeMap中,它會觸發隱式panic。如果處理不當,程序可能會意外崩潰,從而成為一個潛在漏洞。

事實上,index(&self, key: &Q)方法是std::ops::Index trait的底層實現。該特質為不可變上下文中的索引操作(即 container[index])提供了方便的語法糖。開發者可以直接使用 btree_map[key],調用 index(&self, key: &Q) 方法。然而,他們可能會忽略這樣一個事實:如果找不到key,這種用法可能會觸發panic,從而對程序的穩定性造成隱性威脅。

漏洞三:在Sui RPC中觸發隱式panic

Sui模塊發布例程允許用戶通過RPC提交模塊有效載荷。在將請求轉發給后端驗證網絡進行字節碼驗證之前,RPC處理程序使用SuiCommand::Publish函數直接反匯編接收到的模塊。

在這個反匯編過程中,提交模塊中的code_unit部分被用來構建一個VMControlFlowGraph。該構建過程包括創建基本塊,這些塊存儲在一個名為 "'blocks' "的BTreeMap中。該過程包括創建和操作該Map,在某些條件下,隱式panic會在這里觸發。

下面是一段簡化的代碼:

創建VMControlFlowGraph時的隱式panic

在該代碼中,通過遍歷代碼并為每個代碼單元創建一個新的基本塊來創建一個新的VMControlFlowGraph。基本塊存儲在一個名為block的BTreeMap中。

在對堆棧進行迭代的循環中,使用block[&block]對塊圖進行索引,堆棧已經用ENTRY_BLOCK_ID進行了初始化。這里的假設是,在block映射中至少存在一個ENTRY_BLOCK_ID。

然而,這一假設并不總是成立的。例如,如果提交的代碼是空的,那么在“創建基本塊”過程之后,“塊映射”仍然是空的。當代碼稍后嘗試使用&blocks[&block].successors中的for succ遍歷塊映射時,如果未找到key,可能會引起隱式panic。這是因為blocks[&block]表達式本質上是對index()方法的調用,如前所述,如果鍵不存在于BTreeMap中,index()方法將導致panic。

擁有遠程訪問權限的攻擊者可以通過提交帶有空code_unit字段的畸形模塊有效載荷來利用該函數的漏洞。這個簡單的RPC請求會導致整個JSON-RPC進程崩潰。如果攻擊者以最小的代價持續發送此類畸形有效載荷,就會導致服務持續中斷。在區塊鏈網絡中,這意味著網絡可能無法確認新的交易,從而導致拒絕服務(DoS)情況。網絡功能和用戶對系統的信任將受到嚴重影響。

Sui的修復:從RPC發布例程中移除反匯編功能

值得注意的是,Move Bytecode Verifier中的CodeUnitVerifier負責確保code_unit部分絕不為空。然而,操作順序使RPC處理程序暴露于潛在的漏洞中。這是因為驗證過程是在Validator節點上進行的,而該節點是在RPC處理輸入模塊之后的一個階段。

針對這一問題,Sui通過移除模塊發布RPC例程中的反匯編功能來解決該漏洞。這是防止RPC服務處理潛在危險、未經驗證的字節碼的有效方法。

此外,值得注意的是,與對象查詢相關的其他RPC方法也包含反匯編功能,但它們不容易受到使用空代碼單元的攻擊。這是因為它們總是在查詢和反匯編現有的已發布模塊。已發布的模塊必須已經過驗證,因此,在構建VMControlFlowGraph時,非空代碼單元的假設始終成立。

對開發人員的建議

在了解了顯式和隱式panic對區塊鏈中RPC服務穩定性的威脅后,開發人員必須掌握預防或降低這些風險的策略。這些策略可以降低服務意外中斷的可能性,提高系統的彈性。因此CertiK的專家團隊提出以下建議,并作為Rust編程的最佳實踐為大家列出。

Rust Panic Abstraction:  盡可能考慮使用Rust的catch_unwind函數來捕獲panic,并將其轉換為錯誤信息。這可以防止整個程序崩潰,并允許開發人員以可控的方式處理錯誤。

謹慎使用API:隱式panic通常是由于濫用標準或第三方庫提供的API而發生的。因此,充分理解API并學會適當處理潛在錯誤至關重要。開發人員要始終假設API可能會失效,并為這種情況做好準備。

適當的錯誤處理:使用Result和Option類型進行錯誤處理,而非求助于panic。前者提供了一種更可控的方式來處理錯誤和特殊情況。

添加文檔和注釋:確保代碼文檔齊全,并在關鍵部分(包括可能發生panic的部分)添加注釋。這將幫助其他開發人員了解潛在風險并有效處理。

總結

基于Rust的RPC節點在Aptos、StarCoin和Sui等區塊鏈系統中扮演著重要的角色。由于它們用于連接DApp和底層區塊鏈,因此它們的可靠性對于區塊鏈系統的平穩運行至關重要。盡管這些系統使用的是內存安全語言Rust,但仍然存在設計不當的風險。CertiK的研究團隊通過現實世界中的例子探討了這些風險,也足以證明了內存安全編程中需要謹慎和細致的設計。

CertiK中文社區

企業專欄

閱讀更多

金色財經

金色薦讀

Block unicorn

區塊鏈騎士

金色財經 善歐巴

Foresight News

深潮TechFlow

Tags:RPCNICANIPANRPC幣MnICorpAquaniteYPANDA幣

芝麻開門交易所
探索 BTC Layer 2 賽道與機會_比特幣:區塊鏈幣圈幣種知識大全

比特幣交易吞吐量緩慢長期以來一直是其用戶關注的一個問題。雖然比特幣的安全性和去中心化一直是其優勢,但其有限的交易速度阻礙了其有效處理大量交易的能力.

1900/1/1 0:00:00
從Ordinals辯論回顧2014年OP_Return之爭:Dapps與比特幣交易對決

在2014年的OP_RETURN之爭是行業內的一個顯著分裂,與今天的Ordinals辯論有很多相似之處。回顧OP_RETURN之爭在今天看來格外的有意義.

1900/1/1 0:00:00
一文速覽社交龍頭Lens V2 五大新功能_ENS:ANIME價格

在以太坊EthCC的主會場,Stani公布了Lens Protocol V2版本的上線,介紹了詳細內容.

1900/1/1 0:00:00
重新定義流動質押:Lido 如何推動以太坊的質押格局_ETH:LID

作者:David Zareh 來源:medium 編譯:金色財經,善歐巴在以太坊質押的世界中,驗證者在選擇質押方法時面臨各種限制和權衡.

1900/1/1 0:00:00
早期Web3公司應該如何選擇增長策略?_WEB:WEB3COIN

作者:Chainlink Labs ;編譯:BlockMania一般來說,創業公司采取什么樣的營銷策略要取決于它們的商業模式以及所在的垂直領域.

1900/1/1 0:00:00
Coinbase和Binance在與SEC的斗爭中失去市場份額 競爭對手嗅到了機會_COI:OIN

作者:David Thomas,beincrypto 編譯:金色財經,善歐巴 摘要 由于美國 SEC 對 Coinbase 和 Binance 提起訴訟.

1900/1/1 0:00:00
ads