[Coin] Bitcoin Core 0.7ms 的代價
Bitcoin Core 0.7ms 的代價
細說 CVE-2018–17144的來龍去脈
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
圖文好讀 Medium 版 : https://tinyurl.com/y7l8gf53
前言
Bitcoin Core 在 2018/09/18 時緊急發布了新版本 0.16.3,並在其中提到:
We highly recommend users of all affected versions
immediately upgrade to 0.16.3.(Ref#1)
區塊鏈圈無不掀起一波討論,當然各式媒體也相繼報導;最聳動的莫過於這句話:
康奈爾大學教授 EminGünSirer 表示,估計只需不到 8 萬美元的成本
(12.5 枚比特幣)就能癱瘓整條比特幣區塊鏈。(Ref#2)
事情真有這麼可怕?癱瘓整條鏈?只要八萬美元?
秉持著工程師精神,追根究柢找了一些資料終於瞭解整件事情的前因後果,
就讓我娓娓道來。
=============
前因
Bitcoin Core 身為元老級的 bitcoin 用戶端
(Bitcoin 的其餘分支也師承此 source code),算得上是 open source 界經典範例。
擁有五百個以上的全球貢獻者時時都為 Bitcoin Core 上 pull request,
有的為了修正 bug,有的為了提升效能。
那現在我們就要回到 2016/11 的 pull request #9049 (Ref#3):
Benchmark results indicate this saves about
0.5–0.7ms during CheckBlock.
這個 PR 提高了 CheckBlock 的效能,主要是做了以下的 change:
// Check for duplicate inputs — note that this check is slow
so we skip it in CheckBlock
https://i.imgur.com/T2e1MtP.png
(Code Snippet for PR#9049)
簡單來說,礦工們會無所不用其極地節省各式計算的時間,
以期在挖礦時確保能挖的比別人快。所以這個 PR 的用意在於,
想要在 CheckBlock 時略過檢查於 transaction 中是否有兩個相同的 input,
以節省時間。
(檢查的方式算是蠻暴力的,利用 std::set::count 與 std::set::insert 來檢查
是否有重複,時間複雜度為 O(n log n))
其實,有沒有相同的 input 是一個非常重要的檢查,
意義在於避免雙花(double-spending);當初此 PR 作者群認為,
每個 transaction 在上到 mempool 的時候,就應該做過檢查了,
所以當 block 上鏈後,照理說事後應不需多花這個計算時間重複檢驗。
=============
後果
But,就是這個 but ,在將近兩年後的 2018/09/17 ,
這段 comment 被一位 Bitcoin Cash/Bitcoin Unlimited 的開發者 Awemany
於開發時無意發現(Ref#4),於是做了一些實驗,
製造出具有相同的 input 的 transaction,
來測試 Bitcoin ABC (Bitcoin Cash 的 client),居然遇到了 assert(),
程式直接 crash ,當他轉而測試 Bitcoin Core 也得到相同結果
(這並不意外,Bitcoin 子子孫孫的原始程式大多都從 Bitcoin Core fork 出來),
這時候 Awemany 就知道不太妙了,開始做後續通報的動作。
https://i.imgur.com/SOoc2XI.jpg
(bitcoin/src/validation.cpp code snippet)
Assertion failure point 在CheckBlock()之後的鏈結區塊ConnectBlock()。
而其中之 UpdateCoin() 會檢查 input 是否有被重複 spend,若有則 assert()。
Bitcoin Core 團隊迅速的於24小時內提出修正並釋出新版本(Ref#5)。
Fix 非常簡單,就是把原本於CheckBlock() 的duplicate inputs重新打開…(#Ref6)
=============
這件事情為什麼是個區塊鏈圈大新聞,這邊歸納為以下幾點:
1. 影響範圍廣大:許多區塊鏈實作受到影響,尤其是從 Bitcoin 分叉出來的,
除了上述的 Bitcoin Cash、Bitcoin Unlimited 外,Litecoin 也受其影響。
2. 可能引發嚴重後果:普通程式異常關閉雖然是我們生活中的日常,
但在區塊鏈的世界中卻是一件大事。礦工利用程式挖礦,以建立共識並確認交易;
當程式異常關閉(而且是一直關閉),就不會有礦工可以幫交易做確認,
整條區塊鏈可以算是癱瘓;
更嚴重的是,只要駭客成功算出一個包含有重複 input 的區塊放到鏈上,
會成為一種阻斷服務攻擊(DoS),可以大大的降低整體算力,
使 51% 攻擊更容易成功,進而修改區塊鏈上的資料。
3. 修復是一個緩慢的過程:P2P 世界中,成千上萬的節點需要被更新,
這不是像按一個按鈕就可以完成的。截至 9/24 修正釋出的一個禮拜後,
Bitcoin 全網仍有 87% 的節點受此CVE 影響(Ref#7)。(真的是87%….)
=============
反思
理解了來龍去脈,回到最前言的部分,
到現在為止我們已經知道了為什麼大家認為這是一個(目前)史上最嚴重的
Bitcoin bug,會使整條鏈癱瘓。
但讓我再次引用 INSIDE 文章的某一段文字:
康奈爾大學教授 EminGünSirer 表示,
估計只需不到 8 萬美元的成本(12.5 枚比特幣)就能癱瘓整條比特幣區塊鏈。(Ref#2)
那個 8 萬美元的成本(12.5 枚比特幣)到底是怎麼算出來,
一直困擾著我。查閱了 Bitcoin Core 0.16.3 的 release note 後發現:
Such blocks are invalid, so they can only be created by a miner willing to
sacrifice their allowed income for creating a block of at least 12.5 BTC
(about $80,000 USD as of this writing)
原來國內外媒體一直引用的 8 萬美元的成本(12.5 枚比特幣)
就可以癱瘓 Bitcoin 的這句話是有一些誤解的。
原意其實是指:攻擊者先必須真正的算出合法的 hash,
才可將不合法的交易包入區塊中,進而達成攻擊。
反過來說,攻擊者等於是放棄了這 12.5 枚比特幣挖礦獎勵
(時下匯率換算約八萬美元),來達成攻擊,
因為包含了不合法的交易之區塊絕對不會被其他礦工承認。
所以真正要成功完成攻擊,成本絕對是遠高於所謂的 8 萬美元。
(cryptoglobe 文章中提到,www.crypto51.app 已經成功預估出於
Bitcoin Private (BTCP) 網路上,只需 $122 美金即可達成 51% 攻擊(Ref#8),
不過目前還找不到相關佐證文件)
=============
另一個反思則是,區塊鏈世界強調去中心化,但吸引眾多使用者的交易所、
共用的智能合約與區塊鏈全網使用的相同程式,再再的打破去中心化的概念,
只要任何一點被攻破,都是重大的損失,這樣還算是真正的去中心化嗎?
=============
Note : 若有錯誤,歡迎指正;也歡迎討論與指教,謝謝。
References :
1. https://bitcoincore.org/en/2018/09/18/release-0.16.3/
2. https://tinyurl.com/ycg2cmlm
3. https://github.com/bitcoin/bitcoin/pull/9049
4. https://medium.com/@awemany/600-microseconds-b70f87b0b2a6
5. https://bitcoincore.org/en/2018/09/20/notice/
6. https://github.com/bitcoin/bitcoin/pull/14247
7. https://twitter.com/LukeDashjr/status/1044224230114627586
8. https://tinyurl.com/ycq5gzjb
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 1.160.117.189
※ 文章網址: https://www.ptt.cc/bbs/DigiCurrency/M.1538195587.A.998.html
推
09/29 13:10,
6年前
, 1F
09/29 13:10, 1F
推
09/29 13:24,
6年前
, 2F
09/29 13:24, 2F
→
09/29 13:24,
6年前
, 3F
09/29 13:24, 3F
→
09/29 13:25,
6年前
, 4F
09/29 13:25, 4F
→
09/29 13:27,
6年前
, 5F
09/29 13:27, 5F
推
09/29 13:59,
6年前
, 6F
09/29 13:59, 6F
推
09/29 14:11,
6年前
, 7F
09/29 14:11, 7F
推
09/29 14:18,
6年前
, 8F
09/29 14:18, 8F
推
09/29 14:19,
6年前
, 9F
09/29 14:19, 9F
→
09/29 14:20,
6年前
, 10F
09/29 14:20, 10F
→
09/29 14:21,
6年前
, 11F
09/29 14:21, 11F
→
09/29 14:21,
6年前
, 12F
09/29 14:21, 12F
推
09/29 14:23,
6年前
, 13F
09/29 14:23, 13F
推
09/29 14:50,
6年前
, 14F
09/29 14:50, 14F
→
09/29 14:50,
6年前
, 15F
09/29 14:50, 15F
→
09/29 14:51,
6年前
, 16F
09/29 14:51, 16F
→
09/29 14:51,
6年前
, 17F
09/29 14:51, 17F
→
09/29 14:52,
6年前
, 18F
09/29 14:52, 18F
推
09/29 14:54,
6年前
, 19F
09/29 14:54, 19F
→
09/29 14:54,
6年前
, 20F
09/29 14:54, 20F
→
09/29 14:55,
6年前
, 21F
09/29 14:55, 21F
→
09/29 14:55,
6年前
, 22F
09/29 14:55, 22F
→
09/29 15:13,
6年前
, 23F
09/29 15:13, 23F
→
09/29 15:19,
6年前
, 24F
09/29 15:19, 24F
→
09/29 15:22,
6年前
, 25F
09/29 15:22, 25F
→
09/29 15:22,
6年前
, 26F
09/29 15:22, 26F
→
09/29 15:23,
6年前
, 27F
09/29 15:23, 27F
→
09/29 15:24,
6年前
, 28F
09/29 15:24, 28F
→
09/29 15:25,
6年前
, 29F
09/29 15:25, 29F
→
09/29 15:25,
6年前
, 30F
09/29 15:25, 30F
→
09/29 15:26,
6年前
, 31F
09/29 15:26, 31F
→
09/29 15:26,
6年前
, 32F
09/29 15:26, 32F
→
09/29 15:26,
6年前
, 33F
09/29 15:26, 33F
→
09/29 15:27,
6年前
, 34F
09/29 15:27, 34F
→
09/29 15:27,
6年前
, 35F
09/29 15:27, 35F
→
09/29 15:28,
6年前
, 36F
09/29 15:28, 36F
→
09/29 15:30,
6年前
, 37F
09/29 15:30, 37F
→
09/29 15:30,
6年前
, 38F
09/29 15:30, 38F
→
09/29 15:31,
6年前
, 39F
09/29 15:31, 39F
→
09/29 15:32,
6年前
, 40F
09/29 15:32, 40F
→
09/29 15:32,
6年前
, 41F
09/29 15:32, 41F
→
09/29 15:34,
6年前
, 42F
09/29 15:34, 42F
推
09/29 15:35,
6年前
, 43F
09/29 15:35, 43F
→
09/29 15:36,
6年前
, 44F
09/29 15:36, 44F
→
09/29 15:37,
6年前
, 45F
09/29 15:37, 45F
→
09/29 15:37,
6年前
, 46F
09/29 15:37, 46F
推
09/29 15:38,
6年前
, 47F
09/29 15:38, 47F
→
09/29 15:44,
6年前
, 48F
09/29 15:44, 48F
→
09/29 15:45,
6年前
, 49F
09/29 15:45, 49F
→
09/29 15:52,
6年前
, 50F
09/29 15:52, 50F
→
09/29 17:24,
6年前
, 51F
09/29 17:24, 51F
推
09/29 18:49,
6年前
, 52F
09/29 18:49, 52F
推
09/29 23:39,
6年前
, 53F
09/29 23:39, 53F
推
09/30 00:15,
6年前
, 54F
09/30 00:15, 54F
推
09/30 02:08,
6年前
, 55F
09/30 02:08, 55F
推
09/30 02:14,
6年前
, 56F
09/30 02:14, 56F
推
09/30 12:28,
6年前
, 57F
09/30 12:28, 57F
→
09/30 16:32,
6年前
, 58F
09/30 16:32, 58F
→
09/30 16:33,
6年前
, 59F
09/30 16:33, 59F
→
09/30 16:34,
6年前
, 60F
09/30 16:34, 60F
→
09/30 17:08,
6年前
, 61F
09/30 17:08, 61F
推
09/30 17:09,
6年前
, 62F
09/30 17:09, 62F
推
10/01 14:32,
6年前
, 63F
10/01 14:32, 63F
推
10/01 17:41,
6年前
, 64F
10/01 17:41, 64F
推
10/07 10:22,
6年前
, 65F
10/07 10:22, 65F
DigiCurrency 近期熱門文章
PTT數位生活區 即時熱門文章
9
11