什么是重放攻擊?
重放攻擊(Replay Attack)是計算機網(wǎng)絡(luò)中常見而古老的攻擊手段。在區(qū)塊鏈中,重放攻擊特指在硬分叉中,攻擊者將一條鏈上的交易拿到另一條鏈上“重放(Replay,即重新播放之意)”,從而獲取不正當(dāng)利益的攻擊手段。這畢竟是一個技術(shù)概念,小白可能不容易理解,為了解釋清楚,我們干脆用一個真實案例來說明重放攻擊具體是如何實施的。這個真實案例出自大名鼎鼎的以太坊The DAO分叉事件。
The DAO是以太坊上發(fā)起的一個眾籌項目,它運行在智能合約上。由于智能合約存在某種漏洞,黑客轉(zhuǎn)走了合約內(nèi)管理的價值數(shù)千萬美元的以太幣。為了挽回損失,以Vitalik為首的大部分社區(qū)意見支持分叉以實現(xiàn)交易回滾(使得黑客的攻擊無效化),于是通過硬分叉形式發(fā)起了一條新鏈。然而另一部分社區(qū)意見則認為不應(yīng)該回滾,仍舊維護原有的區(qū)塊鏈。這導(dǎo)致以太坊分裂成新鏈(Ethereum, ETH)和原鏈(Ethereum Classic, ETC)兩條不同的區(qū)塊鏈。
那么重放攻擊又是怎樣實施的呢?我們假設(shè)小明在分叉前持有500個ETH。分叉以后,小明的地址(暫且稱為A地址)下就同時持有500個ETH和500個ETC,因為這個A地址在兩條鏈上都是存在的。由于小明是堅定的分叉支持者,因此小明只看好ETH未來的發(fā)展,覺得ETC肯定要歸零。此時小剛找到小明,提議以低價購買小明手中的ETC。小明便將手中的500個ETC全部轉(zhuǎn)賬到了小剛的地址(暫且稱為B地址)。
前面聽起來沒什么不對勁吧,然而小明沒有想到的是,小剛反手就把這筆ETC的轉(zhuǎn)賬交易發(fā)到了ETH的網(wǎng)絡(luò)上。由于ETH、ETC是分叉的產(chǎn)物,因此兩者交易結(jié)構(gòu)、密碼學(xué)體系都是一致的,ETC鏈上的交易在ETH鏈上也一樣可被識別,因此這筆交易就會被驗證上鏈,最終的結(jié)果是ETH鏈上的A地址也轉(zhuǎn)出了500個ETH到B地址去。小剛假意低價收購ETC,卻成功騙取了小明所有的ETH,小明自然是虧大發(fā)了!
如何防范重放攻擊?
我們可以看到,小剛問小明收購ETC這個行為,本身沒有問題;小明將手中的ETC轉(zhuǎn)賬給小剛這個行為,也沒有任何問題。真正出問題的地方在于,由于ETH和ETC兩條鏈使用了完全一致的交易結(jié)構(gòu)和密碼學(xué)體系,導(dǎo)致在ETC上有效的交易在ETH上也同樣有效。這就給了攻擊者可乘之機。
攻擊者可以將ETC上的一筆有效的交易“重放”到ETH的鏈上,仍可形成一筆有效的交易,然而這筆被重放的交易并不是交易者本人的真實意愿,因此容易被攻擊者利用而造成資產(chǎn)損失。
大家可能會有一個疑問:那豈不是在分叉后的鏈之間,比如ETH和ETC之間、BTC和BCH之間,做的所有交易都是有可能被“重放”的?
事實上,重放攻擊的實施是需要一系列嚴苛條件的。只有在剛分叉完畢的一段時間內(nèi),兩條鏈才能夠保持共享幾乎相同的鏈上數(shù)據(jù)的狀態(tài)(因為在分叉高度之前的歷史數(shù)據(jù)都是完全相同的),最容易發(fā)生重放攻擊;一旦運行一段時間,兩條鏈上分別有了新的數(shù)據(jù)輸入,將一條鏈的交易重放到另一條鏈的可行性就大大減弱了。
從防范重放攻擊的角度,我們可以總結(jié)一些規(guī)律。首先,大家要意識到,重放交易本身不是一種Bug,并不能直接竊取您的資產(chǎn),重放攻擊一定是配合或結(jié)合其他惡意行為進行的。就好像我們剛才提到的小明賣ETC案例中,一定是有小剛這樣的角色實施了“假意低價收購ETC、實則圖謀ETH”的欺詐行為。如果您在分叉之后的一段時間內(nèi)保持警惕,時刻意識到您在新鏈上的交易有可能被重放到原鏈(或相反),就可以杜絕絕大多數(shù)與之相關(guān)的欺詐行為。
我們介紹兩種具體的防范手段。
第一種是在分叉后購買極少量“新鮮的幣”到您的地址內(nèi)。所謂“新鮮的幣”是指那些在分叉高度以后挖礦產(chǎn)出的幣,這些幣在另一條鏈上并不存在,因而當(dāng)交易的input引用到它們時,這筆交易就不可能被另一條鏈所驗證。
第二種是在分叉后將您所有地址內(nèi)的幣歸結(jié)到一個新生成的地址。這也就是所謂的“騰籠換鳥”,可以減少攻擊者在另一條鏈重放交易的可行性。
如果您按順序結(jié)合使用兩種方法,基本可以免除遭受重放攻擊的可能性。
Lava團隊關(guān)于分叉期間的風(fēng)險提示和相關(guān)建議
首先,我們特別提醒,本次PoC2+升級使用硬分叉方式,有可能形成兩條鏈,即一條升級協(xié)議后的“新鏈”、一條仍運行舊協(xié)議的“原鏈”。這是區(qū)塊鏈的特性所致,只要原有的協(xié)議有算力維護,那么原鏈也可以保留下來(反之無人維護則逐漸消亡)。
Lava技術(shù)團隊聲明,升級完成后我們不會對運行舊協(xié)議的原鏈進行任何維護和開發(fā)工作。
因此,我們首先建議社區(qū)用戶務(wù)必在分叉前更新您手中的所有全節(jié)點或錢包軟件版本。您可以前往官網(wǎng)(https://www.lavatech.org/zh/)下載最新版本的軟件,并在升級指南頁面(https://www.lavatech.org/zh/poc2Upgrade)檢查您的軟件版本是否為最新。如果您沒有及時更新,仍在使用舊版本的錢包,可能會造成混淆和誤操作。
其次,我們建議您在沒有把握的情況下,分叉后短期內(nèi)謹慎與第三方進行轉(zhuǎn)賬活動。分叉后可能有人提出收購您在原鏈(或新鏈)的LV資產(chǎn),您需要特別意識到交易存在被重放的風(fēng)險。
Lava技術(shù)團隊可能計劃在分叉完成后,向所有持有LV余額較大的地址轉(zhuǎn)賬少量金額的“新鮮LV”,以減少攻擊者實施重放攻擊的可行性。我們建議所有持有大額LV資產(chǎn)的用戶,在接收“新鮮LV”轉(zhuǎn)賬后,將持有的LV歸集到一個新的地址。(具體方法是在您的錢包內(nèi),將所有LV余額都通過發(fā)起一筆轉(zhuǎn)賬交易,轉(zhuǎn)移到您錢包下的另一個新地址中。請參考下列教程。所有方案都為建議方案,您可以自行操作。)
教學(xué):如何做歸集交易
歸集交易(或稱為規(guī)整交易)就是將您錢包內(nèi)分散在各個地址下的資金統(tǒng)一發(fā)送到一個地址下的交易。該地址應(yīng)當(dāng)是一個由您的錢包控制的、最好是沒有使用過的地址。在分叉后進行一次資金歸集,能夠減小被重放攻擊的可能性。
(1)如果您使用帶有界面的錢包,例如輕錢包、GUI錢包:
此處以GUI錢包為例,其他帶有界面的錢包的操作方法類似。
在“接收”界面點擊“請求付款”,錢包會自動展示一個收款地址。
復(fù)制該地址,前往“發(fā)送”界面,將錢包內(nèi)所有資金發(fā)送至該地址即可。
您可以預(yù)先瀏覽您的錢包余額并填寫需要發(fā)送的資金數(shù)額,或者在發(fā)送交易時直接勾選“發(fā)送全部余額”(或在填寫金額時選擇“Max”選項,因錢包而異)以保證所有余額都得到歸集。
(2)如果您使用全節(jié)點錢包(命令行模式):
·使用getbalance查看錢包內(nèi)的總余額;
·使用getnewaddress生成一個新地址;
·使用sendtoaddress將錢包內(nèi)的所有余額轉(zhuǎn)賬到新地址內(nèi)。
注意:要考慮留出交易手續(xù)費,因此可以在轉(zhuǎn)賬之前先設(shè)置settxfee 0.001,然后將剩余余額通過sendtoaddress轉(zhuǎn)入歸集地址。