Введение

Мониторинг деятельности киберпреступной группировки Armored Likho показывает постоянное совершенствование её вредоносного инструментария. Злоумышленники активно разрабатывают собственные решения, регулярно выпуская обновлённые версии вредоноса и модифицируя архитектуру существующих компонентов для расширения функциональности и повышения эффективности атак.

Исследователи обнаружили ранее неизвестный образец RAT под названием BusySnake. Изучение нескольких обнаруженных версий позволило проследить этапы эволюции этого троянца и получить представление о процессе его разработки. Выявлены три основные реализации: версия на Python с использованием Telegram для управления, модификация с переходом на GitLab, а также новейшая версия, полностью переписанная на языке Go.

Несмотря на значительные изменения в структуре инструментов, группировка продолжает применять искусственный интеллект при разработке вредоносных компонентов. В отличие от предыдущих исследований, где признаки использования ИИ наблюдались на этапе получения первичного доступа, новые находки демонстрируют применение LLM при создании утилит для развития атаки.

Помимо собственных разработок, Armored Likho начала использовать открытый исходный код Kharon RAT, получая полный удалённый доступ к скомпрометированным системам и выгружая необходимые файлы.

Заметны изменения в организации командно-управляющей инфраструктуры. Группировка отказалась от публичных репозиториев GitHub в пользу приватных проектов на GitLab и GitHub, что значительно усложняет анализ сетевого взаимодействия.

В настоящей статье подробно рассмотрены новые инструменты Armored Likho и особенности их технической реализации.

BusySnake RAT — версия на Python

Агент с управлением через Telegram

При исследовании деятельности группировки Armored Likho обнаружен DLL-загрузчик, выполнение которого запускает ранее неизвестный троянец удалённого доступа, названный BusySnake RAT. Этот троянец написан на Python, в его коде отсутствуют методы обхода виртуальных окружений и обфускации. Для взаимодействия с командным центром используется инфраструктура ботов Telegram.

Загрузка вредоносной DLL реализуется через технику DLL sideloading, обеспечивающую выполнение кода в контексте легитимного приложения. При инициализации библиотеки создаётся глобальный мьютекс Global\b77c6d0d95a74fde, предотвращающий повторный запуск. Затем загрузчик дешифрует зашифрованные строки с использованием алгоритма XOR, формируя URL:

https://gitlab[.]com/api/v4/projects/[REDACTED]/repository/files/one_liner.txt/raw?ref=main

Загруженный файл one_liner.txt представляет собой скрипт, сохраняемый в переменную окружения процесса ENV_CTX_068A5326.

Загрузчик восстанавливает командную строку для выполнения скрипта и запускает её. При инициировании one_liner.txt осуществляется регистрация скомпрометированного устройства и подготовка параметров через конвейер CI/CD GitLab. Скрипт формирует и отправляет запрос на инициирование конвейера к репозиторию GitLab, передавая имя устройства (DEVICE_HOSTNAME) и информацию об операционной системе (DEVICE_OS). После инициирования конвейера скрипт периодически проверяет его состояние.

По завершении конвейера скрипт получает связанные с ним задачи и определяет задачу register_device, необходимую для загрузки артефактов. Создаётся локальная директория $appdata\updatehelper, в которую загружаются конфигурационные файлы config.json и token.txt. Файл token.txt содержит токен бота Telegram, а config.json — идентификатор администратора (ADMIN_ID).

Также из репозитория загружается стейджер install.ps1 и выполняется без записи на диск. Этот стейджер загружает интерпретатор Python версии 3.12, скрипт get-pip.py для установки менеджера пакетов, а также основную полезную нагрузку bot.py. Все компоненты сохраняются в директории $appdata\updatehelper.

После подготовки окружения стейджер запускает bot.py в фоновом режиме. Этот скрипт считывает из конфигурационных файлов токен Telegram-бота и идентификатор оператора, используемый для проверки прав при обработке входящих команд.

Особенностью BusySnake RAT является кроссплатформенность. Троянец предназначен для Windows, Linux и macOS. При инициализации рабочая директория определяется в зависимости от операционной системы:

  • $APPDATA\updatehelper для Windows;
  • ~/.config/updatehelper для Linux;
  • ~/Library/Application Support/updatehelper для macOS.

