SUI公链Move虚拟机模块的栈溢出漏洞导致全节点崩溃
在SUI Move虚拟机模块里面,有一个未被mainnet-v1.2.1的完全修复的漏洞。在SUI Move虚拟机源码的TypeLayoutBuilder里面,有一个由递归函数调用导致的拒绝服务漏洞,该漏洞通过栈溢出导致fullnode崩溃。
递归函数调用的时候,如果没有限制调用深度,会导致栈溢出或者cpu、内存等资源的耗尽
在SUI mainet v1.2.1里面,已经修复了导致validator崩溃的漏洞。但是没有修复能导致full-node崩溃的漏洞。在full-node的json-rpc-api里面,暴漏了一个"suix_getDynamicFieldObject"的接口。这个接口里面会调用move-bytecode-utils模块里面的TypeLayoutBuilder,TypeLayoutBuilder没有对结构体嵌套的深度做限制。
在SUI move里面,开发者可以在module里面声明struct。struct内部嵌套本module的其他struct、其他package的struct、其他module的struct。我们现在考虑一种攻击方式:定义一个struct A,然后A嵌套struct B,然后B嵌套struct C....这样一直嵌套下去,如果SUI move虚拟机是用一个递归函数来处理这种嵌套关系,那么SUI move虚拟机会因为栈溢出或者资源不足而崩溃。
通过测试,我们发现一个module里面可以定义199个有链式嵌套关系的struct。但是我们可以publish无数个module。
1.生成25个(完全可以比25多)package,每个package包含1个module
2.每个module里面定义199个有链式嵌套关系的struct,每个module里的第一个struct,嵌套上一个module里面的最后一个struct。
4.按照顺序用json-rpc-api调用"suix_getDynamicFieldObject",查询某个object的第199个结构体。这个object的id可以写成任意合法或非法的值
curl --location --request POST 'http://127.0.0.1:9000'
--header 'Content-Type: application/json'
--data-raw '
{
"jsonrpc": "2.0",
"id": 1,
"method": "suix_getDynamicFieldObject",
"params": [
"0xc8359b6b5e3bfeab524e5edaad3a204b4053745b2d45d1f00cd8d24e5b697607",
{
"type": "package_id::hello::T_198",
"value": "xyz"
}
]
}'
5.full-node会在某个时间点因为栈溢出而崩溃
mainnet分支的v1.0.0、v1.1.0、v1.1.1、v1.2.1,testnet分支的v1.0.0、v1.1.0、v1.1.1、v1.2.0、v1.3.0,都有此漏洞
这个漏洞利用非常简单,一次攻击只需要消耗相当于发布6个(有时候会多一点)左右合约的gas
根据immunefi-vulnerability-severity-classification-system-v2-2,我们将其严重等级划分为High
在处理一个结构体引用另外一个结构体的时候,对相关递归函数的深度做限制
https://github.com/MystenLabs/sui/tree/mainnet/external-crates/move
https://github.com/MystenLabs/sui/commit/fe8eb7e1fa647545e5b356796c826c1670e61d08
2.4个ubuntu机器都要安装mainnet的sui和sui-node
sui genesis --benchmark-ips 192.168.15.130 192.168.15.131 192.168.15.132 192.168.15.133
参数里面的ip地址可以修改为你自己的4个机器的地址
4.将生成的~/.sui/sui_config/文件夹复制到其他3个机器上
5.每个机器都运行如下命令,启动validator
sui-node --config-path ~/.sui/sui_config/validator-config-0.yaml
sui-node --config-path ~/.sui/sui_config/fullnode.yaml
7.~/.sui/sui_config/benchmark.keystore对应一个address,这个address里面已经有了一定的资金。我们可以在client.yaml里面指向这个地址
2.安装sui,并将sui添加到Path环境变量。同时要配置sui的client.yaml,使其有一个address,address里面有足够的SUI(10 SUI完全够用)
3.将附件里面的hello-world_xxxxx文件夹、test文件夹、script.py文件,复制到~/Desktop
5.在很短一段时间后,我们将看到fullnode会崩溃
6.在~/Desktop/test文件夹里面,我们将看到我们批量生成的sui package
原文始发于微信公众号(哆啦安全):SUI公链Move虚拟机模块的栈溢出漏洞导致全节点崩溃
评论