以太坊交易所 以太坊交易所
Ctrl+D 以太坊交易所
ads

Solidity編譯器中高危漏洞:誤刪狀態變量賦值-ODAILY_ORE:Storichain

Author:

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

本文從源代碼層面詳解介紹了Solidity(0.8.13<=solidity<0.8.17)編譯器在編譯過程中,因為Yul優化機制的缺陷導致的狀態變量賦值操作被錯誤刪除的中/高漏洞原理及相應的預防措施。

幫助合約開發人員提高合約開發時的安全意識,有效規避或緩解SOL-2022-7漏洞對合約代碼安全性的影響。

1.漏洞詳情

Yul優化機制是Solidity編譯合約代碼的可選項,可以通過優化機制減少合約中某些冗余的指令,從而降低合約部署和執行過程中的gas費用,具體的Yul優化機制可以參考官方文檔。

在編譯過程的UnusedStoreEliminator優化步驟中,編譯器會將“冗余”的Storage寫入操作移除,但由于對“冗余”的識別缺陷,當某個Yul函數塊調用特定的用戶定義函數(函數內部存在某個分支不影響調用塊的執行流),且在該Yul函數塊中被調用函數前后存在對同一狀態變量的寫入操作,會導致在Yul優化機制將塊中該用戶定義函數被調用前的所有的Storage寫入操作從編譯層面被永久刪除。

考慮如下代碼:

contractEocene{

uintpublicx;

Lido V2已上線Solana,節點傭金降為5%:12月21日消息,Lido V2已上線Solana,主要變化是取消了專門的100%傭金,轉而支持公共驗證節點,最高傭金為5%。此外,驗證節點區塊和質押獎勵將獲得SOL而不是stSOL。

官方表示,v2的變化側重于節點運營商的盈利能力和簡單性,最終有助于為Lido用戶提供更安全的質押體驗。[2022/12/21 21:59:11]

functionattack()public{

x=1;

x=2;

}

}

在UnusedStoreEliminator優化時,x=1顯然對于函數attack()的整個執行是冗余的。自然的,優化后的Yul代碼會將x=1;刪除來降低合約的gas消耗。

接下來考慮在中間插入對自定義函數調用:

