Привет, Хабр!
На связи Евгения Устинова, старший аналитик сетевой безопасности группы компаний «Гарда». В статье хочу рассказать, как нам удалось связать инструментарий двух группировок через особенности реализации сетевых протоколов.
Отследить эволюцию инструментов группировки SilverFox – например, ПО Winos – по отпечатку процедуры сетевой коммуникации оказалось сложной задачей, поэтому я решила поделиться кейсом.
Что такое Winos?
Winos – это вредоносный комплекс с модульной структурой, в основном задействуемый в кибератаках китайскими группировками. Аналитики фиксируют следы применения данного инструмента в различных регионах, но в данном случае мы рассмотрим новейшую версию, которая пока получила распространение в передовом азиатско-тихоокеанском регионе.
Winos обладает широким набором возможностей. В частности, этот вредонос способен проводить DDoS-атаки, управлять файлами, получать доступ к веб-камере, делать скриншоты, записывать аудио с микрофона, фиксировать нажатия клавиш и открывать злоумышленникам удаленный доступ к зараженному устройству. Особенность Winos заключается в системе плагинов из более чем 20 компонентов для Windows, а также в возможностях добавления злоумышленниками внешних плагинов.
Почему считаем, что это Winos?
Разработка Winos, как и многих других инструментов удаленного управления, не стоит на месте: их функционал постоянно развивается. Актуальной версией Winos считается 4.0.
Нам удалось «поймать» новый Winos-семпл, который, используя прежнюю схему коммуникации – протокол, уже детектируемый вендорами, – применил опенсорсную реализацию протокола KCP HP-Socket. Особенности протокола я раскрою чуть позже, а сначала посмотрим, с чего начинается атака.
Делюсь хеш-суммой MD5 для семпла, в котором «сплелись» известные протоколы Winos и новая реализация KCP: MD5:518f06379ec6c5d13303b400236842c0.
Дополнительно в приложении к статье приведены ссылки на детонацию в песочнице исследуемого и связующих семплов.
Вектор начальной компрометации
Как правило, в качестве первичного вектора атаки злоумышленники используют фишинг. Например, рассылку целевых писем, содержащих счета-фактуры. При этом данные об отправителе могут быть скомпрометированы или подделаны.

Перевод заголовка письма с китайского на русский:
От: Ti. - <thedear-abuse@jtsuw.cn>
Тема: [Электронный счет] У вас есть электронный счет [Номер счета: 05751366]
Отправлено: Пн, 14 июля 2025 г., 14:05:03 +0800
Кроме того, хакеры задействуют следующие тактики социальной инженерии:
сокрытие и подмена URL-ссылок;
маскировка истинного типа файла;
использование, вредоносных вложений и ссылок, а также сжатых архивов (RAR) для вложений;
психологическая манипуляция и имитация доверенных брендов.
Первичный дроппер
Полезная нагрузка вредоносного ПО содержится в самораспаковывающемся RAR-архиве (RAR Sfx), который автоматически извлекает и запускает вредоносный код. В данном случае RAR-архив выступает в роли дроппера. Все, что нужно злоумышленнику, – это чтобы жертва отреагировала на фишинговое письмо: открыла вложение или перешла по вредоносной ссылке за очень «важным» обновлением ПО.
Что показал анализ дроппера
В ходе расследования атаки я выделила ключевые признаки компиляции, в частности, пути к PDB-файлам, оставшиеся в отладочной информации:
D:\Projects\WinRAR\sfx\build\sfxrar32\Release\sfxrar.pdb.
Дополнительно провела проверку статическим анализатором. Результаты, которые получила, однозначно подтвердили мое исходное предположение из PDB:
PE32
sfx: RAR
Compiler: EP:Microsoft Visual C/C++ (2013-2017) [EXE32]
Основные функции RAR Sfx-архива
Как только жертва запускает RAR-архив, тот в «тихом» режиме, извлекает в целевую папку зашифрованный шелл-код и инициатор. Дроппер запускает инициатор, используя параметр SETUP.

