以太坊漏洞分析————4、底层函数误用漏洞
引子:陣有縱橫,天衡為梁,地軸為柱。梁柱以精兵為之,故觀其陣,則知精兵之所有。共戰他敵時,頻更其陣,暗中抽換其精兵,或竟代其為梁柱,勢成陣塌,遂兼其兵。并此敵以擊他敵之首策?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ——《三十六計第二十五計之偷梁換柱》
時至今日,加密貨幣市場價值富可敵國,已達3000億美元,是加拿大最大銀行RBC兩倍有余。行情較好的加密貨幣蘊含大量的資本,在數字交易所中這座“金庫”中大放光彩,猶如璀璨奪目的寶石。但同時也吸引了眾多行走江湖的黑客神偷。為此,合約的安全成為重中之重,迭代擴展后的新協議帶來的不一定是嚴絲合縫的守護,也可能有意想不到的疏漏,無孔不入的黑客便試圖尋找銜接處的縫隙。
今天我們來說說關于底層函數調用時產生的隱患:可注入call漏洞和delegatecall誤用漏洞
事件回顧
2018年5月11日, 人工智能項目方ATN發現其代幣ATN Token供應量發生異常,市場上流通的代幣無故增加了1100萬個。并且黑客在完事之后還不忘隱藏蹤跡,歸還了權限地址,并且將偷來的Token分發到14個賬戶地址當中,試圖掩人耳目[1]。
好在項目方及時采取了措施,定位了所有可疑賬戶并采用了凍結銷毀等措施,才維持住代幣市場的穩定運行。
ATN項目方為了實現代幣互換,權限擴展以及控制,合約升級三個新型的功能,采用的是更新的ERC223協議來開發智能合約,并且使用了DS-auth庫[1]。按理說雙劍合璧能使安全等級的提升頗有成效,卻被始料未及的攻擊潑了一盆冷水。
追根溯源,主要問題出在代幣互換的實現——call函數,即合約外部調用函數的實現過程中。
合約外部調用在最近的游戲智能合約中使用廣泛,因為這樣能夠提高代碼復用率,簡化代碼。最新的MyCryptoChamp游戲漏洞就源于合約內部算法生成的隨機數可被預測,沒有調用外部可靠的隨機數生成模塊。所以合約外部調用還是很實用的一項功能,但是利是弊就要看合約編寫者的功力了。
?何為合約外部調用
專業的來說,call與delegatecall函數讓 Ethereum開發者將他們的代碼模塊化(Modularise)。用 call函數來處理對合約的外部標準信息調用(Standard MessageCall)時,代碼在外部函數的環境中運行。 delegate函數也是標準消息調用,但在目標地址中的代碼會在調用合約的環境下運行,也就是說,保持msg.sender 和 msg.value不變。該功能支持實現庫,開發人員可以為未來的合約創建可重用的代碼。
但是如果請來的那位并不是悟空,而是假猴王六耳獼猴,可能不光妖怪降服不了,師傅都會被拐跑。
這就是黑客用來投機倒把的伎倆,利用跨合約調用這個過程偷梁換柱,打入合約內部。我們來看具體案例的分析。
漏洞分析以及詳細修復建議
1.?可注入call漏洞
漏洞分析
call是以太坊智能合約編寫語言Solidity提供的底層函數,用來與外部合約或者庫進行交互。此類函數使用時需要對調用參數的安全性進行判定,建議謹慎使用。
案例代碼:
receiver,_custom_fallback,_from, _amount,_data是由用戶控制的,也就是說用戶可以控制整個call調用,包括調用的合約地址(receiver),調用哪個函數(_custom_fallback),以及傳遞的參數(_from,_amount,_data),這實際上是很危險的。在ATN事件中攻擊者通過指定receiver為案例合約地址,利用DS-Auth授權,調用合約自身的函數,從而獲得了合約的控制權[3]。
此外,下面是ERC223標準的另一個call錯誤實現[4]:
漏洞修復
1)推薦使用如下方式調用tokenFallback函數
2 )?DS-Auth在設置權限的時候,不要把合約本身地址加入白名單
2.???delegatecall誤用漏洞
漏洞分析
DELEGATECALL會保持調用環境不變的屬性表明,構建無漏洞的定制庫并不像人們想象的那么容易。庫中的代碼本身可以是安全的,無漏洞的,但是當在另一個應用的環境中運行時,可能會出現新的漏洞。
案例
在主合約Delegation的fallback函數中,可通過delegatecall調用Delegate合約的函數,并在主合約環境下執行,如果msg.data是0xdd365b8b(pwn()的函數簽名),即調用Delegate的pwn函數,那么消息發起者就可以變成主合約的owner[6]。
漏洞修復
Solidity 為實現庫合約提供了關鍵字?library?(參見?SolidityDocs?了解更多詳情)。這確保了library?是無狀態(Stateless)且不可自毀的。強制讓library?成為無狀態的,可以緩解本節所述的存儲環境的復雜性。無狀態library?還可以防止攻擊者直接修改library?狀態以實現對依賴于library?代碼的合約的攻擊。在使用時?DELEGATECALL?時要特別注意庫合約和調用合約可能對狀態變量進行修改,并且盡可能構建無狀態library?。
真假難辨,如何防范
黑客千方百計試圖欺騙合約,或無所不用其極地打開合約的后門,對合約的安全開發過程是一個嚴峻的考驗,從內部和外部我們可以做到以下兩點進行防范:
1, 跨合約調用時,要慎用外部函數,周全考慮可能的調用風險,及時添補相應函數和規則,杜絕外患。
2, 內部權限設置必須考慮可能的權限被奪取的情況,從代碼邏輯性和功能準確性全方面進行考量。
智能合約的安全規則終將會在安全團隊與黑客的較量中不斷完善,我們要做好打持久戰的準備。
?
引用:
[1]ATN抵御合約攻擊的報告:https://atn.io/resource/aareport.pdf
[2]以太坊智能合約call注入攻擊:https://blog.csdn.net/u011721501/article/details/80757811
[3]ATN披露特殊場景下的以太坊合約重大漏洞并與慢霧科技達成戰略合作:https://www.bitansuo.com/articles/512680.html
[4]ERC223-token-standardhttps:/github.com/Dexaran/ERC223-token-standard/tree/Recommended
?
總結
以上是生活随笔為你收集整理的以太坊漏洞分析————4、底层函数误用漏洞的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小型双轮差速底盘实现触须避障
- 下一篇: 熊绎:我看软件工程师的职业规划