摘要:重入攻擊本質上與編程里的遞歸調用類似,當合約將以太幣發送到未知地址時就可能會發生,威脅以太坊智能合約的安全性。知道創宇區塊鏈安全實驗室?從轉賬方法、fallback 函數、漏洞代碼、源碼分析四個方面入手,深入分析攻擊原因,詳解?The?DAO 事件。
智能合約(英文:Smart contract )的概念于 1995 年由 Nick Szabo 首次提出,它是一種旨在以信息化方式傳播、驗證或執行合同的計算機協議,它允許在沒有第三方的情況下進行可信交易,這些交易可追蹤且不可逆轉。
然而智能合約也并非是安全的,其中?重入 (Re-Entrance) 攻擊?漏洞是以太坊中的攻擊方式之一,早在 2016 年就因為 The DAO 事件而造成了以太坊的硬分叉。
在以太坊中,智能合約能夠調用其他外部合約的代碼,由于智能合約可以調用外部合約或者發送以太幣,這些操作需要合約提交外部的調用,所以這些合約外部的調用就可以被攻擊者利用造成攻擊劫持,使得被攻擊合約在任意位置重新執行,繞過原代碼中的限制條件,從而發生重入攻擊。重入攻擊本質上與編程里的遞歸調用類似,所以當合約將以太幣發送到未知地址時就可能會發生。
簡單的來說,發生重入攻擊漏洞的條件有 2 個:
調用了外部的合約且該合約是不安全的
外部合約的函數調用早于狀態變量的修改
下面給出一個簡單的代碼片段示例:
上述代碼片段就是最簡單的提款操作,接下來會給大家詳細分析重入攻擊造成的原因。
藍色光標:與騰訊在作為元宇宙入口的虛擬人業務有較深入合作:11月16日消息,藍色光標在互動平臺表示,公司與騰訊在游戲、動漫、閱文等層面有深入合作;同時,在作為元宇宙入口的虛擬人業務,也有較深入合作。[2021/11/16 21:54:34]
在正式的分析重入攻擊之前,我們先來介紹幾個重點知識。
轉賬方法
由于重入攻擊會發送在轉賬操作時,而 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 回退函數。
回退函數 (fallback function):回退函數是每個合約中有且僅有一個沒有名字的函數,并且該函數無參數,無返回值,如下所示:
聲音 | 華軟資本董事長:負利率是否會影響未來數字貨幣信用或可計算交易體系值得深入探索:12月18日,華軟資本董事長、華夏新供給經濟學研究院院長在第一財經發布評論文章。文章表示,負利率對下一階段的貨幣形態發展帶來新的不確定性,也許為“另辟蹊徑”提供某些啟發。隨著信息技術和互聯網的發展,貨幣及其價值傳遞方式出現了根本性的轉變,以信用卡、網銀和移動支付為代表的電子貨幣,以及數字貨幣、區塊鏈和加密資產等都在快速發展。特別是以Facebook籌備計劃推出Libra(天秤座)為代表,其目標是發展成為一種“不企求對美元匯率穩定而追求實際購買力穩定”的加密數字貨幣,這對未來數字貨幣的重要性、演化形態和利率價格等引發了全球關注。與此同時,中國央行主導的主權數字貨幣DCEP已有實質進展,歐洲央行也開始考慮發行公共數字貨幣的多種方案。數字化相當程度上加速了全球資金流動,可以部分解釋利率下行原因,但負利率是否會影響未來數字貨幣的信用或可計算交易體系,更值得深入探索的。[2019/12/19]
function() public payable{???
? ? ? ...
}
回退函數在以下幾種情況中被執行:
調用合約時沒有匹配到任何一個函數;
沒有傳數據;
智能合約收到以太幣(為了接受以太幣,fallback 函數必被標記為 payable)。
漏洞代碼
下面的代碼就是存在重入攻擊的,實現的是一個類似于公共錢包的合約,所有的用戶都可以使用 deposit() 存款到 Reentrance 合約中,也可以從 Reentrance 合約中使用 withdraw() 進行提款,當然了所有人也可以使用 balanceof() 查詢自己或者其他人在該合約中的余額。
聲音 | 國家醫療保障局副局長:國家醫療保障局將深入研究引入5G和區塊鏈等先進技術:11月24日,全國醫保電子憑證發布式在山東省濟南市舉行。國家醫療保障局副局長施子海表示,國家醫療保障局將不斷探索創新,深入研究引入5G和區塊鏈等先進技術,加快完善電子憑證功能和推廣應用,推進醫保治理體系和治理能力現代化,提升為民服務質量和水平,讓更多便民舉措更加廣泛地惠及人民群眾。(第一財經)[2019/11/24]
首先使用一個賬戶 (0x5B38Da6a701c568545dCfcB03FcB875f56beddC4) 扮演受害者,將該合約在 Remix IDE?點擊 Deploy 按鈕進行部署。
在部署合約成功后在 VALUE 設置框中填寫 5,將單位改成 ether,點擊 deposit 存入 5 個以太幣。
點擊 wallet 查看該合約的余額,發現余額為 5 ether,說明我們的存款成功。
而下面的代碼則是針對上面存在漏洞的合約進行的攻擊:
動態 | 2019年7月國內一級市場區塊鏈融資10強發布 區塊鏈行業的發展不斷向產業端深入:據中國金融信息網報道,8月8日,中國金融信息網與烯牛數據聯合發布2019年7月份國內一級市場區塊鏈項目融資10強榜單。從榜單來看,在整體融資大幅下滑的趨勢下,2019年7月份國內區塊鏈項目融資數量出現回升。監測數據顯示,數字貨幣和交易平臺類融資項目明顯增多,天秤幣白皮書的發布在一定程度上提振了市場預期,但是此類項目將面臨與天秤幣的直接競爭,其商業邏輯未來或將受到天秤幣嚴酷打壓。與實體經濟結合的項目依然占據著榜單的主流,分別涉及金融、大數據、交通運輸、電商、傳媒、產權、房地產和游戲領域。從連續發布的榜單來看,區塊鏈行業的發展不斷向產業端深入,應用端的開發落地越來越具體,與實體經濟結合發展的想象空間逐漸立體化。從技術角度來看,加密、數據庫、共識、P2P和智能合約的發展日益成熟,區塊鏈作為集成性創新技術的發揮邊界正在逐步拓展。[2019/8/8]
使用另外一個賬戶 (0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2) 扮演攻擊者,復制存在漏洞的合約地址到 Deploy 的設置框內,點擊 Deploy 部署上面的攻擊合約。
動態 | 北大光華成立金融科技聯合實驗室 向區塊鏈等五大領域深入研究:10月12日,北京大學光華管理學院與度小滿金融宣布合作成立金融科技聯合實驗室,并在北京大學為實驗室揭牌。聯合實驗室主任劉曉蕾表示實驗室將圍繞數字化資產配置、超大規模關聯網絡、在線機器人、監管科技、區塊鏈技術等五大領域深入研究,積極探索前沿技術在金融場景中的應用,同時推動跨學科人才的培養和輸出。[2018/10/12]
部署成功后先調用 wallet() 函數查看攻擊合約的余額為 0。
攻擊者先存款 1 ether 到漏洞合約中,這里設置 VALUE 為 1 ether,之后點擊攻擊合約的 deposit 進行存款。
再次調用合約的 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
5月31日Coingape消息指出,印度私營銀行HDFC和SBI引用印度央行印度儲備銀行(RBI)2018年的廢止通知告誡客戶不要進行加密貨幣交易.
1900/1/1 0:00:00ETH交易手續費不斷升高,直至很多人無法接受,ETH用戶反轉到幣安智能鏈(BSC),平均每筆交易手續費低于0.3美元,憑借低廉的交易手續費和快速的交易效率,在市場中占領一席之地.
1900/1/1 0:00:00本文發表于2021年5月25日本文假設讀者熟悉 Nick Szabo 的《社交網絡的可擴展性》(https://unenumerated.blogspot.
1900/1/1 0:00:00隨著多國央行加快布局數字貨幣,數字貨幣的起源和發展也受到廣泛關注。在6月7日的人大重陽“央行數字貨幣研究”系列講座中,中國人民大學重陽金融研究院高級研究員、北京航空航天大學教授、清華長江講座教授.
1900/1/1 0:00:002020-2021年的加密繁榮是由美聯儲的流動性推動的,當流動性減少的風險爆發時,比特幣將面臨艱難時期.
1900/1/1 0:00:006月9日,薩爾瓦多成功批準通過了將比特幣作為法定貨幣的提案,該國成為首個采用比特幣作為法幣的主權國家,而此次事件也被法新社列為了貨幣史上的第14次重大事件.
1900/1/1 0:00:00