時(shí)間:2023-06-17|瀏覽:221
8月17日,BSC鏈上的XSURGE協(xié)議遭到閃電貸攻擊,損失超過(guò)500萬(wàn)美元。對(duì)此,知道創(chuàng)宇區(qū)塊鏈安全實(shí)驗(yàn)室對(duì)攻擊流程和代碼細(xì)節(jié)進(jìn)行了全盤(pán)梳理。
全盤(pán)梳理
基礎(chǔ)信息: -攻擊tx:0x7e2a6ec08464e8e0118368cb933dc64ed9ce36445ecf9c49cacb970ea78531d2 -攻擊合約:0x1514AAA4dCF56c4Aa90da6a4ed19118E6800dc46 -SurgeToken:0xE1E1Aa58983F6b8eE8E4eCD206ceA6578F036c21
攻擊流程: 這里有個(gè)小細(xì)節(jié),代幣轉(zhuǎn)移流程中的順序是按照事件先后順序來(lái)顯示的,而重入之后的買(mǎi)操作引起的事件會(huì)在賣(mài)操作引起的事件之前,所以在流程中看到的每一個(gè)單獨(dú)的重入攻擊中是SURGE的買(mǎi)入發(fā)生在賣(mài)出之前。
漏洞原理: 漏洞點(diǎn)在于SurgeToken合約中的sell函數(shù),其中對(duì)調(diào)用者msg.sender的BNB轉(zhuǎn)賬采用的call函數(shù),并且在轉(zhuǎn)賬之后才更新代幣總量_totalSupply,是典型的重入漏洞場(chǎng)景。雖然sell函數(shù)使用了nonReentrant修飾防止了重入,但purchase函數(shù)并沒(méi)有。重入轉(zhuǎn)回BNB給合約,觸發(fā)fallback函數(shù)調(diào)用purchase,由于_totalSupply尚未減去賣(mài)出量,而導(dǎo)致可買(mǎi)入相較正常更多的SURGE代幣。
復(fù)現(xiàn): 價(jià)格分析 sell函數(shù)賣(mài)出過(guò)程中,輸入tokenAmount與輸出amountBNB的關(guān)系: purchase函數(shù)買(mǎi)入過(guò)程中,輸入bnbAmount與輸出tokensToSend的關(guān)系: 在重入過(guò)程中,sell函數(shù)賣(mài)出后獲得的BNB通過(guò)重入打回SurgeToken合約傳入purchase函數(shù)故令sell函數(shù)的輸出amountBNB與purchase函數(shù)的輸入bnbAmount相等,可得到整個(gè)利用流程中輸入與輸出的關(guān)系: 若要實(shí)現(xiàn)套利,需要輸出大于輸入,則有: 最后得到: 也就是說(shuō)重入套利過(guò)程中調(diào)用sell賣(mài)出的代幣量必須在代幣總量的12.383%以上。
模擬演示: 為方便調(diào)試,將SurgeToken合約中的mint函數(shù)可見(jiàn)性改為public,并為構(gòu)造函數(shù)增加payable修飾,在部署時(shí)傳入10^15wei。SurgeToken合約初始化的代幣總量為10^9,根據(jù)前面推導(dǎo)出的結(jié)論,為攻擊合約鑄幣200000000(攻擊成本),則攻擊合約擁有大約SURGE代幣總量16%的代幣。攻擊合約調(diào)用Attack函數(shù)攻擊,查看攻擊合約的代幣余額已變?yōu)?09549307,獲利9549307。
總結(jié): XSURGE協(xié)議被攻擊的本質(zhì)原因在于sell函數(shù)中存在重入漏洞,導(dǎo)致可通過(guò)purchase函數(shù)買(mǎi)入較多的SURGE代幣而獲利。簡(jiǎn)而言之,典型的重入漏洞場(chǎng)景,教科書(shū)級(jí)的案例。