Ризикований бізнес: пояснення самовидаляючихся npm-пакетів

Ризикований бізнес: пакети проти прокторингу, які самі видаляються

TL, д-р

Пакети видаляються самі. Протягом п'ятнадцяти днів серпня один оператор npm опублікував дев'ять пакетів під дев'ятьма іменами з семи облікових записів і особисто відкликав вісім з них. Період, протягом якого кожен пакет залишався активним, скоротився з тринадцяти годин до сімнадцяти хвилин. Цей метод застосовується не лише ними: ще сім пакетів від непов'язаних операторів, що містили зовсім інші корисні навантаження, були відкликані їхніми власними видавцями в середньому за 37.8 хвилини. Артефакт зникає до того, як запускається більшість захисних процесів, і встановлення вже відбулося.

Все, що надає реєстр, обертається; корисне навантаження — ні. Усі дев'ять були відправлені з ідентичним байтом bin/ каталог, той самий SHA-256 дайджестує дані з трьох імен пакетів та двох облікових записів з інтервалом у п'ятнадцять днів. Ідентичність контенту — єдиний сигнал відстеження, який цей оператор не зламав, а єдиний пакет, який вони ніколи не вилучали, є причиною того, що будь-що з цього взагалі можна було перевірити.

Люди, які його встановлюють, не є жертвами та все одно сильно наражаються на небезпеку. Цей інструмент не призначений для розробників: він запобігає віддаленому контролю іспитів завдяки прихованому захопленню екрана, вилученню тексту на екрані та поверненню відповідей у ​​вигляді накладання, тому той, хто біжить npm install є передбачуваним бенефіціаром, а не цільовою аудиторією. Вони також запускають непідписаний бінарний файл, який розшифровує сховище файлів cookie браузера з облікового запису, який видаляється протягом години. Вони не можуть отримати виправлення, не можуть пізніше перевірити, що вони запустили, і не можуть повідомити про шкоду, не розкривши причину встановлення.

Екосистема: npm, та сама закономірність спостерігається на PyPI. Період: Червень–серпень 2026 року.

Вимірювання

Час перебування – це інтервал між появою та зникненням пакета, обчислений на основі власних метаданих реєстру. Це вимірювання, а не оцінки.

пакетОпубліковано (UTC)Ліворуч стоїть
moidev2026-08-16 16:315год 58м
moidevx2026-08-17 03:2413год 23м
moidevz2026-08-26 03:3812год 56м
moideva2026-08-26 18:581год 33м
amicat2026-08-28 20:4817m
bmcat2026-08-28 21:1747m
eyevox2026-08-28 21:4421m
moidevh2026-08-31 03:2247m

Якщо прочитати в порядку публікації, вікно зменшується більш ніж у сорок разів — з 13 годин 23 хвилин у найширшому місці до 17 хвилин у найвужчому. Перші чотири пакети тривають у середньому вісім з половиною годин; останні чотири — тридцять три хвилини. 28 серпня три пакети було опубліковано та відкликано протягом одного 77-хвилинного проміжку.

Скорочення не є поступовим дрейфом. Воно зосереджене між 26 та 28 серпня, і змінилася лише оцінка оператором того, як довго посилка може безпечно стояти.

Кожне вилучення тут ініціюється видавцем. У документі реєстру для кожного з них поруч із час.неопубліковано запис — підпис скасування публікації, а не видалення. Дев'ятий пакет, очні, ніколи не було вилучено; саме тому все це можна було перевірити.

Існує другий режим виведення коштів, і його не слід плутати з цим. Де лише версія корисного навантаження якщо витягнутий і пакет виживе, медіана становить приблизно 73 години для 31 пакета. Ці заміни надходять партіями за сценарієм і залишають порожню оболонку — package.json оголошення основний який не надсилає файл — єдина функція якого — зберігати ім'я. Цей режим — це дотримання графіка. Цей — налаштоване вікно експозиції.

Що переживає видалення

