В апреле 2022 года мы, специалисты PT Expert Security Center, выявили атаку на ряд российских организаций сферы медиа и ТЭК. В атаках использовался вредоносный документ с именем «список.docx», извлекающий из себя вредоносную нагрузку, упакованную VMProtect. Мы проанализировали пакет сетевой коммуникации и выяснили, что он идентичен тому, который мы рассматривали в отчете по исследованию инструментов группировки APT31 (c ее профайлом можно ознакомиться здесь). Это позволило предположить, что и эти инструменты могут принадлежать этой же группировке. Экземпляры изучаемого вредоносного ПО датируются периодом с ноября 2021 года по июнь 2022-го.

Анализ распакованного ВПО подтвердил наши предположения, так как содержащаяся под протектором вредоносная нагрузка оказалась идентичной рассмотренной нами ранее. Дальнейший мониторинг позволил нам найти еще ряд документов, использованных в атаках на те же организации, имеющих схожее по используемым техникам содержимое, однако отличающееся от того, что мы видели ранее как по сетевой части, так и по коду.

Что интересно: детальный анализ инструментов позволил выявить использование сервиса Яндекс.Диск в качестве контрольного сервера. И это нам показалось достаточно любопытным, так как в этом случае потенциально зарубежная группировка использовала российский сервис, в частности для того, чтобы сетевая нагрузка была внешне похожа на легитимную. Техника не новая: ее использовала группировка TaskMasters в своем ВПО Webdav-O. Смысл использования этой техники — обход сетевых средств защиты, так как происходит соединение с легитимным сервисом. Использование ранее группировкой APT31 облачного сервиса Dropbox, а также пересечения с теми инструментами, которые мы уже видели, дают основание предположить, что и в этом случае нами были найдены инструменты группировки APT31.

Что такое KasperskyOneDrive: разбор вредоносных документов

Исходный документ, с которого мы начали наше исследование (рис. 1), используя технику Template Injection, скачивает шаблон с макросом, загружающим вредоносные компоненты (легитимный файл, компонент Java и вредоносную библиотеку msvcr100.dll, упакованную с помощью VMProtect) с удаленного сервера.

Рисунок 1. Внешний вид вредоносного документа
Рисунок 1. Внешний вид вредоносного документа

Что интересно: макрос шаблона, фрагмент которого изображен на рис. 2, создает файлы по пути C:\ProgramData\KasperskyOneDrive. Основная задача легитимного файла­ — передача управления вредоносной библиотеке с помощью техники DLL Side-Loading и формирование инициализирующего пакета, который отправляется на контрольный сервер.

Рисунок 2. Код загруженного макроса
Рисунок 2. Код загруженного макроса

В ходе дальнейшего поиска схожих угроз был найден ряд документов, с полем «Автор», равным pc1q213 (рис. 3), содержащих идентичный код декодирования Base64.

Рисунок 3. Свойства найденного документа
Рисунок 3. Свойства найденного документа

Анализ найденных документов наглядно продемонстрировал их внешнее сходство (рис. 4). Кроме того, код содержащихся в них макросов идентичен вплоть до имен функций и переменных (рис. 5 и 6).

Рисунок 4. Внешний вид найденного документа
Рисунок 4. Внешний вид найденного документа

Характерные особенности всех документов — сохранение компонентов, эксплуатирующих DLL Side-Loading для запуска вредоносной нагрузки, которая находится в них, внешнее сходство встроенных в документы макросов, а также кодирование содержащейся внутри документов нагрузки Base64.

Рисунок 5. Код макроса из найденного документа
Рисунок 5. Код макроса из найденного документа
Рисунок 6. Код макроса из схожего документа
Рисунок 6. Код макроса из схожего документа

Извлекаемая нагрузка также имеет ряд сходств:

  • большинство бинарных файлов упакованы VMProtect;

  • все выявленные легитимные исполняемые файлы являются какими-либо компонентами Яндекс.Браузера и подписаны действительной цифровой подписью;

  • в качестве вредоносных библиотек использовались winhttp.dll, wtsapi.dll, замаскированные под легитимные (в частности, наличием, количеством и именами экспортов).

Разбираем вредоносное ПО: как использовались Яндекс.Диск и Яндекс.Браузер

В ходе анализа вредоносного ПО мы выявили две новых разновидности ВПО, которые мы назвали YaRAT (потому что оно обладает функциональностью RAT и в качестве контрольного сервера использует Яндекс.Диск) и Stealer0x3401 (по константе, используемой при обфускации ключа шифрования). При этом YaRAT мы встречали в двух модификациях — с шифрованием токена внутри кода программы и без него.

YaRAT

В качестве легитимного файла, уязвимого для DLL Side-Loading, использовался инсталлятор Яндекс.Браузера, подписанный действительной цифровой подписью «Яндекса», либо его portable-версия. Файл загружает и вызывает одну из функций вредоносной winhttp.dll.

