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

在以太坊上安裝 “炸彈”_ETH:GETH

Author:

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

本文是講解我在go-ethereum客戶端中發現的Bug系列的第二篇。如果你還不了解它,請看第一篇。

這篇文章要講的bug位于Geth客戶端的狀態下載器內,它可以用來欺騙下載器,使之不能與主網正確同步。攻擊者可以利用這個bug給以太坊區塊鏈設置陷阱、任意觸發硬分叉。

同步

當你想運行一個以太坊節點的時候,首先必須同步上整個網絡,即,下載和計算構建最新區塊時刻的區塊鏈狀態所需的所有數據。根據用戶自身的需要,同步方式可以在安全性和速度之間有所取舍,所以Geth支持兩種同步模式:完全同步和快速同步。

顧名思義,完全同步就是獨立地執行完對以太坊區塊鏈的整個同步過程。這就意味著,你的Geth節點會下載和驗證每個區塊的工作量證明,此外,它還會計算區塊內的每一條事務;由此,節點可以在本地生成區塊鏈的最新狀態,而無需信任其它節點。這種模式更安全,但速度上有很大犧牲。Geth的完全同步可能要花幾天乃至幾周不等的時間。

但是,有些用戶可能不想等上幾周。也許他們的時間很緊,又或者,他們并不覺得這種犧牲是值得的。因此,Geth提供了一個模式:在近期的某個區塊之前的所有鏈數據,都用更快的方法來同步,只有pivot區塊之后的區塊鏈,才使用更慢的完全同步算法。在快速同步模式中,Geth會下載區塊,但僅隨機選取一些區塊來驗證工作量證明,而不是每個區塊都驗證;而且,它也將不再自己執行事務,而是從網絡中的其它節點處直接下載狀態樹,以此獲得最終的區塊鏈狀態。

當然,Geth也不會盲目相信其他節點發回的狀態樹數據,因為一個惡意的節點也可以聲稱某個賬戶只有一點點錢。要理解Geth如何能辨別收到的數據正確與否,我們先要理解默克爾帕特里夏樹。

The Mosque NFT項目將在以太坊上鑄造12000個清真寺NFT,用于推進其慈善計劃:3月26日消息,基于以太坊的The Mosque NFT項目計劃基于世界上最宏偉的清真寺鑄造12000個手繪NFT,并計劃利用出售NFT所得資金來支持他們的慈善計劃和建造清真寺。第一批NFT將于2022年3月29日鑄造,地板價為1 ETH。

每個Mosque NFT都將是獨一無二的,其價值根據每個清真寺在現實世界中的受尊敬程度而有所不同。具體來說,按領土劃分將有65種清真寺。一個地區的清真寺越少,在公開市場上的價值就越高。

The Kaaba Mosque NFT是該系列中最有價值的一件。該項目表示,鑄造該NFT的幸運用戶將在拍賣結束時收到50萬美元的出價。此外,在六個階段中創造最多NFT的用戶將獲得The Mosque NFT獨家合作伙伴“Jacob & Co”贈送的品牌手表。(Bitcoinist)[2022/3/26 14:19:28]

默克爾帕特里夏樹

默克爾帕特里夏樹是Geth客戶端中的一種關鍵數據結構,它是默克爾樹和帕特里夏樹兩者的結合。

簡而言之,帕特里夏樹會基于數據的前綴將數據存到一個樹狀結構中。相較于其它技術來說,帕特里夏樹本身非常適合存儲相似的數據,盡管在速度上可能有所犧牲。下面來看看,多個以r開頭的單詞是如何存到一棵帕特里夏樹里的。

-圖源:https://commons.wikimedia.org/w/index.php?curid=2118795-

Circle在以太坊網絡增發近3800萬枚USDC:Whale Alert數據顯示,Circle在以太坊網絡增發37698382枚USDC。增發哈希為:0x90322438f68c911c9a971573c3c82466ea316b9b37e1973bbcb328db139ec8fd。[2020/12/27 16:39:17]