Дев'ять із цих пакетів належать одному оператору: moidev, moidevx, moidevz, Мойдева, Мойдев, дружок, bmcat, eyevox та очніНазви не мають жодної угоди — будь-хто, хто відстежує moidev stem пропустив би більше половини з них — і вони були опубліковані з семи окремих облікових записів, майже всі зареєстровані на доменах одноразової електронної пошти.

Те, що вони мають спільне, — це запис маніфесту, який не має жодної причини для існування:

"кошик": { "": "bin/kalamasha-tool.js" } }

Ми зберегли копії п'яти перед видаленням. По всіх п'яти, весь смітник / каталог є байтоідентичним:

ФайлSHA-256
bin/kalamasha-tool.js0c293be90c10c8a7618d25f4c4811fa63612b7bc5199b86e10bb31eb36c716dd
bin/uia_extract.exee2fda5aa8397799669f29258f69e803cf05d322c1d93269eef6754ca024c3865
bin/chrome_cookies.ps121b61ec810331850d72423c40c5448e6cd310c4cfad6aed54f92cd7e7cac5f3a
bin/stealth_capture.ps1c9baf5897c03b941c54f736df5af9243ad28794a9e69746d41d4f4a34065589c
bin/uia_extract.pyc20b38c63efd9221930095c54b42cdd5adffa1972c44c4578226cbe1e4dbac3e
bin/uia_get_text.ps14a3f3ada0bdf13aa8e89edb8af817c7816296147dae5be25f169ff960d28a87c

Два подальших сигнали узгоджуються. Три пакети були опубліковані о 03:24, 03:38 та 03:22 UTC 17 серпня, 26 серпня та 31 серпня — шістнадцятихвилинний діапазон протягом п'ятнадцяти днів та трьох окремих облікових записів. Причому два з цих облікових записів були зареєстровані на одному одноразовому домені електронної пошти, що пов'язує їх між собою незалежно від коду.

Рахунки

Це облікові записи видавців npm, які відправили корисне навантаження, з описом кожного завантаженого пакета та часом його перебування:

Обліковий запис видавцяпакетДомен електронної поштиЛіворуч стоїть
letol39119moidev:1.0.0hutdot.com (одноразовий)5год 58м
so1d1a7i27moidevx:1.0.0ogzmail.com (одноразовий)13год 23м
lololololol435678eyiouss:3.0.21, 3.0.22, 4.0.1ogzmail.com (одноразовий)досі опубліковано
tagadob568moidevz:1.0.0ebflyai.com (одноразовий)12год 56м
tayihim489moideva:1.0.0prodbits.com (одноразові)1год 33м
sahihai123amicat:1.0.0, bmcat:2.0.9, eyevox:1.0.0споживча веб-пошта17m / 47m / 21m
heytoshanmoidevh:1.0.0споживча веб-пошта47m

so1d1a7i27 та лололололол435678 поділитися ogzmail.com реєстраційний домен — посилання, яке пов’язує обліковий запис, на якому все ще розміщено активну копію, з обліковим записом, опублікованим під moidev стебло на два тижні раніше. сахіхай123 опублікував та відкликав три окремі назви пакетів протягом одного 77-хвилинного вікна 28 серпня. Гейтошан зареєстрований, опублікований Мойдеві відкликав його через 47 хвилин; це залишається єдиною публікацією цього облікового запису.

Кожен із цих облікових записів не має перевіреної електронної пошти, не має перевіреного посилання на систему контролю версій і не опублікував жодного непов’язаного проекту. Шість із семи більше нічого не розміщують.

Один пакет так і не був вилучений. eyious:4.0.1 було опубліковано 16 серпня і на момент написання статті все ще можна було вирішити проблему. Вісім артефактів неможливо було відновити; кампанію було повністю реконструйовано з того, що залишився. Оператор, який рефлекторно видаляє, зрештою все одно залишить один артефакт.

Що робить інструмент

eyious:4.0.1 описує себе на npm як «Високопродуктивну утиліту DOM та діагностичний міст для сучасних вебзастосунків». Це інструмент для захоплення екрана та отримання відповідей, створений для роботи під віддаленим наглядом за іспитами, і джерело зазначає це власними словами.

