Как JavaScript и картинка превращают MSBuild в звено атаки
📋 Кратко
Обычная картинка сама по себе не запускает MSBuild. Риск появляется, когда JavaScript, обработчик изображений и сценарий сборки передают друг другу данные и команды. Разбираем подтверждённую цепочку с шестью слоями упаковки, Remcos и легитимным MSBuild.exe, а также показываем, как защитить репозиторий, агент CI/CD, артефакты и учётные данные.
Цепочка начинается с невзрачного файла JavaScript. Внутри обнаруживается не один вредоносный объект, а несколько слоёв упаковки. В центре схемы оказывается Remcos RAT 7.3.1 Pro, запущенный через легитимный MSBuild.exe.
Такой сценарий опасен для сборочной среды. Разработчик видит скрипт или ресурс, а агент CI/CD обрабатывает его автоматически. Если сборка имеет широкие права, вредоносный файл получает доступ к секретам, сети и артефактам.
🔍 Что именно происходит в атаке
Исходный образец получает имя dTSlkj83JJD.js. Анализ проходит статически. Ни одна стадия цепочки не запускается. Исследователь раскрывает слои по коду и данным.
В файле находится 1 626 строк. Большая часть строк не выполняет полезных действий. Такой мусорный код мешает анализу и скрывает важные фрагменты.
Цепочка содержит шесть уровней. Сначала идёт JScript для Windows Script Host. Затем появляется PowerShell, спрятанный в переменной окружения.
После этого работает загрузчик PowerShell. Он связан с .NET-сборкой, приклеенной к JPEG-картинке. Далее используется текстовый файл с исполняемым файлом «задом наперёд».
Финальный слой содержит Remcos RAT 7.3.1 Pro внутри легитимного MSBuild.exe. За всё время на диске появляется только исходный файл JavaScript. Остальные части живут в памяти, сети или несколько секунд.
Что сделать сейчас: запретите автоматическую обработку неизвестных JavaScript-файлов на агенте сборки. Сначала сохраните файл, хеш и журналы, затем передайте образец на статический анализ.
🧩 Почему картинка не является программой
JPEG-файл не запускает MSBuild при обычном открытии. Формат изображения хранит данные для декодера. Он не получает права на выполнение команд только из-за расширения.
Риск появляется в связке компонентов. Скрипт может искать данные внутри файла. Конвертер может читать метаданные. Сценарий сборки может передавать результат следующему процессу.
В разобранной цепочке .NET-сборка приклеена к JPEG. Это не означает, что любой JPEG опасен. Опасной становится логика, которая извлекает скрытый объект и передаёт его загрузчику.
Особое внимание нужно уделять генерации ресурсов. Сборка часто преобразует изображения, шрифты и файлы локализации. Каждый такой этап запускает отдельный инструмент или библиотеку.
JavaScript-инструмент может принимать имя файла из репозитория. Он также может запускать дочерний процесс. Поэтому безопасность зависит не только от содержимого картинки.
Что сделать сейчас: отделите обработку изображений от этапов с секретами. Не передавайте одному процессу доступ к ресурсам, репозиторию и ключам выпуска.
⚙️ Роль JavaScript и обработчиков ресурсов
JavaScript связывает разные этапы цепочки. Он может запускаться через Windows Script Host или через инструменты проекта. В первом случае файл получает доступ к системной среде Windows.
В обычной разработке JavaScript также участвует в сборке интерфейса. Он запускает установку зависимостей, генерацию ресурсов и преобразование файлов. Такой код часто выполняется автоматически.
Вредоносный сценарий маскируется мусорными строками. В разобранном файле полезные действия теряются среди 1 626 строк. Это снижает ценность простых правил, которые ищут короткий подозрительный скрипт.
Другой риск создают зависимости. Пакет может запускать сценарий при установке. Сборщик может вызывать внешнюю программу для конвертации изображения. Скрипт может получить переменные среды агента.
Нельзя считать доверенным весь каталог проекта. Репозиторий содержит код, тестовые данные и ресурсы. Каждый объект проходит через инструменты сборки с разными правами.
Что сделать сейчас: составьте список JavaScript-сценариев, которые запускаются в CI/CD. Для каждого сценария укажите входные файлы, дочерние процессы, сеть и доступные секреты.
🛠️ Почему злоумышленник выбирает MSBuild
MSBuild — легитимное средство сборки приложений Windows. Оно участвует в нормальном процессе разработки. Система CI запускает проект, выполняет цели и формирует результат.
Именно доверие делает MSBuild удобным прикрытием. Защитное средство видит знакомый процесс. Команда видит обычную задачу сборки. Подозрительная активность теряется среди разрешённых операций.
В разобранной схеме Remcos находится внутри легитимного MSBuild.exe. Это не доказывает уязвимость самого инструмента. Здесь используется доверенный процесс для выполнения чужой нагрузки.
У MSBuild есть доступ к проектным файлам и временным каталогам. В CI он может видеть переменные среды, токены и сетевые адреса. Поэтому компрометация шага сборки затрагивает весь конвейер.
Важно отличать сбой сборки от атаки. В другом техническом случае ошибка MSBuild связана с XamlTaskFactory и временной DLL. В журнале появляется ошибка MSB4175. Сам факт падения не доказывает вредоносную активность.
Ложные сбои снижают внимание команды. Если сборка часто падает без понятной причины, сотрудники начинают перезапускать её автоматически. Это создаёт удобное окно для скрытой активности.
Что сделать сейчас: включите отдельный контроль запуска MSBuild. Фиксируйте родительский процесс, командную строку, проект, цель, пользователя и дочерние процессы.
🎯 Модель угроз для конвейера сборки
Первый объект риска — репозиторий. В него попадает изменённый скрипт, ресурс или файл проекта. Изменение может выглядеть как обычная правка интерфейса.
Второй объект — агент сборки. Он обрабатывает код и запускает инструменты. Если агент постоянно используется, вредоносный процесс может оставить следы за пределами одной задачи.
Третий объект — хранилище артефактов. Конвейер публикует готовые файлы после сборки. Если проверка отделена от публикации, заражённый результат уходит дальше.
Четвёртый объект — учётные данные. Переменные среды часто содержат токены, ключи и адреса внутренних систем. Доступ к ним превращает локальную атаку на сборку в атаку на инфраструктуру.
Пятый объект — рабочие станции разработчиков. Файл из репозитория может запускаться локально через Windows Script Host. Разработчик ожидает сборку приложения, но получает другое поведение.
- Репозиторий принимает изменённый JavaScript или ресурс.
- Сборщик обрабатывает файл без ручной проверки.
- Дочерний процесс получает права агента.
- Секреты читаются из переменных среды.
- Артефакт публикуется до завершения проверки.
Что сделать сейчас: нарисуйте границы доверия между репозиторием, агентом, хранилищем артефактов и секретами. Для каждой границы назначьте отдельную проверку.
🔒 Как укрепить агент CI/CD
Агент сборки не должен быть постоянной рабочей станцией. Используйте изолированную среду для каждой задачи. После завершения удаляйте временные файлы и переменные.
Разделяйте этапы. Сборка, тесты, анализ ресурсов и публикация не должны работать с одинаковыми правами. Этап публикации получает только проверенный результат.
Не запускайте сборку с непроверенных веток в привилегированном окружении. Для внешних изменений используйте отдельный агент без секретов. Ручное подтверждение нужно перед выпуском артефакта.
Ограничьте сеть. Сборочному процессу не нужен свободный доступ ко всем внутренним системам. Разрешайте только нужные направления и протоколы.
Ограничьте дочерние процессы. JavaScript-инструмент не должен без причины запускать PowerShell, Windows Script Host или MSBuild. Если такой запуск нужен, зафиксируйте его в разрешённом списке.
Сохраняйте полные журналы. В них должны быть имя процесса, родитель, аргументы, пользователь и путь к файлу. Отдельно записывайте сетевые обращения и чтение переменных среды.
Что сделать сейчас: создайте тестовую ветку с безопасным скриптом и проверьте, какие процессы и права видит агент. Список должен быть коротким и понятным.
🧪 Проверка JavaScript, изображений и зависимостей
Фиксируйте версии зависимостей. Храните lock-файлы в репозитории. Проверяйте изменения перед обновлением пакетов.
Проверяйте хеши загруженных архивов и инструментов. Не принимайте файл только по имени или расширению. Сравнивайте формат с фактическим содержимым.
Сканируйте изображения и метаданные. Контролируйте размер, глубину вложенности и необычные поля. Отдельно проверяйте файлы, которые проходят через конвертацию.
Запретите сетевые загрузки во время обычной сборки. Зависимости сначала попадают во внутреннее хранилище. После проверки сборка использует зафиксированный набор файлов.
Разделяйте установку зависимостей и сборку. Установочный сценарий не должен получать ключи выпуска. Генерация ресурсов не должна иметь доступ к хранилищу артефактов.
Проверяйте изменения в сценариях. Любая правка package-файла, проекта или скрипта сборки должна требовать просмотра. Одного одобрения изменения картинки недостаточно, если меняется путь обработки.
Что сделать сейчас: включите обязательную проверку lock-файлов, хешей и сценариев установки. Запретите публикацию результата при ошибке проверки ресурса.
📋 Признаки компрометации сборки
Первый признак — неожиданный запуск JavaScript через Windows Script Host. Особенно опасна цепочка, где скрипт запускает PowerShell или другой интерпретатор.
Второй признак — MSBuild запускается не из ожидаемого процесса. Проверьте родителя, командную строку и проект. Сама по себе легитимность файла MSBuild.exe не подтверждает безопасность действия.
Третий признак — временные файлы появляются и исчезают за секунды. В разобранной цепочке большая часть компонентов не сохраняется на диске.
Четвёртый признак — изображение имеет необычный размер или дополнительные данные. Такой факт не доказывает атаку, но требует проверки источника и обработчика.
Пятый признак — сетевые обращения во время офлайн-сборки. Сравните адреса, время и процесс-инициатор. Отдельно проверьте, читал ли процесс секреты.
Шестой признак — внезапные изменения артефактов. Сравните хеши результата с повторной сборкой. Проверьте, какая ветка запустила задачу.
- Сохраните исходный файл и его хеш.
- Остановите публикацию новых артефактов.
- Изолируйте агент без удаления журналов.
- Сохраните список процессов и сетевых соединений.
- Отзовите секреты, доступные задаче.
- Проверьте соседние сборки и ветки.
Что сделать сейчас: настройте оповещение на связку «JavaScript — PowerShell — MSBuild». Такое правило не заменяет анализ, но ускоряет реакцию.
🚨 Порядок реагирования на инцидент
Сначала остановите выпуск артефактов. Не перезапускайте подозрительную сборку без сохранения состояния. Повторный запуск может уничтожить важные следы.
Затем изолируйте агент от сети. Не удаляйте рабочий каталог до копирования файлов и журналов. Зафиксируйте время задачи, ветку, автора изменения и используемые зависимости.
Проверьте, запускалась ли цепочка фактически. Статический анализ показывает структуру файла, но не доказывает выполнение. Журналы процессов и сетевых соединений помогают разделить находку и инцидент.
Отдельно проверьте секреты. Если задача могла читать переменные среды, считайте их раскрытыми. После фиксации следов замените токены и ограничьте их права.
Проверьте артефакты. Сравните хеши до и после подозрительной сборки. Не доверяйте только названию файла или отметке успешного завершения.
После анализа восстановите конвейер с чистого агента. Удалите непроверенные зависимости. Добавьте правило, которое остановит аналогичную цепочку в будущем.
Что сделать сейчас: подготовьте короткую инструкцию реагирования. В ней укажите владельца агента, место хранения журналов, порядок изоляции и правила замены секретов.
📊 Что показывает разобранный образец
Образец демонстрирует ценность многоуровневой маскировки. Скрипт содержит мусорный код, скрытые команды и несколько форматов данных. Аналитик видит не одну подозрительную строку, а длинную цепочку преобразований.
На момент обнаружения ни одного хеша из цепочки нет в VirusTotal. Один промежуточный компонент собран всего за сутки до попадания на анализ. Это показывает, почему одного поиска по хешам недостаточно.
Статический разбор выявляет режимы, которые не включаются в конкретной атаке. Запуск образца мог бы показать только активную ветку. Поэтому безопасный анализ начинается с изоляции и изучения кода.
Главный урок касается доверия. Легитимная программа не становится вредоносной навсегда. Но злоумышленник может использовать её как часть цепочки. Контекст запуска важнее одного имени файла.
Вторая ошибка — считать ресурс безобидным. Картинка не выполняет код сама. Но автоматический обработчик может извлечь из неё данные и передать их следующему этапу.
Третья ошибка — смешивать сборку и выпуск. Если один агент одновременно компилирует код и публикует результат, атака получает слишком широкий эффект.
Что сделать сейчас: проведите инвентаризацию цепочки сборки. Отметьте каждый файл, процесс и секрет, который появляется между коммитом и публикацией.
📚 Читайте также
- Локальный файрвол для кодинг-агентов: защита действий в CI/CD
- GitHub режет баг-баунти вдвое: новые правила программы и что это значит для безопасников
- Дропперы нового поколения: как распознать тихую загрузку трояна
- Prototype pollution без загрязнения: как атакуют прототипы JavaScript
- Сканирование активов АСУ ТП: как найти забытые Windows-узлы безопасно
📖 Термины
CI/CD · Supply Chain Attack · Безопасность приложений · Инцидент-реагирование · Троян