接著來說說默克爾樹。在一棵默克爾樹上,每個葉節點是數據的哈希值,每個非葉節點是它的兩個子節點的哈希值。如果用戶知道了默克爾樹的默克爾根,并且想要確認某個數據是否存儲在這棵樹里,他只需要用到這棵樹上的一條路徑,這條路徑所涉及的節點數量只跟葉節點數量的對數成正比。如下圖所示,假設用戶要證明L2存儲在這棵樹里,他只需提供Hash0-0和Hash1。接著,驗證者生成Hash0-1、Hash0和TopHash,再將TopHash與其所預期的默克爾根進行比較。

-圖源:https://commons.wikimedia.org/w/index.php?curid=18157888-

默克爾帕特里夏樹將帕特里夏樹基于前綴的存儲結構與默克爾樹相結合,創造出了一種新的數據結構,不僅支持密碼學驗證方式,而且還能保持良好的運行時性能。

在默克爾帕特里夏樹中,鍵和值都是任意的字節串。要想獲得一個鍵的值,我們首先要將這個鍵轉換成一個十六進制字符序列,即,將每個字節變成兩個十六進制字符。然后,我們要先根據序列中的第一個字符,向根節點查詢下一個節點是什么;得到此子節點后,再根據第二個字符向下查詢節點,依次類推,直至找到最后一個節點,獲得最后一個字符。

動態 | Huobi在以太坊區塊鏈增發約190.56萬HUSD:WhaleAlert數據監測,北京時間下午1點05分,Huobi在以太坊區塊鏈增發1,905,611?枚HUSD(1,905,611 USD),交易哈希為:0x3907605faa7c2a2057f86958baf7adcfe307b068be3c41cdf19c385ed1d87c76。[2020/2/7]

在下面這個例子中,我們可以看到默克爾帕特里夏樹實際上包含三種不同的節點。擴展節點是經過優化的,負責存儲一連串字符。在下圖所示案例中,根節點存儲了所有以a7開頭的鍵,無需使用兩個不同的節點來代表a和7。分支節點包含每個可能字符的指針以及一個額外的空檔來存儲當前節點的值。最后,葉節點的key-end字段必然與其所存儲的key的后綴相匹配1。

狀態樹

既然我們已經知道默克爾帕特里夏樹是如何運作的了,我們可以開始探究什么是全局狀態樹。

區塊鏈的絕大部分數據都存儲在全局狀態樹中。雖然將狀態樹作為獨一無二的實體包含在每個區塊內這個設想看似便利,但實際上每個區塊都要復制完整的狀態樹是極其低效的,因為每個區塊之間的狀態樹只有細微差別。Geth采用了不同的方案。你可以想象一下,Geth維護了一個MPT節點池。每個區塊的狀態樹只是整個池的子集。每當有新的區塊被挖出或導入,就會有新的MPT節點被添加到池中。

要想識別節點池中的根節點,我們必須查詢區塊頭。每個區塊都包含一個指向stateRoot的字段,該字段指向MPT的根節點。這樣一來,Geth就可以使用我們上文描述的算法查詢賬戶信息,如任意地址的nonce或余額。

分析 | 絕大多數DeFi DApp建立在以太坊區塊鏈:根據幣安研究院6月6日的報告,以太坊開發者構成了DeFi DApp創作者的絕大多數。DeFi生態系統的主要基礎是支持區塊鏈資產的借貸平臺。該報告認為,按市值計算,以太坊是最大的可編程區塊鏈,因此它是大多數DApps的誕生地。但隨著新的和不斷增長的平臺(如EOS)引入,這種情況可能會改變。[2019/6/8]

請注意,如果是合約的話,賬戶狀態將包含一個非空的storageRoot字段和codeHash字段。storageRoot字段指向另一個根節點。但是,此時所涉及的MPT的用途是存儲該合約的存儲項數據;該MPT會將存儲空檔作為鍵,將原始數據作為值。

為了將MPT存儲在磁盤上,Geth選擇使用LevelDB作為數據庫。然而,LevelDB是只支持字符串到字符串映射的鍵值數據庫,MPT不是字符串到字符串映射。為了解決這個問題,Geth將每個節點編寫成鍵值對,從而實現全局狀態樹的扁平化:將節點的哈希值作為鍵,將序列化的節點作為值。這樣一來,Geth就能查詢任意區塊的狀態樹,因為區塊頭中的stateRoot字段就是鍵,可以用來查找LevelDB中的序列化MPT節點。

