Половина краж с банковских карт в России за последние полгода — дело рук одного семейства троянов. 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:

Теперь на примере поясню, что обозначает каждое поле:

Значение

Назначение элемента

18.192.31.30:15508

Адрес сервера для ответов (взят из сокета)

AppData

Директория для данных приложения (в коде)

system_info

Директория для системной информации (в коде)

system_config

Директория для конфигурации (в коде)

meta_data

Шаблон имени для плагинов (/AppData/meta_data[n])

0.tcp.eu.ngrok.io

Адрес сервера (конфигурация)

11000011

Строка флагов из strings.xml

[CR]

Служебный маркер (код)

V4

Версия протокола (код)

Формирование идентификатора устройства

Чтобы в дальнейшем опознаваться на сервере, устройство-клиент использует специальный идентификатор. Троян собирает длины системных параметров устройства (плата, бренд, процессор, модель и другие), объединяет их в строку и вычисляет MD5-хеш, который становится уникальным и постоянным идентификатором жертвы.

"35" + (Build.BOARD.length() % isten("", 10)) +
(Build.BRAND.length() % isten("", 10)) +
(Build.CPU_ABI.length() % isten("", 10)) +
(Build.DEVICE.length() % isten("", 10)) +
(Build.DISPLAY.length() % isten("", 10)) +
(Build.HOST.length() % isten("", 10)) +
(Build.ID.length() % isten("", 10)) +
(Build.MANUFACTURER.length() % isten("", 10)) +
(Build.MODEL.length() % isten("", 10)) +
(Build.PRODUCT.length() % isten("", 10)) +
(Build.TAGS.length() % isten("", 10)) +
(Build.TYPE.length() % isten("", 10)) +
(Build.USER.length() % isten("", 10))

Важно, что в процессе создания идентификатора собираются не хеш-значения полей, а хеш конкатенации остатков от деления на 10 длин параметров устройства.

Формат сообщения «на проводе»

Как и все остальные сообщения, heartbeat-пакет упаковывается следующим образом:

[GZIP("-A")][GZIP("CraxsApp")]

 После упаковки структура уже имеет такой вид:

[длина GZIP("-A")][0x00][длина GZIP("CraxsApp")][0x00]
[GZIP("-A")][GZIP("CraxsApp")]

Загрузка плагинов

На таймлайне выделен этап загрузки плагинов
На таймлайне выделен этап загрузки плагинов

Процесс загрузки дополнительных модулей является одной из ключевых особенностей архитектуры 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. Таким образом, злоумышленник может изменять разделитель на этапе сборки, используя его в качестве идентификатора и пароля доступа к серверу.

Описание полей команды на примере данных, полученных из трафика

Поле

Значение в примере

Описание

Префикс

Указывает на тип сообщения «загрузка нового плагина»

Идентификатор плагина (полное имя загружаемого модуля)

plugens.angel.plugens.apps 

Задает идентификатор загружаемого модуля (для маршрутизации команд от сервера к плагинам)

Счетчик

Указывает порядковый номер или общее количество частей при множественной загрузке

Shell-команда

rm -r 

Удаляет предыдущие версии плагина перед установкой новой

Тип данных

dex 

Определяет формат передаваемых данных — исполняемый код Android (DEX-файл Dalvik Executable)

Shell-команда

ping -c 1 -W 15 

Проверяет сетевую доступность сервера и сохраняется для последующего выполнения

Опкоды 1-11

1 ... 11 

Служат активаторами для различных функциональных блоков при обработке последующих команд

Служебный маяк

-2 

Отправляет на сервер пустой «отстук»

Флаг отправки

-1 

Регулирует отправку служебного «маяка»

На стороне клиента процесс обработки команды загрузки плагина выглядит следующим образом:

  1. Полученное сообщение разбивается на массив строк с использованием разделителя

  2. Проверяется префикс, направляющий выполнение в ветку загрузки плагинов

  3. Байт-код плагина (он передается следом в этом сообщении) сохраняется во временный файл в директории AppData под именем вида meta_dataX как и указывалось в регистрационном сообщении

  4. Из полученного временного файла загружается класс через DexClassLoader, а ссылка на файл сохраняется в списке активных плагинов

  5. Shell-команды ( rm -r , ping -c 1 -W 15 ) сохраняются в массиве функциональных блоков для последующего выполнения

  6. Триггеры опкодов (opcode) 1-11 и маяки -2, -1 активируют блоки с заранее определенным функционалом

  7. Временный файл плагина удаляется (в штатном режиме), а сам плагин при этом остается в оперативной памяти

Назначение опкодов триггеров команд

Числа от 1 до 11 в команде загрузки плагинов не являются частью shell-команд, а представляют собой самостоятельные триггеры. Они извлекаются из сообщения и управляют заранее запрограммированными действиями.

Функционал каждого опкода

Опкод

Функциональный блок

1

Отправка статуса и логов

