您好,登錄后才能下訂單哦!
最近以太坊也算是問題不斷,多個(gè)游戲都相繼被爆出了黑客攻擊,首當(dāng)其沖的當(dāng)然還是最近比較火爆的類Fomo3d的游戲,比如last winner所遭遇的薅羊毛的攻擊,雖然相關(guān)的攻擊手法早在一個(gè)月前就已經(jīng)有 相關(guān)的披露 ,但是last winner并沒有開源,似乎也沒有采取什么安全措施,加上黑客的手法也進(jìn)行了升級(jí),導(dǎo)致了大量的eth被黑客通過空投的方式拿走,不過這并不是今天的重點(diǎn),這部分可以看看相關(guān)的 解析
另外一個(gè)比較勁爆的消息當(dāng)然就是fomo3d首輪的結(jié)束,獲勝者成功奪得了高達(dá)一萬eth的獎(jiǎng)金,而背后的黑客所使用的手法正是阻塞以太坊網(wǎng)絡(luò),不讓fomo3d相關(guān)的交易能夠被打包進(jìn)區(qū)塊,于是作為最后的購買人的他便成功將巨額的獎(jiǎng)金收入囊中,可以說是利用對以太坊網(wǎng)絡(luò)的DDOS完成了這次攻擊,在這里我們就來簡單談?wù)勔蕴恢械腄DOS
其實(shí)說來也有趣,本身以太坊設(shè)計(jì)的時(shí)候就想過要抗衡DDOS的,其中的gas機(jī)制有一部分作用也是為了防止DDOS,抬高DDOS所需的成本,不過隨著以太坊的不斷發(fā)展現(xiàn)在也暴露出越來越多的問題
這個(gè)問題差不多是兩年前提出來的,主要存在的問題還是在EXTCODESIZE這個(gè)操作碼上,熟悉智能合約的人應(yīng)該也知道這是用來讀取合約的code的大小的,所以其涉及到了相應(yīng)的磁盤操作,但是它所需的gas又非常少,這就導(dǎo)致了惡意的攻擊者可以在交易里實(shí)現(xiàn)調(diào)用很多次這個(gè)操作碼,只要這些操作的gas加起來不超過區(qū)塊的gas limit即可,得益于此操作碼的極少gas消耗,當(dāng)時(shí)的攻擊交易在每個(gè)區(qū)塊調(diào)用了該操作碼近50000次,因此這一個(gè)區(qū)塊內(nèi)的交易所占用的計(jì)算時(shí)間就被大大延長,從而導(dǎo)致了整個(gè)以太坊網(wǎng)絡(luò)的癱瘓,在以太坊官方博客上也有對應(yīng)的 說明 和相應(yīng)的 處理
說到這里我們還是不得不提一下以太坊特色的gas機(jī)制,對于它的存在目前確實(shí)也是褒貶不一,我也不作過多的評價(jià),我們主要來關(guān)注一下要注意的問題
我們知道只要發(fā)送交易就必定會(huì)產(chǎn)生gas費(fèi)用,而我們在發(fā)送一個(gè)交易時(shí)其實(shí)也有兩個(gè)關(guān)于gas可選項(xiàng),即gas Price和gas limit,gas Price即我們愿意為每個(gè)gas所支付的單價(jià),而gas limit則為我們設(shè)定的gas的最多用量,也即我們直接發(fā)送過去的gas數(shù)量,然后在節(jié)點(diǎn)處打包后計(jì)算出了該交易中的操作所消耗的gas數(shù),即gas used,然后gas used*gas Price就是我們實(shí)際支付的tx fee的數(shù)目,剩余的gas則將返還給我們的賬戶,如果設(shè)定的gas limit還不夠操作所需gas的話該交易就失敗了,對應(yīng)的操作也將回滾,但是交易仍然會(huì)打包進(jìn)區(qū)塊,當(dāng)然已經(jīng)給了的那部分gas就別想了
所以有時(shí)候我們碰到發(fā)送的交易失敗可能就是設(shè)定的gas limit少了點(diǎn),你可能會(huì)覺得直接都把gas limit設(shè)置的特別大不就什么事也沒有了,但是這樣的做法可能并不會(huì)得到礦工的好感,因?yàn)橐蕴贿€有一個(gè)特點(diǎn)就是它的區(qū)塊gas limit,不同于比特幣是直接限定區(qū)塊的大小,以太坊是通過區(qū)塊內(nèi)交易所使用的gas來對區(qū)塊進(jìn)行限制,對應(yīng)的限制值就是區(qū)塊gas limit,礦工在選擇要打包進(jìn)區(qū)塊的交易時(shí)必須保證所有交易使用的gas值要小于區(qū)塊的gas limit,所以一個(gè)區(qū)塊內(nèi)所能容納的交易數(shù)目還是比較有限的,同時(shí)一般的交易的gas limit在21000左右,因?yàn)檫@也是很多客戶端默認(rèn)的gas limit,當(dāng)出現(xiàn)一個(gè)gas limit特別大的交易時(shí)礦工可能并不會(huì)給與其優(yōu)先權(quán),因?yàn)榭赡艽虬诉@個(gè)交易后實(shí)際發(fā)現(xiàn)它實(shí)際所使用的gas也將那么點(diǎn),大部分都返還回去了,這樣它倒不如多打包幾個(gè)gas limit較小的交易,能賺取的gas可能更多,所以說較高的gas limit反而可能導(dǎo)致你的交易的效率變低,如果真的希望交易能較快地打包進(jìn)區(qū)塊,應(yīng)該提升的值還是gas price,這樣最終礦工所得到的tx fee才會(huì)變高,也就相應(yīng)的能取得優(yōu)先權(quán)
那么回到這個(gè)垃圾交易的DDOS攻擊上來,官方的緩解方案其實(shí)也是跟區(qū)塊的gas limit有關(guān),一方面是增加對應(yīng)的操作碼所需的gas,另一方面則是減小區(qū)塊gas limit的大小
我們可以來看看當(dāng)時(shí)區(qū)塊gas limit的變化
本來區(qū)塊的gas limit是在470萬左右,之后為了緩解攻擊下調(diào)到了150萬左右,然后又調(diào)整到200萬,這其實(shí)也很好理解,目的就是為了減少每個(gè)區(qū)塊內(nèi)的交易數(shù)目,避免出現(xiàn)一個(gè)區(qū)塊在計(jì)算交易的過程中出現(xiàn)阻塞幾十秒的情況,雖然說這么做也還是治標(biāo)不治本,不過也是為以太坊對該漏洞的修補(bǔ)爭取緩沖時(shí)間,其實(shí)本身區(qū)塊的gas limit也是有動(dòng)態(tài)的調(diào)節(jié)機(jī)制的,它也是在根據(jù)前面的區(qū)塊的gas used進(jìn)行上下波動(dòng),不過在這種局面下它還是失去了調(diào)節(jié)的能力,之后隨著以太坊又進(jìn)行分叉來對漏洞進(jìn)行了修補(bǔ),區(qū)塊的gas limit又開始了不斷的增長,一直到目前的800萬,當(dāng)然,太高的話也還是會(huì)影響性能,因?yàn)檫@樣每個(gè)區(qū)塊里的交易數(shù)就變多了,現(xiàn)在的800萬的gas limit也已經(jīng)穩(wěn)定了很久了
雖然現(xiàn)在這種DDOS方式已經(jīng)被修復(fù),不過還是值得拿出來說道說道
其實(shí)嚴(yán)格說來這種可能也談不上DDOS攻擊,這就相當(dāng)于雙十一的時(shí)候淘寶也爆卡一個(gè)道理,不過它也確實(shí)造成了以太坊的堵塞,這種情況在最近一年來倒也變得愈發(fā)頻繁
我們不妨先來看看近一年來gas Price的變動(dòng)
其實(shí)平均設(shè)置的gas Price就在一定程度上反應(yīng)了以太坊的堵塞程度,因?yàn)楫?dāng)?shù)却慕灰走^多時(shí)想讓自己的交易被礦工優(yōu)先選中就必須提高gas的價(jià)格,否則你的交易可能就一直在交易池里躺著了,這樣就導(dǎo)致了以太坊堵塞時(shí)gas Price的飆漲
從圖中我們可以大致看出幾個(gè)上漲點(diǎn),首先就是17年末到18年初的階段,有印象的話應(yīng)該記得那時(shí)候正是以太貓流行的時(shí)候,當(dāng)時(shí)它名氣那么大也正是因?yàn)樗拇嬖谝欢榷氯苏麄€(gè)以太坊網(wǎng)絡(luò),數(shù)不清的交易躺在交易池里打包不了,帶來的也是gas Price的飆漲,大家都在游戲里搶貓,在上線不到兩周的時(shí)間里便交易了七萬只,交易額達(dá)到了七千多萬,讓人不禁感嘆資本的力量,那應(yīng)該也是以太坊首次出現(xiàn)一個(gè)如此流行的游戲,當(dāng)時(shí)也算是最接近于殺手級(jí)的應(yīng)用了,意義也還是很重大的
之后有一個(gè)比較明顯的漲幅就是來自于不久前也就是七月份爆火的FCoin交易所,因?yàn)槠涮厥獾呐琶J?,也就是對對?yīng)的代幣采用一賬戶一票的方式進(jìn)行排名,導(dǎo)致了對應(yīng)的項(xiàng)目方瘋狂地開賬戶并進(jìn)行投票,這就造成了大量的交易,直接堵塞了整個(gè)以太坊網(wǎng)絡(luò),這樣的行為也受到了多方的譴責(zé),畢竟這樣的行為除了擴(kuò)大了其影響力并沒有任何意義,還造成了gas Price的居高不下,偏偏對于這樣的無賴方式還沒有辦法反抗,這次的事件也再次對以太坊的性能問題敲響了警鐘,畢竟它確實(shí)是很容易引發(fā)大面積的堵塞,可以想象以太坊的網(wǎng)絡(luò)帶寬也就是每15秒800萬gas左右,還有計(jì)算性能的限制,v神也在不斷尋求解決方案,其設(shè)想的分片技術(shù)也是為了提升以太坊性能來減少擁堵情況的發(fā)生,不過卻是會(huì)犧牲部分去中心化的特性,這倒是有點(diǎn)類似于EOS
最后,離我們最近的一個(gè)峰值表示的就是最近仍然火爆的類Fomo3d游戲了,影響到甚至阻塞網(wǎng)絡(luò)的正是風(fēng)頭正勁的last winner游戲,在開始時(shí)他們團(tuán)隊(duì)還準(zhǔn)備了2大量eth進(jìn)行刷單,強(qiáng)行抬高了交易量,吸引用戶注資,當(dāng)時(shí)其交易數(shù)據(jù)甚至夸張到3天吸金近1億,這在當(dāng)時(shí)的市場環(huán)境下確實(shí)是過于夸張,也一度造成了以太坊網(wǎng)絡(luò)的擁堵,而且在這場游戲的背后也是疑云重重,從其營銷策略來看應(yīng)該還是針對國人的,只能說對待這樣的游戲必須得多加小心
關(guān)于gas Price的實(shí)時(shí)情況我們可以在 這里 觀察到,而其在最近一段時(shí)間的變動(dòng)情況也可以在 此處 得到很好的分析
這種類型的DDOS涉及的就是前幾天爆出的Fomo3d的獲勝黑客所使用的攻擊手法了,這名黑客使用這種手法阻斷了以太坊網(wǎng)絡(luò)近三分鐘,使得與fomo3d相關(guān)的交易都無法打包進(jìn)區(qū)塊,于是作為最后一個(gè)購買者的他便成為了最終的獲勝者,獲取了巨額的獎(jiǎng)金
這里涉及到的還是我們前面提到的區(qū)塊的gas limit的限制,目前每個(gè)區(qū)塊的gas limit是800萬左右,攻擊者要做的就是想辦法讓自己的交易耗盡區(qū)塊的gas limit,努力讓區(qū)塊內(nèi)盡量只存在自己的交易,這部分的優(yōu)先權(quán)可以通過提高gas Price取得,而對于gas的消耗則涉及到另一個(gè)操作,也就是對assert的應(yīng)用
熟悉智能合約相關(guān)操作的人應(yīng)該也都知道assert與require類似,都可以用來進(jìn)行錯(cuò)誤的處理,不同之處在于require觸發(fā)使用的是0xfd操作碼,也就相當(dāng)與調(diào)用了revert,它會(huì)回退合約狀態(tài)并返還剩下的未消耗完的gas,而assert則霸道得多,觸發(fā)過后并不會(huì)返還剩下的沒消耗的gas,你只能當(dāng)貢獻(xiàn)給礦工了,你可能會(huì)奇怪既然如此為何還要使用assert,實(shí)際上主要還是在于使用的場景不同,對于require的應(yīng)用場景來說,哪怕其觸發(fā)了,表示的其實(shí)也是正常的合約狀態(tài),因?yàn)槠湟话闶菣z查用戶的輸入抑或是執(zhí)行的狀態(tài)條件,而assert的觸發(fā)場景則一般代表著代碼可能存在某些問題,你可以把這理解為一個(gè)規(guī)范,遵循這樣的規(guī)范的代碼就可以畢竟容易的使用分析工具進(jìn)行檢查,關(guān)于二者更詳細(xì)的分析比較可以參加此處的 資料
對于這一特性,我們可以簡單地來看看效果
部署一個(gè)簡單的測試合約
contract C{ function requires(){ require(false); } function asserts(){ assert(false); } }
我們將其部署到ropsten測試鏈上,因?yàn)闇y試鏈的區(qū)塊gas limit在470萬左右,我們設(shè)置一下發(fā)送交易的gas limit,對于調(diào)用asserts的交易,我們直接將其gas limit設(shè)置為465萬,至于調(diào)用requires的交易我們使用300萬即可,然后我們來看看結(jié)果
對比很明顯,調(diào)用asserts的交易直接耗光了我們設(shè)置的gas limit,而requires僅使用了所需的gas,我們再看看asserts所在交易的區(qū)塊情況
果然,這個(gè)區(qū)塊僅有兩個(gè)交易被打包,我們再看requires所在區(qū)塊
可以看到該區(qū)塊打包了一百多個(gè)交易,那么至少我們是阻塞了asserts所在的區(qū)塊了,不過事實(shí)上這種單個(gè)巨額gas limit的堵塞效果并不是很好,如果你也進(jìn)行嘗試的話應(yīng)該能注意到這個(gè)交易也是等待了一段時(shí)間才被打包,比require那個(gè)交易要慢很多,要知道我設(shè)置的gas Price已經(jīng)很大了,其實(shí)原因前面也提到了,這種單個(gè)的超高gas limit的交易礦工并不是很待見,所以比較好的辦法其實(shí)是將其拆分為幾份,攻擊fomo3d的那位黑客也明白這一點(diǎn),所以他的攻擊的交易大都集中在兩三百萬gas limit左右
這是當(dāng)時(shí)黑客攻擊時(shí)所產(chǎn)生的某個(gè)區(qū)塊,可以看到該區(qū)塊的交易數(shù)量僅為10個(gè),而正常區(qū)塊下一個(gè)區(qū)塊的交易數(shù)目是有好幾百的,其中顯示失敗的那三個(gè)交易其實(shí)就是黑客發(fā)出的交易,目標(biāo)都是一致的,也就是黑客部署的攻擊合約,其實(shí)這目的也就是利用assert消耗gas
我們來看看這幾個(gè)交易分別消耗了多少gas
很有意思,分別是20萬,330萬和420萬,加起來就是770萬,頂去了整個(gè)區(qū)塊gas使用量的絕大部分,在整個(gè)攻擊過程中黑客其實(shí)也在不斷調(diào)整,修改gas使用量,其實(shí)前面也經(jīng)歷了很多的失敗,不過在最后這三分鐘他還是取得了成功,可能還是有一點(diǎn)運(yùn)氣的成分吧,這整個(gè)調(diào)整的過程也挺值得深入研究的,至于這次攻擊手法的詳細(xì)解讀可以參見此處的 分析
隨著這種攻擊方式的成功應(yīng)用,很多黑客團(tuán)體也著手展開了對類fomo3d游戲的攻擊,目前也已經(jīng)有了不少成功的例子,不久前l(fā)ast winner 第二輪也宣告結(jié)束,這是否又意味著這類游戲的新的篇章,在這種形勢下確實(shí)是很難說清了
這里要說的就不是ddos攻擊了,關(guān)于這部分內(nèi)容我感覺真正談得上可攻擊可利用的還是對于區(qū)塊gas limit的限制利用,因?yàn)閰^(qū)塊得gas的800萬限制,如果想辦法讓合約的部分操作的調(diào)用所需的gas超出了800萬的限制,那么這個(gè)合約自然就廢了
比如下面這個(gè)合約的主體部分
contract DistributeTokens { address public owner; // gets set somewhere address[] investors; // array of investors uint[] investorTokens; // the amount of tokens each investor gets function invest() public payable { investors.push(msg.sender); investorTokens.push(msg.value * 5); } function distribute() public { require(msg.sender == owner); for(uint i = 0; i < investors.length; i++) { transferToken(investors[i],investorTokens[i]); } } }
攻擊者就可以通過創(chuàng)建大量的investor來使得最終調(diào)用distribute函數(shù)時(shí)所需的gas超過了區(qū)塊的gas limit,從而使得這個(gè)合約作廢,當(dāng)然這也只算是使智能合約無法提供服務(wù)的方法中的一種,其他的利用可見此處的 資料
最近以太坊所出現(xiàn)的一系列問題還是讓人非常擔(dān)憂,所涉及的金額也越來越大,這樣其實(shí)是侵犯了很多普通用戶的權(quán)益的,希望在后面以太坊團(tuán)隊(duì)能解決以太坊目前存在的性能問題,避免擁堵的再次發(fā)生
本文轉(zhuǎn)載自“安全客”
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。