Програма запуску копіює середовище виконання Electron під хибним ім'ям файлу перед запуском та вказує назву того, чого він уникає:

// 🛡️ ІМ'Я БІНАРНОГО ФАЙЛУ STEALTH: НЕ ПОВИННА конфліктувати зі справжнім Testpad! const STEALTH_NAME = 'SearchApp.exe';

У заголовку того ж файлу його називають Вартовий пес-привид проти Проктора і реалізує цикл відродження, який відступає тим більше, чим швидше його знищують. В інших місцях процес підвищує власний пріоритет. боротися з тротлінгом процесора під час моніторингу, виштовхує екзаменаційну програму з переднього плану, коли вона отримує фокус, та завершує дочірній процес Safe Exam Browser за допомогою taskkill /F /T.

Захоплення виконується через вбудований скрипт PowerShell, який викликається з вимкненою політикою виконання та пригніченим вікном, а текст на екрані збирається паралельно за допомогою автоматизації інтерфейсу користувача Windows. Зображення та текст у черзі надсилаються до сеансу мовної моделі у вбудованому браузері, а відповідь відображається у вигляді оверлею, який завжди знаходиться зверху. Це з'єднання навмисно відкладається, і код пояснює це: щоб уникнути постійного впливу NETSTAT.

Пакет також доставляється chrome_cookies.ps1, очолював ХРОМІЗОВАНИЙ ЕКСТРАКТОР ПЕЧИВА, який розшифровує файли cookie Chrome та Edge через DPAPI та зчитує базу даних файлів cookie з чотирьох профілів браузера. Заявлено заздалегідьcisely: ми не знайшли скрипта, викликаного за назвою, з жодного надісланого JavaScript-файлу. Присутня та досяжна лише частина-споживач, яка вставляє збережені файли cookie сесії у вбудований браузер.

Позиція людей, які його встановлюють

Ніхто не встановлює це випадково. Воно не має жодної функції поза межами контрольованого іспиту, а його результатом є накладання відповіді на екран користувача. Оманливий опис пакета зовсім не спрямований на інсталятора — це маскування, спрямоване на реєстр та будь-кого, хто потім перевіряє машину. Інсталятор знає, що він отримує; опис існує, тому запис встановлення цього не відображає.

Постраждали треті сторони, які ніколи не торкалися npm: установа, що проводить іспит, інші кандидати та всі, хто нижче за течією, і хто покладається на те, що посвідчення має певний сенс.

Але інсталятор таким чином не є безпечним, і саме на цьому варто зупинитися, оскільки сама модель зникаючого пакета створює цей вплив.

Вони запускають непідписаний бінарний файл від nobody. uia_extract.exe постачається скомпільованим, без зазначення джерела та походження збірки, з облікового запису, якого більше не існує. Той самий файл, за хешем, був переопублікований letol39119, so1d1a7i27, лололололол435678, tagadob568, тайіхім489, сахіхай123 та Гейтошан протягом п'ятнадцяти днів. Немає супроводжуючого, якого потрібно було б запитати, немає репозиторію, який потрібно було б прочитати, і немає історії, яку потрібно було б перевірити — кожна ідентифікаційна особа, яка його надсилала, сама себе видалила.

Вони надали йому саме ті можливості, які потрібні шкідливому програмному забезпеченню. Прихований процес, що працює під фальшивим іменем, який розшифровує сховище файлів cookie браузера, безперервно зчитує екран, завершує роботу програмного забезпечення безпеки та перезапускається після завершення роботи. Сьогодні розшифрування файлів cookie обмежено доменами одного постачальника та обслуговує власний сеанс користувача. Ця область дії — це зміна в один рядок, і ніщо в моделі доставки не виявить її, якщо вона зміниться — нове ім'я, новий обліковий запис, нове завантаження.

Вони не можуть отримати виправлення. Пакет скасовується протягом години. Немає шляху оновлення, жодного повідомлення та жодного способу дізнатися пізніше, що встановлена ​​ними версія відрізняється від тієї, яку встановив їхній друг. Все, що є на комп’ютері, там і залишається.