Рисунок 7. Сведения о цифровой подписи легитимного исполняемого файла
Рисунок 7. Сведения о цифровой подписи легитимного исполняемого файла

А вот пример вызовов функций внутри легитимного бинарного файла.

Рисунок 8. Вызов функции вредоносной библиотеки
Рисунок 8. Вызов функции вредоносной библиотеки

Сама вредоносная библиотека упакована и зашифрована, ее распаковка производится при вызове DllEntryPoint, который происходят всякий раз при загрузке библиотеки. В этом случае DllEntryPoint содержит код, близкий к UPX, вероятно заимствованный, однако немного модифицированный.

На первом этапе также происходит распаковка LZMA, после чего дважды происходит расшифровка распакованных данных (отдельно расшифровываются секции кода и прочие секции — импорты, данные и т. д.).

Расшифровка данных производится алгоритмом RC4, оба ключа шифрования вшиты в код. Отличительной особенностью обоих блоков расшифровки данных является характерный тип обфускации кода (Control Flow Flattening), затрудняющий статический анализ. Наряду с этой техникой внутри тела функции вставлен лишний байт 0xB9, который сбивает дизассемблер с толку и не дает сгенерировать декомпилированный вид функции.

Пример кода, отвечающего за расшифровку данных после этапа PRNG, приведен на рис. 9.

Рисунок 9. Фрагмент обфусцированного блока, отвечающего за расшифровку кода и данных
Рисунок 9. Фрагмент обфусцированного блока, отвечающего за расшифровку кода и данных

Последующий код, отвечающий за восстановление импортов, их адресов (разрешение адресов функций и библиотек), а также за изменение атрибутов на блоки виртуальной памяти (вызовы VirtualProtect), идентичны обычному UPX (на рис. 10 — фрагмент кода упаковщика, на рис. 11 — обычный UPX). Также стоит отметить отличительные и характерные для UPX вызовы push и pop соответственно в начале и конце функции распаковки. После распаковки управление передается на полезную нагрузку.

Рисунки 10 и 11. Фрагменты кода рассматриваемого упаковщика (слева) и обычного UPX (справа)
Рисунки 10 и 11. Фрагменты кода рассматриваемого упаковщика (слева) и обычного UPX (справа)

Разбор полезной нагрузки

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

Рисунок 12. Создание мьютекса и обеспечение закрепления в системе
Рисунок 12. Создание мьютекса и обеспечение закрепления в системе

Далее ВПО формирует строковые запросы к Яндекс.Диску с параметром Authorization: OAuth, к которому конкатенируется токен для этого аккаунта. Сам токен вшит в код. Мы обнаружили несколько ключей, принадлежащих трем аккаунтам — jethroweston, Poslova.Marian, upy4ndexdate.

Рисунок 13. Формирование запроса к Яндекс.Диску
Рисунок 13. Формирование запроса к Яндекс.Диску

После этого формируются две строки по паттерну: pcname + /a.psd и pcname + /b.psd, например: DESKTOP-IM5NM8R/a.psd, DESKTOP-IM5NM8R/b.psd.

Первый запрос, который ВПО отправляет на контрольный сервер, это PUT на https://cloud-api.yandex.net:443/v1/disk/resources?path= (пример формирования показан на рис. 14). Его можно рассматривать как инициализирующий запрос, на основе которого будет создан каталог на Яндекс.Диске (рабочий удаленный каталог).

Рисунок 14. Формирование PUT-запроса и его передача на сервер
Рисунок 14. Формирование PUT-запроса и его передача на сервер

В случае успешного соединения вредонос скачивает файл (рис. 15) с именем, состоящим из следующих строк: имени, сгенерированного на предыдущем этапе, и строкового модификатора «a.psd», который завершает (конкатенируется в конец) строку-имя. К примеру, https://cloud-api.yandex.net/v1/disk/resources/download?path=DESKTOP-IM5NM8R%2Fa.psd.

Рисунок 15. Содержимое загруженного с C2 файла
Рисунок 15. Содержимое загруженного с C2 файла

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

Команды исполняются в стандартном шелле Windows (cmd.exe), ВПО конкатенирует их результаты, а также формирует их как ответ и отправляет на Яндекс.Диск как файл b.psd. Стоит отметить, что результат исполнения каждой команды отделен от других строкой ==============\r\n (на рис. 16 отчетливо видны результаты исполнения, разделенные этой строкой).

Рисунок 16. Содержимое файла с собранными данными
Рисунок 16. Содержимое файла с собранными данными