Делюсь хеш-суммой MD5 дроппера: 527f59d0ab8798f59e7638282b2130f6.
Действия инициатора (ConsoleApplica.exe)
Инициатор выполняет следующие действия.
Создает механизм персистентности. При каждом запуске инициатор создает и регистрирует себя через скрипт, обеспечивая тем самым устойчивость заражения.
Путь к скрипту: C: Windows\Templrunme_4F116F21.vbs;
Функция скрипта: Запуск инициатора ConsoleApplica.exе с помощью метода Run объекта WshShell.
Регистрирует задания в планировщике задач. Злоумышленники используют планировщик задач так, чтобы при входе любого пользователя в систему выполнялась команда PowerShell. Она перепроверяет наличие закрепления в задаче с именем MуApр_4F116F21. В противном случае создает скрытое задание с наивысшими привилегиями, запускающее VBS-скрипт по триггеру.
Активирует сетевые интерфейсы. Для обеспечения сетевым подключением выполняется специальный скрипт, который включает все возможные отключенные сетевые адаптеры.
Запускает шелл-код. Инициатор активирует шелл-код (лоадер) из файла С:\Windows\EVAAA.bin, расшифровывая его XOR с ключом 0х58. Хотя шелл-код хранится в зашифрованном виде, он дополнительно снабжен обфусцированными вызовами сетевых функций, необходимыми для создания подключения через библиотеку ws2_32.dll. Обфускация производится за счет деления строк на части. Это частая практика на ряду с хешированием имен функций.
Хранение части важных компонентов инициатора в зашифрованном виде затрудняет обнаружение атаки методами статического анализа файлов на диске.
Лоадер, запущенный инициатором, загружает второй шелл-код (стейджер) и передает ему управление последующим этапом развертывания.
Второй шелл-код и техника загрузки основного модуля
Главная функция стейджера – загрузить, расшифровать и передать управление основному модулю ValleyRAT.
Код стейджера обладает уже значительно большей функциональностью по сравнению с лоадером. Внутри предусмотрены механизмы для обхода детектирования и реализации техники Reflective DLL Injection.
Такая последовательность действий затрудняет обнаружение атаки, а учитывая, что хакеры используют две низкоуровневые компоненты, препятствий для загрузки и исполнения вредоносного кода на компьютере жертвы почти нет.
Динамическое разрешение АРІ. Как и в лоадере, злоумышленники применяют алгоритм слайсинга строк, чтобы скрыть вызовы функций из экспорта системных библиотек. В частности, критические имена собираются в коде посимвольно.
Приведу фрагмент машинного кода с примерами.
Сегментация строк для обхода статического анализа
HEX-код  | 
Подстрока  | 
6E 74 64 6C  | 
ntdl  | 
6C 2E 64 6C  | 
l.dl  | 
6C 00  | 
l\0  | 
52 74 6C 41  | 
RtlA  | 
6C 6C 6F 63  | 
lloc  | 
61 74 65 48  | 
ateH  | 
65 61 70 00  | 
eap\0  | 
В теле шелл-кода отсутствуют строковые имена функции, что затрудняет его детектирование простыми методами анализа сетевого трафика и статического анализа.
Поиск базовых адресов модулей. Адреса системных DLL-библиотек определяются через PEB без использования импортов. Это распространенная техника обхода ASLR (Address Space Layout Randomization). Благодаря этому злоумышленники могут находить PEB через адрес GS:0x30, а через него – базовые адреса DLL, даже при включенном ASLR. Это работает, так как адрес GS:0x30 (PEB) фиксирован и не рандомизируется ASLR.
Что такое сегментные регистры
Сегментные регистры ‒ это специальные регистры в архитектуре x86/x64, которые хранят указатели на сегменты памяти.
GS стал основным для системных структур Windows
Стейджер загружает и расшифровывает основной модуль удаленного доступа (RAT). Вот хеш-сумма MD5 расшифрованного модуля: dadafc81ccf75248b1cf18c206a3e255
Основной модуль (Winos/ValleyRAT)
Хотя статические анализаторы (VirusTotal) детектируют файл основного модуля на диске, но по замыслу атакующих его не должно там оказаться. Это достигается за счет Reflective Injection.
Давайте посмотрим, что приготовили злоумышленники в сетевой части атаки.
После того как инициатор закрепился и успешно загрузил основной модуль в память системы, устанавливается связь с командным сервером злоумышленников. В случае задействования протокола резервного канала управления эта процедура проходит в три этапа:
Регистрация жертвы на командном сервере;
Получение конфигурации резервного канала связи;
Соединение по резервному каналу.
На первом этапе трафик между хостом жертвы и сервером злоумышленников шифруется и маскируется своим кастомным протоколом поверх ТСР. Далее на резервном канале в качестве транспорта используется UDP, а для контроля состояния потока – КСР. При этом для KCP-модуля применяется особая реализация процедуры «рукопожатия».
Отсутствие в протоколе KCP стандарта на установление связи или «рукопожатие» дает возможность аналитикам отслеживать различные варианты реализации процедуры и использовать их как отпечатки.
Стоит отметить, что протокол KCP находили у бэкдоров, таких как Keyplug, а также в других инструментах группировки APT41 (Winnti) еще с 2020 года. Однако в Winos мы видим его впервые. В дополнение к этому протоколу нам удалось обнаружить реализацию инкапсуляции прежнего протокола Winos в протокол WebSocket. Но в рамках этой статьи хочу рассказать исключительно об особенностях KCP.
Как уже упоминала ранее, коммуникация с резервным сервером происходит через порт 80 с помощью модифицированного KCP. Данная версия протокола получила рабочее название Gh0stKCP. Судя по коду из репозитория HP-Socket, это не что иное, как вариант реализации KCP, используемый в Winos, включая процедуру «рукопожатия» из файла ArqHelper.h.
Описание протокола ниже.
Кастомное «рукопожатие». Состоит из серии пакетов размером 12 байт, содержащих заголовок KCP (4 байта) и идентификаторы, выбранные случайным образом для каждой процедуры согласования. Это необходимо для установления уникальности клиентского и серверного потоков.

