a SUI Move VM DoS vulnerability
2023-10-11 06:10:52 Author: 哆啦安全(查看原文) 阅读量:15 收藏

A stack overflow vulnerability of the SUI Move VM causes a full-node crash
Bug Description
In the SUI Move VM module, there is a vulnerability that is not fully fixed by mainnet-v1.2.1. In the "TypeLayoutBuilder" of the SUI Move VM source code, there is a denial of service vulnerability caused by a recursive function call. This vulnerability causes a fullnode to crash through stack overflow.
Brief/Intro
When a recursive function is called, and the depth of the call is not limited, it will cause stack overflow or exhaustion of resources such as cpu and memory.
Details
In SUI mainet_v1.2.1, the vulnerability that caused validators to crash has been fixed. But there is no fix for the bug that can cause full-node to crash. In the json-rpc-api of full-node, a "suix_getDynamicFieldObject" interface is exposed. This interface use "TypeLayoutBuilder" in the "move-bytecode-utils" module. "TypeLayoutBuilder" does not limit the depth of structure nesting.
In SUI move language, developers can declare structures in modules. Inside the structure, other structures of this module, structures of other packages, and structures of other modules can be nested. We now consider an attack method: define a struct A, then A nests struct B, and then B nests struct C.... Nesting continues like this. if the SUI move virtual machine uses a recursive RUST function to handle this nested relationship, the SUI move virtual machine will crash due to stack overflow.
Through testing, we found that a module can only define up to 199 structs with chained nesting relationships. But we can publish countless modules.
In this way, we have an attack idea:
1. Generate 25 (it can be more than 25) packages, each package contains 1 module
2. Each module defines 199 structs with a chain nesting relationship. The first struct in each module is nested with the last struct in the previous module.
3. Publish each package in order
4. Use json-rpc-api to call "suix_getDynamicFieldObject" in order to query the 199th structure of an object. The id of this object can be any legal or illegal value
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 will crash due to stack overflow at some point
   
Impact
At the time of writing this bug report, v1.0.0, v1.1.0, v1.1.1, v1.2.0, v1.2.1 of the mainnet branch, v1.0.0, v1.2.0, v1.3.0 of the testnet branch all have this vulnerability
Risk Breakdown
The exploitation of this vulnerability is very simple, an attack only needs to consume the gas equivalent to publishing about 6 contracts (sometimes a little more)
According to immunefi-vulnerability-severity-classification-system-v2-2, we classify its severity as High
Recommendation
When dealing with a structure nesting another structure, limit the depth of related recursive RUST functions
References
https://github.com/MystenLabs/sui/tree/mainnet/external-crates/move
bug patch:  
https://github.com/MystenLabs/sui/commit/fe8eb7e1fa647545e5b356796c826c1670e61d08
Proof of Concept
Construct a local mainnet network (I think you can ignore this step, after all you are developers of SUI )
1. Prepare 4 ubuntu machines
2. Sui and sui-node of mainnet must be installed on all 4 ubuntu machines
3. In one ubuntu machine, run the following command
     sui genesis --benchmark-ips 192.168.15.130 192.168.15.131 192.168.15.132 192.168.15.133
     The ip addresses in the parameter can be modified to the addresses of your own 4 machines
4. Copy the generated ~/.sui/sui_config/ folder to the other 3 machines
5. Each machine runs the following command to start the validator
     sui-node --config-path ~/.sui/sui_config/validator-config-0.yaml
     Among them, 0 represents the machine number, which is different for each machine
6. In a certain machine, run the following command to start a full node
     sui-node --config-path ~/.sui/sui_config/fullnode.yaml
7. ~/.sui/sui_config/benchmark.keystore corresponds to an SUI address, and there is already a certain amount of funds in this address. We can point to this address in ~/.sui/sui_config/client.yaml
Run the PoC
1. ubuntu
2. Install sui and add sui to the Path environment variable. At the same time, configure ~/.sui/sui_config/client.yaml so that it  point to an address, and there are enough SUIs in the address (10 SUIs are enough)
3. Copy the hello-world_xxxxx folder, test folder, and script.py file in the document attachment(PoC.tar.gz) to ~/Desktop
4. Run ~/Desktop/script.py
5. we will see that the the fullnode that script.py connects to will crash
6. In the ~/Desktop/test folder, we will see the Sui packages we generated in batches
Code Analysis
1. If you have any questions, you can send an email to [email protected]
 
2. See the attached "code-analysis" folder

文章来源: http://mp.weixin.qq.com/s?__biz=Mzg2NzUzNzk1Mw==&mid=2247496301&idx=1&sn=9538ba1b9e274d8feef88c00d69b442e&chksm=ceb8b723f9cf3e357900ab0cf10cece8395b36bbba29f0d20812cfb750c5c11d97fd20ba85e0&scene=0&xtrack=1#rd
如有侵权请联系:admin#unsafe.sh