比特幣交易所 比特幣交易所
Ctrl+D 比特幣交易所
ads
首頁 > 世界幣 > Info

Solidity編譯器漏洞分析:ABI重編碼的缺陷_SOL

Author:

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

漏洞詳情

ABI?編碼格式是用在用戶或合約對合約進行函數調用,傳遞參數時的標準編碼方式。具體可以參考?Solidity?官方關于ABI?編碼的詳細表述。

在合約開發過程中,會從用戶或其他合約傳來的?calldata?數據中,獲取需要的數據,之后可能會將獲取的數據進行轉發或?emit?等操作。限于?evm?虛擬機的所有?opcode?操作都是基于?memory、stack?和?storage,所以在?Solidity?中,涉及到需要對數據進行?ABI?編碼的操作,都會將?calldata?中的數據根據新的順序按照?ABI?格式進行編碼,并存儲到?memory?中。

該過程本身并沒有大的邏輯問題,但是當和?Solidity?的cleanup?機制結合時,由于?Solidity?編譯器代碼本身的疏漏,就導致了漏洞的存在。

根據?ABI?編碼規則,在去掉函數選擇符之后,ABI?編碼的數據分為?head?和?tail?兩部分。當數據格式為固定長度的?uint?或?bytes?32?數組時,ABI?會將該類型的數據都存儲在?head?部分。而?Solidity?對?memory?中?cleanup?機制的實現是在當前索引的內存被使用后,將下一個索引的內存置空,以防止下一索引的內存使用時被臟數據影響。并且,當?Solidity?對一組參數數據進行?ABI?編碼時,是按照從左到右的順序進行編碼!!

Solana:2月25日主網故障因主要區塊傳播協議“Turbine”的擁堵:4月19日消息,Solana發文稱,北京時間2月25日大約13:46:16,Solana主網Beta集群(cluster)降級的原因是主要區塊傳播協議“Turbine”的擁堵,異常的網絡流量致使Turbine容量飽和,迫使大部分區塊數據通過極慢的后備區塊修復協議進行傳輸。核心工程師已經確定,這個問題是由碎片轉發服務中的重復數據刪除邏輯故障引起的。

此外,重傳管道中的重復數據刪除過濾器最初并不是為了防止Turbine樹中的環路而設計的。現在對重復數據刪除邏輯進行增強,以減輕SolanaLabs驗證程序客戶端v1.13.7和v1.14.17中此過濾器的飽和。核心工程師還與碎片轉發服務提供商合作,以提高其設計的彈性和兼容性。此外,SolanaLabs驗證器客戶端的一個補丁已經被應用,它將導致產生大區塊的區塊生產者中止,從而向節點運營商發出信號,檢查其節點并使其在集群中恢復到健康狀態。[2023/4/19 14:12:44]

為了便于后面的漏洞原理探索,考慮如下形式的合約代碼:

contractEocene{

????????eventVerifyABI(bytes,?uint);

????????functionverifyABI(bytescalldataa,uintcalldatab)public?{

Solana發布改進網絡升級計劃,將組建對抗團隊并改進重啟過程:金色財經報道,Solana 聯合創始人 Anatoly Yakovenko 發布“改進網絡升級的計劃”,將改進 Solana 升級過程、組建對抗團隊、改進重啟過程、以穩定為中心。

Solana 核心工程師計劃幫助改進流程如下:

在主網測試版升級之前,將測試網降級到當前的主網測試版和功能集;

將測試網升級為新版本的發布候選;

觀察測試網遷移是如何實時進行的;

將測試網降級回當前的主網測試版;

在對測試網進行壓力測試時重復此過程;

發布新版本給 mainnet-beta 驗證器進行升級。[2023/3/1 12:36:00]

????????????????emitVerifyABI(a,b);?//Event數據會按照?ABI?格式編碼之后存儲到鏈上

??????}

}

合約?Eocene?中?verifyABI?函數的作用,僅僅是將函數參數中的不定長?bytesa?和定長?uintb?進行?emit。

這里需要注意,event?事件也會觸發?ABI?編碼。這里參數?a,?b?會編碼成?ABI?格式后再存儲到鏈上。

我們使用?v?0.8.14?版本的?Solidity?對合約代碼進行編譯,通過?remix?進行部署,并傳入verifyABI(,)。

NFT項目Okay Bears地板價觸及150 SOL,創歷史新高:4月29日消息,據 OpenSea 數據顯示,Solana 鏈上 NFT 項目Okay Bears地板價觸及 150 SOL,創歷史新高。此外,Okay Bears 交易總額已達到 38.83 萬枚 SOL。[2022/4/29 2:40:41]

首先,我們看一看對verifyABI(,)的正確編碼格式:

0x?5?2c?d?1?a?9?c?????????????????????????????????//bytes?4(sha?3("verify(btyes,?uint)"))

0000000000000000000000000000000000000000000000000000000000000060??????//indexof?a

0000000000000000000000000000000000000000000000000000000000011111??????//b

0000000000000000000000000000000000000000000000000000000000022222??????//b

0000000000000000000000000000000000000000000000000000000000000002??????//lengthofa

Raydium將于10月11日發布stSOL-USDC Fusion Pool:10月11日,基于Solana的鏈上訂單簿AMM Raydium Protocol發推稱,通過與流動性質押協議Lido合作,將于UTC時間10月11日12點發布stSOL-USDC Fusion Pool,將提供wLDO獎勵。[2021/10/11 20:19:10]

0000000000000000000000000000000000000000000000000000000000000040??????//indexofa

0000000000000000000000000000000000000000000000000000000000000080??????//indexofa

0000000000000000000000000000000000000000000000000000000000000003??????//lengthofa

aaaaaa?0000000000000000000000000000000000000000000000000000000000??????//a

0000000000000000000000000000000000000000000000000000000000000003??????//lengthofa

bbbbbb?0000000000000000000000000000000000000000000000000000000000??????//a

交易所聚合器OpenOcean啟用Solana網絡上的交易:金色財經報道,加密貨幣交易所聚合器OpenOcean已連接到Solana區塊鏈生態系統。OpenOcean已經在以太坊、Binance Smart Chain、Tron和Ontology上可用,由于用戶請求的數量而增加了Solana。[2021/5/29 22:54:06]

如果?Solidity?編譯器正常,當參數a,?b被?event?事件記錄到鏈上時,數據格式應該和我們發送的一樣。讓我們實際調用合約試試看,并對鏈上的?log?進行查看,如果想自己對比,可以查看該TX。

成功調用后,合約?event?事件記錄如下:

!!震驚,緊跟?b的,存儲?a?參數長度的值被錯誤的刪除了!!

0000000000000000000000000000000000000000000000000000000000000060??????//indexof?a

0000000000000000000000000000000000000000000000000000000000011111??????//b

0000000000000000000000000000000000000000000000000000000000022222??????//b

0000000000000000000000000000000000000000000000000000000000000000??????//lengthofa???whybecome0??

0000000000000000000000000000000000000000000000000000000000000040??????//indexofa

0000000000000000000000000000000000000000000000000000000000000080??????//indexofa

0000000000000000000000000000000000000000000000000000000000000003??????//lengthofa

aaaaaa?0000000000000000000000000000000000000000000000000000000000??????//a

0000000000000000000000000000000000000000000000000000000000000003??????//lengthofa

bbbbbb?0000000000000000000000000000000000000000000000000000000000??????//a

為什么會這樣?

正如我們前面所說,在?Solidity?遇到需要進行?ABI?編碼的系列參數時,參數的生成順序是從左至,具體對?a,?b?的編碼邏輯如下

Solidity?先對?a?進行?ABI?編碼,按照編碼規則,a?的索引放在頭部,a?的元素長度以及元素具體值均存放在尾部。

處理?b?數據,因為?b?數據類型為?uint格式,所以數據具體值被存放在?head?部分。但是,由于?Solidity?自身的?cleanup?機制,在內存中存放了?b之后,將?b數據所在的后一個內存地址(被用于存放?a?元素長度的內存地址)的值置?0?。

ABI?編碼操作結束,錯誤編碼的數據存儲到了鏈上,SOL-2022-6?漏洞出現。

在源代碼層面,具體的錯誤邏輯也很明顯,當需要從?calldata?獲取定長?bytes?32?或?uint?數組數據到?memory?中時,Solidity?總是會在數據復制完畢后,將后一個內存索引數據置為?0?。又由于?ABI?編碼存在?head?和?tail?兩部分,且編碼順序也是從左至右,就導致了漏洞的存在。

