[bitcoin-dev] [Lightning-dev] Full Disclosure: CVE-2023-40231 / CVE-2023-40232 / CVE-2023-40233 / CVE-2023-40234 "All your mempool are belong to us"

Undescribed Horrific Abuse, One Victim & Survivor of Many gmkarl at gmail.com
Fri Oct 20 14:31:13 PDT 2023


On 10/17/23, Antoine Riard via bitcoin-dev
<bitcoin-dev at lists.linuxfoundation.org> wrote:
> Hi Zeeman,
>
>> At block height 100, `B` notices the `B->C` HTLC timelock is expired
> without `C` having claimed it, so `B` forces the `B====C` channel onchain.
>> However, onchain feerates have risen and the commitment transaction and
> HTLC-timeout transaction do not confirm.
>
> This is not that the HTLC-timeout does not confirm. It is replaced in
> cycles by C's HTLC-preimage which is still valid after `B->C` HTLC timelock
> has expired. And this HTLC-preimage is subsequently replaced itself.
>
> See the test here:
> https://github.com/ariard/bitcoin/commit/19d61fa8cf22a5050b51c4005603f43d72f1efcf
>
>> At block height 144, `B` is still not able to claim the `A->B` HTLC, so
> `A` drops the `A====B` channel onchain.
>> As the fees are up-to-date, this confirms immediately and `A` is able to
> recover the HTLC funds.
>> However, the feerates of the `B====C` pre-signed transactions remain at
> the old, uncompetitive feerates.
>
> This is correct that A tries to recover the HTLC funds on the `A===B`
> channel.
>
> However, there is no need to consider the fee rates nor mempool congestion
> as the exploit lays on the replacement mechanism itself (in simple
> scenario).
>
>> At this point, `C` broadcasts an HTLC-success transaction with high
> feerates that CPFPs the commitment tx.
>> However, it replaces the HTLC-timeout transaction, which is at the old,
> low feerate.
>> `C` is thus able to get the value of the HTLC, but `B` is now no longer
> able to use the knowledge of the preimage, as its own incoming HTLC was
> already confirmed as claimed by `A`.
>
> This is correct that `C` broadcasts an HTLC-success transaction at block
> height 144.
>
> However `C` broadcasts this high feerate transaction at _every block_
> between blocks 100 and 144 to replace B's HTLC-timeout transaction.
>
>> Let me also explain to non-Lightning experts why HTLC-timeout is
> presigned in this case and why `B` cannot feebump it.
>
> Note `B` can feebump the HTLC-timeout for anchor output channels thanks to
> sighash_single | anyonecanpay on C's signature.
>
> Le mar. 17 oct. 2023 à 11:34, ZmnSCPxj <ZmnSCPxj at protonmail.com> a écrit :
>
>> Good morning Antoine et al.,
>>
>> Let me try to rephrase the core of the attack.
>>
>> There exists these nodes on the LN (letters `A`, `B`, and `C` are nodes,
>> `==` are channels):
>>
>>     A ===== B ===== C
>>
>> `A` routes `A->B->C`.
>>
>> The timelocks, for example, could be:
>>
>>    A->B timeelock = 144
>>    B->C timelock = 100
>>
>> The above satisfies the LN BOLT requirements, as long as `B` has a
>> `cltv_expiry_delta` of 44 or lower.
>>
>> After `B` forwards the HTLC `B->C`, C suddenly goes offline, and all the
>> signed transactions --- commitment transaction and HTLC-timeout
>> transactions --- are "stuck" at the feerate at the time.
>>
>> At block height 100, `B` notices the `B->C` HTLC timelock is expired
>> without `C` having claimed it, so `B` forces the `B====C` channel
>> onchain.
>> However, onchain feerates have risen and the commitment transaction and
>> HTLC-timeout transaction do not confirm.
>>
>> In the mean time, `A` is still online with `B` and updates the onchain
>> fees of the `A====B` channel pre-signed transactions (commitment tx and
>> HTLC-timeout tx) to the latest.
>>
>> At block height 144, `B` is still not able to claim the `A->B` HTLC, so
>> `A` drops the `A====B` channel onchain.
>> As the fees are up-to-date, this confirms immediately and `A` is able to
>> recover the HTLC funds.
>> However, the feerates of the `B====C` pre-signed transactions remain at
>> the old, uncompetitive feerates.
>>
>> At this point, `C` broadcasts an HTLC-success transaction with high
>> feerates that CPFPs the commitment tx.
>> However, it replaces the HTLC-timeout transaction, which is at the old,
>> low feerate.
>> `C` is thus able to get the value of the HTLC, but `B` is now no longer
>> able to use the knowledge of the preimage, as its own incoming HTLC was
>> already confirmed as claimed by `A`.
>>
>> Is the above restatement accurate?
>>
>> ----
>>
>> Let me also explain to non-Lightning experts why HTLC-timeout is
>> presigned
>> in this case and why `B` cannot feebump it.
>>
>> In the Poon-Dryja mechanism, the HTLCs are "infected" by the Poon-Dryja
>> penalty case, and are not plain HTLCs.
>>
>> A plain HTLC offerred by `B` to `C` would look like this:
>>
>>     (B && OP_CLTV) || (C && OP_HASH160)
>>
>> However, on the commitment transaction held by `B`, it would be infected
>> by the penalty case in this way:
>>
>>     (B && C && OP_CLTV) || (C && OP_HASH160) || (C && revocation)
>>
>> There are two changes:
>>
>> * The addition of a revocation branch `C && revocation`.
>> * The branch claimable by `B` in the "plain" HTLC (`B && OP_CLTV`) also
>> includes `C`.
>>
>> These are necessary in case `B` tries to cheat and this HTLC is on an
>> old,
>> revoked transaction.
>> If the revoked transaction is *really* old, the `OP_CLTV` would already
>> impose a timelock far in the past.
>> This means that a plain `B && OP_CLTV` branch can be claimed by `B` if it
>> retained this very old revoked transaction.
>>
>> To prevent that, `C` is added to the `B && OP_CLTV` branch.
>> We also introduce an HTLC-timeout transaction, which spends the `B && C
>> &&
>> OP_CLTV` branch, and outputs to:
>>
>>     (B && OP_CSV) || (C && revocation)
>>
>> Thus, even if `B` held onto a very old revoked commitment transaction and
>> attempts to spend the timelock branch (because the `OP_CLTV` is for an
>> old
>> blockheight), it still has to contend with a new output with a *relative*
>> timelock.
>>
>> Unfortunately, this means that the HTLC-timeout transaction is
>> pre-signed,
>> and has a specific feerate.
>> In order to change the feerate, both `B` and `C` have to agree to re-sign
>> the HTLC-timeout transaction at the higher feerate.
>>
>> However, the HTLC-success transaction in this case spends the plain `(C
>> &&
>> OP_HASH160)` branch, which only involves `C`.
>> This allows `C` to feebump the HTLC-success transaction arbitrarily even
>> if `B` does not cooperate.
>>
>> While anchor outputs can be added to the HTLC-timeout transaction as
>> well,
>> `C` has a greater advantage here due to being able to RBF the
>> HTLC-timeout
>> out of the way (1 transaction), while `B` has to get both HTLC-timeout
>> and
>> a CPFP-RBF of the anchor output of the HTLC-timeout transaction (2
>> transactions).
>> `C` thus requires a smaller fee to achieve a particular feerate due to
>> having to push a smaller number of bytes compared to `B`.
>>
>> Regards,
>> ZmnSCPxj
>>
>


More information about the cypherpunks mailing list