摘要:重入攻擊本質上與編程里的遞歸調用類似,當合約將以太幣發送到未知地址時就可能會發生,威脅以太坊智能合約的安全性。知道創宇區塊鏈安全實驗室?從轉賬方法、fallback 函數、漏洞代碼、源碼分析四個方面入手,深入分析攻擊原因,詳解?The?DAO 事件。
智能合約(英文:Smart contract )的概念于 1995 年由 Nick Szabo 首次提出,它是一種旨在以信息化方式傳播、驗證或執行合同的計算機協議,它允許在沒有第三方的情況下進行可信交易,這些交易可追蹤且不可逆轉。
然而智能合約也并非是安全的,其中?重入 (Re-Entrance) 攻擊?漏洞是以太坊中的攻擊方式之一,早在 2016 年就因為 The DAO 事件而造成了以太坊的硬分叉。
在以太坊中,智能合約能夠調用其他外部合約的代碼,由于智能合約可以調用外部合約或者發送以太幣,這些操作需要合約提交外部的調用,所以這些合約外部的調用就可以被攻擊者利用造成攻擊劫持,使得被攻擊合約在任意位置重新執行,繞過原代碼中的限制條件,從而發生重入攻擊。重入攻擊本質上與編程里的遞歸調用類似,所以當合約將以太幣發送到未知地址時就可能會發生。
簡單的來說,發生重入攻擊漏洞的條件有 2 個:
調用了外部的合約且該合約是不安全的
外部合約的函數調用早于狀態變量的修改
下面給出一個簡單的代碼片段示例:
上述代碼片段就是最簡單的提款操作,接下來會給大家詳細分析重入攻擊造成的原因。
三星宣布啟動Discord服務器以深入Web3.0領域:6月7日消息,三星(Samsung)宣布啟動Samsung US Discord官方服務器,以加深與消費者的聯系并培養創作者社區。在Samsung US Discord中,粉絲、游戲玩家和創作者能夠互動,并可以獲得對產品、活動、NFT等的獨家訪問權。在6月7日的前24小時內,服務器的早期采用者將獲得OG角色。[2022/6/7 4:09:03]
在正式的分析重入攻擊之前,我們先來介紹幾個重點知識。
轉賬方法
由于重入攻擊會發送在轉賬操作時,而 Solidity 中常用的轉賬方法為
<address>.transfer(),<address>.send() 和 <address>.gas().call.vale()(),下面對這 3 種轉賬方法進行說明:
<address>.transfer():只會發送 2300 gas 進行調用,當發送失敗時會通過 throw 來進行回滾操作,從而防止了重入攻擊。
<address>.send():只會發送 2300 gas 進行調用,當發送失敗時會返回布爾值 false,從而防止了重入攻擊。
<address>.gas().call.vale()():在調用時會發送所有的 gas,當發送失敗時會返回布爾值 false,不能有效的防止重入攻擊。
fallback 函數
接著我們來講解下 fallback 回退函數。
中國證券報:隨著區塊鏈等金融科技應用深入 需加強個人金融信息保護:5月11日,中國證券報刊文稱,相關金融基礎設施亟待完善,隨著大數據、區塊鏈等金融科技應用不斷深入,涉及個人金融信息保護的基礎網絡設施、IT架構、數據結構治理等亟待監管部門協調構建。[2020/5/11]
回退函數 (fallback function):回退函數是每個合約中有且僅有一個沒有名字的函數,并且該函數無參數,無返回值,如下所示:
function() public payable{???
? ? ? ...
}
回退函數在以下幾種情況中被執行:
調用合約時沒有匹配到任何一個函數;
沒有傳數據;
智能合約收到以太幣(為了接受以太幣,fallback 函數必被標記為 payable)。
漏洞代碼
下面的代碼就是存在重入攻擊的,實現的是一個類似于公共錢包的合約,所有的用戶都可以使用 deposit() 存款到 Reentrance 合約中,也可以從 Reentrance 合約中使用 withdraw() 進行提款,當然了所有人也可以使用 balanceof() 查詢自己或者其他人在該合約中的余額。
首先使用一個賬戶 (0x5B38Da6a701c568545dCfcB03FcB875f56beddC4) 扮演受害者,將該合約在 Remix IDE?點擊 Deploy 按鈕進行部署。
北京方正公證處楊和平:與騰訊在多個方面達成深入合作:金色財經報道,4月17日,騰訊安全領御區塊鏈-北京方正公證取證平臺正式發布。在發布會上,北京方正公證處副主任楊和平表示:“區塊鏈作為一種可以在完全不信任的節點之間建立信任機制的技術,具有高可靠度、高透明度、可追溯、永久保存和無法篡改的特性,這些特性與公證的職業要求和行業發展需求具有天然的融合性、互補性,特別是在公證三大效力之一的證據效力方面雙方高度契合。騰訊安全與北京市方正公證處聯合打造的領御區塊鏈北京方正公證取證平臺,就是要在深度整合兩者優勢基礎上通過國家公信力+技術信任力的雙重增信,向社會提供電子證據安全存儲、取證維權、在線公證等智能化服務,從而形成一套規范和標準的互聯網數據公證服務新模式。”
此外,北京方正公證處副主任楊和平還介紹說,未來方正公證處與騰訊將在以下幾方面進行深度合作:1、構件新型公證法律服務業態上進行新的探索;2、拓展公證服務領域上取得新的突破;3、提升公證服務效率上再上新臺階;4、人才培養方面積累新經驗;5、體制機制建設上走出新路子;6、公證服務助力互聯網方面走出新天地。[2020/4/17]
在部署合約成功后在 VALUE 設置框中填寫 5,將單位改成 ether,點擊 deposit 存入 5 個以太幣。
點擊 wallet 查看該合約的余額,發現余額為 5 ether,說明我們的存款成功。
聲音 | 平安銀行高管:運用區塊鏈等深入生態場景重塑征信模型:據人民網報道,在“金蟬獎”頒獎典禮上,平安銀行交易銀行事業部副總裁許紅輝表示,平安銀行正在實現貸前、貸中和貸后風險的全程閉環控制。運用大數據、區塊鏈、物聯網等技術,深入生態場景重塑征信模型,并基于真實貿易背景跟單放款,確保銀行融資能夠真正支持實體經濟。[2018/12/30]
而下面的代碼則是針對上面存在漏洞的合約進行的攻擊:
使用另外一個賬戶 (0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2) 扮演攻擊者,復制存在漏洞的合約地址到 Deploy 的設置框內,點擊 Deploy 部署上面的攻擊合約。
部署成功后先調用 wallet() 函數查看攻擊合約的余額為 0。
攻擊者先存款 1 ether 到漏洞合約中,這里設置 VALUE 為 1 ether,之后點擊攻擊合約的 deposit 進行存款。
中國科技大學原黨委書記郭傳杰:要促進區塊鏈等技術在教育領域的深入應用:5月30日,第四屆“互聯網+教育”創新周在北京閉幕。中國科技大學原黨委書記郭傳杰表示,要促進人工智能、云計算、大數據、區塊鏈、物聯網等技術在基礎教育研究領域的深入應用,提升互聯網和教育的深度融合及創新。[2018/6/2]
再次調用合約的 wallet 函數查看漏洞合約的余額,發現已經變成了 6 ether。
攻擊者 (0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2) 調用攻擊合約的 attack 函數模擬攻擊,之后調用被攻擊合約的 wallet 函數去查看合約的余額,發現已經歸零,此時回到攻擊合約查看余額,發現被攻擊合約中的 6 ether 已經全部提款到了攻擊者合約中,這就造成了重入攻擊。
源碼分析
上面講解了如何進行重入攻擊已經漏洞原因,這里梳理了漏洞源碼和攻擊的步驟,列出了關鍵代碼。
2016 年 6 月 17 日,TheDAO 項目遭到了重入攻擊,導致了 300 多萬個以太幣被從 TheDAO 資產池中分離出來,而攻擊者利用 TheDAO 智能合約中的 splitDAO() 函數重復利用自己的 DAO 資產進行重入攻擊,不斷的從 TheDAO 項目的資產池中將 DAO 資產分離出來并轉移到自己的賬戶中。
下列代碼為 splitDAO() 函數中的部分代碼,源代碼在 TokenCreation.sol 中,它會將代幣從 the parent DAO 轉移到 the child DAO 中。平衡數組 uint fundsToBeMoved = (balances[msg.sender] * p.splitData.splitBalance) ?/ p.splitData.totalSupply 決定了要轉移的代幣數量。
下面的代碼則是進行提款獎勵操作,每次攻擊者調用這項功能時 p.splitData 都是一樣的(它是 p 的一個屬性,即一個固定的值),并且 p.splitData.totalSupply 與 balances[msg.sender] 的值由于函數順序問題,發生在了轉賬操作之后,并沒有被更新。
paidOut[_account] += reward 更新狀態變量放在了問題代碼 payOut 函數調用之后。
對 _recipient 發出 .call.value 調用,轉賬 _amount 個 Wei,.call.value 調用默認會使用當前剩余的所有 gas。
通過上面對重入攻擊的分析,我們可以發現重入攻擊漏洞的重點在于使用了 fallback 等函數回調自己造成遞歸調用進行循環轉賬操作,所以針對重入攻擊漏洞的解決辦法有以下幾種。
使用其他轉賬函數
在進行以太幣轉賬發送給外部地址時使用 Solidity 內置的 transfer() 函數,因為 transfer() 轉賬時只會發送 2300 gas 進行調用,這將不足以調用另一份合約,使用 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.?區塊鏈的那些事 — THE DAO 攻擊事件源碼分析:
https://blog.csdn.net/Fly_hps/article/details/83095036
區塊鏈技術是一種幾乎所有加密貨幣都會采用的核心創新性數據庫技術,通過在整個網絡中分發相同的數據庫副本,使得黑客破解或欺騙系統變的非常困難.
1900/1/1 0:00:00在NFT生態系統中,很多人都不懂得分析和理解鏈上數據有多么重要。如果你沒有定期跟蹤鏈上活動,這就有點像無頭蒼蠅.
1900/1/1 0:00:00本周,來自The Block的數據顯示,所有穩定幣的總供應量突破 1000 億美元。到目前為止,最大的穩定幣仍然是Tether?,也是最家喻戶曉的穩定幣。它是許多加密貨幣陰謀和理論的中心.
1900/1/1 0:00:00特斯拉CEO埃隆·馬斯克第N次發布比特幣相關推特,并在后面附上“心碎”的表情。數小時前,馬斯克在社交平臺更新動態,發布了比特幣心碎的表情,配發圖文中還是一段情侶分手的文字.
1900/1/1 0:00:00公鏈賽道一直流傳著一句話——「ETH 2.0 正式落地之前的這段時間,是所有新生代公鏈最后的窗口期.
1900/1/1 0:00:00人民網首爾6月11日電(楊帆) 韓國金融委員會稱,今年第一季度虛擬貨幣總交易額已超去年全年。據悉,韓國主要虛擬貨幣交易平臺超過10家,但實名交易的僅有4家.
1900/1/1 0:00:00