Далее ВПО переходит в режим исполнения команд. Команды, исполняемые ВПО:

  • DIR — получение списка файлов каталога;

  • EXEC — исполнение команды (по факту, вызов функции WinExec библиотеки kernel32.dll);

  • SLEEP — вызов функции Sleep с параметром (0x3E8 умножить на переданную константу);

  • UPLOAD — скачать файл с Яндекс.Диска;

  • DOWNLOAD — загрузить файл на Яндекс.Диск.

Вся сетевая коммуникация осуществляется при помощи curl. В свою очередь, передача данных осуществляется в формате JSON, для работы с ним используется библиотека nlohmann/json. Обе библиотеки статически скомпилированы с проектом.

Широкий модельный ряд: вторая модификация YaRAT

Был также найден ряд образцов, «накрытых» VMProtect и неупакованных описанным выше пакером. Отличительной особенностью всех образцов является то, что «накрыта» протектором лишь DllEntryPoint, в то время как экспорты, в которых находится основная функциональность, виртуализации не подверглись (кроме некоторых WinAPI-вызовов).

Также отличительной чертой подобных экземпляров ВПО является шифрование токена шифром Blowfish со встроенным в код ключом.

Рисунок 17. Ключ расшифровки внутри ВПО
Рисунок 17. Ключ расшифровки внутри ВПО

Несмотря на виртуализацию API-вызовов, приложение поддается статическому анализу и имеет функциональность, достаточно схожую с рассмотренной выше. Имена встроенных команд не изменились, некоторые команды при этом могут отсутствовать.

При этом коммуникация, как и в предыдущем случае, осуществляется при помощи curl, для обработки JSON используется та же самая библиотека.

Смотрим внимательно на Stealer0x3401

Механизм заражения в этом случае идентичен рассмотренному в нашем отчете: легитимный бинарный файл dot1xtray.exe подгружает вредоносную msvcr110.dll. В этом случае вредоносным был экспорт __crtGetShowWindowMode.

Что интересно: на первом этапе ВПО проверяет имя запущенного процесса: оно не должно быть qip.exe, aim.exe, icq.exe. В противном случае управление не будет передано на основную функциональность.

Далее расшифровывается адрес контрольного сервера (рис. 18). Очевидна идентичность этого алгоритма рассмотренному в предыдущем отчете. Неизменным остались как ключ шифрования, так и формат его расположения.

Рисунок 18. Алгоритм расшифровки адреса контрольного сервера
Рисунок 18. Алгоритм расшифровки адреса контрольного сервера

Далее ВПО собирает необходимую информацию о системе по определенным группам. Перечень этих групп представлен на рис. 20. Стоит отметить, что этот перечень весьма детальный и ранее такого перечня мы не встречали, также более ранние инструменты группировки собирали другие данные. Кроме того, любопытен факт наличия в ВПО строк на русском языке (рис. 19).

Рисунок 19. Пример команды, содержащейся в ВПО
Рисунок 19. Пример команды, содержащейся в ВПО
Рисунок 20. Собираемая информация о системе
Рисунок 20. Собираемая информация о системе

Все собранные данные перед отправкой шифруются RC4 и кодируются Base64. В отличие от того, что мы видели ранее, ключ шифрования генерируется для каждого нового запуска, алгоритм формирования ключа следующий (рис. 21): на основе текущего времени генерируется 16 псевдослучайных чисел типа qword (цикл заполняет 64-разрядными числами до конкретного адреса, разность между ними 128 байт, соответственно по типу данных получится 16 qword-значений), к которым после будет применена стандартная для RC4 процедура расширения ключа. После этого расширенным ключом происходит шифрование собранных данных.

Рисунок 21. Формирование ключа шифрования
Рисунок 21. Формирование ключа шифрования

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

Сама процедура состоит из двух этапов: формирование таблицы расчета хеша и непосредственный подсчет результата. На первом этапе циклически рассчитываются остатки от деления инициализирующей константы (в этом случае 0x3401) по модулю 2 (пока она не станет нулем), то есть число раундов на каждом этапе подсчета контрольной суммы будет идентичным.

На втором этапе производится модификация исходного значения (на рис. 22 _inputVal) в соответствии с двумя переменными, изначально равными 0 и 1 (на рис. 22 temValDword_1 и tempvalDword2), из которых на каждом этапе формируется значение типа __int64 по модулю 0x90c9bff (на рис. 22 result_x64Val). Сами константы также модифицируются на каждом раунде.

Как видно, исходное значение модифицируется на конкретном раунде в соответствии с таблицей остатков, сформированной на первом этапе. Eсли остаток равен 1, то происходит модификация как хеша, так и самих переменных, участвующих в подсчете промежуточных значений и итогового значения. Таким образом, за указанные 14 раундов (заранее известных в плане модификации исходного значения, так как таблица для всех раундов одна и та же) формируется итоговое значение.

Сформированный хеш для каждого из qword-составляющих ключа шифрования и будет передаваться на сторону сервера вредоносной программой.