樹混亂

因此,假設你啟動了一個Geth節點,并使用快速同步模式連接到網絡。Geth將快速下載所有區塊數據,但是不執行任何事務。不久之后,你將得到一個沒有狀態信息的區塊鏈。此時,Geth通過狀態下載器從pivot區塊的stateRoot開始進行同步。

動態 | Tether在以太坊網絡新增發1.5億枚USDT:據PeckShield態勢感知平臺數據顯示:晚間22時53分,Tether向以太坊網絡新增發1筆價值1.5億美元的USDT,塊高度為7855157,交易哈希值為:0x131bf3d84dac4c1092aa29a1a77fe76815b3e40f8fda3878b5ea0ada2d43948c 。截至目前,Tether在以太坊網絡上的ERC20 USDT總發行量已達650,010,000枚。[2019/5/30]

來源:https://github.com/ethereum/go-ethereum/blob/87c463c47aa6d10a55a4b860bab3d53199814d01/trie/sync.go#L246-L255

狀態下載器會向對等節點請求與MPT節點鍵對應的MPT節點數據。收到結果后,狀態下載器會對節點數據進行哈希計算,驗證得到的哈希值是否與節點鍵相同。如果相同,狀態下載器就知道這個MPT節點是正確的,然后就會發送更多請求,請求該MPT節點的每個子節點。

來源:https://github.com/ethereum/go-ethereum/blob/87c463c47aa6d10a55a4b860bab3d53199814d01/trie/sync.go#L205-L218

如果遇到葉節點,賬戶的代碼和狀態樹將排隊等待被獲取。

來源:https://github.com/ethereum/go-ethereum/blob/87c463c47aa6d10a55a4b860bab3d53199814d01/core/state/sync.go#L31-L39

請注意同步子樹和原始條目之間的區別。雖然二者都下載任意的數據塊,但是如果同步器預期要同步的是原始樹,它會將該數據解析為樹節點,并開始同步其子節點。另一方面,如果同步器預期要同步的是原始條目,它會將數據塊寫入數據庫并終止。

來源:https://github.com/ethereum/go-ethereum/blob/87c463c47aa6d10a55a4b860bab3d53199814d01/trie/sync.go#L183-L197

另外還要注意的是,Geth想要多次向同一個節點發送請求的情況并不少見。例如,如果兩個合約存儲相同的數據,那它們的stateRoot可能相同,也有可能出現兩個賬戶擁有同樣的賬戶狀態。在這些情況下,Geth不想讓網絡充斥這些請求,因此會將它們合并。

來源:https://github.com/ethereum/go-ethereum/blob/87c463c47aa6d10a55a4b860bab3d53199814d01/trie/sync.go#L246-L255

然而,同步器不會合并請求的raw屬性。這意味著,如果已經有了一個未決的原始條目請求,但是同步器又安排了一個具有相同哈希值的子樹請求,后者將被合并,最終結果還是只有一個原始條目請求。

請記住,原始條目請求不會為了同步子節點而處理節點。這意味著,如果我們能以某種方式在原始條目和子樹節點之間引發沖突,我們就能讓Geth同步一個不完整的狀態樹。另外,遇到一個本地不存在的樹節點時,Geth不會退出,這等于是假設,如果下載器報告同步成功,這種情況就不會發生。這就意味著,缺少一個樹節點的Geth節點在行為上與其它完全同步樹的節點截然不同。

那么,如何引發沖突呢?事實證明非常簡單:我們只需用我們控制的某個合約的序列化狀態根部署另一個合約,因此該合約代碼的哈希值必定與狀態根哈希值相同,這就意味著如果合約代碼先同步,另一個合約的狀態樹不會被全部下載下來。

綜上

如果有人利用這個漏洞作惡,需完成要多個步驟并等待很長時間。

首先,我們部署一個合約。這個合約應該有一個獨一無二的stateRoot,從而避免與這個stateRoot相關的MPT節點提前同步。

