以太坊JSON-RPC接口多種盜幣揭秘之知識(shí)篇區(qū)塊鏈
WF曲速未來表示:以太坊,作為區(qū)塊鏈2.0時(shí)代的代表,通過智能合約平臺(tái),解決比特幣拓展性不足的問題,在金融行業(yè)有了巨大的應(yīng)用。
前面寫的話:
以太坊,作為區(qū)塊鏈 2.0 時(shí)代的代表,通過智能合約平臺(tái),解決比特幣拓展性不足的問題,在金融行業(yè)有了巨大的應(yīng)用。
通過智能合約進(jìn)行交易,不用管交易時(shí)間,不用管交易是否合法,只要能夠符合智能合約的規(guī)則,就可以進(jìn)行無限制的交易。在巨大的經(jīng)濟(jì)利益下,總會(huì)有人走上另一條道路。
在2018年6月29日,以太坊黑色情人節(jié)事件(即偷渡漏洞)新型攻擊手法被發(fā)現(xiàn)。該攻擊手法在本文中亦稱之為:離線攻擊。在結(jié)合蜜罐數(shù)據(jù)復(fù)現(xiàn)該攻擊手法的過程中發(fā)現(xiàn),在真實(shí)場景中,還存在另外兩種新型的攻擊方式:重放攻擊和爆破攻擊,由于此類攻擊方式出現(xiàn)在偷渡漏洞曝光后,我們將這些攻擊手法統(tǒng)一稱為后偷渡時(shí)代的盜幣方式。
下面將會(huì)在介紹相關(guān)知識(shí)點(diǎn)后,針對偷渡漏洞及后偷渡時(shí)代的盜幣方式,模擬復(fù)現(xiàn)盜幣的實(shí)際流程,對攻擊成功的關(guān)鍵點(diǎn)進(jìn)行分析。
關(guān)鍵知識(shí)點(diǎn)
1.1 RLP 編碼
RLP(遞歸長度前綴)從名字可以看出它的特點(diǎn):一個(gè)是遞歸,被編碼的數(shù)據(jù)是遞歸的結(jié)構(gòu),編碼算法也是遞歸進(jìn)行處理的;二是長度前綴,也就是RLP編碼都帶有一個(gè)前綴,這個(gè)前綴是跟被編碼數(shù)據(jù)的長度相關(guān)的,RLP提供了一種適用于任意二進(jìn)制數(shù)據(jù)數(shù)組的編碼,RLP已經(jīng)成為以太坊中對對象進(jìn)行序列化的主要編碼方式。
RLP編碼會(huì)對字符串和列表進(jìn)行序列化操作,具體的編碼流程如下圖:
在此,也以3.4.1節(jié)中eth_signTransaction接口返回的簽名數(shù)據(jù)為例,解釋該簽名數(shù)據(jù)是如何經(jīng)過tx編碼后得到的。
根據(jù)RLP編碼的規(guī)則,我們對tx字段當(dāng)作一個(gè)列表按順序進(jìn)行編碼(hash 除外)。由于長度必定大于55字節(jié),所以采用最后一種編碼方式。
暫且先拋開前兩位,對所有項(xiàng)進(jìn)行RLP編碼,結(jié)果如下:
合并起來就是:
一共是214位,長度是107比特,也就意味著第二位是0x6b,第一位是0xf7 len(0x6b)=0xf8, 這也是最終raw的內(nèi)容:
1.2 keystore 文件及其解密
keystore文件用于存儲(chǔ)以太坊私鑰。為了避免私鑰明文存儲(chǔ)導(dǎo)致泄漏的情況發(fā)生,keystore文件應(yīng)運(yùn)而生。讓我們結(jié)合下文中的keystore文件內(nèi)容來看一下私鑰是被如何加密的:
在此,將結(jié)合私鑰的加密過程說明各字段的意義:
加密步驟一:使用aes-128-ctr對以太坊賬戶的私鑰進(jìn)行加密
開頭那里已經(jīng)說到,keystore文件是為了避免私鑰明文存儲(chǔ)導(dǎo)致泄漏的情況發(fā)生而出現(xiàn)的,所以加密的第一步就是對以太坊賬戶的私鑰進(jìn)行加密。這里使用了aes-128-ctr方式進(jìn)行加密。設(shè)置解密密鑰和初始化向量iv就可以對以太坊賬戶的私鑰進(jìn)行加密,得到加密后的密文。
keystore文件中的cipher、cipherparams、ciphertext參數(shù)與該加密步驟有關(guān):
加密步驟二:利用kdf算法計(jì)算解密密鑰
經(jīng)過加密步驟一,以太坊賬戶的私鑰已經(jīng)被成功加密。我們只需要記住解密密鑰就可以進(jìn)行解密,但這里又出現(xiàn)了一個(gè)新的問題,解密密鑰長達(dá)32位且毫無規(guī)律可言。所以以太坊又使用了一個(gè)密鑰導(dǎo)出函數(shù)(kdf)計(jì)算解密密鑰。在這個(gè)keystore文件中,根據(jù)kdf參數(shù)可以知道使用的是scrypt算法。最終實(shí)現(xiàn)的效果就是:對我們設(shè)置的密碼與kdfparams中的參數(shù)進(jìn)行scrypt計(jì)算,就會(huì)得到加密步驟 1中設(shè)置的解密密鑰.
keystore文件中的kdf、kdfparams參數(shù)與該加密步驟有關(guān):
加密步驟三:驗(yàn)證用戶密碼的正確性
假設(shè)用戶輸入了正確的密碼,只需要通過步驟一二進(jìn)行解密就可以得到正確的私鑰。但我們不能保證用戶每次輸入的密碼都是正確的。所以引入了驗(yàn)算的操作。驗(yàn)算的操作十分簡單,取步驟二解密出的密鑰的第十七到三十二位和ciphertext進(jìn)行拼接,計(jì)算出該字符串的sha3_256的值。如果和mac的內(nèi)容相同,則說明密碼正確。
keystore文件中的mac參數(shù)與該步驟有關(guān):
綜上所述,要從keystore文件中解密出私鑰,所需的步驟是:
流程圖如下:
1.3 以太坊交易的流程
根據(jù)源碼以及網(wǎng)上已有的資料總結(jié)了以太坊的交易流程如下:
1.用戶發(fā)起轉(zhuǎn)賬請求。
2.以太坊對轉(zhuǎn)賬信息進(jìn)行簽名
3.校驗(yàn)簽名后的信息并將信息加入交易緩存池 (txpool)
4.從交易緩存池中提取交易信息進(jìn)行廣播
對本文來說,步驟2:以太坊對轉(zhuǎn)賬信息進(jìn)行簽名對于理解3.4節(jié)利用離線漏洞進(jìn)行攻擊十分重要。
從上文中我們可以知道,私鑰已經(jīng)被加密在keystore文件中,所以在步驟2進(jìn)行簽名操作之前,需要將私鑰解密出來。在以太坊的操作中有專門的接口用于解鎖賬戶:personal.unlockAccount
在解鎖對應(yīng)的賬戶后,我們將可以進(jìn)行轉(zhuǎn)賬操作。在用私鑰進(jìn)行簽名前,存在一些初始化操作:
這里可以注意一點(diǎn):Transaction結(jié)構(gòu)體中是不存在from字段的。這里不添加from字段和后面的簽名算法有著密切的關(guān)系。
使用私鑰對交易信息進(jìn)行簽名主要分為兩步:
對構(gòu)造的列表進(jìn)行RLP編碼,然后通過sha3_256計(jì)算出編碼后字符串的hash值。
由于以太坊的地址是公鑰去除第一個(gè)比特后經(jīng)過sha3_256加密的后40位,所以在交易信息中不包含from的情況下,我們依舊可以知道這筆交易來自于哪個(gè)地址。這也是前文說到Transaction結(jié)構(gòu)體中不存在from的原因。
在簽名完成后,將會(huì)被添加進(jìn)交易緩存池(txpool),在這個(gè)操作中,from將會(huì)被還原出來,并進(jìn)行一定的校驗(yàn)操作。同時(shí)也考慮到交易緩存池的各種極端情況,例如:在交易緩存池已滿的情況下,會(huì)將金額最低的交易從緩存池中移除。
最終,交易緩存池中存儲(chǔ)的交易會(huì)進(jìn)行廣播,網(wǎng)絡(luò)中各節(jié)點(diǎn)收到該交易后都會(huì)將該交易存入交易緩存池。當(dāng)某節(jié)點(diǎn)挖到新的區(qū)塊時(shí),將會(huì)從交易緩存池中按照gasPrice高低排序交易并打包進(jìn)區(qū)塊。
所謂磨刀不誤砍柴功,只有清楚地掌握了關(guān)鍵知識(shí)點(diǎn),才能在理解下面的漏洞原理時(shí)游刃有余。
1.TMT觀察網(wǎng)遵循行業(yè)規(guī)范,任何轉(zhuǎn)載的稿件都會(huì)明確標(biāo)注作者和來源;
2.TMT觀察網(wǎng)的原創(chuàng)文章,請轉(zhuǎn)載時(shí)務(wù)必注明文章作者和"來源:TMT觀察網(wǎng)",不尊重原創(chuàng)的行為TMT觀察網(wǎng)或?qū)⒆肪控?zé)任;
3.作者投稿可能會(huì)經(jīng)TMT觀察網(wǎng)編輯修改或補(bǔ)充。