2

Проверка статуса администратора

3

Выполнение команд загруженных плагинов

4

Запуск сервиса геолокации

5

Остановка сервиса геолокации

6

Выполнение shell-команды

7

Отправка данных

8

Отправка статуса и логов

9

Отправка данных

10

Логирование (echo)

11

Зарезервирован или используется в других модулях

Запрос информации о зараженном устройстве

На таймлайне отражен процесс запроса информации о клиенте
На таймлайне отражен процесс запроса информации о клиенте

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

1|plugens.angel.plugens.info|method|1NRQ704|infox0D0xnullx0D0xnull

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

После получения команды плагин info приступает к сбору полной информации об устройстве. В зависимости от реализации, плагин может извлекать:

  • модель и производителя устройства;

  • версию операционной системы;

  • объем оперативной памяти;

  • состояние аккумулятора;

  • список установленных приложений;

  • данные об аккаунтах;

  • информацию о сети и сотовом операторе, а также множество других параметров.

Собранные данные упаковываются и отправляются на сервер в ответном сообщении с тем же идентификатором сессии 1NRQ704. Через идентификатор сервер связывает запрос и полученный ответ.

Сбор информации об установленных приложениях

Информация об приложениях отправляется в начале общения с сервером при каждом новом подключении
Информация об приложениях отправляется в начале общения с сервером при каждом новом подключении

Для формирования цифрового профиля жертвы злоумышленнику важно знать, какие приложения установлены на устройстве. Эту задачу выполняет плагин apps, который активируется командой следующего формата:

1|plugens.angel.plugens.apps|method|16QoV423|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|.

Структура данных

Поля разделены вертикальной чертой ( | - встроенный разделитель):

  • Приложение-отправитель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

Для выполнения команды трансляции экрана не нужен плагин. Эта функция реализована в основном коде трояна. Трансляция может осуществляться на сторонний сервер, указанный в команде.

Структура команды для захвата экрана

Команда состоит из нескольких обязательных элементов, разделенных маркером:

Элемент

Значение

Описание

Префикс

2

Команда для основного модуля

Команда

sc:on 

Включение захвата экрана (screen capture on)

Параметры

20~30~23ddfcd79dc9d589~450x300 

Настройки захвата

IP сервера

18.192.31.30 

Адрес для отправки скриншотов

Порт

15508 

Порт для отправки

Маркер

ddll 

Сигнал начала основной команды

Флаги

0|0 

Зарезервированные параметры

Разделитель

x0A0x 

Служебный маркер

ID жертвы

23ddfcd79dc9d589

Уникальный идентификатор бота

Параметры захвата экрана

Особого внимания заслуживает строка параметров 20~30~23ddfcd79dc9d589~450x300. Каждое поле в строке отделено символом ~ :

Параметр

Значение

Назначение

Качество

20

Степень сжатия JPEG (от 1 до 100). Низкое качество уменьшает размер передаваемых данных

FPS

30

Частота кадров в секунду. Определяет плавность транслируемого контента

ID сессии

23ddfcd79dc9d589

Уникальный идентификатор данной сессии захвата (совпадает с ID жертвы)

Разрешение

450x300

Размер передаваемого изображения в пикселях

Маршрут обработки команды захвата экрана в коде

Получение и парсинг (основной модуль):

  • Префикс 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-формате.

Итоговая структура данных скринкаста «на проводе»:

[GZIP(заголовок)][GZIP(GZIP(JPEG))]

Аудиостриминг: прослушивание через микрофон

Аудиотрансляция по интенсивности отправки пакетов сравнима с трансляцией экрана
Аудиотрансляция по интенсивности отправки пакетов сравнима с трансляцией экрана

Злоумышленник может прослушивать микрофон зараженного устройства. Эта функция реализована в плагине microphone и работает по принципу непрерывной трансляции аудиопотока на сервер. Запуск прослушивания инициируется командой от сервера с префиксом 1:

1
plugens.angel.plugens.microphone
method
-1
start
18.192.31.30
15508
8000
14VsL546
23ddfcd79dc9d589
0

Команда к загруженному плагину содержит следующие параметры, разделенные маркером x0D0x.

 Параметры команды

 Описание

 18.192.31.30

IP-адрес сервера для отправки аудиопотока

 15508

порт сервера

 8000

частота дискретизации (8 кГц, стандартное качество для голоса)

 14VsL546

уникальный идентификатор сессии записи

 23ddfcd79dc9d589

ID жертвы

 0

тип потока (0 — голосовой, 1 — музыкальный)

Принцип работы команды аудиостриминга

Получая команду start, плагин устанавливает прямое сокет-соединение с указанным сервером, минуя основной канал управления. Это важная деталь.

Аудиотрансляция идет по отдельному каналу, не смешиваясь с остальным трафиком, снижая нагрузку и усложняя обнаружение.