現在我們就大功告成了。當新的Geth節點使用快速同步加入網絡時,它們會先請求Exploit合約,同步其狀態子樹及代碼。當Exploit合約的代碼被同步時,它會創建一個看起來與Discrepancy的狀態根請求完全相同的原始條目請求,但它不會被當作子樹請求處理。這意味著,該節點永遠不會下載Discrepancy的狀態trie,因此未來讀取magic的請求將返回0而非1。

經過足夠長的時間后,我們要做的就是調用Hardfork.hardfork(discrepancy)。每個正確同步整個網絡的節點都會看到一個回滾交易,而每個使用快速同步加入網絡的Geth節點都會看到一個成功的交易。這將導致一個區塊產生兩個不同的狀態根,也就是說我們可以隨心所欲地觸發鏈分裂。

Geth團隊通過處理PR#21039中的樹讀取錯誤快速解決了該攻擊,然后通過區分PR#21080中的代碼部分和樹部分完全修復了這個漏洞。

結論

這是一個非常有趣的漏洞,它可以讓攻擊者在以太坊網絡上設置一個“炸彈”,并隨時引爆,從而導致所有使用快速同步的Geth節點從主網中分叉。這個陷阱利用的是Geth的同步和數據存儲代碼中極其復雜的邏輯,這或許是它很長時間來都沒有引起人們注意的原因。

敬請期待本系列的第三篇也是最后一篇文章。在這篇文章中,我們將探索Geth客戶端的最新bug,具體細節不便透露。

腳注

從技術層面來說,Geth中的值節點不包含后綴。你可以將其理解成一個后面跟著值節點的擴展節點。

實際上,Geth使用的是“安全的trie”,即,通過SHA-3算法對所有鍵進行哈希計算,從而確保所有鍵都是固定長度。

原文鏈接:https://samczsun.com/booby-trapping-the-ethereum-blockchain/

作者:samczsun

翻譯&校對:閔敏&阿劍

Tags:ETHGETGETHTHEYETHtogetherbnb手游下載蘋果togetherbnb喝醉之后能干嘛ethereal有什么特殊的含義

歐易交易所app下載
關于投資以太坊“第二層擴展”項目的看法_以太坊:eosdac幣怎么沒了

在最近的一期疑問回復中,有不少讀者問到了對第二層擴展的投資。對第二層擴展的投資,我曾經在三月份的文章中寫過,這次我更詳細地再把這個經歷和大家分享一下.

1900/1/1 0:00:00
被勒索一月后比特幣贖金被追回 現在價值幾何?_比特幣:Dark Matter

5月份,黑客組織DarkSide攻擊了美國大型輸油管道運營商——科洛尼爾輸油管道公司。DarkSide通過加密手段鎖住該公司計算機系統并劫持了科洛尼爾近100GB的數據.

1900/1/1 0:00:00
觀察 | 環境VS利益,紐約州的加密礦場何去何從?_比特幣:GREEN

本文來源于decrypt.co,分布式資本翻譯國內新疆、甘肅、內蒙古多地宣布禁止比特幣挖礦,不少礦工準備轉戰海外之后,國外的一些地區對于比特幣挖礦也存在著諸多聲音.

1900/1/1 0:00:00
加密貨幣價格再度跳水 比特幣跌破3.3萬美元_比特幣:ROS

6月8日,比特幣突然跳水,下破33000美元,最低至32352美元,日內跌幅一度達10.36%,其他加密貨幣跌幅也大都超10%。其中,以太坊跌破2500美元,至2428美,跌幅達13.05%.

1900/1/1 0:00:00
工信部、中央網信辦:推動區塊鏈標準化組織建設,建立區塊鏈標準體系_區塊鏈:ORA

來源:工業和信息化部 原標題:《工業和信息化部中央網絡安全和信息化委員會辦公室關于加快推動區塊鏈技術應用和產業發展的指導意見》發布時間:2021-06-0711:48來源:信息技術發展司2021.

1900/1/1 0:00:00
巴塞爾委員會:銀行對比特幣應采用1250%的風險權重_比特幣:代幣化債券

若銀行持有加密貨幣風險敞口,應如何衡量其風險級別?6月10日,巴塞爾銀行監管委員會就審慎處理銀行加密資產風險敞口的初步建議發表了一份公開征求意見稿.

1900/1/1 0:00:00
ads