Skip to content

Instantly share code, notes, and snippets.

@HildisviniOttar
Last active January 1, 2022 22:04
Show Gist options
  • Save HildisviniOttar/c2478894fc849d7339b1b9619dd56309 to your computer and use it in GitHub Desktop.
Save HildisviniOttar/c2478894fc849d7339b1b9619dd56309 to your computer and use it in GitHub Desktop.

Vulnerability in utxo mempool observation

THORChain operates by delegating a large number of small transactions to nodes that each hold their own hot wallet called "Yggdrasil" that is constantly topped up.

Node operators know their Yggdrasil wallet private key. To prevent theft, the Yggdrasil wallet is monitored for outbounds and any unauthorised outbounds results in a bond fine of 1.5x stolen.

A vulnerability exists where an attacker can replace legitimate outbounds in the mempool with nefarious non-observable transactions resulting in theft from SWAP/WITHDRAW recipients (customers).

Attack

A node operator first modifies their Bifrost to send outbound transactions to support Bitcoin Replace-by-fee (RBF). This involves setting the vin sequence number (normally 0xFFFFFFFF) to 0xFFFFFFFD.

This allows the UTXO to be re-spent by the Yggdrasil owner once in the mempool.

The nefarious node operator then monitors their Yggdrasil outbounds using a mempool scanner. These are also observed by all Bifrosts as a legitimate outbound and as far as the network is concerned, THORChain has done its job.

The nefarious node operator then re-broadcasts another tx re-spending the UTXO, but to attackers address, in a format that is unrecognisable by Bifrost (completely skipped). For example with greater than 4 vout.

For example:

Legitimate Yggdrasil outbound

vin (1 BTC)   --> 0.5 btc customer
<RBF>         --> 0.5 btc change to Yggdrasil

Observed in mempool.

Attacker re-broadcasts:

vin (1 BTC)   --> 0.1 BTC attacker, 
<RBF>         --> 0.1 BTC attacker,
              --> 0.1 BTC attacker,
              --> 0.1 BTC attacker,
              --> 0.1 BTC attacker,
              --> 0.5 BTC change,

This is not observed by any Bifrost and results in the customer not receiving their payment. Yggdrasil vault remains fully solvent.

This is a silent crime; nothing can stop it until the customer complaints are loud enough to be investigated and trading is halted.

Fix

In Bifrost client.go it should ignore any outbound tx from a Ygg vault where any vin.sequence is not exactly 0xFFFFFFFF. It should allow inbound tx to have RBF which many wallets support.

https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki

Explicit signaling: A transaction is considered to have 
opted in to allowing replacement of itself if any of its 
inputs have an nSequence number less than (0xffffffff - 1).

Damage / Difficulty

Medium - need a custom Bifrost, and tool to scan utxo and re-broadcast. Also need 300,000 RUNE to BOND in to become an active validator (~$2-3m).

If 24h BTC volume is $20m, and there is 40 nodes, each Ygg could be transacting up to $500k volume per day, or $20k/hr.
A clever attacker would begin the attack with a large Yggdrasil out command (e.g. $50-100k), then continue until enough complaints shut down the network. It could be operational for 1-6 hours I think.

@HildisviniOttar
Copy link
Author

This is fully patched in 0.64.0 so releasing to public

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment