智能合約的漏洞與攻擊3/3-攻擊

以太坊 ethereum andy 4年前 (2020-09-14) 1445次浏览 已收录 0个评论 扫描二维码
文章目录[隐藏]

智能合約的漏洞與攻擊3-攻擊

攻擊

攻擊, 主要是指被用來利用智能合約的手段。

前置運行又稱為交易順序依賴 Front-running aka transaction-ordering dependence

這個翻譯名詞在我們的環境裡面不那麼切合語意,它的意思,就是預先知道市場的動態,利用這個資訊來獲利。
例如,已預先知道某個代幣會有大量的買單,用戶可以先買入該代幣,等待買單成交後,代幣價格上漲再獲利賣出。

前置運行攻擊在金融市場存在已久,而且由於區塊鏈天生就透明的特性,這個問題依然存在於加密貨幣市場。

由於這個問題在每個合約發生的情況都不一樣,所以難以預防。可能預防的方式,包括批處理交易,和預提交方案。

限制區塊燃料的阻斷服務

在 ethereum 的區塊鏈,區塊有燃料限制。這個限制的其中一個好處,就是防止攻擊者建立無限交易迴圈,如果燃料使用超過了限制,交易就會失敗,這也導致了數種阻斷服務攻擊。

無限制運行

把資金送到一個地址數組,區塊燃料限制就可能導致問題。就算沒有任何惡意,也很容易導致錯誤。只要用戶地址的數組夠大,這種支付行為就可以導致超過區塊燃料限制,使交易永遠不會成功。

這種情況,也可以被用來攻擊。假設攻擊者,建立一個巨大的地址數組,然後用智能合約來支付每個地址一個少量金額。如果可以這麼做,交易就可能被無限期的阻斷,甚至阻止即將到來的交易。

這個問題的有效解決方案,就是使用請求支付(pull-payment) 來取代 推送支付(push-payment) 。讓資金的接收者自己請求支付,把支付分散到每個交易裡面。

如果有某些理由一定要支付到一個未知數量的數組,至少預計它可能需要多個區塊,然後允許支付分散到多個交易裡運行。

Block stuffing

在某些情況下,就算智能合約沒有迭代不定長度的數組,也會被區塊燃料限制攻擊。攻擊者可以籍由提供夠高的燃料,在交易完成之前,塞入許多區塊。

這種攻擊是透過發起幾筆很高燃料價格的交易來完成。如果合約消耗足夠多的燃料並且燃料價格夠高的話,就可以藉此塞入數個區塊,並防止其他的交易被執行。

Ethereum 交易要求發起者支付燃料費用,以此來減少垃圾攻擊,但是在某些情況下,還是有足夠的利潤來發起此類攻擊。例如之前提過的 博奕類遊戲 Fomo3D ,這個遊戲有一個倒數計時器,每次有人購買鑰匙,倒數計時器就會增加時間,最後一個購買鑰匙的用戶可以贏得彩金。攻擊者在買入鑰匙之後,塞入13個區塊,然後就可以贏得彩金。

要防止這種攻擊發生,重點就是小心思考計時為基礎的APP 是否安全。

意外導致的回溯,帶有此種類的阻斷服務

當發送資金到用戶,並且依賴於資金發送是否成功,就可能導致此類阻斷服務發生。
問題點發生在,惡意的用戶會建立一個合約B,然後透過合約A把資金發送到合約B,在合約B的fallback 裡面使用 revert 還原,這樣就會導致後續的程式問題,比如

智能合約的漏洞與攻擊3/3-攻擊

在第9行,程式依賴於資金傳送成功,如果惡意用戶,建立了合約B ,使用合約 B 參加競標,然後在 合約 B的fallback 函數裡 revert ,導致
在這以後的所有競標都將無法成功。

這種 revert 問題,也會發生在沒有攻擊者的狀況之下。比如說,有一個合約要退回所有用戶的資金,退回資金的地址存在於一個數組裡面。於是有一個函數透過迭代這個數組來發送資金,并且在檢查發送成功之後,才會進行下一個發送。代碼如下

智能合約的漏洞與攻擊3/3-攻擊

第7行,假設就是在其中一個地址發生了問題導致傳送失敗,這個refundAll 函數,將永遠無法成功執行。

一個有效的方案,就是把這樣的推送支付,改為請求支付。把支付分散在每個接收者的交易裡面,讓接收者自行調用此函數。

強制發送 ether 到合約

