曲速區(qū)警惕!你的RAM可能已被EOS惡意合約吞噬區(qū)塊鏈
曲速區(qū):惡意EOS合約存在吞噬用戶RAM的安全風(fēng)險(xiǎn)。現(xiàn)將漏洞分析公布出來(lái),供社區(qū)研究參考,以方便自查和防御。
寫(xiě)在前面的話:
7月24日消息,據(jù)有消息稱收到情報(bào):惡意 EOS 合約存在吞噬用戶 RAM 的安全風(fēng)險(xiǎn)。本次發(fā)現(xiàn)的漏洞,恰好會(huì)導(dǎo)致用戶賬戶內(nèi)的RAM可能被惡意消耗,引發(fā)直接財(cái)產(chǎn)損失。
惡意EOS合約存在吞噬用戶RAM的安全風(fēng)險(xiǎn),需要引起各大交易所、錢(qián)包、token空投方、DApp、用戶等的警惕,避免遭受損失。
EOS的最新消息
EOS,是專門(mén)為商用分布式應(yīng)用而設(shè)計(jì)的一款高性能區(qū)塊鏈操作系統(tǒng),是一種新的區(qū)塊鏈架構(gòu),旨在實(shí)現(xiàn)分布式應(yīng)用的高性能擴(kuò)展。EOS的發(fā)布,被譽(yù)為區(qū)塊鏈3.0時(shí)代的到來(lái)。
在EOS智能合約執(zhí)行過(guò)程中,需要消耗EOS節(jié)點(diǎn)的cpu和內(nèi)存資源,這些資源按照交易發(fā)生時(shí)的CPU資源和RAM資源價(jià)格,支付給EOS節(jié)點(diǎn),從前一段時(shí)間被爆炒的RAM價(jià)格就可以看到RAM的稀缺性。
7月27日就有報(bào)道 EOS的內(nèi)存RAM,曾一個(gè)星期漲了15倍,兩個(gè)星期漲了50倍,暴漲把EOS推到了風(fēng)口浪尖,也著實(shí)讓RAM火了一把。現(xiàn)在EOS的RAM容量上限為64Gb,此后通過(guò)逐步增加容量到1Kb。目前,EOS交易價(jià)格約為8.79美元,該加密貨幣總市值已經(jīng)達(dá)到78.75億美元,在所有加密貨幣市值排名中位列第四位。
什么是RAM?
RAM就是EOS的內(nèi)存,它不是一種代幣或通證,它就是EOS的內(nèi)存資源而已。它在EOS軟件平臺(tái)上對(duì)應(yīng)的就是內(nèi)存數(shù)據(jù)庫(kù)資源。作為DAPP開(kāi)發(fā)者,RAM是一項(xiàng)寶貴資源,數(shù)據(jù)庫(kù)記錄需要消耗RAM。為了保持超級(jí)節(jié)點(diǎn)的高效運(yùn)行,節(jié)點(diǎn)、RAM、內(nèi)存總量有上限(以后會(huì)擴(kuò)容),如果要保持區(qū)塊鏈數(shù)據(jù)可以隨時(shí)存儲(chǔ)、修改,就需要這部分?jǐn)?shù)據(jù)存儲(chǔ)在內(nèi)存中,而內(nèi)存的使用需要用戶自己去EOS系統(tǒng)中購(gòu)買(mǎi),不需要的時(shí)候再賣(mài)給系統(tǒng),換回EOS代幣。而隨著RAM不斷地被租用,剩余可用的RAM越來(lái)越少時(shí),RAM所需要抵押的EOS就會(huì)越來(lái)越多,也就是說(shuō)RAM的價(jià)格會(huì)越來(lái)越貴。
RAM有什么作用?
在 EOS 網(wǎng)絡(luò)上,大量的操作都需要消耗RAM來(lái)存儲(chǔ)數(shù)據(jù),比如創(chuàng)建一個(gè) EOS 賬號(hào)、創(chuàng)建一個(gè) EOS 智能合約、進(jìn)行 EOS 轉(zhuǎn)賬等。
經(jīng)過(guò)幾天的反復(fù)調(diào)試確認(rèn)溝通后,已經(jīng)充分了解漏洞危害。為了避免在這段真空期內(nèi)發(fā)生惡意利用攻擊,現(xiàn)決定將漏洞細(xì)節(jié)公布出來(lái),供社區(qū)研究參考,以方便自查和防御。
EOS 的合約可以通過(guò)require_recipient觸發(fā)調(diào)用其他合約,設(shè)計(jì)這樣的機(jī)制給合約的開(kāi)發(fā)者提供了很大的便利性, 但是也帶了新的問(wèn)題,因?yàn)樵跍y(cè)試的時(shí)候發(fā)現(xiàn)require_recipient 有可利用的漏洞導(dǎo)致RAM在不知情的情況下被濫用。
某個(gè)用戶給合約轉(zhuǎn)賬,合約可以在用戶不知情的情況下消耗用戶的RAM(下面的例子中可以消耗200多人民幣的RAM)
隨后得到了官方的回應(yīng):
這一漏洞需要引起各大交易所,錢(qián)包,空投方,以及用戶的注意
在問(wèn)題沒(méi)有解決之前,用戶應(yīng)避免使用有大量RAM的賬號(hào)給陌生賬號(hào)轉(zhuǎn)賬
問(wèn)題分析
在DAPP 的開(kāi)發(fā)過(guò)程中, 為了獲取轉(zhuǎn)賬信息, 一種方法是采用require_recipient來(lái)訂閱轉(zhuǎn)賬通知, 原理是這樣的:
在系統(tǒng)合約eosio.token 的transfer 中, 轉(zhuǎn)賬時(shí)會(huì)分別通知from 和 to;
如果賬戶to 本身是個(gè)合約賬戶, 并且也實(shí)現(xiàn)了相同的transfer 方法, 則這個(gè)to合約的transfer方法會(huì)被調(diào)用。
在自己的合約實(shí)現(xiàn)相同的transfer 方法:
這個(gè)流程看似沒(méi)什么問(wèn)題,但是卻帶了安全隱患,可以惡意消耗賬號(hào)from 的RAM 資源。 在上面的例子中 komo::transfer 故意用賬戶from 的授權(quán)寫(xiě)了很多無(wú)用的記錄到state db, 而這個(gè)操作用戶在授權(quán)eosio::transfer時(shí)是不知情的。
問(wèn)題驗(yàn)證
在測(cè)試網(wǎng)絡(luò)中分別創(chuàng)建3個(gè)賬號(hào), test11111111, test22222222, komo11111111(合約賬戶, 部署了上面的合約komo)
測(cè)試之前查看 test11111111 RAM 資源
給普通賬戶 test22222222 轉(zhuǎn)賬
再次查看test11111111 RAM資源
沒(méi)有變化, 還是107.5 KiB;再給合約賬戶 komo11111111 轉(zhuǎn)賬
再次查看test11111111 RAM資源, 發(fā)現(xiàn)被消耗了(142.2-107.5)= 34.7K 字節(jié)! 原因是上面komo::transfer 中的for 循環(huán)用賬戶test11111111的授權(quán)寫(xiě)了很多數(shù)據(jù)到state db
代碼分析
因?yàn)閗omo::transfer 這個(gè)handler 是被eosio.token::transfer 中的require_recipient 觸發(fā)的, 在代碼中當(dāng)前action 已有賬戶 from 的授權(quán)。 所以檢查權(quán)限時(shí)不會(huì)報(bào)錯(cuò)。
并且我們發(fā)現(xiàn), 只要維持這個(gè)數(shù)據(jù)結(jié)構(gòu)占據(jù)的字節(jié)不變,這個(gè)竊取的RAM在komo合約中是可以一直使用的。
修復(fù)辦法
曲速區(qū)建議:在require_recipient觸發(fā)action handler 執(zhí)行時(shí), 禁止被觸發(fā)的handler 使用當(dāng)前action 的授權(quán)。
被觸發(fā)的 action handler 有存儲(chǔ)要求怎么辦? 可以使用inline actions 來(lái)解決, inline action 被執(zhí)行時(shí)就不會(huì)用到原來(lái)action 的授權(quán)了。
防御手段
相關(guān)項(xiàng)目方在做轉(zhuǎn)賬操作時(shí)可通過(guò)命令行 “cleos get code” 判斷目標(biāo)地址是否為合約地址,避免RAM被惡意吞噬導(dǎo)致?lián)p失。
另外在問(wèn)題未解決之前,可以減少用來(lái)轉(zhuǎn)賬的賬戶持有的 RAM 數(shù)量,盡可能避免遭受損失。
曲速未來(lái)實(shí)驗(yàn)室。
1.TMT觀察網(wǎng)遵循行業(yè)規(guī)范,任何轉(zhuǎn)載的稿件都會(huì)明確標(biāo)注作者和來(lái)源;
2.TMT觀察網(wǎng)的原創(chuàng)文章,請(qǐng)轉(zhuǎn)載時(shí)務(wù)必注明文章作者和"來(lái)源:TMT觀察網(wǎng)",不尊重原創(chuàng)的行為T(mén)MT觀察網(wǎng)或?qū)⒆肪控?zé)任;
3.作者投稿可能會(huì)經(jīng)TMT觀察網(wǎng)編輯修改或補(bǔ)充。