33222 - [BC - Critical] An attacker can control which nodes can and can...
Submitted on Jul 15th 2024 at 16:35:46 UTC by @infosec_us_team for Boost | Shardeum: Core
Report ID: #33222
Report type: Blockchain/DLT
Report severity: Critical
Target: https://github.com/shardeum/shardus-core/tree/dev
Impacts:
Network not being able to confirm new transactions (total network shutdown)
Direct loss of funds
Description
Background For Immunefi's Triagger
The trigger reviewing this report may not be as familiar with Shardeum's architecture and codebase as Shardeum's team itself, therefore, to facilitate their understanding of this report and its impact, we are dedicating this section to explain some important concepts of Shardus's Core.
Sharduss' team shared via the Discord Channel of this Boost their interest in preventing malicious validators from manipulating which nodes join the active set, because by doing so they could take over a sufficient percentage of a shard's voting (by having malicious or modified nodes join a shard), therefore, the attacker would own the outcome of any consensus vote and be able to create any transaction outcome desired.
The above was almost a word-by-word quote of Chris Chatbot's message: https://discord.com/channels/787092485969150012/1256211020482084987/1259779922616913940
Inspired by Shardu's concerns and request, we discovered during our research a way to kick any or all nodes from a shard, manipulating who can and cannot join a specific shard.
The impact of such actions was described above by the Shardeum's team.
Summary
During the 1st and 2nd Quarter of every cycle, the nodes of a shard can sign a vote to remove a specific node from the network.
To pass the consensus it is required a min. amount of valid signatures.
Unfortunately, the function shardus.validateClosestActiveNodeSignatures(...)
, which is used to verify the amount of signatures and their validity, does not check for duplicated signatures.
As a consequence, 1 node can Gossip a remove-by-app
request containing the same signature (his signature) repeated an unlimited amount of times, to bypass the check for the min. requirement of signers.
This results in 1 node being able to kick anyone/everyone out of his shard, keeping only his other malicious nodes.
Vulnerability Details
Below is the vulnerable function as a reference:
Code snippet from: https://github.com/shardeum/shardus-core/blob/dev/src/shardus/index.ts#L1780-L1827
As it can be seen by reading the function, there is nothing that prevents sending the same signature for the same owner multiple times, to bypass the validNodeCount >= minRequired
check.
In the Proof of Concept section we'll describe how we created a malicious node that receives an HTTP GET request with the public key of any node within his shard and kicks him out.
This can be exploited to control which nodes can join your shard, hence, manipulating your percentage of a shard's voting.
Proof of Concept
Download locally Shardus Core repo and Shardeum's repo, then point Shardeum to use the local copy of Shardu's Core.
Steps to do so are well documented in the respective repos.
Below, we'll create a way for a malicious node to Gossip the exploit to the network.
In your local copy of Shardus Core, open the file /src/shardus/index.ts
and add the following function:
In your local copy of Shardeum, open the file /src/index.ts
and add the following function:
Build Shardus Core with npm run build:dev
, build Shardeum with npm ci && npm run prepare
, and - assuming that you are using the patch for running a network of 10 active nodes - start the network with 12 nodes or more nodes using shardus start 12
In our case, it takes anywhere from 15 minutes to 25 minutes for nodes to activate. Wait until the network is running.
Then visit the following link in your browser:
Replace the placeholders PUBLIC_KEY_OF_ACTIVE_NODE_WITHIN_YOUR_SHARD_TO_KICK, NODE_EXTERNAL_IP, and NODE_EXTERNAL_PORT with the correct values.
Last updated