Описание полей и структуры пакета
4f bb – magik-байты для Winos (служат триггером входящего подключения)
01 [00|01] – служебное поле (тип соединения и его флаг завершения)
7e 5e 1a 00 – идентификатор клиентского стрима
3d fa f4 01 – идентификатор серверного стрима
В данной реализации «рукопожатия» для процедуры согласования клиенту и серверу требуется целых семь пакетов, где в финальном пакете устанавливается флаг завершения процедуры согласования, равный единице. При этом идентификатор клиентского стрима проходит многоэтапное согласование на стороне сервера, а идентификатор серверного стрима – на стороне клиента.
Почему количество пакетов в «рукопожатии» привлекло мое внимание?
Обычно в «рукопожатии» для проведения процедуры согласования клиенту и серверу необходимо три пакета, и разработчики протоколов борются за быстродействие, стремясь сократить «рукопожатие». А тут – целых семь пакетов!

На самом деле, логически это обычное трехстороннее «рукопожатие», только с лишними, на мой взгляд, пакетами. Весь этот процесс можно сократить до трех пакетов:
Клиент отправляет идентификатор своего стрима;
Сервер отправляет идентификатор своего стрима;
Клиент отправляет подтверждение, содержащее оба идентификатора.
Служебные пакеты протокола KCP (24 байта). На рисунке ниже показан пример стандартного протокола KCP.

Описание полей
7e 5e 1a 00 52 – идентификатор стрима
52 – тип пакета – IKCP_CMD_ACK в соответствии со спецификацией
00 02 – размер «окна» для сообщений
eb 6a 21 04 – метка времени
01 00 00 00 – количество принятых сегментов
00 00 00 00 – последние четыре октета. Это размер данных, которых нет в сообщении типа IKCP_CMD_ACK, но есть в случае передачи данных от приложения
Пакет KCP с данными Winos. Содержит стандартный KCP-заголовок пакета (24 байта) типа IKCP_CMD_PUSH и данные кастомного протокола, часть из которых зашифрована XOR с ключом 0x3A.
Учитывая, что служебная часть кастомного протокола имеет минимальный размер 56 байт, пакеты с данными за счет инкапсуляции будут иметь размер 80 байт и более.