Вызывается функция setup_autostart() для закрепления в системе. Механизм закрепления зависит от целевой операционной системы.

На Windows закрепление осуществляется через запланированную задачу с именем TelegramBot, создаваемую PowerShell-скриптом, содержащимся в bot.py. Задача запускается через 30 секунд после входа в систему при условии наличия сетевого подключения.

Для macOS механизм закрепления реализуется созданием агента launchd. В директории ~/Library/LaunchAgents создаётся файл com.telegrambot.plist, выполняющий запуск BusySnake RAT.

Для Linux закрепление происходит через планировщик cron, создающий задачу для запуска бота при каждой загрузке системы.

Образец формирует сообщение оператору с информацией об операционной системе, имени хоста и рабочей директории.

Telegram-бот функционирует в режиме опроса: самостоятельно проверяет наличие новых сообщений через Telegram API. Обработка команд основана на системе фильтров библиотеки aiogram. Реализовано два обработчика сообщений: первый обрабатывает команду /start, второй — все остальные текстовые сообщения. Для каждого используется фильтр IsAdmin(), проверяющий соответствие идентификатора пользователя значению ADMIN_ID из конфигурационного файла.

При получении команды /start вызывается функция cmd_start(). Повторно определяются тип и версия операционной системы, имя хоста, после чего бот отправляет оператору сообщение с этими данными.

При получении других текстовых сообщений вызывается функция execute_command(). Текст сообщения интерпретируется как команда и выполняется с использованием asyncio.create_subprocess_shell(). Перед выполнением оператору отправляется уведомление. После завершения формируется сообщение с результатами. Максимальный объём передаваемых данных ограничен 3500 символами с учётом лимита Telegram на 4096 символов.

Агент с управлением через GitLab

Развитие BusySnake RAT сопровождалось изменением инфраструктуры управления. В последующей версии троянца атакующие отказались от Telegram и стали использовать GitLab в качестве командного канала. Вероятно, это позволило ускорить регистрацию скомпрометированных устройств и их администрирование, исключив необходимость создания отдельного бота для каждой системы.

Изменения коснулись и первичной полезной нагрузки. В новой версии запуск вредоносной DLL приводит только к загрузке и запуску стейджера install.ps1.

Функциональность install.ps1 была расширена: после установки зависимостей и загрузки полезной нагрузки стейджер формирует конфигурационный файл. В этот файл записываются два токена доступа к проекту GitLab с различными уровнями прав: один для чтения, другой для изменения переменных CI/CD. Также сохраняются идентификатор проекта и имя хоста.

Сформированный файл сохраняется в $appdata\updatehelper\config.json.

Стейджер запускает bot.py. В новой версии образец проверяет наличие уже запущенного экземпляра на машине. На Windows используется именованный мьютекс Local\OneDriveHelperBot. На Linux и macOS используется PID-файл bot.pid с проверкой существования соответствующего процесса в системе.

На этапе инициализации образец считывает из конфигурационного файла параметры работы, включая токены доступа к GitLab и идентификатор проекта. Также определяется рабочая директория.

Вызывается функция setup_autostart() для закрепления. Запланированная задача на Windows создаётся под именем OneDriveHelper. На macOS используется plist-файл com.onedrive.helper.plist.

После закрепления запускаются две основные функции heartbeat_loop() и command_loop(), обеспечивающие взаимодействие с GitLab инфраструктурой.

Обмен данными с GitLab осуществляется через переменные окружения CI/CD проекта с использованием внутреннего API по адресу:

https://gitlab[.]com/api/v4/projects/{PROJECT_ID}/variables

API включает функцию gl_get() для чтения значений переменных и функцию gl_set() для их создания и изменения.

В коде определён набор переменных CI/CD для обмена данными между оператором и скомпрометированным устройством. Названия переменных содержат имя хоста, позволяя управлять несколькими устройствами в одном проекте.

Функция heartbeat_loop() обеспечивает передачу данных о скомпрометированном устройстве. При первом запуске происходит регистрация через установку значения переменной PING_{HOSTNAME}, содержащей текущее время, IP-адрес и версию ОС. Далее значение обновляется каждые 60 секунд, позволяя оператору определять доступность устройства.