Вони не можуть перевірити, що вони виконали. Їхній файл блокування тепер посилається на пакет, який більше не розв'язується. Якщо вони пізніше захочуть встановити, що було на їхній машині — після інциденту чи суперечки — реєстр не матиме запису, щоб надати їм це.

І вони не можуть повідомити про шкоду. Користувач, якого скомпрометував цей інструмент, не може подати звіт про зловживання, не розкривши причину його встановлення. Це не випадково. Звіти про зловживання реєстром є основним каналом, через який виловлюються короткочасно діючі пакети, а база користувачів цього оператора структурно не здатна його використовувати. Єдиним супротивником, що залишився, є автоматичне сканування, для якого калібрується сімнадцятихвилинне вікно.

Структура жертви та час перебування – це один і той самий факт, який спостерігається двічі. Це також пояснює аномалію у часовій шкалі: якби відмова була зумовлена ​​страхом скарг, то довгоживучий популярний пакет зник би першим. Цього не сталося, бо скарги ніколи не надходять.

Той самий шаблон, інший оператор

Оператор прокторингу не самотній у цьому, і найчіткіший паралель виконується на непов'язаному корисному навантаженні.

Між 24 та 27 серпня з’явилися чотири npm-пакети під назвами, запозиченими з інструментів двофакторної автентифікації — автентифікаційний OTP, секретний ключ-2fa, секретний ключ2фа та 2fa-секретний ключ — що містять шістнадцять версій. Кожна з них була опублікована з власного щойно зареєстрованого облікового запису (бейілол, jeanpaul686g, zzzalipay, длууууу), усі неперевірені електронною поштою, жодні з перевіреним посиланням на систему контролю версії, жодні не публікують нічого іншого. Кожну з них було відкликано власним видавцем.

Корисне навантаження не має нічого спільного з програмним забезпеченням для іспитів. Воно зчитує сховища облікових даних браузера та токени Discord, а також проходить сходи автентифікації Xbox Live до лаунчера Minecraft, щоб отримати токен оновлення. Тут інсталятор is жертва у звичайному розумінні — саме це робить порівняння корисним, оскільки поведінка доставки ідентична незалежно від цього.

Чотири цикли виконувалися в порядку публікації з часом 274.9, 37.8, 37.6 та 35.7 хвилини: одна довга перша спроба, потім збіжність на заданому значенні. Ще три пакети знову належать іншим операторам і демонструють таку ж поведінку вилучення.

пакетОператорЛіворуч стоїть
octopus-actionрозвідувальний маяк2.5 хв
mt-ts-serverless-starterрозвідувальний маяк9.6 хв
2fa-secretkeyНазви обкладинок 2FA35.7 хв
secretkey2faНазви обкладинок 2FA37.6 хв
secretkey-2faНазви обкладинок 2FA37.8 хв
auth-otpНазви обкладинок 2FA274.9 хв
hex-encode-utilsІнше724.2 хв

Сім пакетів, медіана 37.8 хвилини, жоден з них не пов'язаний з програмним забезпеченням для іспитів.

Три непов'язані корисні навантаження, три непов'язані набори облікових записів, одна спільна техніка.

Чому вікно зачиняється

Протягом 2026 року в середовищі реєстру відбулися певні зміни, і очевидним кандидатом є те, що сканування стало швидшим.

Донедавна шкідливі пакети виявляли переважно постфактум: коли користувач щось помічав, за допомогою звіту нижче за течією або за допомогою періодичної перевірки. Затримка виявлення вимірювалася днями. Це вже не єдиний режим. Аналіз щойно опублікованих пакетів майже в режимі реального часу — Власна система раннього попередження про шкідливе програмне забезпечення від Xygeni серед зростаючого набору таких систем у галузі — значно скорочує розрив між публікацією та перевіркою.

Оператор, який стикається з цим, має два варіанти. Зробити корисне навантаження складнішим для розпізнавання або скоротити час його доступності для перегляду. Другий варіант дешевший, не потребує інженерії, а реєстр надає механізм безкоштовно: протягом 72-годинного вікна скасування публікації npm видавець може односторонньо видалити пакет, а назву можна буде використовувати повторно згодом. Скасування нічого не коштує оператору.