有時候不需要用戶發送 ether 到合約裡,但還是有強制發送 ehter 到合約的可能性。
一種方式是透過 selfdestruct 方法來強制發送,因為 selfdestruct 可以避開 fallback 函數的檢查。
另一種方式,是預先計算合約部署的地址,在合約部署之前把 ether 發送到該地址。很驚訝,但這是可能發生的。

燃料不足

在線上遊戲裡面,帶有惡意的玩家,使用意外的方式來玩遊戲,進而打擾其他玩家。這裡說的攻擊就是這種攻擊方式。這種攻擊方式,用來阻止交易按照預期的方式運行。

當合約允許資料傳入,並且允許其他合約使用子調用時發生。而這種運行方式通常發生在多重簽名的錢包以及交易中繼者。如果子調用失敗,會有兩種結果,全部恢復,或繼續執行。

舉一個簡單的中繼合約例子,中繼合約允許用戶,建立及簽名一個交易,但不執行這個交易。這個情況通常發生在用戶無法支付交易所需的燃料。

智能合約的漏洞與攻擊3/3-攻擊

真正執行這個交易的人,可以透過檢查交易來確定足夠的燃料,但是無法確定子調用所需要的燃料。這會導致意外的失敗。

要防止這個問題,有兩種方式,一種是只允許信任的用戶來中繼這個合約,另一種方式是真正執行這個合約的人要提供足夠的燃料。

重入攻擊

重入攻擊是指,合約內有bug的函數,允許與其交互的函數多次執行,這種多次執行應該是被禁止的。這可以被用來抽乾合約內的資金。

單一函數的重入攻擊

單一函數的重入攻擊,指的是有漏洞的函數,可以被遞歸的調用。舉例如下,

智能合約的漏洞與攻擊3/3-攻擊

問題出在第4行執行完之後才會執行第5行將餘額歸零,這就導致攻擊者可以在餘額歸零之前,多次調用這個函數,結果就是整個合約內的餘額都被抽乾了。

跨函數重入攻擊

跨函數的重入攻擊,是比較複雜的版本。發生在有漏洞的函數,傳出狀態值給另一個函數時,被攻擊者利用。

智能合約的漏洞與攻擊3/3-攻擊

問題出在第11行,如果 msg.sender是一個合約的話 msg.sender.call 會調用 msg.sender 的 fallback 函數。
攻擊者可以在合約B的 fallback 函數裡多次調用 transfer函數,直到 withdraw 函數裡餘額被歸零。

預防重入攻擊

在合約內移轉資金時,使用 send 或是 transfer ,不要用 call 。使用 call 時,不像其他函數,沒有 2300 燃料的限制,這表示可以被外部函數調用,用來做為重入攻擊。
另一個也很好的預防方式,是標記為不信任的函數,不使用。

另外,最好的安全方案,就是使用checks-effects-interactions模式。
函數應該由 checks 開始,例如使用 require 或是 assert
然後 effects , 合約應該完成的, 例如狀態修改。
最後interactions 就是跟其他合約的互動,例如外部調用的結果。

這個結構可以有效防止重入攻擊,因為修改狀態可以防止惡意的互動。
例如

智能合約的漏洞與攻擊3/3-攻擊

這個例子,就是先修改狀態,再跟其他合約互動。就算遞歸的被執行,在第一次交易時餘額被為零之後,就不會再執行了。

參考
https://consensys.github.io/smart-contract-best-practices/known_attacks/#dos-with-block-gas-limit
https://medium.com/better-programming/the-encyclopedia-of-smart-contract-attacks-vulnerabilities-dfc1129fdaac
https://gist.github.com/KadenZipfel/a3ccdd3d11160165770615213c83a232#file-insecureauction-sol
https://gist.github.com/KadenZipfel/2e26bb8d903172024f99611bc0b689bb#file-refund-sol
https://github.com/tenthirtyone/weaponized_math
https://medium.com/@alexsherbuck/two-ways-to-force-ether-into-a-contract-1543c1311c56
https://gist.github.com/KadenZipfel/a5d23fd9291c4d0dede4abbe13b92e72#file-relayer-sol
https://gist.github.com/KadenZipfel/05af7f6feee0d863bd0e18d98d21fd7e#file-singlefunctionreentrancy-sol
https://gist.github.com/KadenZipfel/82866f8c63dffd91a9fc3dbfb9214beb#file-crossfunctionreentrancy-sol
https://ethereum.stackexchange.com/questions/42521/what-does-msg-sender-call-do-in-solidity


神隊友學長Andy , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:智能合約的漏洞與攻擊3/3-攻擊
喜欢 (0)
[[email protected]]
分享 (0)
andy
关于作者:
中年大叔,打拼 like young students.
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址