#39678 [BC-Critical] Bypass certificate signing validation by double counting signatures due to capitalization
Was this helpful?
Was this helpful?
Submitted on Feb 4th 2025 at 18:37:25 UTC by @Blockian for
Report ID: #39678
Report Type: Blockchain/DLT
Report severity: Critical
Target: https://github.com/shardeum/shardus-core/tree/bugbounty
Impacts:
Bypassing Staking Requirements
Network not being able to confirm new transactions (total network shutdown)
Bypass stake certificate validation, allowing for non-staking nodes and network take-over
Bypass nodes removal validation, allowing to remove nodes from the network
Note: same impact as reports and but a different root cause.
The function validateClosestActiveNodeSignatures
counts unique signatures, but double counts duplicate signatures with different capitalization.
Malicious node generates a fake JoinRequest
with a fake StakingCertificate
It brute-forces StakingCertificate
fields to make sure its one of the closest nodes to the hash of the staking certificates. This is easy, as only 1 node is needed to be close.
It creates the full JoinRequest
, with multiple copies of its signature, instead of signatures from many other nodes, changing only the capitalization of the signatures.
It calls gossip-join-request
Other nodes receive the join request, and validate it using validateClosestActiveNodeSignatures
.
The validation bypasses, as the signatures are valid because capitalization is ignored.
The new node joins the network without staking.
Malicious node generates a fake RemoveCertificate
.
It fills it with multiple copies of its signature, instead of signatures from many other nodes, changing only the capitalization of the signatures.
It calls remove-by-app
gossip route.
Other nodes receive the certificate, and validate it using validateClosestActiveNodeSignatures
.
The validation bypasses, as the signatures are valid because capitalization is ignored.
The victim node is kicked from the network.
on the signatures, which ignore capitalization.
I suggest to do two think:
Ensure lowercase
on any payload on any gossip and http endpoint.
Count signers and not signatures.
I feel like my time was spent roughly 20% on researching, and 80% on trying to create POCs that match your standard or to answer question you give on the reported bugs. I believe there are more bugs to be found in the project, and that the current approach is the reason that bugs keep being found. I suggest you do an invite only competition, without defaultly requesting a POC, and only requesting one if you truly believe there is no bug. This would allow whitehats to actually uncover bugs.
Both shardeum
and core
should be on the bugbounty
branch
Apply debug-10-nodes
as stated in the docs
Apply the following patch on core:
Apply the following patch on shardeum
(obviously the logs are just for convenience)
Runhttp://NODE_EXTERNAL_IP:NODE_EXTERNAL_PORT/blockian_gossipRemoveNode/?pk=PUBLIC_KEY_OF_ACTIVE_NODE_WITHIN_YOUR_SHARD_TO_KICK
The function uses which uses ' which calls which calls on the signature which
This allows to take over the network (by kicking nodes / adding nodes) and so it critical. In addition, this is the same as and which were treated as critical.
Note: this strongly relies on infosec_us_team
's POC for so thanks to them :)