WF曲速未來 安全課堂| Solidity安全之delegatecall 的濫用問題區塊鏈
WF曲速未來:Soildity作為編寫智能合約的語言,已經被廣泛的應用。但同時,開發者和用戶也得到了慘痛的教訓,智能合約的安全問題層出不窮。因此,我們總結了一些常見的Solidity安全問題。前車之鑒,后車之師,希望后來者能有所警惕。
區塊鏈安全公司WF曲速未來 安全開課:
Soildity 作為編寫智能合約的語言,已經被廣泛的應用。但同時,開發者和用戶也得到了慘痛的教訓,智能合約的安全問題層出不窮。因此,我們總結了一些常見的Solidity安全問題。前車之鑒,后車之師,希望后來者能有所警惕。
delegatecall 「濫用」問題
在 Solidity 中提供了delegatecall函數來實現合約之間相互調用及交互。各種調用,導致了delegatecall函數被合約開發者“濫用”,甚至“肆無忌憚”提供任意調用“功能”,導致了各種安全漏洞及風險。
Delegatecall是一種常用的調用函數,它的特點是調用后內置變量 msg 的值不會修改為調用者,但執行環境為調用者的運行環境。
代碼分析
在智能合約的開發過程中,合約的相互調用是經常發生的。開發者為了實現某些功能會調用另一個合約的函數。比如下面的例子,調用一個合約 A 的 test() 函數,這是一個正常安全的調用。
但是在實際開發過程中,開發者為了兼顧代碼的靈活性,往往會有下面這種寫法:
這將引起任意 public 函數調用的問題:合約中的 delegatecall 的調用地址和調用的字符序列都由用戶傳入,那么完全可以調用任意地址的函數。
相關事件
7 月 19 日,Parity發布安全警報,警告其錢包軟件1. 5 版本及之后的版本存在一個漏洞。據該公司的報告,確認有153,000ETH(大約價值 3000 萬美元)被盜。
因為initWallet函數是公開函數( public function) , 攻擊者調用initWallet,重新初始化錢包會把之前合約錢包所有者覆蓋, 即可改變錢包所有者。
漏洞代碼:
攻擊過程技術分析還原:
第一步:成為合約的owner
通過往這個合約地址轉賬一個value = 0 ,msg.data.length > 0 的交易, 執行到_walletLibrary.delegatecall的分支,該函數能無條件的調用合約內的任何一個函數,黑客調用了一個叫做 initWallet的函數:
這個函數再次調用initMultiowned函數:
不幸的是,initWallet沒有檢查以防止攻擊者在合同初始化后調用到initMultiowned, 這個函數使得這個合約的所有者被改為攻擊者,相當于從unix中獲得了root權限。
第二步: 轉賬, 剩下的事情就很清晰了,通過調用execute函數轉賬到黑客的地址:
第一個參數: address to= 0xb3764761e297d6f121e79c32a65829cd1ddb4d32, 轉賬額度116779808c03e4140000是為以Wei為單位的的eth,即 82189000000000000000000,可以通過如下的代碼獲得具體數值。
區塊鏈安全公司WF曲速未來 表示:
作為已經有過被利用先例的漏洞,開發者在智能合約在部署前必須通過嚴格的審計和測試,在編寫時使用delegatecall要更加小心。
1.TMT觀察網遵循行業規范,任何轉載的稿件都會明確標注作者和來源;
2.TMT觀察網的原創文章,請轉載時務必注明文章作者和"來源:TMT觀察網",不尊重原創的行為TMT觀察網或將追究責任;
3.作者投稿可能會經TMT觀察網編輯修改或補充。