摘要:新年前,我們最后來談一談以太坊安全性的特點(diǎn)。以太坊使用了一個(gè)硬分叉解決了這一問題。合約擁有者利用函數(shù)的異常處理和調(diào)用棧大小限制進(jìn)行攻擊。結(jié)語通過這幾期對(duì)參考文獻(xiàn)的學(xué)習(xí),我們看到了一些以太坊合約中設(shè)計(jì)的弱點(diǎn)。
新年前,我們最后來談一談以太坊安全性的特點(diǎn)。不可能修改的bug
當(dāng)合約公開在區(qū)塊鏈上之后,它就不能去修改了。相應(yīng)的,合約中出現(xiàn)的任何 bug 也沒有機(jī)會(huì)改正。如果希望能夠修改bug,合約編寫者就需要在編寫合約的時(shí)候預(yù)留一些用來修改或終止合約的代碼。但預(yù)留修改后門這一方式具有爭議,因?yàn)樵谝蕴坏脑妇爸校悄芎霞s一旦部署,其設(shè)定就應(yīng)當(dāng)是不可更改的。
正式因?yàn)?bug 不可修改,可能會(huì)導(dǎo)致一些很嚴(yán)重的攻擊事件沒有彌補(bǔ)的方法。DAO 攻擊是唯一的例外。以太坊使用了一個(gè)硬分叉解決了這一問題。但這種做法沒有得到整個(gè)社區(qū)的贊同,因?yàn)樗`背了“代碼即法則”這一準(zhǔn)則。
每次合約調(diào)用另一個(gè)合約的時(shí)候,調(diào)用棧就會(huì)增加一個(gè) frame. 上限是 1024 個(gè)。當(dāng)這一上限達(dá)到的時(shí)候,下一次調(diào)用會(huì)觸發(fā)一個(gè)異常。如果攻擊者先將自己的調(diào)用棧離填滿只差一個(gè) frame,然后去調(diào)用受害者合約的函數(shù),那么受害者函數(shù)執(zhí)行中任何調(diào)用將會(huì)導(dǎo)致執(zhí)行失敗。如果受害者函數(shù)沒有正確的處理執(zhí)行成功與否,將可能導(dǎo)致意料之外的結(jié)果。在文章后續(xù)部分,我們將以一個(gè)例子說明這一點(diǎn)。
為了解決這一問題,在一次以太坊升級(jí)中,規(guī)定了每次通過 call 或 delegatecall 調(diào)用合約函數(shù)時(shí),只能為被調(diào)用函數(shù)分配最多 63/64 的剩余 gas. 而以太坊中每個(gè)區(qū)塊最多只能包含約 470 萬的 gas。也就是說,如果調(diào)用者最初投入了數(shù)量為 a 的 gas, 在 10 層遞歸調(diào)用后,最內(nèi)層的函數(shù)最多只有 (63/64)^10*a 的 gas. 因此,調(diào)用深度不可能超過 1024. 后面的攻擊案例中,假設(shè)還沒有這一修補(bǔ)方案。
大量的應(yīng)用使用時(shí)間約束來決定某些行為什么時(shí)候被允許。比如在一個(gè) ERC 20 合約中,從某個(gè)時(shí)刻開始,允許用戶使用 ether 購買一個(gè) token.
在智能合約的執(zhí)行過程中,當(dāng)前時(shí)間取自給定交易所在區(qū)塊的區(qū)塊時(shí)間戳。所以,一個(gè)區(qū)塊中的所有交易在執(zhí)行時(shí)使用的是相同的時(shí)間戳。這一設(shè)定保證了智能合約在每個(gè)礦工那里的執(zhí)行結(jié)果是一致的。
但這個(gè)設(shè)定也可能導(dǎo)致一些攻擊,因?yàn)榈V工在選擇時(shí)間戳的時(shí)候有一定的自主權(quán),這可能為一些攻擊埋下了后門。
GovernMental 是一個(gè)“龐氏騙局游戲”型合約。嚴(yán)格來說,其實(shí)不能叫騙啦,因?yàn)辇嬍向_局的規(guī)則被公開地寫在合約里。在這個(gè)合約中,每個(gè)人通過向合約中轉(zhuǎn)一筆錢來加入這個(gè)龐氏騙局游戲。合約通過兩個(gè)數(shù)組記錄參與者的地址和每個(gè)參與者轉(zhuǎn)入的錢的數(shù)量。如果最后一個(gè)人加入后 12 小時(shí)后都沒有下一個(gè)人加入,那么最后一個(gè)人就可以獲得全部的收益。(這個(gè)設(shè)定是不是有點(diǎn)像著名的 Fomo3D,值得注意的是,F(xiàn)omo3D 的出現(xiàn)晚于這篇論文呦。)
下面是一個(gè)簡化版的 GovernMental 合約
在這個(gè)合約中,參與者可以通過 invest() 函數(shù)來投入 ether 并加入這個(gè)游戲。合約維護(hù)一個(gè)名為 jackpot的變量,表示如果后續(xù)沒有人加入,贏家將拿走多少 ether. 新來的參與者必須投入多于 jackpot 一半的 ether, 同時(shí),新來的參與者投入的 ether 中,會(huì)有一半被加入 jackpot. 如果連續(xù)一分鐘沒有人新來的參與者,最后一個(gè)人獲得 jackpot 中的 ether,同時(shí)合約擁有者拿走剩下的錢(留下 1 個(gè) ether 作為下一輪的啟動(dòng)資金)。需要注意的是,這里并沒有檢查最后分錢的時(shí)候,通過 send() 函數(shù)進(jìn)行的轉(zhuǎn)賬是否成功。
這個(gè)簡化版的合約有幾個(gè)點(diǎn)可供被攻擊。
這個(gè)攻擊來自合約擁有者自身,目的是讓本來的游戲贏家無法拿到錢。合約擁有者利用 send() 函數(shù)的異常處理和調(diào)用棧大小限制進(jìn)行攻擊。
攻擊的方式是,通過預(yù)先進(jìn)行大量的遞歸調(diào)用,導(dǎo)致執(zhí)行 resetInvestment() 時(shí),調(diào)用棧達(dá)到了大小上限,無法再執(zhí)行給游戲贏家和合約擁有者的 send() 函數(shù)。合約擁有者和游戲贏家都拿不到錢,錢依然留在合約中,但之后重置合約狀態(tài)的代碼會(huì)照常執(zhí)行。只要再進(jìn)行一輪正常的游戲,合約擁有者就可以將本該屬于上一輪游戲贏家的錢收入囊中。
這一攻擊方式來自礦工。礦工可以通過拒絕打包其他人與 GovernMental 合約的交易,來使自己希望的人成為合約游戲的贏家。更多地,進(jìn)行攻擊的礦工在打包區(qū)塊時(shí)可以任意決定交易順序,來影響這個(gè)區(qū)塊過后誰是 lastInvestor.
之前也提到過,每一個(gè)新參與者需要投入的 ether 數(shù)量不能低于合約中 jackpot 中 ether 數(shù)量的一半。而一個(gè)人在發(fā)起交易的時(shí)候看到的 jackpot 數(shù)值,與它的交易被執(zhí)行時(shí) jackpot 的數(shù)值可能是不一樣的。這就導(dǎo)致這個(gè)人可能發(fā)起交易時(shí)以為自己投入的 ether 數(shù)量是符合要求的。但是執(zhí)行時(shí),由于 jackpot 數(shù)值的改變,變成了一筆無效交易。這就是上篇文章中提過的不可預(yù)測狀態(tài)問題。
另外,礦工擁有決定區(qū)塊時(shí)間戳的權(quán)利。而合約在執(zhí)行時(shí),判定 resetInvestment 是否可以執(zhí)行,就是讀取礦工決定的區(qū)塊時(shí)間戳。通過影響區(qū)塊時(shí)間戳,也可以影響游戲結(jié)果。
通過這幾期對(duì)參考文獻(xiàn) [1] 的學(xué)習(xí),我們看到了一些以太坊 Solidity 合約中設(shè)計(jì)的弱點(diǎn)。雖然這些弱點(diǎn)稱不上是漏洞,但是如果在編寫合約時(shí),對(duì)這些點(diǎn)不了解,沒有充分考慮,就可能寫出有安全問題的合約出來。
參考文獻(xiàn):
[1] Atzei, Nicola, Massimo Bartoletti, and Tiziana Cimoli. "A survey of attacks on ethereum smart contracts (sok)." Principles of Security and Trust. Springer, Berlin, Heidelberg, 2017. 164-186.
--
Conflux 是致力于打造下一代高性能的 DAPP 公鏈平臺(tái)
歡迎關(guān)注我們的微信公眾號(hào):Conflux中文社區(qū)(Conflux-Chain)
添加微信群管理員 Confluxgroup 回復(fù)“加群”加入 Conflux官方交流群
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/11457.html
摘要:新年前,我們最后來談一談以太坊安全性的特點(diǎn)。以太坊使用了一個(gè)硬分叉解決了這一問題。合約擁有者利用函數(shù)的異常處理和調(diào)用棧大小限制進(jìn)行攻擊。結(jié)語通過這幾期對(duì)參考文獻(xiàn)的學(xué)習(xí),我們看到了一些以太坊合約中設(shè)計(jì)的弱點(diǎn)。 新年前,我們最后來談一談以太坊安全性的特點(diǎn)。 不可能修改的bug 當(dāng)合約公開在區(qū)塊鏈上之后,它就不能去修改了。相應(yīng)的,合約中出現(xiàn)的任何 bug 也沒有機(jī)會(huì)改正。如果希望能夠修改bu...
摘要:新年前,我們最后來談一談以太坊安全性的特點(diǎn)。以太坊使用了一個(gè)硬分叉解決了這一問題。合約擁有者利用函數(shù)的異常處理和調(diào)用棧大小限制進(jìn)行攻擊。結(jié)語通過這幾期對(duì)參考文獻(xiàn)的學(xué)習(xí),我們看到了一些以太坊合約中設(shè)計(jì)的弱點(diǎn)。 新年前,我們最后來談一談以太坊安全性的特點(diǎn)。 不可能修改的bug 當(dāng)合約公開在區(qū)塊鏈上之后,它就不能去修改了。相應(yīng)的,合約中出現(xiàn)的任何 bug 也沒有機(jī)會(huì)改正。如果希望能夠修改bu...
摘要:很多以太坊的智能合約控制著有實(shí)際價(jià)值的數(shù)字資產(chǎn)。這幾期為大家?guī)硪黄陮?duì)以太坊合約攻擊調(diào)研的文獻(xiàn),來幫助大家避免以太坊智能合約設(shè)計(jì)中的一些可能導(dǎo)致安全性問題的弱點(diǎn)。攻擊攻擊是以太坊歷史上最著名的攻擊,盜走了價(jià)值萬美元的以太幣。 showImg(https://segmentfault.com/img/bVbnRDB?w=1080&h=460); 很多以太坊的智能合約控制著有實(shí)際價(jià)值的數(shù)...
閱讀 1240·2021-11-22 13:54
閱讀 1425·2021-11-22 09:34
閱讀 2698·2021-11-22 09:34
閱讀 4008·2021-10-13 09:39
閱讀 3342·2019-08-26 11:52
閱讀 3361·2019-08-26 11:50
閱讀 1529·2019-08-26 10:56
閱讀 1913·2019-08-26 10:44