#41014 [BC-Low] The signer can submit multi-tx first to make the coordinator's submission fail

Submitted on Mar 9th 2025 at 13:52:17 UTC by @f4lc0n for Attackathon | Stacks II

  • Report ID: #41014

  • Report Type: Blockchain/DLT

  • Report severity: Low

  • Target: https://github.com/stacks-network/sbtc/tree/immunefi_attackaton_1.0

  • Impacts:

    • Permanent freezing of funds (fix requires hardfork)

Description

Brief/Intro

Each BTC block will have a coordinator, which is responsible for submitting all Stacks transactions and BTC transactions. The process is briefly described as follows:

  1. Coordinator broadcasts signature request

  2. Each signer broadcasts their signature

  3. After the Coordinator collects enough signatures, he submits the transaction to the Stacks or BTC network

The problem now is that since everyone can receive the broadcast message, a malicious signer can collect enough signatures and submit transactions to Stacks or the BTC network. This will cause the transaction submitted by the Coordinator to be rejected. The scenario is as follows.

  1. Coordinator broadcasts signature request

  2. Each signer broadcasts their signature

  3. The malicious signer collects enough signatures and submits the transaction to the Stacks or BTC network

  4. After the Coordinator collects enough signatures, he submits the transaction to the Stacks or BTC network, but fails.

Although this transaction will be executed successfully, it will cause all subsequent transaction submissions to fail. The PoC will use Stacks as an example to illustrate the problem.

Vulnerability Details

For Stacks transaction. Once a process_sign_request fails to execute, the wallet nonce will be reduced, which will cause all subsequent transactions to fail.

For BTC transaction. The signer/src/transaction_coordinator.rs::TxCoordinatorEventLoop::construct_and_sign_bitcoin_sbtc_transactions function code is as follows. If a sign_and_broadcast fails to execute, the function stops executing and throws an error.

Impact Details

Malicious Signers can make each BTC Block (every 10 minutes) execute only 1 Stacks transaction and 1 BTC transaction. This will almost stop the transaction on the Stacks side, because the transaction production speed on the Stacks side is likely to be greater than 1 transaction every 10 minutes.

Malicious signers can further exploit this by generating a deposits request every 10 minutes, which will completely stop the withdrawal behavior on the Stacks side. Because deposit transactions will always take precedence over withdrawal transactions. Then, some sBTC will be frozen.

References

None

Proof of Concept

Proof of Concept

  • Base on: https://github.com/stacks-network/sbtc/tree/immunefi_attackaton_1.0

  • Auditor wallet address: ST2BEV097EV2R9ZMFRMRT904QB5RFYMA0683TC111

  • Auditor wallet mnemonics: spawn knee orchard patrol merge forget dust position daring short bridge elevator attitude leopard opera appear auction limit magic hover tunnel museum quantum manual

  1. Patch docker/stacks/stacks-regtest-miner.toml. Give the auditor address some STX for testing.

  2. Add this code to signer/src/bin/pocinit.rs. On the basis of ./signers.sh demo command, it also deposited some sBTC to the auditor address for testing

  3. Add pocinit bin to signer/Cargo.toml

  4. Patch docker/docker-compose.yml, add attacker flag to sbtc-signer-3

  5. Patch signer/src/config/mod.rs, add attacker flag config

  6. Patch signer/src/main.rs, let signer load the attacker flag

  7. Patch signer/src/network/libp2p/event_loop.rs, add attack action

  8. Add this code to signer/src/bin/pocii7.rs.

  9. Add pocii7 bin to signer/Cargo.toml

  10. Run devenv and run pocinit

  11. Run pocii7. It will execute 100 deposits.

  12. Observe the logs and you will find that some transactions were rejected when submitting the Stacks transaction.

Was this helpful?