Час підходить. Обидва вищезгадані оператори сходяться до певного числа та утримують його, а не відхиляються, що є радше схожістю на налаштований параметр, ніж питанням зручності. А параметр, до якого вони зійшлися — десятки хвилин — знаходиться заздалегідь.cisде йому потрібно було б розташуватися, щоб пройти автоматичну перевірку, залишаючи пакет придатним для встановлення достатньо довго, щоб він дійшов до своєї аудиторії.

Це залишається гіпотезою. Дані про час не можуть відокремити реакцію на сканування від реакції на дотримання реєстру або від звичайного операційного дозрівання, оскільки ці оператори навчаються один в одного. Те, що можна сказати без висновків, є вужчим і все ще корисним: вікно експозиції тепер достатньо коротке, щоб будь-який контроль, що залежить від перевірки пакета після публікації, випереджав час, встановлений оператором. Елементи керування, які не залежать від перевірки — карантин за віком, вимкнені скрипти встановлення — не залежать від цієї раси, що є практичною причиною надавати їм перевагу.

Що з цим робити

Карантин за віком. Ніщо в таблиці часу перебування не пережило тринадцять годин. Політика, згідно з якою жодна версія залежностей не може бути встановлена, поки вона не проіснує 72 години, виключила б кожну з них, нічого не виявивши.

Вимкнути скрипти встановлення за замовчуванням. –Ігнорувати сценарії видаляє механізм доставки, від якого залежать пакети крадіжки облікових даних у цьому корпусі. Це не допомагає проти інструменту, який користувач запускає навмисно, що єcisрізниця, яку варто зрозуміти.

Розглядайте зникнення як подію, пов'язану з безпекою. Повідомляти, коли встановлена ​​залежність перестає вирішуватися. Докази зберігаються у вашому файлі блокування, а не в реєстрі.

Відстежуйте контент, а не імена. Шість дайджестів вище збігаються незалежно від назви пакета, облікового запису видавця чи рядка версії — кожне поле, яке цей оператор продемонстрував, зміниться. Правило на стороні реєстру, яке передбачає, що щойно зареєстрований обліковий запис, який відкликає свій єдиний пакет протягом години, є шаблоном звітності, спрацювало б для кожного пакета тут, лише на основі метаданих.

А якщо ви розглядаєте можливість встановлення чогось із цієї категорії: Властивості, які ускладнюють виявлення реєстром, — це ті самі властивості, які не залишають вам жодних шансів на захист. Немає видавця, якого можна було б притягнути до відповідальності, немає шляху оновлення та немає запису про те, що ви виконали.

індикатори

типзначення
Файлbin/kalamasha-tool.js — не-standard точка входу в контейнер
SHA-2560c293be90c10c8a7618d25f4c4811fa63612b7bc5199b86e10bb31eb36c716dd
SHA-256e2fda5aa8397799669f29258f69e803cf05d322c1d93269eef6754ca024c3865
ПроцесSearchApp.exe написаний поруч із легітимним середовищем виконання Electron
Поведінкаpowershell -ExecutionPolicy Bypass -File з windowsHide: true
Поведінкаtaskkill /F /T орієнтація на процес безпечного браузера для іспитів
метаданіПорожній список супроводжуючих поруч time.unpublished запис
Рахункиletol39119, so1d1a7i27, lololololol435678, tagadob568, tayihim489, sahihai123, heytoshan
Реєстраціяogzmail.com, hutdot.com, ebflyai.com, prodbits.com — домени одноразової пошти

Посилання

інструменти-для-аналізу-складу-програмного-засобу-sca
Визначте пріоритети, усуньте та захистіть ризики, пов'язані з програмним забезпеченням
Отримайте свій безкоштовний обліковий запис.
Не потрібна кредитна картка.

Забезпечте розробку та доставку програмного забезпечення

з пакетом продуктів Xygeni