摘要:重入攻擊本質上與編程里的遞歸調用類似,當合約將以太幣發送到未知地址時就可能會發生,威脅以太坊智能合約的安全性。知道創宇區塊鏈安全實驗室?從轉賬方法、fallback函數、漏洞代碼、源碼分析四個方面入手,深入分析攻擊原因,詳解?The?DAO事件。
前言
智能合約的概念于1995年由NickSzabo首次提出,它是一種旨在以信息化方式傳播、驗證或執行合同的計算機協議,它允許在沒有第三方的情況下進行可信交易,這些交易可追蹤且不可逆轉。
然而智能合約也并非是安全的,其中?重入(Re-Entrance)攻擊?漏洞是以太坊中的攻擊方式之一,早在2016年就因為TheDAO事件而造成了以太坊的硬分叉。
漏洞概述
在以太坊中,智能合約能夠調用其他外部合約的代碼,由于智能合約可以調用外部合約或者發送以太幣,這些操作需要合約提交外部的調用,所以這些合約外部的調用就可以被攻擊者利用造成攻擊劫持,使得被攻擊合約在任意位置重新執行,繞過原代碼中的限制條件,從而發生重入攻擊。重入攻擊本質上與編程里的遞歸調用類似,所以當合約將以太幣發送到未知地址時就可能會發生。
CZ:個人沒有深入參與BNB Chain的研發是希望能維持去中心化:3月8日消息,Binance 創始人 CZ 在 AMA 中發言表示,個人沒有深入參與 BNB Chain 研發的原因之一是因為希望 BNB Chain 維持去中心化,自己平常更專注于處理 CEX 的事,未來有充裕時間也會關注 BNB 生態。[2023/3/8 12:49:54]
簡單的來說,發生重入攻擊漏洞的條件有2個:
調用了外部的合約且該合約是不安全的
外部合約的函數調用早于狀態變量的修改
下面給出一個簡單的代碼片段示例:
上述代碼片段就是最簡單的提款操作,接下來會給大家詳細分析重入攻擊造成的原因。
漏洞分析
在正式的分析重入攻擊之前,我們先來介紹幾個重點知識。
轉賬方法
由于重入攻擊會發送在轉賬操作時,而Solidity中常用的轉賬方法為
.transfer(),.send()和.gas().call.vale()(),下面對這3種轉賬方法進行說明:
中央財經大學:與中國銀行在數字人民幣領域深入開展合作:金色財經報道,中央財經大學近日與中國銀行簽署戰略合作協議,雙方將圍繞數字經濟、數字人民幣等方面開展研究,推動合作項目落地實施。根據協議,雙方還將進一步在銀校系統對接、數字人民幣等領域深入開展合作。(中央財經大學官方公眾號)[2021/10/5 17:24:39]
.transfer():只會發送2300gas進行調用,當發送失敗時會通過throw來進行回滾操作,從而防止了重入攻擊。
.send():只會發送2300gas進行調用,當發送失敗時會返回布爾值false,從而防止了重入攻擊。
.gas().call.vale()():在調用時會發送所有的gas,當發送失敗時會返回布爾值false,不能有效的防止重入攻擊。fallback函數
接著我們來講解下fallback回退函數。
回退函數(fallbackfunction):回退函數是每個合約中有且僅有一個沒有名字的函數,并且該函數無參數,無返回值,如下所示:
昆明兩會:將深入推動云南省區塊鏈中心建設:2月2日上午,昆明市第十四屆人民代表大會第六次會議在昆開幕,昆明市委副書記、代市長劉佳晨作政府工作報告。
他表示,昆明將深入推進云南省數字經濟開發區、云南省區塊鏈中心建設,力爭引進數字經濟創新企業100家,打造3—5個區塊鏈示范項目,新認定1—2家數字經濟園區。
加大5G基礎設施建設,新增5G基站1萬個,實現主城區5G信號全覆蓋,加快與VR/AR、醫療、旅游、智慧辦會、刷臉就行等場景結合,拓展5G典型應用。[2021/2/2 18:41:39]
function()publicpayable{???
???...
}
回退函數在以下幾種情況中被執行:
調用合約時沒有匹配到任何一個函數;
沒有傳數據;
智能合約收到以太幣。
漏洞代碼
下面的代碼就是存在重入攻擊的,實現的是一個類似于公共錢包的合約,所有的用戶都可以使用deposit()存款到Reentrance合約中,也可以從Reentrance合約中使用withdraw()進行提款,當然了所有人也可以使用balanceof()查詢自己或者其他人在該合約中的余額。
聲音 | 交通運輸部副部長:積極參與區塊鏈等貿易服務 更深入地參與國際競爭:據上證網消息,交通運輸部副部長劉小明在2018全球貿易與國際物流高峰論壇上透露,要把創新能力建設擺到更加突出的戰略地位,全力推進互聯網+高效物流融合發展。堅持全面開放發展,推進物流領域開放向縱深發展。積極參與跨境電商、區塊鏈等貿易服務,更深入地參與國際競爭。[2018/11/20]
首先使用一個賬戶(0x5B38Da6a701c568545dCfcB03FcB875f56beddC4)扮演受害者,將該合約在RemixIDE?點擊Deploy按鈕進行部署。
在部署合約成功后在VALUE設置框中填寫5,將單位改成ether,點擊deposit存入5個以太幣。
點擊wallet查看該合約的余額,發現余額為5ether,說明我們的存款成功。
而下面的代碼則是針對上面存在漏洞的合約進行的攻擊:
使用另外一個賬戶(0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2)扮演攻擊者,復制存在漏洞的合約地址到Deploy的設置框內,點擊Deploy部署上面的攻擊合約。
貴陽高新區黨工委副書記黃昌祥:深入推進區塊鏈等技術與實體經濟深度融合:貴陽網6月4日報道, 日前,高新區黨工委副書記、管委會主任黃昌祥率隊對區內大數據創新平臺進行調研。黃昌祥要求,大力實施“千企引進”“萬企融合”“千企改造”等工程,推進“智力收割機”計劃,深入推進物聯網、人工智能、區塊鏈以及大數據與實體經濟深度融合,引領大數據技術創新、加快大數據產業聚集,構筑大數據產業生態體系,以大數據引領全區經濟實現高質量發展。[2018/6/4]
部署成功后先調用wallet()函數查看攻擊合約的余額為0。
攻擊者先存款1ether到漏洞合約中,這里設置VALUE為1ether,之后點擊攻擊合約的deposit進行存款。
再次調用合約的wallet函數查看漏洞合約的余額,發現已經變成了6ether。
攻擊者(0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2)調用攻擊合約的attack函數模擬攻擊,之后調用被攻擊合約的wallet函數去查看合約的余額,發現已經歸零,此時回到攻擊合約查看余額,發現被攻擊合約中的6ether已經全部提款到了攻擊者合約中,這就造成了重入攻擊。
源碼分析
上面講解了如何進行重入攻擊已經漏洞原因,這里梳理了漏洞源碼和攻擊的步驟,列出了關鍵代碼。
相關案例
2016年6月17日,TheDAO項目遭到了重入攻擊,導致了300多萬個以太幣被從TheDAO資產池中分離出來,而攻擊者利用TheDAO智能合約中的splitDAO()函數重復利用自己的DAO資產進行重入攻擊,不斷的從TheDAO項目的資產池中將DAO資產分離出來并轉移到自己的賬戶中。
下列代碼為splitDAO()函數中的部分代碼,源代碼在TokenCreation.sol中,它會將代幣從theparentDAO轉移到thechildDAO中。平衡數組uintfundsToBeMoved=(balances*p.splitData.splitBalance)?/p.splitData.totalSupply決定了要轉移的代幣數量。
下面的代碼則是進行提款獎勵操作,每次攻擊者調用這項功能時p.splitData都是一樣的,并且p.splitData.totalSupply與balances的值由于函數順序問題,發生在了轉賬操作之后,并沒有被更新。
paidOut=reward更新狀態變量放在了問題代碼payOut函數調用之后。
對_recipient發出.call.value調用,轉賬_amount個Wei,.call.value調用默認會使用當前剩余的所有gas。
解決辦法
通過上面對重入攻擊的分析,我們可以發現重入攻擊漏洞的重點在于使用了fallback等函數回調自己造成遞歸調用進行循環轉賬操作,所以針對重入攻擊漏洞的解決辦法有以下幾種。
使用其他轉賬函數
在進行以太幣轉賬發送給外部地址時使用Solidity內置的transfer()函數,因為transfer()轉賬時只會發送2300gas進行調用,這將不足以調用另一份合約,使用transfer()重寫原合約的withdraw()如下:
先修改狀態變量
這種方式就是確保狀態變量的修改要早于轉賬操作,即Solidity官方推薦的檢查-生效-交互模式(checks-effects-interactions)。
使用互斥鎖
互斥鎖就是添加一個在代碼執行過程中鎖定合約的狀態變量以防止重入攻擊。
使用?OpenZeppelin官方庫
OpenZeppelin官方庫中有一個專門針對重入攻擊的安全合約:
https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol
參考文獻
1.以太坊的幾次硬分叉:
https://zhuanlan.zhihu.com/p/111446792
2.以太坊智能合約安全漏洞(1):重入攻擊:
https://blog.csdn.net/henrynote/article/details/82119116
3.?區塊鏈的那些事—THEDAO攻擊事件源碼分析:
https://blog.csdn.net/Fly_hps/article/details/83095036
Tags:THEDAOALLTRATHEORYPDAO價格Gallant Nactive Little SuperASTRADAO
尊敬的用戶: 夏日炎炎,WBF推出“MATIC交易&持倉競賽贏10000USDT清涼獎勵”,讓您在六月酷暑中享受片刻清涼.
1900/1/1 0:00:00尊敬的歐易OKEx用戶:歐易OKEx已完成K資產的升級工作,將于2021年5月9日16:00(HKT)開放K資產的OKExChain網絡充提.
1900/1/1 0:00:00尊敬的用戶: RACA/USDT交易對自上線以來,成交量持續低迷,應社區成員反饋和保護平臺用戶的權益,將對RACA/USDT交易對進行隱藏.
1900/1/1 0:00:00親愛的用戶: 幣安將于2021年06月06日18:00上線XVG/USDT、ATM/BUSD、CELR/BUSD、FTM/BUSD、KAVA/BUSD、RLC/BUSD、THETA/BUSD、W.
1900/1/1 0:00:00SUN代幣根據官方說明已經開啟1:1000拆分計劃。Gate.io按此前公告計劃已于2021年6月3日12點之后停止了SUN交易交易,并進行了1:1000拆分,拆分后進行公告并于2021年6月3.
1900/1/1 0:00:00你覺得現在最火的NFT項目是哪個?是長期雄霸各個榜單、登陸佳士得拍賣行的CryptoPunks,還是推動NFT走入主流視野、被各大NBA球星追捧的NBATopShot.
1900/1/1 0:00:00