Функция command_loop() реализует цикл получения и выполнения команд. Каждые пять секунд производится чтение переменной CMD_{HOSTNAME} для получения команды. Полученная команда выполняется. Результат записывается в переменную RESULT_{HOSTNAME} с максимальным размером 8000 символов, соответствующим ограничению GitLab на длину значения переменной CI/CD. Затем переменная CMD_{HOSTNAME} очищается.

BusySnake RAT — версия на Go

Модернизация арсенала Armored Likho продолжилась обнаружением альтернативного образца BusySnake RAT, написанного на Go. В его составе имеется модуль patches.go, реализующий патчинг памяти для обхода AMSI и ETW. Для обхода песочниц используется модуль antisandbox.go. Также входят модуль для выполнения команд от С2 — commands.go и модуль для закрепления — persistence.go. Новый подход позволил избавиться от множества зависимостей и перейти на бинарный формат, усложняя анализ.

При инициализации определяются имя мьютекса для проверки наличия образца, частота опроса С2 и отправки heartbeat-запросов, а также базовый URL-адрес С2.

Запускается функция acquireMutex(), пытающаяся создать мьютекс. Если он уже существует, выполнение завершается. Если успешно создан, управление переходит функциям patchETW() и patchAMSI(), осуществляющим поиск DLL-библиотек и получение их базовых адресов.

Функции патчинга определяют расположение ключевых функций ETW и AMSI и перезаписывают их заданной последовательностью байт, отключая логирование.

Управление переходит функции antiSandbox(). Образец проверяет наличие отладчика через IsDebuggerPresent(), при обнаружении завершает работу. Запрашивает имя пользователя и сравнивает с WDAGUtilityAccount, активной при изолированной среде Application Guard. Для проверки на эмуляцию используется функция timingOK(), засекающая время выполнения и анализирующая результаты.

Также проводится проверка размера оперативной памяти через GlobalMemoryStatusEx: общая доступная память должна превышать 2 ГБ.

Образец собирает данные для регистрации на С2, обращаясь к переменным среды для получения имени хоста, находя предпочитаемый локальный IP-адрес через UDP-запрос, выполняя PowerShell-команды для получения версии ОС.

Для закрепления образец проверяет наличие запланированной задачи; при её отсутствии создаёт новую с именем MicrosoftUpdateSync, запускающейся только при входе в систему.

Основная логика реализована в двух функциях: heartbeatLoop(hostname, ip, osVer) и commandLoop(hostname), запускаемых как отдельные рабочие потоки. Первая отправляет heartbeat-запросы для подтверждения доступности. Запрос отправляется в формате JSON с именем хоста, локальным IP-адресом, версией ОС и токеном для записи в GitLab.

Токен зашифрован алгоритмом XOR с жёстко заданным 32-битным ключом, позволяя обойти YARA-сканеры. После функция glUpsert() выполняет регистрацию устройства на GitLab путём записи JSON-запроса в переменные проекта.

Функция commandLoop(hostname) опрашивает переменные GitLab для получения команды по переданному значению hostname. Используется токен для чтения. После переменная очищается функцией clearCommand(hostname), и команда передаётся на выполнение.

Образец оснащён следующими командами:

  • CMD_shell — запускает PowerShell в режиме скрытого окна
  • CMD_file_upload — загружает файлы размером более 4,5 КБ в ветку GitLab
  • CMD_file_list — проверяет список файлов в директории
  • CMD_file_get — загружает файлы размером до 4,5 КБ в переменную, закодировав Base64
  • CMD_uninstall — удаляет задачу, очищает переменные и рабочую директорию

Кампания с использованием Kharon RAT

При анализе методов и техник Armored Likho выявлена ранее неизвестная кампания с использованием Kharon RAT. Для доставки троянца использован загрузчик формата EXE, представляющий собой разработку злоумышленников. Он обладает нетипичной структурой и позволяет дешифровывать и загружать основной образец, зашифрованный алгоритмом ChaCha20.

Заражение начинается с HTA-загрузчика new text document.hta. В скриптовой части явно видны признаки использования генеративного ИИ, а комментарии написаны на украинском языке.

Скрипт состоит из трёх ключевых функций — StartDownload, SchTsk и RegK — где первая загружает следующий загрузчик, остальные осуществляют закрепление на хосте жертвы. В отличие от предыдущих кампаний, используются приватные репозитории, доступ к которым регулируется API-токеном. Загрузчик скачивается из репозитория foxxy-lgtm/officeupdt и сохраняется как AutoUpdt.exe и CheckMissed.exe.

