Return-Path: Received: from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136]) by lists.linuxfoundation.org (Postfix) with ESMTP id B2824C0032; Tue, 17 Oct 2023 18:35:06 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 71290613EF; Tue, 17 Oct 2023 18:35:06 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org 71290613EF Authentication-Results: smtp3.osuosl.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=jTEFNoP8 X-Virus-Scanned: amavisd-new at osuosl.org X-Spam-Flag: NO X-Spam-Score: -2.098 X-Spam-Level: X-Spam-Status: No, score=-2.098 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001] autolearn=ham autolearn_force=no Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id SKvrXBHiA65i; Tue, 17 Oct 2023 18:35:04 +0000 (UTC) Received: from mail-io1-xd36.google.com (mail-io1-xd36.google.com [IPv6:2607:f8b0:4864:20::d36]) by smtp3.osuosl.org (Postfix) with ESMTPS id 52EB9613D7; Tue, 17 Oct 2023 18:35:04 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org 52EB9613D7 Received: by mail-io1-xd36.google.com with SMTP id ca18e2360f4ac-79f9acc857cso216159839f.2; Tue, 17 Oct 2023 11:35:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1697567703; x=1698172503; darn=lists.linuxfoundation.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=Vmzl/6LUF5jOPFXTaWppJwarQcnTEBT2dGdn4evdWmM=; b=jTEFNoP8V8Fzi4Mu45TzA/8HdjMQFbQPesqPPj0hGrcr5qi078KveaZKeo9/V/OuU9 wZLPyLapnIApvZf56I7/+I8F4Bu7GSS8p7VQfyh7+0kg7hfj+EamfSOjKMeZcAQYM9Ly Iib+ZjAJ7rV1NH+JCxbBZMaCU84FugJ8Y89jVUI5qcQoxGjpHes6oMhgdDrju+u4z18e lybgV6UN6sk74sdupJqmUaVczIJa0Qdo1l2Qg3S/LSv3nesytbiEBlRmQH/aost9dRSU FFNXzZP9h4LDOkLn1cz2bA7UmtxMTNYudyKW3U7ha368aQGIuAcQqAoffp3Ljx72d/dr EDEg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697567703; x=1698172503; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=Vmzl/6LUF5jOPFXTaWppJwarQcnTEBT2dGdn4evdWmM=; b=Y07yjdg7UeMSGkKgFDUu3vidR9GCoG0jdbZE/t4qMdC7zLPmZW0zMmAqMeJg3OWszr 9TqxeCqnr1Lo7aVG/Qa1X5nSfHnWarNt0Czx8KvAaxTXq/cO6U01eq1MUd7nCu9Q2hvm oV9/NE0iK3u5JbAFFRu1uJidDdcQuYZlGEtzqjU8AbcYdZLnEs8IRUQfr3eJMU+QsKpt c83c+pehWhxHPwp2z+kdjc5kwz8rikKvc/BIjNdAJclI5bHTKLgN/ERGUbnJbz7+zmRy aa8AyAp8Ta5VX8vRW2ImRt1GqprHXY5yzZ0bb7saE2kNOJTUXbnsx3TyXQO7TZLWkIKi W6dg== X-Gm-Message-State: AOJu0YzbxdZheM8w1oIXfQvUDBN8cK9pnJRrxcQpCfNA6eQF5OnCUp+V yTNSFjf65jTPAoL7an2W9qcmCsH/iHeY/Y005jg= X-Google-Smtp-Source: AGHT+IH9+dx6j9PqlUQoJsOQoB0qJpFvkkUudlLJo5iQEB2b8AI6WvuvEpqxNpoCm7VW4UvGFEmy3sJMw00Jxw9Y7p4= X-Received: by 2002:a05:6e02:54e:b0:357:4509:a3c6 with SMTP id i14-20020a056e02054e00b003574509a3c6mr2958994ils.32.1697567703270; Tue, 17 Oct 2023 11:35:03 -0700 (PDT) MIME-Version: 1.0 References: <64VpLnXQLbeoc895Z9aR7C1CfH6IFxPFDrk0om-md1eqvdMczLSnhwH29T6EWCXgiGQiRqQnAYsezbvNvoPCdcfvCvp__Y8BA1ow5UwY2yQ=@protonmail.com> In-Reply-To: <64VpLnXQLbeoc895Z9aR7C1CfH6IFxPFDrk0om-md1eqvdMczLSnhwH29T6EWCXgiGQiRqQnAYsezbvNvoPCdcfvCvp__Y8BA1ow5UwY2yQ=@protonmail.com> From: Antoine Riard Date: Tue, 17 Oct 2023 19:34:52 +0100 Message-ID: To: ZmnSCPxj Content-Type: multipart/alternative; boundary="000000000000ef8adb0607edc7c2" X-Mailman-Approved-At: Wed, 18 Oct 2023 00:07:44 +0000 Cc: Bitcoin Protocol Discussion , security@ariard.me, "lightning-dev\\\\\\\\\\\\\\\\@lists.linuxfoundation.org" Subject: Re: [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" X-BeenThere: bitcoin-dev@lists.linuxfoundation.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Bitcoin Protocol Discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 17 Oct 2023 18:35:06 -0000 --000000000000ef8adb0607edc7c2 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable 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=3D=3D=3D=3DC` channel o= nchain. > 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/19d61fa8cf22a5050b51c4005603f43d72= f1efcf > At block height 144, `B` is still not able to claim the `A->B` HTLC, so `A` drops the `A=3D=3D=3D=3DB` 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=3D=3D=3D=3DC` pre-signed transactions rem= ain at the old, uncompetitive feerates. This is correct that A tries to recover the HTLC funds on the `A=3D=3D=3DB` 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 =C3=A0 11:34, ZmnSCPxj a =C3= =A9crit : > 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, > `=3D=3D` are channels): > > A =3D=3D=3D=3D=3D B =3D=3D=3D=3D=3D C > > `A` routes `A->B->C`. > > The timelocks, for example, could be: > > A->B timeelock =3D 144 > B->C timelock =3D 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=3D=3D=3D=3DC` 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=3D=3D=3D=3DB` 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=3D=3D=3D=3DB` 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=3D=3D=3D=3DC` pre-signed transactions rem= ain 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 presigne= d > 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 ol= d > 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-timeou= t > out of the way (1 transaction), while `B` has to get both HTLC-timeout an= d > 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 > --000000000000ef8adb0607edc7c2 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
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=3D=3D=3D=3DC` channel onchain.
> However, o= nchain feerates have risen and the commitment transaction and HTLC-timeout = transaction do not confirm.

This is not that t= he 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. An= d this HTLC-preimage is subsequently=C2=A0replaced itself.

> At block height 144, `B` is still not able to claim the `= A->B` HTLC, so `A` drops the `A=3D=3D=3D=3DB` channel onchain.
> A= s the fees are up-to-date, this confirms immediately and `A` is able to rec= over the HTLC funds.
> However, the feerates of the `B=3D=3D=3D=3DC` = pre-signed transactions remain at the old, uncompetitive feerates.

This is correct that A tries to recover the HTLC funds= on the `A=3D=3D=3DB` channel.

However, there is n= o 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 wit= h high feerates that CPFPs the commitment tx.
> However, it replace= s 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` b= roadcasts an HTLC-success transaction at block height 144.

However `C` broadcasts this high feerate transaction at _every blo= ck_ 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.<= /div>

Note `B` can feebump the HTLC-timeout for anchor o= utput channels thanks to sighash_single |=C2=A0anyonecanpay=C2=A0on C's= signature.

Le=C2=A0mar. 17 oct. 2023 =C3=A0=C2=A011:34, ZmnSCPxj <= ZmnSCPxj@protonmail.com> = a =C3=A9crit=C2=A0:
Good morning Antoine et al.,<= br>
Let me try to rephrase the core of the attack.

There exists these nodes on the LN (letters `A`, `B`, and `C` are nodes, `= =3D=3D` are channels):

=C2=A0 =C2=A0 A =3D=3D=3D=3D=3D B =3D=3D=3D=3D=3D C

`A` routes `A->B->C`.

The timelocks, for example, could be:

=C2=A0 =C2=A0A->B timeelock =3D 144
=C2=A0 =C2=A0B->C timelock =3D 100

The above satisfies the LN BOLT requirements, as long as `B` has a `cltv_ex= piry_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 transactio= ns --- are "stuck" at the feerate at the time.

At block height 100, `B` notices the `B->C` HTLC timelock is expired wit= hout `C` having claimed it, so `B` forces the `B=3D=3D=3D=3DC` channel onch= ain.
However, onchain feerates have risen and the commitment transaction and HTL= C-timeout transaction do not confirm.

In the mean time, `A` is still online with `B` and updates the onchain fees= of the `A=3D=3D=3D=3DB` 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=3D=3D=3D=3DB` channel onchain.
As the fees are up-to-date, this confirms immediately and `A` is able to re= cover the HTLC funds.
However, the feerates of the `B=3D=3D=3D=3DC` pre-signed transactions remai= n at the old, uncompetitive feerates.

At this point, `C` broadcasts an HTLC-success transaction with high feerate= s 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 abl= e to use the knowledge of the preimage, as its own incoming HTLC was alread= y 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:

=C2=A0 =C2=A0 (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:

=C2=A0 =C2=A0 (B && C && OP_CLTV) || (C && OP_HASH1= 60) || (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 imp= ose 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 &&am= p; C && OP_CLTV` branch, and outputs to:

=C2=A0 =C2=A0 (B && OP_CSV) || (C && revocation)

Thus, even if `B` held onto a very old revoked commitment transaction and a= ttempts to spend the timelock branch (because the `OP_CLTV` is for an old b= lockheight), it still has to contend with a new output with a *relative* ti= melock.

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 t= he HTLC-timeout transaction at the higher feerate.

However, the HTLC-success transaction in this case spends the plain `(C &am= p;& 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 transact= ions).
`C` thus requires a smaller fee to achieve a particular feerate due to havi= ng to push a smaller number of bytes compared to `B`.

Regards,
ZmnSCPxj
--000000000000ef8adb0607edc7c2--