買以太坊 買以太坊
Ctrl+D 買以太坊
ads
首頁 > DOT > Info

WTF Solidity 合約安全: S07. 壞隨機數

Author:

Time:1900/1/1 0:00:00

我最近在重新學solidity,鞏固一下細節,也寫一個“WTFSolidity極簡入門”,供小白們使用,每周更新1-3講。

這一講,我們將介紹智能合約的壞隨機數漏洞和預防方法,這個漏洞經常在NFT和GameFi中出現,包括Meebits,Loots,WolfGame等。

偽隨機數

很多以太坊上的應用都需要用到隨機數,例如NFT隨機抽取tokenId、抽盲盒、gamefi戰斗中隨機分勝負等等。但是由于以太坊上所有數據都是公開透明且確定性的,它沒有其他編程語言一樣給開發者提供生成隨機數的方法,例如random()。很多項目方不得不使用鏈上的偽隨機數生成方法,例如blockhash()和keccak256()方法。

壞隨機數漏洞:攻擊者可以事先計算這些偽隨機數的結果,從而達到他們想要的目的,例如鑄造任何他們想要的稀有NFT而非隨機抽取。更多的內容可以閱讀WTFSolidity極簡教程第39講:偽隨機數。

goblintown.wtf系列NFT24小時交易額為90.35萬美元:金色財經消息,據NFTGo.io數據顯示,goblintown.wtf系列NFT總市值達6264萬美元,在所有NFT項目總市值排名中位列第38;其24小時交易額為90.35萬美元,跌幅達12.69%。截止發稿時,該系列NFT當前地板價為3ETH,漲幅為3.81%。[2022/6/13 4:21:22]

壞隨機數案例

下面我們學習一個有壞隨機數漏洞的NFT合約:BadRandomness.sol。

contract?BadRandomness?is?ERC721?{????uint256?totalSupply;????//?構造函數,初始化NFT合集的名稱、代號????constructor()?ERC721("",?""){}????//?鑄造函數:當輸入的?luckyNumber?等于隨機數時才能mint????function?luckyMint(uint256?luckyNumber)?external?{????????uint256?randomNumber?=?uint256(keccak256(abi.encodePacked(blockhash(block.number?-?1),?block.timestamp)))?%?100;?//?get?bad?random?number????????require(randomNumber?==?luckyNumber,?"Better?luck?next?time!");????????_mint(msg.sender,?totalSupply);?//?mint????????totalSupply++;????}}

goblintown.wtf系列NFT24小時交易額為102.41萬美元:金色財經消息,據NFTGo.io數據顯示,goblintown.wtf系列NFT總市值達6238萬美元,在所有NFT項目總市值排名中位列第39;其24小時交易額為102.41萬美元,跌幅達9.35%。截止發稿時,該系列NFT當前地板價為3.15ETH,跌幅為26.01%。[2022/6/12 4:19:11]

它有一個主要的鑄造函數luckyMint(),用戶調用時輸入一個0-99的數字,如果和鏈上生成的偽隨機數randomNumber相等,即可鑄造幸運NFT。偽隨機數使用blockhash和block.timestamp聲稱。這個漏洞在于用戶可以完美預測生成的隨機數并鑄造NFT。

下面我們寫個攻擊合約Attack.sol。

Nansen:目前有184個“無聊猿”BAYC 持有者同時持有“哥布林” GoblintTown.wtf:金色財經報道,據 Nansen 官方社交媒體賬號披露數據顯示,目前有184個“無聊猿”BAYC 持有者同時持有“哥布林” GoblintTown.wtf,占比約為 2.94%。Nansen 指出,“無聊猿”BAYC和“哥布林” GoblintTown.wtf 的一大區別在于,前者是在加密牛市期間為無聊的“行業老炮兒”們創建的,而后者則是在加密熊市期間通過免費公售的形式在以太鏈上發售。[2022/6/3 4:00:25]

contract?Attack?{????function?attackMint(BadRandomness?nftAddr)?external?{????????//?提前計算隨機數????????uint256?luckyNumber?=?uint256(????????????keccak256(abi.encodePacked(blockhash(block.number?-?1),?block.timestamp))????????)?%?100;????????//?利用?luckyNumber?攻擊????????nftAddr.luckyMint(luckyNumber);????}}

OpenSea上Goblintown.wtf NFT系列地板價達到8ETH:6月2日消息,據OpenSea數據,目前Goblintown.wtf NFT系列地板價今日最高漲至9ETH,目前為8ETH,近7日交易量逾13135枚ETH,累計交易量為21800枚ETH。[2022/6/2 3:58:52]

攻擊函數attackMint()中的參數為BadRandomness合約地址。在其中,我們計算了隨機數luckyNumber,然后將它作為參數輸入到luckyMint()函數完成攻擊。由于attackMint()和luckyMint()將在同一個區塊中調用,blockhash和block.timestamp是相同的,利用他們生成的隨機數也相同。

Remix復現

由于Remix自帶的RemixVM不支持blockhash函數,因此你需要將合約部署到以太坊測試鏈上進行復現。

部署BadRandomness合約。

部署Attack合約。

將BadRandomness合約地址作為參數傳入到Attack合約的attackMint()函數并調用,完成攻擊。

調用BadRandomness合約的balanceOf查看Attack合約NFT余額,確認攻擊成功。

預防方法

我們通常使用預言機項目提供的鏈下隨機數來預防這類漏洞,例如ChainlinkVRF。這類隨機數從鏈下生成,然后上傳到鏈上,從而保證隨機數不可預測。更多介紹可以閱讀WTFSolidity極簡教程第39講:偽隨機數。

總結

這一講我們介紹了壞隨機數漏洞,并介紹了一個簡單的預防方法:使用預言機項目提供的鏈下隨機數。NFT和GameFi項目方應避免使用鏈上偽隨機數進行抽獎,以防被黑客利用。

推特:@0xAA_Science|@WTFAcademy_

社區:Discord|微信群|官網wtf.academy

所有代碼和教程開源在github:?github.com/AmazingAng/WTFSolidity

來源:bress

Tags:INTNFTWTFUCKExperience PointsNFTCWTF價格ZuckMeta

DOT
ARK:一文帶你初步了解隱私Layer1_ETW

隱私計算,最開始萌芽于Zcash、Dash、Monera等匿名幣,在近兩年開始逐漸開始有了自己的聲量.

1900/1/1 0:00:00
比特幣:FTX隕落后行業現狀概況_AVASTR Vault (NFTX)

首先讓我們簡單介紹一下FTX的背景。這是一家擁有超過100萬用戶的加密貨幣交易所,由SamBankman-Fried和GaryWang于2019年5月創立.

1900/1/1 0:00:00
比特幣:10 年回溯 Crypto 投融資演化史_Cryptopay

撰文:wesely FTX,花了兩年時間坐上二把手的位置,只在一夕之間跌落神壇,百億估值如曇花泡影,一朝散盡,放在年輕的加密行業發展史中,它也如一顆巨石,跌落湖中央.

1900/1/1 0:00:00
WEB:如何發揮「NFT+DAO」的可組合性?_DAO

撰文:Kyle 來源:WebX實驗室 NFT+DAO這樣的想法目前對Web3可持續發展愛好者非常有吸引力,對于項目團隊也是如此.

1900/1/1 0:00:00
FTX:FTX事件后的思考:加密行業將何去何從?_加密貨幣

文:knower 來源:knower''ssubstack加密行業的終局止于此了嗎?未來一年可能發生什么?下一個十年可能發生什么?也許是下個世紀可能發生什么?有沒有人可以給你一個答案?當然沒有.

1900/1/1 0:00:00
MET:Meta大裁員:1.1萬人從元宇宙里“消失”_TERA2

文:杜晨寒冬來了,沒有人能逃過 該來的還是來了。 在裁員的消息已經醞釀了一整個周末之后,馬克·扎克伯格終于美國時間在周三11月9日早上,正式宣布了Meta裁員的消息:這是Meta/Faceboo.

1900/1/1 0:00:00
ads