Закрепление происходит через модуль win32com.client, обращающийся к COM-объекту Schedule.Service и создающий запланированную задачу OfficeUpdt с путём C:\Office\AutoUpdt.exe. Также добавляется запись в ключ реестра Software\Microsoft\Windows\CurrentVersion\Run.

Обнаружена упрощённая цепочка доставки Kharon RAT, в которой используются BAT-скрипты в качестве первичных загрузчиков. При запуске загружается PDF-приманка и идентичный загрузчик второго этапа, переименовываемый в svch0st.exe для мимикрии под легитимный процесс.

Запущенный загрузчик — это бинарный файл EXE, написанный на C++. При анализе обнаружены мусорные функции, возвращающие код 0.

Основная логика заложена в функции sub_140007610, состоящей из нескольких ключевых этапов. Сначала образец проверяет наличие отладчиков через функции IsDebuggerPresent() и CheckRemoteDebuggerPresent(), размер доступной памяти и обходит песочницу.

После проверок функция sub_1400096E0 дешифрует четыре аргумента: url_host, url_path, local_buf, context. Дешифровка осуществляется по нечётным байтам с использованием XOR с ключом 0xAA. Аргументы собираются в сетевой запрос к GitHub-репозиторию с API-ключом. По полученному адресу загружается полезная нагрузка.

Образец загружает wininet.dll и разрешает функции через хэши их имён, затем скачивает файл update.bin. Этот файл структурно разбивается на три части: первый блок 12 байт, второй 32 байта, третий с 45 байт до конца.

Первые два блока представляют собой счётчик и ключ шифрования ChaCha20, третий — зашифрованный Kharon RAT. Загрузчик дешифрует третий блок, выделяет память через NtAllocateVirtualMemory, записывает расшифрованный Kharon RAT в формате позиционно независимого кода, создаёт отдельный поток через NtCreateThreadEx и запускает троянец.

Kharon RAT — позиционно независимый RAT-троянец, распространяющийся в форматах EXE, DLL, SVC и BIN. Его серверная часть интегрируется в экосистему фреймворка AdaptixC2. Поддерживается коммуникация по HTTPS и SMB. Троянец содержит встроенную функциональность двойного шифрования через XOR и LOKI с последующим Base64-кодированием.

Образец имеет модульную архитектуру с модулями file_system, injection, kit, include. Имеет возможность инъекции в запускаемые процессы, мимикрирует под легитимный сервис и создаёт именованный канал \\.\pipe\spoolss для получения ответов от внедрённого кода.

Образец может загружать файлы на целевое устройство и выгружать данные с него через нативные модули на C++.

В образце обнаружены конфигурационные профили с параметрами: Jitter (30%), Sleep (5000 ms), Mask (ON), Ppid (2), BlockDlls (3), Spawn (C drive letter), Worktime (не задан), HeapObf (ON), KilldateSelfdel (1), AmsiEtwBypass (ON), Syscall (OFF), ForkPipeName (\\.\pipe\spoolss), BofApiProxy (1).

Для циклического опроса сервера используется функция Sleep со значением Jitter. Для сетевой коммуникации используется профиль GET-запросов по путям /api/v1/status, /api/v1/health для запроса команд и проверки доступности сервиса.

Обращения через метод POST по путям /api/v1/upload, /api/v1/submit позволяют загружать файлы на С2-сервер. Первый предназначен для эксфильтрации файлов, второй — для отправки результатов выполнения команд.

Выводы

Группировка Armored Likho продолжает разрабатывать новые версии BusySnake RAT и использует Kharon RAT для проведения атак с использованием легитимной инфраструктуры. Стали использоваться приватные репозитории GitHub вместо публичных. Полезная нагрузка загружается с GitLab через однострочные скрипты.

Злоумышленники применяют генеративный ИИ для создания первичных загрузчиков и полезных нагрузок, автоматизируя работу и усложняя атрибуцию. Появились новые методы проверки виртуальных сред и статическая обфускация передаваемых полезных нагрузок. Мониторинг деятельности Armored Likho продолжается с информированием об актуальных угрозах.