#39355 [BC-Critical] tricking legit node to sign their own apoptosis request payload

#39355 [BC-Critical] Tricking Legit node to sign their own apoptosis request payload

Submitted on Jan 28th 2025 at 11:28:53 UTC by @ZhouWu for Audit Comp | Shardeum: Core III

  • Report ID: #39355

  • Report Type: Blockchain/DLT

  • Report severity: Critical

  • Target: https://github.com/shardeum/shardeum/tree/bugbounty

  • Impacts:

    • Network not being able to confirm new transactions (total network shutdown)

Description

Description

The gist of the vulnearbility is legit node are blindly signing the payload send by another active validator which in the case of malicious node it'll conceal malicious properties along with legitimate infromation for sign_app_data endpoint and legit node will sign it. Due to this we obtain the legitimate signature for the victim node and later malicious node can use this signature to kill the vicitim node via apoptosis gossip. The other legit node in the network will follow through because the signature is legitimately sign by the victim.

This exploit is almost identtical to this report in shardeum CORE 1 program. The shardeum team has attempted to fix this issue adding AJV validation and custom binary serializationi protocol. However, these fixes are incomplete and does not cover all type of payload. In such cases the code fallback to just stringifying/ parsing all the properties in the payload. Such that shardeum team fixes for this attack is not workingand the attack is still possible.

Shardeum's code failure to serialize/deserialize the payload

Shardus's code failure to serialize/deserialize the strict payload

Impact

The attack can cause total network shutdown by killing all the node one by one. Or just killing the competition node that malicious operator have competition with.

Proof of Concept

Proof of Concept

The attack flow will be like this there will be a legitimate nodes in the network, almost all of them are staked already. We will need to use queryCertificateHandler() from malicious node to let legit node sign the payload. In the payload malicious node will put extra properties in it along with legitimate staking information about malicious node. The nature of the sign_app_data is legit node will sign the staking info and give it back to the requester in this case malicious node. Such that we'll be working staking information that mean in your local test node will have to be staked yourself to simulate mainnet. So that's why genesis account is added. In the real world live attack to live network this is not necessary at all.

  1. Please apply this patch to legitimate node to the shardeum repo

  1. Run the network with about 10 legit node and wait for it to all go active

  2. let's work on malicious node

  3. Please apply this patch to the core repo of the malicious node

  1. Please apply the following patch the shardeum repo of the malicious node

  1. In the malicious node core please compile and ready to be linked to the malicious shardeum repo

  2. Link the malicious shardeum repo to the malicious core repo

  3. Run the malicious node by doing npm run compile; node dist/src/index.js

  4. Let's Stake the malicious node

  5. Please create a directory to host our staking tool code by doing mkdir staking-tool and go into the directory by doing cd staking-tool

  6. And create a file called index.js and paste the following code

  1. Create package.json file and paste the following code. After that install the dep by doing npm i

  1. Make sure your rpc server is running at port 8080 in the same machine as staking script.

  2. Stake your malicious node by doing node index.js [your malicious node publicKey]. Important to make sure it's your malicious node's publicKey

  3. Wait for the malicious node to go active. Please wait until 2-3 cycles after malicious node is active.

  4. We can start the exploit by calling the malicious node http://0.0.0.0:1338/murder/[victimeNodeId]

  5. Wait for a cycle to see that node kill itself.

Was this helpful?