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