Хаквайте като хакери с черни шапки. Курс за пълно обучение по етично хакерство от нула до експерт.
Проникващо тестване, Kali Linux, WiFi и уеб хакерство, както и хакерският начин на мислене зад всичко това.
Червей изхвърли 1300 скривалища с откраднати ключове на разработчици в публични хранилища на GitHub за един ден. Вие просто стартирахте npm install. Това беше всичко. Отровата се намираше в библиотека, която npm разпространява по 153 милиона пъти седмично. 🧐
Нямаше фишинг имейл и нищо подознително за изтегляне. Вие написахте npm install или вашият сървър за компилация направи това в три часа сутринта, докато спяхте, и кодът на атакуващия се изпълни, преди инсталацията да е приключила.
На 4 август 2026 г. някой влезе в GitHub акаунта на Джаред Рей, поддържащия разработчик на keyv и семейството библиотеки за кеширане cacheable. Това са малките спомагателни пакети, които рядко добавяте във вашия собствен package.json, но които все пак попадат във вашата директория node_modules, тъй като нещо друго, което сте инсталирали, зависи от тях. Само keyv се изтегля около 153 милиона пъти седмично. flat-cache и file-entry-cache са от същото семейство, като и двете надхвърлят половин милиард инсталации на месец.
Атакуващият направи push директно в главния клон (main) и публикува версия, а метаданните на коммита записват това с точност до секунда.
В 09:02:37 ч. двата злонамерени файла попаднаха в хранилището. Две минути по-късно, в 09:04:30 ч., ги последваха още пет файла, които изобщо нямаха нищо общо с npm, и към тях ще се върна по-късно, защото те са най-лошата част от тази история. В 09:23:50 ч. той изтри файл, който сам беше написал двадесет и една минути по-рано. В 09:35:00 ч. заразената версия keyv@6.0.0 беше пусната на живо в регистъра, а в 09:39:45 ч. той копира злонамерения код в пакетите @keyv в монохранилището, подготвен и чакащ следващата версия.
Тридесет и две минути от първия commit до заразен пакет, наличен в регистъра.
Първият доклад за проблем се появи в хранилището в 09:49:31 ч., четиринадесет минути след публикуването. Още два последваха в рамките на следващите две минути, а четвърти – двадесет минути след това. Това беше бързо, но все пак не достатъчно бързо, тъй като с часове след това няколко от заразените пакети бяха това, което npm ви доставяше по подразбиране.
Тази последна част не беше късмет. keyv определяше коя основна версия получава последния таг (latest) чрез настройка, съхранявана в GitHub Actions – умишлено пазена извън хранилището, за да не може commit да я премести. Атакуващият отстрани това ограничение (коригира скрипта за публикуване), така че ново поле в собствения package.json на хранилището да пренебрегва тази настройка, и го зададе на 6. Той премести източника на истината на територия, на която можеше да пише. Без тази корекция за сигурност, npm install keyv щеше да продължи да ви дава версия 5.6.0.
До 18:10 UTC същия ден 444 пакета в 2212 версии бяха заразени, което общо се равнява на около 2 милиарда инсталации на месец, и бройката продължаваше да расте. Там бяха и пакети, принадлежащи на Deliveroo, Picsart и Qlik, препубликувани от червея с помощта на идентификационни данни, които той беше откраднал от техните собствени поддържащи разработчици.
Всеки заразен пакет получи два нови файла – setup.mjs и Math_Symbol.js, както и един нов ред в package.json:
Preinstall скриптът е команда, която npm изпълнява вместо вас, преди да приключи инсталирането на даден пакет. Той съществува, за да може библиотеката да компилира нещо или да провери вашата платформа. Той се изпълнява с вашите права, във вашия терминал, преди който и да е от вашия собствен код да се изпълни и преди който и да е тест или скенер да получи ред.
Кодът на библиотеката под dist/ никога не е бил докосван. keyv продължи да работи точно както винаги. Ето защо разликата (diff) се преглежда толкова лесно без да се забележи: два файла са добавени към списъка с разрешени файлове и един ред е добавен в скриптовете.
setup.mjs е обфускиран dropper (програма за инсталиране на зловреден софтуер) с една единствена задача. Той проверява дали Bun е наличен на машината и ако Bun липсва, изтегля официална компилация на Bun 1.3.13 директно от github.com/oven-sh/bun, използва я за изпълнение на Math_Symbol.js и след това изтрива средата за изпълнение.
Прочетете това отново, защото това е най-умната част от дизайна. По време на инсталацията единственият хост, с който машината комуникира, е GitHub. В трафика няма домейн на атакуващия, така че списъците с разрешени изходящи адреси и мониторингът на базата на репутация няма за какво да се задействат. Търсенето в setup.mjs за команден сървър не връща нищо, защото на този етап такъв няма. И това, че нямате инсталиран Bun, не е защита, защото dropper-ът носи свое собствено копие и го почиства на излизане.
Math_Symbol.js е обфускиран Bun архив с размер 727 680 байта и тук се случват щетите.
Той знае къде разработчиците пазят нещата си. Той чете файла, в който npm съхранява вашия токен за публикуване, и файла, в който инструментът за команден ред на GitHub съхранява вашите данни за вход. Той чете вашите идентификационни данни за AWS, включително профила, който сте настроили за стар проект и сте забравили. Той преминава през вашите SSH ключове, вашите .env файлове, състоянието на Terraform, данните за вход в Docker, вашата база данни на KeePass и конфигурациите за VPN, изпълнявайки приблизително 200 различни шаблона за търсене на диска.
След това прави нещо, което го отличава от обикновения крадец на пароли. Той не просто копира ключовете. Той влиза с тях.
Откраднатият npm токен се проверява в регистъра, за да се види на чий акаунт принадлежи...