Плагин создает AudioTrack с заданными параметрами (частота 8000 Гц, моно, 16-битный PCM). В зависимости от типа потока он автоматически устанавливает максимальную громкость соответствующего канала через AudioManager. Это гарантирует качественную запись независимо от пользовательских настроек.

Разбивка аудиопотока на пакеты

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

  1. Заголовок с идентификатором сессии, 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

Описание

 1F 8B 

Magic bytes (gzip signature)

 08 

CM — deflate

 00 

FLG — все флаги сброшены

 00 00 00 00 

MTIME — не задано

 00 

XFL — компрессия по умолчанию

 00 

OS — FAT/Windows

 D3 35 04 00 

Compressed data (DEFLATE, 4 байта)

 2A 48 2D 30 

CRC32 (LE)

 02 00 00 00 

ISIZE — оригинал 2 байта (длина команды -1 )

Информационная строка также сжимается GZIP. Причем для разных исходных данных она будет своя. А вот Magic bytes и служебные поля Gzip останутся прежними: 1F8B 0800 0000 0000 0000 … 

Вычисление длин

  1. Длина сжатой строки -1 составляет 22 байта. В ASCII-представлении — 22. В шестнадцатеричном виде это дает байты 32 32.

  2. Длина сжатой информационной строки составляет 108 байт. В ASCII-представлении —108, или байты 31 30 38

Формирование заголовка

Заголовок формируется путем конкатенации: [ASCII длины ч.A] + [0x00] + [ASCII длины ч.B] + [0x00]. В шестнадцатеричном виде это выглядит как: 32 32 00 31 30 38 00 .

Финальная сборка сообщения

К заголовку последовательно дописываются сжатые части A и B. Затем на сервер отправляется итоговый поток данных следующего вида:

32 32 00 31 30 38 00
1f8b0800... (GZIP строки префикса)
1f8b0800... (GZIP информационной строки)

В конечном счете в трафике будет передана примерно вот такая конструкция:

Формат сообщения «на проводе»
Формат сообщения «на проводе»

Детектирование трояна средствами 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.

Гарда

t.me/garda_ai — создаем решения в сфере безопасности данных и сетевой инфрастуктуры

Приложение

Индикаторы компрометации (IoC) IP-адреса C2 серверов CraxsRAT

Список IoC

IP-адрес

Описание

 103.167.151.149 

C2 сервер

 

 

 

 

 

 

 

 103.180.213.98 

 103.216.117.207 

 103.74.100.176 

 107.148.12.75 

 144.31.30.235 

 147.185.221.30 

 147.185.221.31 

 151.243.219.185 

 151.243.219.251 

 154.198.49.119 

 158.69.214.127 

 178.250.188.120 

 18.156.13.209 

 18.157.68.73 

 18.192.31.30 

 18.192.93.86 

 18.197.239.5 

 18.198.52.32 

 187.33.146.20 

 191.96.79.201 

 192.169.69.25 

 193.161.193.99 

 193.233.113.17 

 194.26.192.200 

 209.25.140.20 

 212.64.210.140 

 212.64.215.198 

 23.26.201.95 

 3.127.138.57 

 3.68.171.119 

 3.69.115.178 

 3.74.27.83 

 3.79.221.78 

 35.157.111.131 

 38.246.73.190 

 41.103.124.211 

 41.36.68.119 

 49.13.127.132 

 80.211.137.34 

 85.192.48.17 

 87.242.106.13 

 94.1

Таблица 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

Проверка параметров системы ( Build.BRAND , Build.HARDWARE , Build.MODEL ) на наличие признаков эмулятора и завершение работы при их обнаружении. Это возможно благодаря наличию функции isEmu_DIV_ID_lator() 

T1628

Hide Application

Маскировка своей иконки из меню приложений, отключая основную активность через PackageManager.setComponentEnabledSetting()

Credential Access (TA0031)

T1417

Input Capture

Перехват вводимых данных несколькими способами: через JavaScript-скиммер, через кейлоггер, реализованный как кастомная клавиатура (InputMethodService), и через Accessibility Service, который считывает текст с экрана

T1636

Protected User Data

Извлечение SMS-сообщений, журнала звонков, данных адресной книги и списка установленных приложений с иконками

Discovery (TA0032)

T1420

File and Directory Discovery

Навигация по файловой системе устройства за счет наличия плагина files. Команда lodp<*>l<*> запрашивает листинг данных.

T1421

System Information Discovery

Сбор детальной информации с помощью плагина info.

T1636.003

Protected User Data: Contact List

Извлечение из устройства списка контактов с помощью плагина contacts.

T1430

Location Tracking

Отслеживание геолокации устройства через сервис, который активируется командой с опкодом 4. Сервис использует LocationManager для получения данных от GPS и сетевых провайдеров.

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

Кодировка данных с использованием кастомных разделителей (1234, x0D0x , x0A0x) и сжатие их GZIP перед отправкой

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