"Memory Bomb" Vulnerability Causes Sui Node to Crash

user-image
BEOSIN
BEOSIN
Sep 12, 2023

"Memory Bomb" Vulnerability Causes Sui Node to Crash

 

This vulnerability has now been fixed by the official team. Sui mainnet_v1.6.3 (August 1, 2023) has addressed this vulnerability.

 

 

Background

Previously, our team discovered several vulnerabilities related to public blockchains. One of them was particularly interesting, so we are publicly disclosing the details. It is a denial of service vulnerability in the Sui blockchain's p2p protocol that could cause nodes in the Sui network to crash due to memory exhaustion. This denial of service vulnerability was caused by an old attack technique - the "memory bomb".

 

Through an introduction to this vulnerability, we hope to raise awareness and understanding of "memory bomb" attacks and defenses against them. As a leading blockchain security company, Beosin continuously monitors the security of public blockchain platforms.

 

 

Memory Bomb

The earliest memory bomb was the zip bomb, also called the zip of death, which is a malicious computer file designed to crash or incapacitate programs that read it. A zip bomb does not hijack the operation of a program, but exploits the time, disk space, or memory required to unzip a compressed file. See wikipedia--Zip_bomb

 

An example of a zip bomb is the file 42.zip, which is a 42KB zip file containing 16 nested zip files 5 levels deep, each bottom-level archive containing a 4.3 GB (4,294,967,295 bytes; 4 GiB - 1 B) file for a total of 4.5 PB (4,503,599,626,321,920 bytes; 4 PiB - 1 MiB) of uncompressed data.

 

The basic principle of a zip bomb is that we generate a very large file filled with 0s (or other values), then compress it into a zip file. Due to the high compression ratio for files with the same content, the resulting zip file is very small. When the victim decompresses the zip file, it needs to consume a huge amount of memory to store the decompressed file, quickly exhausting available memory and causing the target to crash from an out of memory error.

 

We can do a simple demo of this on Windows:

 

 

1. We can generate a 1GB file filled with 0s using the following command:

We can generate a 1GB file filled with 0s using the following command:

2. We can compress the file into a zip using 7zip:

We can compress the file into a zip using 7zip:

3. The compressed file size is: 1.20 MB

 

From this we can see the compression ratio for a file of all 0s using zip is close to 851:1

 

In fact, any compression format can potentially become a memory bomb, not just zip files.

 

We can continue the experiment by compressing the 1GB file filled with 0s into different formats using 7zip on Windows. This gives us the following compression ratios:

We can continue the experiment by compressing the 1GB file filled with 0s into different formats using 7zip on Windows.

Different file formats support different compression algorithms. For example, zip files can use Deflate, Deflate64, BZIP2, LZMA, PPMd etc., each with different compression ratios. The above table shows test results using the default algorithm for 7zip.

 

We can defend against "memory bomb" attacks by limiting the decompressed file size. The following methods can restrict the decompressed size:

 

  1. Include the decompressed data size in the archive. Read this value from the compressed file and check if the size meets requirements.
  2. The first method can't fully solve the problem, since the decompressed size can be spoofed. So we can pass a fixed size buffer for decompression. If the data exceeds the buffer boundary during decompression, stop and return a failure.
  3. Another approach is streaming decompression. Pass small chunks of the compressed data, decompressing each chunk and accumulating the decompressed size. If the size exceeds a threshold at any point, stop and return a failure.

 

Historical "Memory Bomb" Vulnerabilities:

  1. CVE-2023-3782

This was a vulnerability in the OKHttp library. OKHttp supports the Brotli compression algorithm. If an HTTP response specified Brotli compression, due to lack of defenses against "memory bomb" attacks in OKHttp, the client could crash from memory exhaustion.

 

Vulnerability description:

https://github.com/square/okhttp/issues/7738

 

Vulnerability fix:

https://github.com/envoyproxy/envoy/commit/d4c39e635603e2f23e1e08ddecf5a5fb5a706338#diff-88b327a1e72d55d1bb686b3b1f28f594b6b08139968304e6804a808fbb375ff0R26

 

We can see the vulnerability fix limits the compression ratio.

 

We can see the vulnerability fix limits the compression ratio.

 

2. CVE-2022-36114

This was a vulnerability in the Rust package manager Cargo. When downloading packages from source code repositories, Cargo did not have defenses against “memory bomb” zip files, allowing maliciously crafted zips to fill up disk space during extraction.

 

Vulnerability description:

https://github.com/rust-lang/cargo/security/advisories/GHSA-2hvr-h6gw-qrxp

 

Vulnerability fix:

https://github.com/rust-lang/cargo/commit/d1f9553c825f6d7481453be8d58d0e7f117988a7

 

