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