/ home / newsletters /
Zpravodaj „Bitcoin Optech” č. 274
Tento týden přinášíme popis replacement cycling útoku na HTLC používané v
LN i jiných systémech, zkoumáme opatření nasazená proti tomuto útoku a
vypisujeme návrhy na další možná opatření. Dále popisujeme významnou chybu
postihující Bitcoin Core RPC, výzkum kovenantů vyžadujících pouze minimální
změny bitcoinového Scriptu a návrh BIPu na opkód OP_CAT
. Též nechybí naše
pravidelná měsíční rubrika se souhrnem oblíbených otázek a odpovědí z
Bitcoin Stack Exchange.
Novinky
-
● Zranitelnost replacement cycling postihující HTLC: Jak bylo krátce zmíněno v minulém čísle zpravodaje, zaslal Antoine Riard do emailových skupin Bitcoin-Dev a Lightning-Dev příspěvek popisující zodpovědně nahlášenou zranitelnost postihující starší verze všech implementací LN. V době od nahlášení byla do implementací přidána opatření před útokem, důrazně doporučujeme aktualizovat vámi používaný LN software na poslední verzi. Postiženy jsou pouze uzly přeposílající platby; uzly používané pouze pro zahajování či přijímání plateb postiženy nejsou.
Náš popis této zranitelnosti je rozdělen do tří částí: samotný popis zranitelnosti (tento bod), popis opatření dosud nasazených implementacemi LN a souhrn dodatečných opatření a řešení navržených v emailové skupině.
Pro připomenutí: je možné využít nahrazování transakcí k odstranění jednoho či více vstupů transakce (mající více vstupů) z mempoolu. Mějme jednoduchý příklad, drobně odlišný od původního Riardova popisu: Mallory zveřejní transakci se dvěma vstupy, které utrácí výstupy A a B. Potom nahradí tuto transakci alternativní verzi s jediným vstupem, který utrácí pouze výstup B. Po tomto nahrazení je vstup A (a všechna související data) odstraněn z mempoolů, které toto nahrazení zpracovaly.
Ač není tento postup pro běžnou peněženku bezpečný1, je to chování, kterého může Mallory zneužít k odstranění vstupu z mempoolů.
Konkrétně sdílí-li Mallory kontrolu nad výstupem s Bobem, může počkat, až Bob výstup utratí, poté může nahradit jeho utracení svým vlastním, které obsahuje dodatečný vstup, a nato může nahradit své utracení transakcí, která společný výstup již neutrácí. A právě toto je replacement cycle („cyklus nahrazování“). Těžaři sice obdrží od Mallory transakční poplatky, ale s velkou pravděpodobností nebude Bobovo ani Mallořino utracení výstupu během krátké doby od zveřejnění potvrzeno.
To je důležité v případě LN a několika dalších protokolů, protože určité transakce se musí objevit během určitého časového okna, aby bylo zajištěno, že uživatelé přeposílající platby nepřijdou o peníze. Příklad: Mallory použije jeden ze svých uzlů (nazývejme ho MalloryA) pro přeposlání platby Bobovi a Bob přepošle tuto platbu dalšímu z Mallořiných uzlů (MalloryB). Od MalloryB se očekává, že buď poskytne Bobovi předobraz (který mu umožní obdržet přeposlanou platbu od MalloryA) nebo přeposílanou platbu od Boba během určité doby zruší (revokuje). Namísto toho ale MalloryB během určené doby nic neudělá, a Bob je tak donucen zavřít kanál a zveřejnit transakci, která by mu zpět poslala tuto přeposílanou platbu. Tato transakce by měla být ihned potvrzena, aby tím mohl Bob zrušit (revokovat) platbu od MalloryA, čímž by se zůstatek každého účastníka vrátil do stavu před pokusem o přeposlání platby (kromě transakčních poplatků za zavření a urovnání kanálu mezi Bobem a MalloryB).
Druhou možností je, že Bob kanál zavře a pokusí se utratit přeposílanou platbu zpět sobě. MalloryB toto utracení nahradí svým vlastním a tím odhalí předobraz. Je-li tato transakce včas potvrzena, může Bob pomocí tohoto předobrazu nárokovat platbu od MalloryA. Bob by tak byl spokojen.
Pokud však MalloryB nahradí Bobovu transakci svou vlastní transakcí, která obsahuje předobraz, a nato rychle ten vstup odstraní, je nepravděpodobné, že by se Bobova transakce i předobraz MalloryB objevily na blockchainu. Bob by tak nedostal od MalloryB své peníze zpět. Bez předobrazu by nebyl Bob schopen držet přeposílanou platbu od MalloryA, musel by ji tedy refundovat. V tento okamžik by mohla MalloryB zveřejnit a nechat potvrdit transakci s předobrazem, což by jí umožnilo nárokovat přeposílanou platbu od Boba. Byla-li by přeposílaná částka x, MalloryA by nezaplatila nic, MalloryB by obdržela x a Bob by o x přišel (různé poplatky nejsou zahrnuty).
Aby byl útok výnosný, musí MalloryB sdílet s Bobem kanál, ale MalloryA může být kdekoliv na cestě k Bobovi, například:
MalloryA -> X -> Y -> Z -> Bob -> MalloryB
Replacement cycling má pro LN uzly podobné důsledky jako transaction pinning útoky. Avšak techniky jako přeposílání transakcí verze 3, které byly navrženy na ochranu před pinningem, jsou pro replacement cycling nedostatečné.
-
● Opatření proti replacement cycling nasazená v LN uzlech: jak popsal Antoine Riard, v LN implementacích bylo nasazeno několik opatření.
-
● Častá opakovaná zveřejňování: poté, co mempool uzlu nahradí Bobovu transakci Mallořinou a Mallořin vstup odstraní pomocí její druhé nahrazovací transakce, je tento uzel okamžitě ochoten znovu přijmout Bobovu transakci. Bob ji jen musí znovu zveřejnit, což ho bude stát stejný poplatek, jaký byl ochoten zaplatit již předtím.
Před soukromým odhalením replacement cycling útoku LN implementace opakovaně zveřejňovaly své transakce méně často, jednou za blok či méně. Zveřejňování či opakované zveřejňování transakcí obvykle přináší náklady v určité ztrátě soukromí: třetí strany mohou snáze asociovat Bobovu onchain LN aktivitu s jeho IP adresou. Jen málo veřejných LN uzlů to však v současnosti bere v potaz. Nově budou Core Lightning, Eclair, LDK i LND opakovaně zveřejňovat častěji.
Po každém Bobově opakovaném zveřejnění může Mallory opět použít stejnou techniku k nahrazení jeho transakce. Avšak pravidla nahrazení dle BIP125 budou po Mallory vyžadovat dodatečný poplatek za každé další nahrazení, čili každé další Bobovo zveřejnění snižuje Mallory ziskovost útoku.
Z toho vyplývá hrubý vzorec pro nejvyšší částku HTLC, kterou by měl uzel přijmout. Jsou-li útočníkovy náklady za každé kolo nahrazení x, počet bloků, který má obránce k dispozici, je y a počet efektivních zveřejnění, která obránce průměrně za blok učiní, je z, je HTLC pravděpodobně rozumně zabezpečené do výše kousek pod
x*y*z
. -
● Delší CLTV expiry delta: když Bob akceptuje od MalloryA HTLC, souhlasí, že jí umožní nárokovat onchain refundaci po určitém počtu bloků (řekněme 200 bloků). Když Bob nabídne ekvivalentní HTLC MalloryB, dovoluje mu nárokovat refundaci po nižším počtu bloků (řekněme 100 bloků). Tyto expirační podmínky jsou zapsány pomocí opkódu
OP_CHECKLOCKTIMEVERIFY
(CLTV), proto se rozdíl mezi nimi nazývá CLTV expiry delta.Čím delší je CLTV expiry delta, tím déle musí původní odesílatel platby čekat na návrat svých prostředků v případě selhání platby, proto odesílatelé preferují posílat platby cestami s kratšími delta. Avšak také platí, že čím delší je delta, tím více času má přeposílající uzel (jako Bob) na reakci na problémy jako transaction pinning a masové zavírání kanálů. Tyto protichůdné požadavky vedly k častým změnám v LN software v nastavení výchozích delta, viz zpravodaje čísla 40, 95, 109, 112, 142 (vše angl.), 248 a 255.
V případě replacement cycling útoku dává Bobovi delší CLTV delta více možností opakovaného zveřejnění, což zvyšuje náklady útoku podle výše zmíněného vzorce.
Navíc pokaždé, když je Bobova opakovaně zveřejněná transakce v mempoolu těžaře, existuje šance, že ji těžař vybere do šablony bloku, kterou poté vytěží. Tím by byl útok zmařen. Mallořino úvodní nahrazení s předobrazem by též mohlo být vytěženo před tím, než by měla možnost jej nahradit. I toto by útok překazilo. Stráví-li v každém cyklu tyto dvě transakce určitou dobu v těžařově mempoolu, každé Bobovo opakované zveřejnění tuto dobu násobí, stejně jako ji dále násobí CLTV expiry delta.
Například i když tyto transakce stráví v mempoolu průměrného těžaře pouze 1 % času na blok, existuje zhruba 50% šance, že útok selže, je-li CLTV expiry delta jen 70 bloků. Následující graf ukazuje pravděpodobnost selhání Mallořina útoku za použití současných výchozích hodnot CLTV expiry delta v různých LN implementacích vypsaných v Riardově emailu. Předpokladem je, že očekávané HTLC transakce jsou v mempoolech těžařů 0,1 % času, 1 % času nebo 5 % času. Pro referenci: je-li průměrný čas mezi bloky 600 sekund, odpovídají tato procenta pouhým 0,6 sekundám, 6 sekundám a 30 sekundám z každých 10 minut.
-
● Skenování mempoolu: design HTLC dává Mallory podnět, aby nechala potvrdit transakci s předobrazem před tím, než může Bob nárokovat refundaci. Pro Boba je to praktické: blockchain je široce dostupný a jeho velikost omezena, Bob tedy může snadno najít jakýkoliv předobraz, který se ho týká. Kdyby tento systém fungoval podle záměru, Bob by mohl z blockchainu získat všechny informace potřebné pro provoz LN.
Bohužel, replacement cycling znamená, že Mallory již nemusí být motivována k potvrzení své transakce před Bobovým nárokováním refundace. Ale aby mohla Mallory zahájit replacement cycle, musí krátce odhalit předobraz v rámci mempoolů těžařů, chce-li nahradit Bobovu transakci. Pokud Bob provozuje přeposílající plný uzel, Mallořina transakce s předobrazem může procházet i Bobovým uzlem. Pokud by Bob včas detekoval předobraz, útok by odrazil a Mallory by ztratila všechny peníze, které během pokusu o útok utratila.
Skenování mempoolu není všemocné: neexistuje záruka, že Mallořina nahrazující transakce proteče Bobovým uzlem. Avšak čím častěji Bob opakovaně zveřejňuje svou transakci (viz častá opakovaná zveřejňování) a čím déle musí Mallory před Bobem skrývat svůj předobraz (viz delší CLTV expiry delta), tím pravděpodobnější je, že se jedna z transakcí s předobrazem včas dostane do Bobova mempoolu.
Eclair a LND v současnosti implementují skenování mempoolu u přeposílajících uzlů.
-
● Diskuze o účinnosti opatření: Riard v úvodním oznámení napsal: „Věřím, že replacement cycling útoky jsou pro schopné útočníky nadále praktické.” Matto Corallo napsal, že „nasazená opatření problém neodstraňují; lze argumentovat, že neposkytují víc než pouhé PR vyjádření.” Olaoluwa Osuntokun polemizoval: „[podle mého názoru] se jedná spíše o vratký druh útoku, který vyžaduje určité aranžmá jednotlivých uzlů, extrémně přesné načasování a provedení, nepotvrzující postavení všech transakcí a okamžitou propagaci celou sítí.”
My v Optechu si myslíme, že je důležité znovu zdůraznit, že tento útok postihuje pouze přeposílající uzly. Přeposílající uzel je bitcoinová horká peněženka neustále připojená k internetu. Jedná se o druh nasazení, který je neustále jednu zranitelnost od ztráty všech prostředků. Každý, kdo vyhodnocuje dopad replacement cyclingu na rizikovost provozu přeposílajícího LN uzlu, by tak měl činit v rámci již existujícího rizika. Pochopitelně je dobré hledat další způsoby snižování rizika. Tím se zabývá náš další bod.
-
-
● Nahrazení výpočtu hashe množiny bitcoinových UTXO: Fabian Jahr zaslal do emailové skupiny Bitcoin-Dev příspěvek s oznámením o objevení chyby v Bitcoin Core ve výpočtu hashe aktuální množiny UTXO. Výpočet hashe UTXO nebral do úvahy výšku a coinbase, které jsou nutné pro vynucování pravidel 100blokové zralosti coinbasových transakcí a relativních časových zámků dle BIP68. Všechny tyto informace zůstávají v databázi uzlu, který se synchronizuje od nuly (všechny současné Bitcoin Core uzly), a jsou nadále používané pro vynucování, takže tato chyba nepostihuje žádný známý vydaný software. Avšak experimentální assumeUTXO plánované pro příští hlavní verzi Bitcoin Core umožní uživatelům navzájem sdílet své UTXO databáze. Neúplný commitment znamená, že upravená databáze by mohla mít stejný hash jako ověřená databáze, což by mohlo otevřít úzké okno útokům proti uživatelům assumeUTXO.
Pokud víte o software, který používá pole
hash_serialized_2
, upozorněte prosím autory na tento problém a doporučte jim přečtení Jahrova emailu popisující změny, které budou v příštím hlavním vydání Bitcoin Core tuto chybu adresovat. -
● Výzkum obecných kovenantů s minimálními změnami Scriptu: Rusty Russell zaslal do emailové skupiny Bitcoin-Dev příspěvek s odkazem na svůj výzkum použití několika jednoduchých nových opkódů umožňujících skriptu spouštěnému v transakci nahlížet do výstupních skriptů, na které se platí v té stejné transakci (introspekce). Schopnost provádět introspekci výstupních skriptů (a jejich commitmentů) by umožnila implementaci kovenantů. Uvádíme některá z jeho zjištění, která pokládáme za významná:
-
● Jednoduchost: v jediném výstupním skriptu a jeho taprootovém commitmentu by bylo možné plně provádět introspekci pomocí tří nových opkódů a jednoho z dříve navrhovaných kovenantových opkódů (např. OP_TX). Každý z nových opkódů je snadno pochopitelný a jeví se jednoduše implementovatelný.
-
● Stručnost: Russellovy příklady používají pro účely introspekce kolem 30 vbytů (vynucovaný skript by byl nad rámec těchto vbytů).
-
● Změny v OP_SUCCESS by prospěly: BIP342 specifikace tapscriptu definuje několik
OP_SUCCESSx
opkódů, které úspěšně ukončí skript, jež je obsahuje. To umožňuje budoucím soft forkům přidělit těmto opkódům nové podmínky (a učinit tak z nich běžné opkódy). Avšak kvůli tomuto chování by bylo používání introspekce s kovenanty, jež mohou obsahovat části libovolných skriptů, nebezpečné. Například by mohla Alice vytvořit kovenant, který by jí umožnil utratit prostředky na libovolnou adresu, pokud by tyto prostředky nejdříve utratila v oznamovací transakci úschovny a čekala určitý počet bloků, aby dala možnost zmrazovací transakci toto utracení blokovat. Pokud by však ona libovolná adresa obsahovala opkódOP_SUCCESSx
, mohl by kdokoliv její peníze ukrást. Russell ve svém článku navrhuje dvě možná řešení tohoto problému.
Výzkum obdržel několik reakcí a Russell naznačil, že pracuje na dalším příspěvku popisující introspekci výstupních částek.
-
Vybrané otázky a odpovědi z Bitcoin Stack Exchange
Bitcoin Stack Exchange je jedním z prvních míst, kde hledají přispěvatelé Optechu odpovědi na své otázky a kde – najdou-li volnou chvíli – pomáhají zvědavým či zmateným uživatelům. V této měsíční rubrice nabízíme některé z otázek a odpovědí, které obdržely vysoký počet hlasů.
-
● Jak funguje algoritmus výběru mincí Branch and Bound? Murch shrnuje své bádání o algoritmu Branch and Bound („metoda větví a mezí”) pro výběr mincí, který „hledá nejméně plýtvající množinu vstupů, která produkuje transakci bez zůstatku.“
-
● Proč se v bitcoinové síti posílá každá transakce dvakrát? Antoine Poinsot odpovídá na starší Satoshiho příspěvek v emailové skupině, který tvrdí, že „každá transakce musí být poslána dvakrát.” Poinsot vysvětluje, že sice v té době byla transakce poslána dvakrát (jednou během přeposílání transakce, podruhé během přeposílání bloku), avšak po následném přidání přeposílání kompaktních bloků dle BIP152 se data transakcí posílají jen jednou na každé spojení.
-
● Proč jsou v bitcoinu OP_MUL a OP_DIV neaktivní? Antoine Poinsot se domnívá, že opkódy
OP_MUL
aOP_DIV
byly pravděpodobně deaktivovány (spolu s dalšími opkódy) v reakci na chyby „1 RETURN” a OP_LSHIFT crash objevené několik týdnů předtím. -
● Proč jsou hashSequence a hashPrevouts počítány odděleně? Pieter Wuille vysvětluje, že rozdělením hashovaných dat transakce na předchozí výstupy a sekvence je možné hashe vypočítat pouze jednou a použít je na výpočet všech druhů sighash.
-
● Jak může být poplatek v příštím bloku nižší, než je vylučovací poplatek mempoolu? Uživatel Steven odkazuje na rozhraní mempool.space, které ukazuje výchozí vylučovací poplatek 1,51 sat/vB, ale zároveň odhaduje, že příští blok bude obsahovat transakci s poplatkem 1,49 sat/vB. Podle Glozow je pravděpodobným vysvětlením, že plný mempool vyloučil transakci, která navyšovala minimální jednotkový poplatek (
-incrementalRelayFee
), ale ponechal v mempoolu některé transakce s nižším jednotkovým poplatkem, které vyloučeny být nemusely.Též zmiňuje, že asymetrie mezi skórem předků pro výběr šablony bloku a skórem potomků pro vyloučení z mempoolu může být dalším možným vysvětlením. Odkazuje na problém související s cluster mempool, který asymetrii vysvětluje a nabízí možný nový přístup.
Vydání nových verzí
Vydání nových verzí oblíbených páteřních bitcoinových projektů. Prosíme, zvažte upgrade či pomoc s testováním.
-
● Bitcoin Core 25.1 je údržbovým vydáním obsahujícím hlavně opravy chyb. Jedná se o aktuálně doporučovanou verzi Bitcoin Core.
-
● Bitcoin Core 24.2 je údržbovým vydáním obsahujícím hlavně opravy chyb. Je doporučována každému, kdo stále používá 24.0 nebo 24.1 a není schopen či ochoten aktualizovat na verzi 25.1.
-
● Bitcoin Core 26.0rc1 je kandidátem na vydání příští hlavní verze této převládající implementace plného uzlu. Ověřené testovací binárky nebyly v době psaní zveřejněny, očekáváme však jejich zveřejnění na této adrese krátce po vydání zpravodaje. Kandidáti na předchozí vydání mívají průvodce testování na Bitcoin Core developer wiki a sezení Bitcoin Core PR Review Club věnované testování. Vyzýváme čtenáře, aby pravidelně kontrolovali, zda jsou tyto zdroje již dostupné i pro tohoto kandidáta.
Významné změny kódu a dokumentace
Kvůli objemu novinek v tomto čísle a nedostatku času našeho hlavního autora jsme nebyli schopni zpracovat přehled změn kódu za poslední týden. Budou obsaženy v příštím vydání. Za zpoždění se omlouváme.
Poznámky
-
Replacement cycle útok popsaný zde je založen na nahrazení transakce transakcí s nižším počtem vstupů, než měla transakce původní. Autoři peněženek jsou většinou před tímto chováním varováni. Například kniha Mastering Bitcoin, 3rd edition uvádí:
Buďte obzvláště opatrní, vytváříte-li více než jedno nahrazení stejné transakce. Musíte zajistit, aby byly všechny verze transakce v konfliktu se všemi ostatními. Pokud by v konfliktu nebyly, mohlo by dojít k potvrzení více transakcí, což by vedlo k přeplacení. Například:
-
Transakce verze 0 obsahuje vstup A.
-
Transakce verze 1 obsahuje vstupy A a B (např. jste museli přidat vstup B k zaplacení poplatku).
-
Transakce verze 2 obsahuje vstupy B a C (např. jste museli přidat vstup C k platbě zvláštních poplatků, ale C bylo dostatečně velké, že už jste nepotřebovali A).
V tomto scénáři může těžař, který uložil transakci verze 0, potvrdit verze 0 i 2. Platí-li obě verze stejnému příjemci, obdrží prostředky dvakrát (a těžař obdrží poplatky ze dvou transakcí).
Jednoduchým způsobem, jak se tomuto problému vyhnout, je ujistit se, že nahrazující transakce vždy obsahuje všechny vstupy jako její předchozí verze.
-