Съдържание

/liquid-network-range-proof-cache-bitcoin/liquid-network-range-proof-cache-bitcoin.png

Пълен курс по етично хакерство от нула до експерт

Хаквайте като „черна шапка“ хакери. Тестване за проникване, Kali Linux, WiFi и уеб хакерство, както и хакерското мислене зад всичко това.

Атакуващ изпразни трезор от 3 996 биткойна и след това поиска от собствениците да се свържат с него. Той написа съобщението в блокчейна, където останалите от нас можехме да четем заедно с тях. Това, което последва, не беше откуп.

В неделя едно плащане напусна биткойн портфейла, който компанията зад Liquid държи като обезпечение за собствената си монета. Излязоха 3 996 биткойна, около 320 милиона долара, а 197 останаха. Единадесет от петнадесетте компании, които охраняват този портфейл, бяха сложили подписа си под него и всеки подпис беше коректен. Доколкото софтуерът можеше да прецени, клиент беше отишъл до гишето и беше поискал парите си.

Той не беше клиент и монетите, които предаде, не съществуваха. Той ги беше създал от нищото малко повече от половин час по-рано и софтуерът не можеше да ги разграничи от тези, които съществуват.

Четири часа по-рано той направи нещо, което рядко се вижда. Написа бележка на хората, от които току-що ги беше взел. Той я постави в самия биткойн блокчейн, където тя остава завинаги:

Час по-късно, в последващ блок, дойде отговор:

Ето как двамата се оказаха в преговори на публично място, блок по блок. Останалите от нас четяхме през рамото им.

Можете да запишете малка част от текст в биткойн трансакция. Той отива в поле, наречено OP_RETURN, струва няколко цента и остава във веригата за толкова дълго, колкото съществува биткойн. Използва се за времеви печати и кратки бележки. Тези двамата го използваха, за да разговарят, тъй като никой от тях нямаше друг начин да достигне до някого, в когото може да бъде сигурен.

Той не поиска пари. Поиска нещо друго:

Мъж, държащ 320 милиона долара, казва на хората, от които ги е взел, да побързат и да затворят дупката, преди някой друг да премине през нея.

След това нещата се комплицираха, защото и други хора четяха и някои от тях видяха своя шанс.

В понеделник сутринта две съобщения пристигнаха в една и съща минута. Това беше едното от тях:

Само първото дойде от компанията. Второто беше от някой, който се надяваше да прихване парите по пътя им обратно, звучейки официално в точния момент, а 98-те, които подхвърлиха, бяха избрани внимателно. Това е приблизително колкото награда за откривател. Достатъчно голяма да изкуши и достатъчно малка, за да не повдигне въпроси.

Следобед се появи трето съобщение:

Той пренебрегна и двете, а скучната предпазливост е това, което направи това възможно. Компанията подписа съобщенията си с PGP ключа, публикуван на собствения ѝ уебсайт. Този подпис носи същия отпечатък като този на техния сайт. Не можете да фалшифицирате това без ключа, а нито едно от двете фалшиви съобщения не носеше подпис изобщо. Адресът, на който ги върна, беше този, който самият той беше поставил писмено предишната вечер, и те бяха потвърдили с подпис. По-късно същия ден той ги помоли да го потвърдят още веднъж.

Този фалшив адрес не е получил абсолютно нищо. Нула трансакции, нула биткойни.

Оня следобед той го изпрати. Една трансакция, две плащания, нищо друго в нея:

  • → 3 400 биткойна обратно към портфейла, от който ги взе
  • → 598.49955894 биткойна към адрес, който той запази

598 биткойна са около 47 милиона долара. Това възлиза на 15 процента от това, което той взе. Това е приблизително това, което се плаща като награда за уязвимост (bug bounty) в този ъгъл на индустрията, в дните, когато плаща нещо. Публично никога не е била предлагана награда и не е публикувано споразумение. Той запази 598-те и върна останалото.

Страничната верига (sidechain) все още е спряна. Мостовите възли са изключени и борсите получиха заявка за замразяване на депозити и тегления. Веригата също се раздели по време на паузата, така че това трябва да бъде изчистено, преди каквото и да е да се рестартира. Самсън Моу, който управлява JAN3 и преди е работил в компанията, каза в понеделник, че първо се въвеждат още корекции за сигурност и дейности по подобряване на защитата. Самата компания не е казала нищо публично за липсващите 598. Стабилните монети и другите активи в страничната верига не са били докоснати.

До понеделник вечерта адресът присъстваше в репортажите и съобщенията започнаха да пристигат. Повече от двеста бележки стоят там и бройката все още се увеличава.

  • → „Пич, просто ми дай 10 BTC и ми позволи да се съсредоточа върху живота, вместо да се блъскам 9-5 глупости“
  • → „в момента 10 BTC са стотинки за теб, но са всичко за мен“
  • → „Трябват ми 10 BTC, за да спася семейството си от Peña, моля ти се сър, семейството ми!“
  • → „Желая 0.1 BTC, за да стартирам моето крипто пътешествие, оценявам всяка подкрепа.“
  • → „Бих ти позволил да ме риташ в топките за 10 BTC :)))“
  • → „достатъчно умен да изпратя това съобщение, не достатъчно умен да избягам от моето 9-5… Дай ми 10 BTC и ще кръстя първородното си дете както ми кажеш!“
  • → „Ако наистина си с бяла шапка и върнеш това, ти не само ще си спасил моето семейство, което включва бебе на няколко месеца, но и ще влезеш в историята като легитимен герой и легенда.“
  • → „Господ да те благослови за това, че си милостив. Прави добро по света с твоята награда.“

А някои са бизнес. Една и съща реклама за меме монета, копирана десетки пъти, пусната на гърба на историята, докато тя все още течеше. Измама за удвояване, сочеща към фалшив сайт за раздаване на награди. Няколко души обясняват, непоискано, как той трябва да ги изпере: в ETH чрез набор от мостове и след това миксиращ пул, или в Monero на малки суми. Поредица от обвинения също преминава през това, именувайки ръководители на компанията и наричайки инцидента инсцениран. Нищо не подкрепя нищо от това, така че тези имена остават извън това.

Няколко часа след изпращането на 3 400 обратно, той записа два знака в биткойн блок:

Той не е казал защо. Сега това стои в блок и няма да излезе оттам.

Той все още е наблизо. Тази сутрин той събра малките трансакции, които хората му бяха изпращали, публикува друго криптирано съобщение и плати няколко хиляди сатошита, за да го пренесе. 598-те биткойна не са напускали портфейла му.

Създаването на около 4 000 монети от нищото му отне две неща: пролука в начина, по който софтуерът помни собствената си работа, и един уикенд търпение.

В Liquid сумите в една транзакция са скрити. Това е самата цел: компания, прехвърляща монети, не иска останалата част от пазара да я наблюдава. Един възел все пак трябва да бъде сигурен, че скритата сума е разумно число, а не нещо отрицателно или измислено. Той проверява това с доказателство за диапазон (range proof) — математически елемент, който показва, че скрита стойност се намира в рамките на валиден диапазон, без да разкрива самата стойност.

Проверката на едно доказателство изисква време за обработка, а даден възел проверява много от тях. Затова той запаметява отговорите. Проверява доказателството веднъж, запазва резултата и пропуска работата, когато същото доказателство се появи отново.

Запазеният отговор е бил индексиран по две неща: доказателството и ангажимента към сумата. Той не е включвал за коя конкретно монета се отнася доказателството. Не е включвал и накъде отиват парите.

Ето къде е уязвимостта. Потвърждавате едно доказателство и по-късно възелът ви предоставя същия запазен отговор за съвсем различна монета, насочена към друго място.

Така той прекарва събота срещу неделя, разполагайки 68 копия на едно и също доказателство в 92 транзакции. Четиринадесет часа тиха работа, запълваща паметта на възлите, които по-късно трябва да проверят подаденото от него. След това той създава около 4000 монети без никакво обезпечение зад тях и ги занася на търговско гише, което ги разменя за биткойни. Гишето си върши работата. То изгаря токените и иска от пазачите да изплатят сумата. Пазачите проверяват заявката, единадесет от тях се подписват и парите заминават.

Това гише не е било хакнато и ключът му не е бил откраднат. От гишето заявиха това и са прави. Криптографията направи точно това, което ѝ бе наредено. Но ѝ бе наредено грешното нещо.

Корекцията за сигурност за този бъг вече съществуваше. Инженер в компанията я написа в началото на август. Тя влезе в публичния изходен код на първи септември, пет дни преди той да влезе. Два файла, една функция, два допълнителни параметъра, така че запазеният отговор да се индексира и по монетата, и по дестинацията. Прочетете тези няколко реда и ще видите какво е липсвало преди тях.

Тя не пристигна с предупреждение. Корекцията за сигурност бе включена като последния от десет ангажимента (commits) в заявка за изтегляне (pull request), озаглавена „blind/blindpsbt fixes“. В нейното собствено описание тя е наречена „малки проблеми, открити по време на LLM сканирания“. Машина откри това и то бе вкарано като рутинно почистване на кода. Прочетете заглавието на тази заявка за изтегляне и няма да научите нищо. Прочетете заглавията на ангажиментите (commits) вътре и ще разберете къде са парите.

Проблемът е, че корекцията в изходния код не е корекция на работещите машини. Най-новата издадена версия на този софтуер излезе на 13 април. Оттогава нищо не е издавано. Така че корекцията за сигурност си стоеше на открито, където се четат логовете на ангажиментите (commits), но нито една официално издадена версия не я съдържаше.

Той знаеше. Вижте отново собствените му думи: веригата е изложена на риск при най-новия commit в момента. При най-новия commit. Той ги е чел.

Нищо от това не е скрито от вас. Веригата е публична база данни и отговаря на заявки през мрежата. Ето транзакцията, с която парите се върнаха:

Погледнете в vout и ще видите двете плащания. Насочете същото нещо към неговия адрес и чувалът с писма започва да излиза:

Това ви дава най-новите 25, плюс каквото все още stoi непотвърдено. За да върнете назад през останалите, вземете txid на последното получено и поискайте страницата зад него. Повтаряйте, докато върне празен резултат:

Съобщенията стоят като хексадесетичен код в полето scriptpubkey_asm на изходите, маркирани като op_return. Два от операционните кодове за качване ги носят: OP_PUSHBYTES за кратките и OP_PUSHDATA за дългите. Ако прочетете само първия вид, ще изпуснете най-добрите бележки. Декодирането им отнема един ред на Python.

Две неща трябва да запомните от това.

  • → Корекция за сигурност, която е публична без издадена версия зад нея, е съобщение. Хората, които четат логовете на ангажиментите (commits) на софтуер за сигурност, не са само поддържащите го.
  • → Поставянето на биткойн зад нещо не му дава сигурността на биткойн. Основната верига остана недокосната. Това, което се провали, беше един запазен отговор в кеша, а петнадесет подписа не можаха да открият разликата.

Можете да изтеглите тези транзакции и да прочетете съобщенията сами с браузър и терминал, без да са необходими профил или портфейл.