舊文整理
面向非技術(shù)人員
用戶可利用Mt.Gox系統(tǒng)的漏洞重復(fù)提取比特幣到個人錢包,所以Mt.Gox 暫停比特幣提款。
舉個例子:
用戶張三在Mt.Gox有50個比特幣错沃,張三提取這50個幣到自己的本地錢包方库。Mt.系統(tǒng)發(fā)出一個支付交易,約10分鐘后违寞,交易完成贞瞒。張三的錢包余額多了50個幣,MT的錢包余額少了50個幣坞靶。但是在這個支付交易在中途被修改了交易的ID號°灸現(xiàn)在張三再次請求提取50個幣,Mt竟然不檢查自己的錢包是否少了幣彰阴,僅依據(jù)自己記錄的交易ID號沒有被確認(rèn)瘾敢,就認(rèn)為上次交易失敗,從而再次發(fā)給張三50個幣尿这。
這聽取來很搞笑簇抵,但這就是MT出現(xiàn)的問題。現(xiàn)在Mt.Gox在忙于檢查自己的賬本射众,看看那些支付交易受騙了碟摆,同時也看看哪些用戶是騙子,看看能否通過法律追回被騙的幣叨橱。
面向技術(shù)人員
事件的起因是:比特幣的一個被稱為“交易可鍛性”(Transaction Malleability)的瑕疵典蜕。
這是比特幣系統(tǒng)的一個小問題,不影響比特幣網(wǎng)絡(luò)的完整性罗洗,不算是一個漏洞愉舔,兩年多前就被提出并討論過,技術(shù)上有相應(yīng)的應(yīng)對措施伙菜。Mt.Gox顯然忽視了這個問題轩缤,沒有采取相應(yīng)的技術(shù)措施,導(dǎo)致了此事件贩绕。
比特幣世界很多名詞都是比喻火的,如挖礦,礦機淑倾,礦工等馏鹤,這里的“可鍛性”也是個比喻,
在討論“交易可鑄鍛性”前娇哆,我們先看看“金幣的可鑄鍛性”假瞬,一個金幣在使用中,被人用錘子砸了幾下迂尝,凹了幾處,變得不是很圓剪芥。這個金幣的本質(zhì)含金量沒變垄开,只是外觀看上去與標(biāo)準(zhǔn)的金幣有些不同,這個金幣依舊是一個被認(rèn)可的金幣税肪。這就是“金幣的可鍛性”溉躲。
“交易可鍛性”指的是榜田,比特幣支付交易發(fā)出后、確認(rèn)前可被修改(準(zhǔn)確說是被偽造復(fù)制)锻梳,用戶簽名過的信息不能更改箭券。
原因是:用戶簽名的內(nèi)容不是整個交易的信息,只是交易信息中的核心重要信息疑枯,如發(fā)送方辩块,接受方,金額等荆永。在不改變用戶簽名內(nèi)容的前提下废亭,對交易信息做些微調(diào),可產(chǎn)生一個全新的交易字符串具钥,由此產(chǎn)生新的交易HASH值,也就是交易ID Transaction ID豆村, 由于簽名內(nèi)容沒有更改,修改過的“交易”可通過挖礦程序確認(rèn)寫入塊鏈(block chain)骂删。
對交易信息的微調(diào)有兩種方式掌动,
第一,修改簽名字符串本身宁玫。首先粗恢,多數(shù)挖礦程序是用openssl 庫校驗用戶簽名,而openssl兼容多種編碼格式撬统,還有适滓,就是橢圓曲線數(shù)字簽名算法(ECDSA)本身,簽名(r,s) 和 簽名(r,-s(mod n))都是有效的。所以恋追,對簽名字符串本身的表現(xiàn)方式做些調(diào)整凭迹,依舊是有效簽名。
第二苦囱,修改交易信息中的scriptSig的值嗅绸,scriptSig中含有簽名字符串,scriptSig本身不含在簽名內(nèi)容里撕彤。scriptSig做些適當(dāng)?shù)男薷挠沭膊挥绊懡灰仔畔⒌尿炞C。
注意羹铅,以上兩種調(diào)整蚀狰,都不會改變簽名的核心內(nèi)容,但是卻產(chǎn)生一個新的交易字符串职员,由此產(chǎn)生新的交易HASH值麻蹋。交易的本質(zhì)內(nèi)容(發(fā)方、收方焊切、金額)沒變扮授,外觀看上去確變了芳室。
從交易信息發(fā)出到最終確認(rèn)通常有約10分鐘的時間,時間上刹勃,偽造的交易信息產(chǎn)生于正品交易信息之后堪侯。由于挖礦程序的確認(rèn)過程是一個隨機的過程,后產(chǎn)生的偽造的交易信息可能首先通過確認(rèn)荔仁,這時正品交易信息反而被認(rèn)為是重復(fù)支付被丟棄伍宦。發(fā)送方看到自己發(fā)的正品交易沒通過校驗,誤以為支付失敼窘(其實已成功支付)雹拄,再次發(fā)送交易,支付方就支付了多余的幣掌呜。
Mt.Gox通過公司的錢包對用戶的比特幣集中管理滓玖,同時通過總賬本記錄每個用戶比特幣的存取,依據(jù)這個賬本計算每個用戶賬戶上的比特幣余額质蕉。
而其記賬依據(jù)是基于交易HASH值,也就是交易ID (Transaction ID)势篡。這就導(dǎo)致其可被攻擊者重復(fù)提幣。
Mt.Gox發(fā)現(xiàn)其錢包的幣在不斷減少模暗,而支付交易又常常失敗禁悠。意識到有點不對勁,只有暫停提幣兑宇。
攻擊細(xì)節(jié):
1碍侦,攻擊者需要一個性能普通的礦機聯(lián)入比特幣網(wǎng)絡(luò),以便獲取和發(fā)送交易信息(比特幣網(wǎng)絡(luò)是開放的隶糕,誰都可以聯(lián)入)
2瓷产,登錄Mt.Gox平臺上,請求提幣到個人錢包枚驻。Mt.Gox隨后向網(wǎng)絡(luò)廣播支付交易信息濒旦。
3,Mt.Gox發(fā)出的支付交易信息再登,通常要等約10分鐘才能被確認(rèn)尔邓。攻擊者得到這個待確認(rèn)的交易信息,偽造出一個簽名內(nèi)容不變而ID不同的支付交易锉矢,隨后向網(wǎng)絡(luò)廣播這個偽造交易梯嗽。如果正品交易先通過挖礦確認(rèn),則攻擊失敗沽损。如果偽造交易先通過挖礦確認(rèn)灯节,則正品交易被丟棄,攻擊成功。
事實上显晶,如果攻擊者太過招搖,可以偽造多個交易信息壹士,增加率先通過確認(rèn)的幾率磷雇。
4,向Mt.Gox請求再次提幣躏救,Mt.Gox看到正品交易沒有成功寫入(block chain)唯笙。誤以為支付失敗,再次發(fā)送交易盒使。攻擊者行騙成功崩掘。
啟示
無論是交易平臺還是個人,不能僅依靠交易的HASH值判斷一個交易是否成功少办。
最可靠的辦法是:每筆交易后苞慢,檢查錢包余額的增減來判斷支付交易成功與否。
啟示更新(2017年3月)
從技術(shù)角度看:
1. 寫入?yún)^(qū)塊鏈英妓,經(jīng)過多次確認(rèn)的交易ID挽放,不會變,可信賴蔓纠。(至于確認(rèn)次數(shù)是另一個話題)
2. 未寫入?yún)^(qū)塊鏈的交易ID辑畦,可能發(fā)生變化,不可信賴腿倚。
站在用戶的角度看:
1纯出,對收款方?jīng)]有影響。
2敷燎,對于支付方暂筝,如果是人工手動支付,通常也沒有影響懈叹,因為人工操作乖杠,發(fā)生異常會被警覺。
如果允許用戶自動提款澄成,這個時候就要注意這個“交易可鍛性”的問題胧洒。這個主要影響交易所,普通用戶通常不會讓他人自動提款墨状。經(jīng)過Mt.Gox 事件后卫漫,很多交易所都使用人工操作來處理用戶提款。