Поля протокола KCP (24 байта), подчеркнутые на рисунке выше красным, представляют собой:
7e 5e 1a 00 – идентификатор стрима;
51 – тип пакета – IKCP_CMD_PUSH;
38 00 00 00 – длина сегмента данных (56 байт).
Зеленым цветом на рисунке выделены данные кастомного протокола Winos, включая 16-байтовый идентификатор сообщения и зашифрованную служебную часть размером 40 байт.
Если приложение захочет обменятся полезной нагрузкой в протоколе, то его данные будут расположены по смещению 80 байт от начала пакета KCP.
Полезная нагрузка. Данные в payload перед отправкой зашифровываются XOR (0x3A) и сжимаются библиотекой zLib. Затем они дополняются заголовком кастомного протокола 56 байт и упаковываются в KCP.

На рисунке выше красным выделены байты заголовка стандартного KCP-пакета, зеленым – служебные данные кастомного протокола Winos, а синим – полезная нагрузка протокола Winos.

Техники уклонения и сокрытия
Далее приведу несколько тактик и техник, которые я встретила в процессе разбора угрозы. Есть различные подходы к описанию действий хакеров. Я руководствуюсь ATT&CK MATRIX – доступной базой знаний MITRE, основанной на анализе реальных атак.
Трафик. Хакеры использовали многоэтапный процесс получения полезной нагрузки, кастомное шифрование в канале передачи, обфускацию в протоколах передачи:
TA0011 Command and Control
T1095 Non-Application Layer Protocol
T1573 Encrypted Channel
T1001 Data Obfuscation
T1104 Multi-Stage Channels
Память. Для сокрытия резидентного кода от средств мониторинга процессов и модулей применялся полнофункциональный PE-лоадер/инжектор:
TA0005 Defense Evasion
T1055.002 Portable Executable Injection
T1620 Reflective Code Loading
Дополнительные тактики и техники. Техники и тактики, указанные ниже, были необходимы атакующим, чтобы создавать задания в планировщике задач, использовать PowerShell для выполнения команд, исполнять VBS-скрипт и собирать данные об операционной системе, пользователях и процессах для отправки на С2-сервер:
TA0003 Persistence
T1053.005 Scheduled Task
TA0002 Execution
T1059.001 PowerShell
T1064 Scripting
TA0007 Discovery
T1082 System Information Discovery
Вместо заключения
В данный момент SilverFox демонстрирует продуманную многоступенчатую схему атаки: социальная инженерия для входа, дроппинг, укрепление присутствия через скрипты и задания, а также попытки маскировать свое поведение в атакуемой сети и процессах. Злоумышленники постоянно модифицируют свой не публичный инструментарий удаленного доступа для скрытного нахождения в инфраструктуре.
Такие действия представляют реальную угрозу корпоративному сектору. Однако, несмотря на усилия хакеров по маскировке и адаптации инструментария, поведенческие аномалии на различных этапах атаки остаются устойчивыми индикаторами компрометации.
Приложение
IOC:
Индикатор  | 
Объект  | 
518f06379ec6c5d13303b400236842c0  | 
QQBrowserLiveup.exe  | 
397117f23e73b2f3f6d97be441487410  | 
yiosrecovery.exe  | 
0511b46fe1ed1f9b51cf2da868f741c8  | 
x2ajrmtq.exe  | 
397117f23e73b2f3f6d97be441487410  | 
2025-5-25-05851336.exe  | 
9b1939b09bedc759169ca41eb97fef0d  | 
iuythtrh.bin  | 
844ec5141cc19d86074874e404898930  | 
通讯录管理系统15.exe  | 
384671e3078cb8ba0c0b5706a8437bb0  | 
通讯录管理系统.exe  | 
507cf41361cbbf6a01d8e1712557f726  | 
runme_48A6DB93.vbs  | 
82240ff5f78335c2bb0bdaf70c63b62c  | 
runme_4F116F21.vbs  | 
527f59d0ab8798f59e7638282b2130f6  | 
2025-05-20-05751366.exe  | 
ed5a7a2c0f4e9a56f12bf3dbb38f2f29  | 
ConsoleApplica.exe  | 
0b986e02d93c7b2f1911b1326ecde6ed  | 
EVAAA.bin  | 
43.133.39.217: 80  | 
UDP KCP C2  | 
103.214.174.238: 8899  | 
TCP C2  | 
27.124.3.234: 8443  | 
UDP KCP C2  | 
Динамический анализ: