火星链 火星链
Ctrl+D收藏火星链
首页 > SOL > 正文

SOL:Solidity编译器漏洞分析:ABI重编码的缺陷-ODAILY

作者:

时间:1900/1/1 0:00:00

总览

本文从源代码层面对Solidity编译器(0.5.8<=version<0.8.16)在ABIReencoding过程中,由于对固定长度的uint和bytes32类型数组的错误处理所导致的漏洞问题进行详细分析,并提出相关的解决方案及规避措施。

漏洞详情

ABI编码格式是用在用户或合约对合约进行函数调用,传递参数时的标准编码方式。具体可以参考Solidity官方关于ABI编码的详细表述。

在合约开发过程中,会从用户或其他合约传来的calldata数据中,获取需要的数据,之后可能会将获取的数据进行转发或emit等操作。限于evm虚拟机的所有opcode操作都是基于memory、stack和storage,所以在Solidity中,涉及到需要对数据进行ABI编码的操作,都会将calldata中的数据根据新的顺序按照ABI格式进行编码,并存储到memory中。

该过程本身并没有大的逻辑问题,但是当和Solidity的cleanup机制结合时,由于Solidity编译器代码本身的疏漏,就导致了漏洞的存在。

根据ABI编码规则,在去掉函数选择符之后,ABI编码的数据分为head和tail两部分。当数据格式为固定长度的uint或bytes32数组时,ABI会将该类型的数据都存储在head部分。而Solidity对memory中cleanup机制的实现是在当前索引的内存被使用后,将下一个索引的内存置空,以防止下一索引的内存使用时被脏数据影响。并且,当Solidity对一组参数数据进行ABI编码时,是按照从左到右的顺序进行编码!!

基于Solana的房地产代币化平台Homebase已上线测试版本:2月7日消息,基于Solana的房地产代币化平台Homebase在推特上宣布Homebase Investment Platform上线测试版本,下周将推出首项资产,用户将能够以低至100美元的价格投资于代币化住宅房地产。[2023/2/7 11:52:39]

为了便于后面的漏洞原理探索,考虑如下形式的合约代码:

contractEocene{

eventVerifyABI(bytes,uint);

functionverifyABI(bytescalldataa,uintcalldatab)public{

emitVerifyABI(a,b);//Event数据会按照ABI格式编码之后存储到链上

}

}

合约Eocene中verifyABI函数的作用,仅仅是将函数参数中的不定长bytesa和定长uintb进行emit。

这里需要注意,event事件也会触发ABI编码。这里参数a,b会编码成ABI格式后再存储到链上。

我们使用v0.8.14版本的Solidity对合约代码进行编译,通过remix进行部署,并传入verifyABI(,)。

首先,我们看一看对verifyABI(,)的正确编码格式:

Solana流支付协议Zebec宣布将集成USDr支付方式:金色财经报道,Solana流支付协议Zebec宣布将集成USDr支付方式,允许协议使用Zebec将资金存入Ratio,铸造USDr,并允许他们将Ratio平台用作高收益储蓄账户。通过将Ratio与Zebec的连续结算协议集成,用户可以通过Ratio获得其工资支付。[2022/6/4 4:01:31]

0x52cd1a9c//bytes4(sha3("verify(btyes,uint)"))

0000000000000000000000000000000000000000000000000000000000000060//indexofa

0000000000000000000000000000000000000000000000000000000000011111//b

0000000000000000000000000000000000000000000000000000000000022222//b

0000000000000000000000000000000000000000000000000000000000000002//lengthofa

0000000000000000000000000000000000000000000000000000000000000040//indexofa

Solana网络中断分析报告:套利机器人垃圾邮件导致:1月24日消息,Solana生态借贷协议Solend发布了一份网络中断分析报告,其中解释了Solana在1月21日至22日遭受网络不稳定和持续近30小时的中断原因,本次事故是继1月6日至1月12日服务中断和性能下降之后本月的第二次网络中断。

根据Solend分析,本次中断的根本原因是加密货币市场崩盘创造了大量套利机会,因此清算机器人和套利机器人开始提交大量交易,以赢得清算和交易,结果大量垃圾邮件被发送到Solana网络上引发严重负载。另一方面,Solana区块链本身也存在一些问题,比如其网络没有过滤重复交易的能力,导致数以千计的重复机器人交易也淹没了合法的用户交易。[2022/1/24 9:09:51]

0000000000000000000000000000000000000000000000000000000000000080//indexofa

0000000000000000000000000000000000000000000000000000000000000003//lengthofa

aaaaaa0000000000000000000000000000000000000000000000000000000000//a

0000000000000000000000000000000000000000000000000000000000000003//lengthofa

Solana生态去中心化衍生品交易平台Drift Protocol上线alpha版本主网:据官方公告,Solana生态去中心化衍生品交易平台Drift Protocol宣布封闭alpha版本主网现在已经上线。[2021/10/25 20:55:51]

bbbbbb0000000000000000000000000000000000000000000000000000000000//a

如果Solidity编译器正常,当参数a,b被event事件记录到链上时,数据格式应该和我们发送的一样。让我们实际调用合约试试看,并对链上的log进行查看,如果想自己对比,可以查看该TX。

成功调用后,合约event事件记录如下:

!!震惊,紧跟b的,存储a参数长度的值被错误的删除了!!

0000000000000000000000000000000000000000000000000000000000000060//indexofa

0000000000000000000000000000000000000000000000000000000000011111//b

