Одиннадцатого июля 2026 года официальный npm-клиент коммерческого сервиса по обфускации JavaScript jscrambler был скомпрометирован. Злоумышленник опубликовал пять вредоносных версий пакета, используя учётную запись jscrambler_, принадлежащую легитимному разработчику. Атака затронула версии 8.14.0, 8.16.0, 8.17.0, 8.18.0 и 8.20.0, и представляет серьёзную угрозу для всех, кто использует этот инструмент в своих проектах или CI/CD-пайплайнах. Примерно 60 тысяч ежемесячных загрузок пакета делают радиус поражения значительным.
Описание
Сценарий атаки развивался в течение примерно трёх часов. Первая вредоносная версия 8.14.0 появилась в реестре в 15:12 UTC. Она содержала новый файл dist/setup.js и скрипт preinstall в package.json. При установке пакета этот скрипт запускался автоматически. Он считывал файл dist/intro.js размером 7,8 МБ, который, несмотря на расширение .js, на самом деле представлял собой контейнер для трёх сжатых исполняемых файлов - для Linux, Windows и macOS. Дроппер определял операционную систему жертвы, распаковывал соответствующий бинарный файл во временную директорию под случайным именем, начинающимся с точки, и запускал его в откреплённом режиме (detached). Таким образом, процесс продолжал работу даже после завершения npm install.
Мейнтейнеры быстро отреагировали, выпустив чистую версию 8.15.0 в 17:07 UTC. Однако атакующий не остановился. Он переиздал вредоносную 8.16.0 всего через 19 минут, используя тот же самый payload. Далее последовала версия 8.17.0, в которую была добавлена директива allowScripts для совместимости с менеджером пакетов pnpm. На этом этапе механизм внедрения оставался прежним - preinstall-скрипт.
Наиболее опасное изменение произошло в версиях 8.18.0 и 8.20.0. Атакующий убрал скрипт preinstall из package.json, переместив код дроппера непосредственно в главные файлы модуля: dist/index.js и dist/bin/jscrambler.js. Теперь полезная нагрузка срабатывала не при установке, а при любом вызове require('jscrambler') или запуске CLI-команды. Это критический момент: стандартные механизмы аудита, проверяющие только наличие install-скриптов, пропускают такие версии. При этом сам контейнер intro.js остался идентичным предыдущим вредоносным релизам - SHA256 совпадает для всех пяти версий.
Предоставленный анализ бинарных файлов показал, что полезная нагрузка представляет собой кроссплатформенный Rust-компилированный стилер, собранный с использованием ночной версии компилятора rustc 1.98.0-nightly от 4 июня 2026 года. Все три версии (ELF для Linux, PE32+ для Windows, Mach-O arm64 для macOS) содержат идентичную логику. Встроенный движок SQLite позволяет читать базы данных браузеров Chrome, Brave, Edge и Chromium, включая Login Data, Cookies и Web Data. Специально закодирован идентификатор расширения Bitwarden nngceckbapebfimnlniiiahkandclblb - стилер извлекает данные из локального хранилища этого менеджера паролей, что ставит под угрозу все сохранённые учётные данные.
Кроме того, полезная нагрузка нацелена на файлы cookie Steam (steamLoginSecure, sessionid), которые дают полный доступ к аккаунту без ввода пароля. Для Windows предусмотрено создание скрытой задачи в планировщике (Task Scheduler) с параметрами перезапуска каждую минуту до 999 раз. На macOS полезная нагрузка создаёт LaunchAgent с флагами RunAtLoad и KeepAlive с интервалом 30 секунд, что обеспечивает постоянную переживаемость после перезагрузки.
Анализ сетевых вызовов показал, что скомпрометированные хосты соединялись с ресурсами Tor Project (check.torproject.org, archive.torproject.org) и двумя IP-адресами: 37.27.122.124 и 57.128.246.79. Командный сервер использует шифрованный протокол поверх прямых TCP-соединений с применением встроенной библиотеки rustls, что обходит системные HTTP-библиотеки, которые могли бы быть объектом мониторинга. C2-адреса не видны в открытом виде - они расшифровываются во время выполнения через AES-NI и scrypt. Бинарные файлы содержат механизмы самообороны: на Windows - вызов IsDebuggerPresent, на macOS - sysctl для обнаружения отладчика. Linux-версия включает загрузку eBPF-программ из памяти, что даёт возможность перехвата системных вызовов на уровне ядра.
Важно отметить, что версии 8.18.0 и 8.20.0 до сих пор не помечены как скомпрометированные в npm-реестре. Они продолжают числиться опубликованными, и любой проект, использующий диапазон версий (например, ^8.18.0), может случайно установить их. Атакующий также добавил самоссылающуюся зависимость "jscrambler": "^8.17.0" в package.json этих версий - этот приём может способствовать внедрению вредоносного кода в дерево зависимостей.
Полная хронология выглядит так: после первой чистой версии 8.13.0 (30 июня) последовала серия атак. Мейнтейнер публиковал чистые сборки (8.15.0, 8.22.0), но атакующий каждый раз перехватывал лабел latest, выпуская новую вредоносную версию. Итоговая чистая 8.22.0 была опубликована в 18:12 UTC. Все остальные пакеты экосистемы Jscrambler (jscrambler-webpack-plugin, gulp-jscrambler и др.) не пострадали.
Последствия для пострадавших систем максимальны. Исполняемый файл, запущенный при установке или импорте, имеет доступ к локальным хранилищам браузеров, менеджерам паролей, сессионным cookie и облачным секретам. Через AWS Secrets Manager и Hashicorp Vault он может извлечь токены доступа к целой облачной инфраструктуре. Наличие в Linux-версии кода для генерации новых экземпляров дроппера с уникальными именами позволяет инфицировать другие npm-пакеты или Electron-приложения на скомпрометированной машине.
Всем, кто устанавливал любую из указанных вредоносных версий, следует немедленно переустановить чистую версию 8.22.0, ротировать все пароли, сохранённые в браузере, сменить мастер-пароль Bitwarden и проверить активность Steam-сессий. На Windows нужно просканировать планировщик задач на скрытые задания, на macOS - проверить ~/Library/LaunchAgents на незнакомые plist-файлы. Компрометация CI/CD-окружений означает, что все секреты, переданные в рабочий процесс, должны считаться скомпрометированными. Пока мейнтейнеры не подтвердят смену учётных данных для публикации и закрытие всех каналов доступа, любая новая версия пакета должна рассматриваться с крайней осторожностью.
Индикаторы компрометации
Package
- jscrambler@8.14.0
- jscrambler@8.16.0
- jscrambler@8.17.0
- jscrambler@8.18.0
- jscrambler@8.20.0
IPv4
- 37.27.122.124
- 57.128.246.79
MD5
- 6976bd1e56f6b4214c4c44205044422e
SHA1
- c05bf7dc45672d7a59cbd5e300f586482da14d00
SHA256
- 9eeffcb5c3445ef9512f7776045f99ea23f9ebed989f8570bc4634b4e340de5d
- a41a523ef9517aab37ed6eea0ec881821bdcb7aefcb5c5f603adc7907f868c86
- b7ca95d1b23c8e67416a25cedf741de0917c2096bbc9d24649eea7853d054903
- c8fd47d36bdf7c825378593ab82ed8c24d1dc52e26b507812393e24e1d5201fd
- fbbcf4d8f98168f78f5c0c47a9ae56d59ec8ac84a7c9ca6b797fedfb8d62d2bd