具體漏洞的?Solidity?編譯代碼如下:

當源數據存儲位置為?Calldata,且源數據類型為?ByteArray,String,或者源數組基礎類型為?uint?或?bytes?32?時進入ABIFunctions::abiEncodingFunctionCalldataArrayWithoutCleanup()

進入之后,會首先通過fromArrayType.isDynamicallySized()對源數據是否為定長數組來對源數據進行判斷,只有定長數組才符合漏洞觸發條件。

將isByteArrayOrString()判斷結果傳遞給YulUtilFunctions::copyToMemoryFunction(),根據判斷結果來確定是否在?calldatacopy?操作完成后,對后一個索引位置進行?cleanup。

上訴幾個約束條件結合,就只有位于?calldata?中的源數據格式為定長的?uint?或?bytes?32?的數組復制到內存時才能觸發漏洞。也即是漏洞觸發的約束條件產生的原因。

由于?ABI?進行參數編碼時,總是從左到右的順序,考慮到漏洞的利用條件,我們必須要明白,必須在定長的?uint?和?bytes?32?數組前,存在動態長度類型的數據被存儲到?ABI?編碼格式的?tail?部分,且定長的?uint?或?bytes?32?數組必須位于待編碼參數的最后一個位置。

原因很明顯,如果定長的數據沒有位于最后一個待編碼參數位置,那么對后一內存位置的置?0?不會有任何影響,因為下個編碼參數會覆蓋該位置。如果定長數據前面沒有數據需要被存儲到?tail?部分,那么即便后一內存位置被置?0?也沒有關系,因為該位置并不背?ABI?編碼使用。

另外,需要注意的是,所有的隱式或顯示的?ABI?操作,以及符合格式的所有?Tuple,都會受到該漏洞的影響。

具體的涉及到的操作如下:

event

error

abi.encode*

returns??????//thereturnoffunction

struct???????//theuserdefinedstruct

allexternalcall

當合約代碼中存在上訴受影響的操作時,保證最后一個參數不為定長的?uint?或?bytes?32?數組

使用不受漏洞影響的?Solidity?編譯器

尋求專業的安全人員的幫助,對合約進行專業的安全審計

Learnmore:Website?|Medium?|Twitter

Tags:SOLLIDSolanaSOLAsol幣最新動態消息Lido DAO Tokensolana幣最新消息solana幣官網

世界幣
Lido 將如何去中心化? Lido 的質押理念是什么?_IDO

Lido協議的代幣模型 Lido協議目前的核心代幣是stETH,它是回基代幣模型。回基意味著,每天stETH的數量增長與在信標鏈上質押的ETH和獎勵數量相匹配.

1900/1/1 0:00:00
樂觀的 BTC鯨魚可能需要做的不僅僅是增持,這就是為什么……_PLE

隨著對B??TC的看漲情緒增加,比特幣交易所存款下降。鯨魚對BTC的興趣增加,但是,短期持有者獲利并離開。在過去三個月上漲之后,比特幣的價格開始出現波動.

1900/1/1 0:00:00
ETH周報 | 以太坊坎昆升級預計今年晚些進行;法興業銀行在以太坊上推出歐元穩定幣(4.17-4.23)_穩定幣

一、整體概述 以太坊核心開發人員會議中表示,計劃對區塊鏈的共識層進行代碼修改,為下一次坎昆升級做準備,坎昆升級預計將于今年晚些時候進行.

1900/1/1 0:00:00
加密貨幣影響者揭示了神秘的比特幣( BTC) 鯨魚運動_LOOK

4月25日,鏈上分析師Lookonchain指出來自BTC地址的活動已經休眠了十多年。因此,網友們對鯨魚的行動反應不一.

1900/1/1 0:00:00
半年內將會有超過20條新Rollup誕生,機會在這里_EFI

公眾號:小七財圈 做Rollup是一門好生意,這里面會有兩種模式。一種是專門做Rollup的項目,目的是吸引別的應用前來部署到自己的Rollup上,自己則能掙礦工費的差價.

1900/1/1 0:00:00
關于支持Band Protocol(BAND)網絡升級的公告_AND

親愛的用戶:幣安將支持BandProtocol的網絡升級,具體安排如下:幣安預計將于東八區時間2023年04月27日21:00暫停BAND代幣的充值、提現業務.

1900/1/1 0:00:00
ads