As we can see, the vulnerability fix limits the decompressed file size to a maximum of 512 MB.

 

As we can see, the vulnerability fix limits the decompressed file size to a maximum of 512 MB.

 

 

3. CVE-2022-32206

This was a vulnerability in the popular network tool curl. The versions curl < 7.84.0 supported "chain" HTTP compression, meaning the server response could be compressed multiple times, possibly using different algorithms. The number of accepted "links" in this "decompression chain" was unlimited, allowing a malicious server to insert nearly unlimited compression steps. Using such a decompression chain could result in a "memory bomb", causing curl to ultimately spend huge amounts of memory and error due to insufficient memory.

 

Vulnerability details:

https://lists.debian.org/debian-lts-announce/2022/08/msg00017.html

 

 

Sui Vulnerability Description

1. In Sui's p2p protocol, some RPC messages are compressed with the snappy algorithm to reduce bandwidth pressure.

 

2. Every Sui node (validator or fullnode) provides node discovery ("/sui.Discovery/GetKnownPeers") and data sync ("/sui.StateSync/PushCheckpointSummary") RPC services in the p2p network. The node discovery and data sync RPC messages are actually snappy compressed data. During RPC message processing, the node first decompresses the data entirely into memory, then deserializes with the bcs algorithm, and finally releases the decompressed data and original data. The RPC data processing code is in the "crates/mysten-network/src/codec.rs" file.

 

Every Sui node (validator or fullnode) provides node discovery

 

3. The maximum size for RPC messages is hardcoded to 2G in the "crates/sui-node/src/lib.rs" file.

 

The maximum size for RPC messages is hardcoded to 2G in the "crates/sui-node/src/lib.rs" file.

 

4. We can create a 1.97G snappy compressed file that decompresses to 42 G, with all file content as 0s.

 

5. We choose the "/sui.Discovery/GetKnownPeers" p2p RPC as the target interface, and send a 1.97G RPC message to it. The node then needs at least 42 + 1.97 = 43.97G of memory to decompress this message.

 

6. If the Sui node (validator or fullnode) has >43.97G of available memory, we can send n RPC messages simultaneously, so that at some point the sui node needs m (usually m < n) * 43.97G memory to process our attack payloads.

 

7. If memory is insufficient, the sui node will crash.

 

Here are the test results:

 

We can see the node was killed by the system due to "Out of memory".

 

We can see the node was killed by the system due to "Out of memory".

 

 

PoC

1. Creating a "memory bomb" based on the snappy algorithm:

 

Creating a "memory bomb" based on the snappy algorithm:

 

2. Attacking the node:

 

Attacking the node:

 

Code Analysis of the Patch

Patch link:

https://github.com/MystenLabs/sui/commit/42d4ad103a21d23fecd7c0271453da41604e71e9

 

We can see the patch code utilizes streaming decompression, and limits the maximum decompressed size to 1G. It also reduces the RPC message size limit from 2G to 1G.

We can see the patch code utilizes streaming decompression, and limits the maximum decompressed size to 1G. It also reduces the RPC message size limit from 2G to 1G.

 

Vulnerability Impact

This vulnerability could cause individual nodes (validators and fullnodes) to crash. Exploiting it is very simple - just start multiple threads sending payloads to the node to trigger a crash, without needing to spend any gas fees. Versions before Sui mainnet_v1.6.3 (excluding) are affected.

 

Vulnerability Fix

Sui mainnet_v1.6.3 (August 1, 2023) has addressed this vulnerability.



Original Link

주의사항
본 글에 기재된 내용들은 작성자 본인의 의견을 정확하게 반영하고 있으며 외부의 부당한 압력이나 간섭 없이 작성되었음을 확인합니다. 작성된 내용은 작성자 본인의 견해이며, (주)크로스앵글의 공식 입장이나 의견을 대변하지 않습니다. 본 글은 정보 제공을 목적으로 배포되는 자료입니다. 본 글은 투자 자문이나 투자권유에 해당하지 않습니다. 별도로 명시되지 않은 경우, 투자 및 투자전략, 또는 기타 상품이나 서비스 사용에 대한 결정 및 책임은 사용자에게 있으며 투자 목적, 개인적 상황, 재정적 상황을 고려하여 투자 결정은 사용자 본인이 직접 해야 합니다. 보다 자세한 내용은 금융관련 전문가를 통해 확인하십시오. 과거 수익률이나 전망이 반드시 미래의 수익률을 보장하지 않습니다.
본 제작 자료 및 콘텐츠에 대한 저작권은 자사 또는 제휴 파트너에게 있으며, 저작권에 위배되는 편집이나 무단 복제 및 무단 전재, 재배포 시 사전 경고 없이 형사고발 조치됨을 알려드립니다.