0000000000000000000000000000000000000000000000000000000000022222//b

0000000000000000000000000000000000000000000000000000000000000000//lengthofa??whybecome0??

Manhattan Solar将在美国德州建立可再生能源加密挖矿中心:金色财经报道,Manhattan Solar Partners有限责任公司宣布计划在美国德克萨斯州建造最大的可再生能源加密货币挖矿数据中心。该中心预计将在2021年底之前启动。[2021/6/11 23:29:26]

0000000000000000000000000000000000000000000000000000000000000040//indexofa

0000000000000000000000000000000000000000000000000000000000000080//indexofa

0000000000000000000000000000000000000000000000000000000000000003//lengthofa

aaaaaa0000000000000000000000000000000000000000000000000000000000//a

0000000000000000000000000000000000000000000000000000000000000003//lengthofa

bbbbbb0000000000000000000000000000000000000000000000000000000000//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获取定长bytes32或uint数组数据到memory中时,Solidity总是会在数据复制完毕后,将后一个内存索引数据置为0。又由于ABI编码存在head和tail两部分,且编码顺序也是从左至右,就导致了漏洞的存在。

具体漏洞的Solidity编译代码如下:

当源数据存储位置为Calldata,且源数据类型为ByteArray,String,或者源数组基础类型为uint或bytes32时进入ABIFunctions::abiEncodingFunctionCalldataArrayWithoutCleanup()

进入之后,会首先通过fromArrayType.isDynamicallySized()对源数据是否为定长数组来对源数据进行判断,只有定长数组才符合漏洞触发条件。

将isByteArrayOrString()判断结果传递给YulUtilFunctions::copyToMemoryFunction(),根据判断结果来确定是否在calldatacopy操作完成后,对后一个索引位置进行cleanup。

上诉几个约束条件结合,就只有位于calldata中的源数据格式为定长的uint或bytes32的数组复制到内存时才能触发漏洞。也即是漏洞触发的约束条件产生的原因。

由于ABI进行参数编码时,总是从左到右的顺序,考虑到漏洞的利用条件,我们必须要明白,必须在定长的uint和bytes32数组前,存在动态长度类型的数据被存储到ABI编码格式的tail部分,且定长的uint或bytes32数组必须位于待编码参数的最后一个位置。

原因很明显,如果定长的数据没有位于最后一个待编码参数位置,那么对后一内存位置的置0不会有任何影响,因为下个编码参数会覆盖该位置。如果定长数据前面没有数据需要被存储到tail部分,那么即便后一内存位置被置0也没有关系,因为该位置并不背ABI编码使用。

另外,需要注意的是,所有的隐式或显示的ABI操作,以及符合格式的所有Tuple,都会受到该漏洞的影响。

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

event

error

abi.encode*

returns//thereturnoffunction

struct//theuserdefinedstruct

allexternalcall

解决方案

当合约代码中存在上诉受影响的操作时,保证最后一个参数不为定长的uint或bytes32数组

使用不受漏洞影响的Solidity编译器

寻求专业的安全人员的帮助,对合约进行专业的安全审计

关于我们

AtEoceneResearch,weprovidetheinsightsofintentionsandsecuritybehindeverythingyouknowordon'tknowofblockchain,andempowereveryindividualandorganizationtoanswercomplexquestionswehadn'tevendreamedofbackthen.

Learnmore:Website|Medium|Twitter

标签:SOLSOLIDDITLIDSolyard FinanceSOLID币BITCOIN ADDITIONALMOSOLID

SOL热门资讯
TRO:波场版稳定币本周日均转账额超126亿美元-ODAILY

据区块链浏览器TRONSCAN数据,过去一周,波场版稳定币日均转账额为12,619,283,327美元,超过126亿美元.

1900/1/1 0:00:00
SPACE:一文梳理ParaSpace“内斗”大戏始末

今日下午,多位KOL纷纷发文预警NFT借贷协议ParaSpace团队内部出现矛盾,并建议用户尽快撤资,此事在社区内速发酵,大量用户出于恐慌纷纷顶着高额gas从ParaSpace内撤出资金.

1900/1/1 0:00:00
MAR:沃尔玛或将区块链技术应用于物流,解决配送的“身份验证”问题

当地时间周四,美国专利商标局(USPTO)公布了去年10月沃尔玛提交的专利申请文件。文件透露,通过区块链技术连接的自动送货车,将在沃尔玛的物流配送中落地应用.

1900/1/1 0:00:00
GOO:为吸引区块链人才,谷歌前员工创立xGoogler区块链联盟

据PRNewswire报道,三位前谷歌员工组建了xGoogler区块链联盟,这一社区将成为从业者进行区块链技术探索、开展对话的开放环境,能够汇集现任和前任谷歌员工分享想法并在区块链领域开展合作.

1900/1/1 0:00:00
MEME:Meme币和BRC-20外,近期还有这四件事值得关注-ODAILY

本文原作者:@EasyEatsBodega,经Odaily星球日报littlebear编译在一些硬核开发者的眼中,近期的Web3世界可以说是乏善可陈.

1900/1/1 0:00:00
WEB:去中心化存储,值得关注的问题与成功用例-ODAILY

去中心化存储,是近年来Web3发展的关注热点之一。去中心化存储以安全、可靠和反审查的方式实现对数据的存储和管理,这可能彻底改变各种行业和应用程序的运作方式.

1900/1/1 0:00:00