Skip to content

Rooch validator network Shutdown: OOM caused by load a malicious module

High
jolestar published GHSA-xfmq-crqf-429m Nov 22, 2024

Package

moveos

Affected versions

<0.8.0

Patched versions

None

Description

Summary

This vulnerability allows an attacker to attack all validators in the network by sending a Tx, occupying a large amount of memory and causing the validator to trigger out of memory exception, and be killed by the OS.

The exploit can lead to a total network shutdown, making the entire network unable to confirm new transactions.

We recommend keeping the information private to avoid attracting any unwanted attention from malicious actors.

Details

Reproduced on

  • main branch (7567703)
    Affected Module:
    moveos

In Rooch move, when executing a function call in Tx, if the callee module is not in ModuleCache, add_module will be called to load the target module in memory. During the module loading process, a malicious module can consume a large amount of memory, due to inadequate restrictions on module complexity enforced by Rooch.

// language/move-vm/runtime/src/loader.rs
        for (idx, func) in module.function_defs().iter().enumerate() {
	// …
            function.parameter_types = function
                .parameters
                .0
                .iter()
                .map(|tok| self.make_type_while_loading(module, tok))
                .collect::<PartialVMResult<Vec<_>>>()
                .map_err(|err| err.finish(Location::Undefined))?;
            self.functions.push(Arc::new(function));
        }

Please note that there might be other payload constructions to achieve similar impact and consume even more memory.

Once an attacker exploits this vulnerability to send a malicious transaction and successfully attacks the validator, the entire validator network will be shut down, because the transaction will be broadcasted in the network.

PoC

Server-side setup

rooch server start

Attack-side

Due to the default toolchain limitations, we constructed the malformed payload at the binary level (in the attached poc.mv file). The poc.mv file can be downloaded directly from this Google Drive link.

To successfully reproduce the attack, please use your own way to directly submit the malformed binary payload to the blockchain. Based on our own experience, this can be easily achieved by replacing the poc.mv file by slightly modifying the client.

You can also inspect the deserialized CompiledModule of poc.mv for more information about our construction of the attacking payload.

  1. Publish the poc.mv as a fresh module on the blockchain, e.g. <address>::M.
    We do not compile the poc.mv from the source code, but directly construct the binary file

  2. Call the function f0 in <address>::M

rooch move run --function <address>::M::f0

This Tx will take up more than 16 GB of memory.

Impact

An attacker can carefully construct a malicious module and send a Tx to attack all validators in the network, occupying a large amount of memory and triggering Out of memory. An attacker only needs to send one transaction to attack all validators.

The exploit can lead to a total network shutdown, making the entire network unable to confirm new transactions.

Severity

High

CVE ID

No known CVE

Weaknesses

Credits