Рисунок 22. Процедура обфускации ключа шифрования
Рисунок 22. Процедура обфускации ключа шифрования

Таким образом, структура, описывающая кодируемые данные, достаточно проста:

Сформированные данные кодируются Base64, после чего предваряются строкой data= и в таком виде передаются на сервер (рис. 23).

Рисунок 23. Отправляемые данные
Рисунок 23. Отправляемые данные

Сформированные данные ВПО отсылает на контрольный сервер ramblercloud[.]com, который маскируется под легитимный облачный диск Rambler, однако таковым не является.

Атрибуция

В ходе исследования документа, использующего Template Injection, в результате запуска которого происходило заражение системы, мы выявили трафик, описанный нами в предыдущем отчете (рис. 24).

Рисунок 24. Фрагмент выявленного трафика (характерна схожесть формата передачи с рассмотренным ранее ВПО)
Рисунок 24. Фрагмент выявленного трафика (характерна схожесть формата передачи с рассмотренным ранее ВПО)

После заражения системы ВПО производит обмен данными с С2, затем происходит выполнение команд с сервера управления.

В ходе анализа распакованного образца были выявлены сходства с образцами, выявленными нами ранее. В частности, идентичными оказались имена RTTI-объектов (в том числе и имена таблиц vtbl, используемых для имплементации коммуникации с сервером управления), а также функциональность обоих приложений. Каких-либо изменений архитектуры, исполняемых команд или способов формирования пакетов не выявлено, не изменился и ключ шифрования трафика, вшитый в код программы. Единственным отличием образцов ВПО является частичная виртуализация API-вызовов внутри защищенного приложения (что характерно для любой программы, накрытой VMProtect). Фрагмент функции, выполняющей обработку команд с сервера, приведен на рис. 25.

Рисунок 25. Функция, отвечающая за исполнение команд
Рисунок 25. Функция, отвечающая за исполнение команд

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

В ходе анализа различных вредоносных компонентов был выявлен характерный признак, предположительно указывающий на единую кодовую базу. Во всех случаях ВПО собирали информацию о сетевых адаптерах, причем код функций, последовательность вызовов во всех случаях идентичны: вызов GetAdaptersInfo и затем получение значения ключей NetCfgInstanceId и Characteristics ветки реестра SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}.

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

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

Рисунок 26. Фрагмент кода, присутствующий во всем найденном ВПО
Рисунок 26. Фрагмент кода, присутствующий во всем найденном ВПО

Таким образом, можно подтвердить наше предположение, что это ВПО относится к группировке APT31.

Все найденные нами вредоносные компоненты можно разделить на несколько групп:

  • документы с одинаковой заглушкой;

  • исходные документы имеют идентичное поле «Автор»;

  • вредоносные компоненты имеют уникальные (в рамках нашего покрытия) фрагменты кода, ранее нам нигде не встречавшиеся;

  • ВПО использует облачный сервис в качестве контрольного сервера.

Первое, на что стоит обратить внимание, — внешнее сходство заглушки в документах, которые мы чуть выше отнесли к группировке APT31, и заглушки в документе, который извлекал вредоносные компоненты, взаимодействующие с Яндекс.Диском. Второе — это идентичный код, получающий информацию о сетевых адаптерах, который мы встретили как в атрибутированных инструментах, так и в инструментах, описанных в этом отчете.

Отдельно стоит отметить ВПО, которое собирало информацию о зараженной системе. Этот вредоносный компонент содержит в себе код, который мы видели в предыдущем отчете о деятельности группировки APT31, причем сам код идентичен тому, который был там. Также это ВПО устанавливало в системе документ с полем «Автор», которое мы видели в остальных найденных нами вредоносах.

Таким образом, это ВПО является связующим элементом для всех рассмотренных выше вредоносных компонентов.

Проанализировав рассмотренные выше инструменты, мы можем с большой долей уверенности отнести исследованные нами образцы ВПО к одной группировке. А с учетом использования облачных сервисов в качестве серверов управления (в этом случае Яндекс.Диска), которые уже были в арсенале этой группировки (ранее она использовала Dropbox), можно сделать предположение о единой кодовой базе, используемой для написания вредоносных компонентов.

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

Ознакомиться с полной версией нашего исследования и получить индикаторы компрометации (файловые и сетевые индикаторы, а также MITRE TTPs) можно по ссылке. Еще больше отчетов PT ESC об актуальных киберугрозах, новых образцах ВПО, активности APT-группировок, техниках и инструментах хакеров и о расследованных инцидентах вы найдете в нашем блоге

 

Авторы:

Даниил Колосков

Старший специалист отдела исследования угроз PT Expert Security Center

Денис Кувшинов

Руководитель отдела исследования угроз ИБ PT Expert Security Center


Читайте также в нашем хабраблоге:

Комментарии (0)