contractEocene{

uintpublicx;

functionattack(uinti)public{

x=1;

y(i);

x=2;

}

幣安將于8月4日為Acala、Solana等多個網絡執行錢包維護,大約需要2小時:8月1日消息,幣安官方宣布,將從8月4日14:00開始為多個網絡執行錢包維護,大約需要2小時。受影響的網絡包括Acala Network(ACA)、aelf Network(ELF)、Astar Network(ASTR)、Bifrost Network(BNC)、Bitcoin Gold(BTG)、Cardano Network(ADA)、DigiByte Network(DGB)、Flow Network(FLOW)、Hedera Hashgraph Network(HBAR)、Helium Network(HNT)、Horizen Network(ZEN)、IOST Network(IOST)、NULS Network(NULS)、Oasis Network(ROSE)、Qtum Network(QTUM)、RSK Network(RSK)、Solana Network(SOL)、Syscoin Network(SYS)、Tezos Network(XTZ)、THORChain Network(RUNE)、Verge Network(XVG)。[2022/8/1 2:51:36]

functiony(uinti)internal{

數據:Solana鏈上NFT交易總額突破21億美元 “淡定熊”Okay Bears超7600萬美元:金色財經報道,據cryptoslam數據顯示,Solana鏈上NFT交易總額已突破21億美元,創下歷史新高,本文撰寫時為2,179,870,012美元,鏈上交易總量達到5,143,431筆。當前Solana區塊鏈上NFT交易額最大的NFT項目是SolanaMonkeyBusiness,交易額為184,434,992美元,Degenerate Ape Academy排名第二,交易額為137,011,205美元,此外“淡定熊”Okay Bears當前交易額已超過7600萬美元。[2022/5/9 3:00:01]

if(i>0){

return;

}

assembly{return(0,0。

}

}

顯然,由于y()函數的調用,我們需要判斷y()函數是否會影響函數attack()的執行,如果y()函數可以導致整個函數執行流終止(注意,不是回滾,Yul代碼中的return()函數可以實現),那么x=1顯然是不能刪除的,所以對于上面的合約來說由于y()函數中存在assembly{return(0,0。可以導致整個消息調用終止,x=1自然不能被刪除。

數據:Lido Finance上質押的SOL數量已超25萬枚,價值近4500萬美元:9月11日消息,以太坊2.0質押流動性解決方案Lido Finance在推特上表示,在宣布支持Solana之后至今的三天時間里,Lido上已質押了251255枚SOL,總價值約4478萬美元。[2021/9/11 23:18:00]

但在Solidity編譯器中,由于代碼邏輯的問題,使得x=1在編譯時被錯誤的刪除,永久改變了代碼邏輯。

實際編譯測試結果如下:

震驚!不應該被優化的x=1的Yul代碼丟了!欲知后事如何,請往下看。

在solidiry編譯器代碼的UnusedStoreEliminator中,通過SSA變量追蹤和控制流追蹤來判斷一個Storage寫入操作是否是冗余的。當進入一個自定義函數中時,UnusedStoreEliminator如果遇到:

memory或storage寫入操作:將memory和storage寫入操作存儲到m_store變量中,并將該操作的初始狀態設置為Undecided;

加密市場監控公司SolidusLabs獲2000萬美元A輪融資:加密市場監控初創公司SolidusLabs宣布完成2000萬美元A輪融資,EvolutionEquityPartners領投,其他投資方包括HanacoVentures(曾參與種子輪融資)、FTX、富達投資母公司FMRLLC旗下風險投資基金AvonVenture、前美國商品期貨交易委員會(CFTC)主席ChristopherGiancarlo、前美國證券交易委員會(SEC)專員TroyParedes、前CFTC首席創新官DanielGorfine、合規軟件解決方案提供商StarCompliance創始人MarcEpstein、國際證券交易所(ISE)創始人DavidKrell、AngelList創始人NavalRavikant等。[2021/5/25 22:41:31]

函數調用:獲取函數的memory或storage讀寫操作位置,并和m_store變量中存儲的所有Undecided狀態下的操作進行對比:

1.如果是對m_store中存儲操作的寫入覆蓋,則將m_store中對應的操作狀態改為Unused

2.如果是對m_store中存儲操作的讀取,則將對應m_store中的對應操作狀態改為Used

3.如果該函數沒有任何可以繼續執行消息調用的分支,將m_store中所有的內存寫操作改為Unused

1.在上訴條件下,如果函數可以終止執行流,將m_store中,狀態為Undecided狀態的storage寫操作改為Used;反之,標識為Unused

函數結束:將所有標記為Unused的寫入操作刪除

對memory或storage寫入操作的初始化代碼如下:

可以看到,將遇到的memory和storage寫入操作存儲到m_store中

遇到函數調用時的處理邏輯代碼如下:

其中,operationFromFunctionCall()和applyOperation()實現上訴的2.1,2.2處理邏輯。位于下方的基于函數的canContinue和canTerminate進行判斷的If語句實現2.3邏輯。

需要注意,正是下方的If判斷的缺陷,導致了漏洞的存在!!!

operationFromFunctionCall()來獲取該函數的所有memory或storage讀寫操作,這里需要注意,Yul中存在很多的內置函數,例如sstore(),return()。這里可以看到對于內置函數和用戶定義函數有不同的處理邏輯。

而applyOperation()函數則是將從operationFromFuncitonCall()獲取的所有讀寫操作進行對比,來判斷存儲到m_store中的是否在該次函數調用中被讀寫,并修改m_store中的對應的操作狀態。

考慮上述的UnusedStoreEliminator優化邏輯對Eocene合約的attack()函數的處理:

將x=1存儲操作到m_store變量中,狀態設置為Undecided

1.遇到y()函數調用,獲取y()函數調用的所有讀寫操作

2.遍歷m_store變量,發現y()調用引起的所有讀寫操作和x=1無關,x=1狀態仍然是Undecided

1.獲取y()函數的控制流邏輯,因為y()函數存在可以正常返回的分支,所以canContinue為True,不進入If判斷。x=1狀態仍然為Undecided!!!

3.遇到x=2存儲操作:

1.遍歷m_store變量,發現處于Undecided狀態的x=1,x=2操作覆蓋x=1,設置x=1狀態為Unused。

2.將x=2操作存入m_store,初始狀態為undecided。

4.函數結束:

1.將所有m_store中undecided狀態的操作狀態改為Used

2.將所有m_store中Unused狀態的操作刪除

顯然,在調用函數時,如果被調用函數可以終止消息執行,應該將被調用函數前所有的Undecided狀態的寫入操作改為Used,而不是依舊保留為Undecided,導致位于被調用函數前的寫入操作被錯誤的刪除。

此外,需要注意的是,每個用戶自定義函數控制流標識是會傳遞的,所以在多個函數遞歸調用的場景下,即便最底層函數滿足上訴邏輯,x=1也有可能被刪除。

在Solidity中,舉例了基本相同的邏輯下,不會受到影響的合約代碼。但,該代碼不受該漏洞的影響并不是因為UnusedStoreEliminator的處理邏輯存在其他可能,而是在UnusedStoreEliminator之前的Yul優化步驟中,存在FullInliner優化過程會將微小或只有一次調用的被調用函數,嵌入到調用函數中,避免了漏洞觸發條件中的用戶定義函數。

contractNormal{

uintpublicx;

functionf(boola)public{

x=1;

g(a);

x=2;

}

functiong(boola)internal{

if(!a)

assembly{return(0,0。

}

}

編譯結果如下:

函數g(boola)被嵌入到函數f()中,避免了用戶定義函數的漏洞條件,避免了漏洞的產生。

2.解決方案

最根本的解決方案是不使用在受影響范圍的solidity編譯器進行編譯,如果需要使用漏洞版本的編譯器,可以考慮在編譯時去除UnusedStoreEliminator優化步驟。

如果想要從合約代碼層面進行漏洞緩解,考慮到多個優化步驟的復雜性,以及實際函數調用流的復雜性,請尋找專業的安全人員進行代碼審計來幫助發現合約中的因為該漏洞導致的安全問題。

Tags:TORSTOSTORORESTOREMainstonStorichainFOREX

歐易交易所
Bitfinex一周簡報(0206-0212)-ODAILY_FIN:FINE

BitfinexAlpha|美聯儲繼續加息,但鏈上數據顯示底部可能已接近在上周加息25個基點之后,早期關于暫停加息的呼吁可能會被忽略。目前通脹率為6.5%,我們仍遠高于美聯儲2%的目標.

1900/1/1 0:00:00
狂飆的ChatGPT,進軍的預言機-ODAILY_GPT:GGPT價格

前言:如果說,ChatGPT的出現,象征著一場新的、關于“智能”的工業革命的萌芽正破土而出。那么,預言機的落地,代表著一次新的,關于“數據”的區塊鏈變革的哥倫布之旅.

1900/1/1 0:00:00
Bitfinex一周簡報(0327-0402)-ODAILY_BITG:BIT

BitfinexAlpha|比特幣因銀行擠兌而走強隨著我們再次加息25個基點,美聯儲上周強化了對抗通貨膨脹的訊息。盡管最近銀行倒閉,但它仍然專注于對抗通貨膨脹.

1900/1/1 0:00:00
DeFi借貸協議黑客攻擊不斷,2023年信任該如何重塑?-ODAILY_TOKE:KEN

DeFi借貸是相對簡單的借貸方式。放款人只需將數字貨幣存入借貸池,即可從其存入的資產中獲得利息。而借款人可以通過在平臺上提供抵押品,以換取放款人提供的借貸資產.

1900/1/1 0:00:00
火必推出ETH2.0質押獎勵活動助力以太坊上海升級-ODAILY_以太坊:ETH

Goerli測試網順利完成過渡后,以太坊上海升級終于臨近了。近日,以太坊基金會正式確認了以太坊上海升級時間,主網將在epoch194048激活Shapella網絡升級,預計在北京時間4月13日0.

1900/1/1 0:00:00
一文了解多項式承諾協議Brakedown-ODAILY_VER:coinbasepro官網app下載

原文作者:FoxTechCEO康水躍,FoxTech首席科學家孟鉉濟前言:如果密碼學家沒有發現張量積和多項式取值之間的聯系,那就很難出現多項式承諾協議Brakedown.

1900/1/1 0:00:00
ads