![](https://habrastorage.org/getpro/habr/upload_files/5b0/d3b/dd0/5b0d3bdd04a3b2ecec5cd37053f46099.jpg)
В апреле 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. Внешний вид вредоносного документа](https://habrastorage.org/getpro/habr/upload_files/10a/235/c5e/10a235c5e1b7665e7224d3110026afbd.jpg)
Что интересно: макрос шаблона, фрагмент которого изображен на рис. 2, создает файлы по пути C:\ProgramData\KasperskyOneDrive. Основная задача легитимного файла — передача управления вредоносной библиотеке с помощью техники DLL Side-Loading и формирование инициализирующего пакета, который отправляется на контрольный сервер.
![Рисунок 2. Код загруженного макроса Рисунок 2. Код загруженного макроса](https://habrastorage.org/getpro/habr/upload_files/eb7/16a/b43/eb716ab4360128b6a2e96073346fc38d.png)
В ходе дальнейшего поиска схожих угроз был найден ряд документов, с полем «Автор», равным pc1q213 (рис. 3), содержащих идентичный код декодирования Base64.
![Рисунок 3. Свойства найденного документа Рисунок 3. Свойства найденного документа](https://habrastorage.org/getpro/habr/upload_files/695/30f/8dd/69530f8ddeb0d3e67e82394110a7d714.png)
Анализ найденных документов наглядно продемонстрировал их внешнее сходство (рис. 4). Кроме того, код содержащихся в них макросов идентичен вплоть до имен функций и переменных (рис. 5 и 6).
![Рисунок 4. Внешний вид найденного документа Рисунок 4. Внешний вид найденного документа](https://habrastorage.org/getpro/habr/upload_files/549/63e/1ac/54963e1ac1502cd16891d194e39c4d53.jpg)
Характерные особенности всех документов — сохранение компонентов, эксплуатирующих DLL Side-Loading для запуска вредоносной нагрузки, которая находится в них, внешнее сходство встроенных в документы макросов, а также кодирование содержащейся внутри документов нагрузки Base64.
![Рисунок 5. Код макроса из найденного документа Рисунок 5. Код макроса из найденного документа](https://habrastorage.org/getpro/habr/upload_files/d69/4ce/0d7/d694ce0d70de55466fb8980f08c79e67.png)
![Рисунок 6. Код макроса из схожего документа Рисунок 6. Код макроса из схожего документа](https://habrastorage.org/getpro/habr/upload_files/37c/8d6/fe1/37c8d6fe17248e3f4914715da4e3713c.png)
Извлекаемая нагрузка также имеет ряд сходств:
большинство бинарных файлов упакованы VMProtect;
все выявленные легитимные исполняемые файлы являются какими-либо компонентами Яндекс.Браузера и подписаны действительной цифровой подписью;
в качестве вредоносных библиотек использовались winhttp.dll, wtsapi.dll, замаскированные под легитимные (в частности, наличием, количеством и именами экспортов).
Разбираем вредоносное ПО: как использовались Яндекс.Диск и Яндекс.Браузер
В ходе анализа вредоносного ПО мы выявили две новых разновидности ВПО, которые мы назвали YaRAT (потому что оно обладает функциональностью RAT и в качестве контрольного сервера использует Яндекс.Диск) и Stealer0x3401 (по константе, используемой при обфускации ключа шифрования). При этом YaRAT мы встречали в двух модификациях — с шифрованием токена внутри кода программы и без него.
YaRAT
В качестве легитимного файла, уязвимого для DLL Side-Loading, использовался инсталлятор Яндекс.Браузера, подписанный действительной цифровой подписью «Яндекса», либо его portable-версия. Файл загружает и вызывает одну из функций вредоносной winhttp.dll.
![Рисунок 7. Сведения о цифровой подписи легитимного исполняемого файла Рисунок 7. Сведения о цифровой подписи легитимного исполняемого файла](https://habrastorage.org/getpro/habr/upload_files/334/e06/6f9/334e066f90072c060f0f4c22ab519dcc.png)
А вот пример вызовов функций внутри легитимного бинарного файла.
![Рисунок 8. Вызов функции вредоносной библиотеки Рисунок 8. Вызов функции вредоносной библиотеки](https://habrastorage.org/getpro/habr/upload_files/b4e/067/824/b4e067824992fe2799dd0012e7c8def1.png)
Сама вредоносная библиотека упакована и зашифрована, ее распаковка производится при вызове DllEntryPoint, который происходят всякий раз при загрузке библиотеки. В этом случае DllEntryPoint содержит код, близкий к UPX, вероятно заимствованный, однако немного модифицированный.
На первом этапе также происходит распаковка LZMA, после чего дважды происходит расшифровка распакованных данных (отдельно расшифровываются секции кода и прочие секции — импорты, данные и т. д.).
Расшифровка данных производится алгоритмом RC4, оба ключа шифрования вшиты в код. Отличительной особенностью обоих блоков расшифровки данных является характерный тип обфускации кода (Control Flow Flattening), затрудняющий статический анализ. Наряду с этой техникой внутри тела функции вставлен лишний байт 0xB9, который сбивает дизассемблер с толку и не дает сгенерировать декомпилированный вид функции.
Пример кода, отвечающего за расшифровку данных после этапа PRNG, приведен на рис. 9.
![Рисунок 9. Фрагмент обфусцированного блока, отвечающего за расшифровку кода и данных Рисунок 9. Фрагмент обфусцированного блока, отвечающего за расшифровку кода и данных](https://habrastorage.org/getpro/habr/upload_files/5fe/1ef/f3e/5fe1eff3ec38101a2ee658e8c71df9bd.png)
Последующий код, отвечающий за восстановление импортов, их адресов (разрешение адресов функций и библиотек), а также за изменение атрибутов на блоки виртуальной памяти (вызовы VirtualProtect), идентичны обычному UPX (на рис. 10 — фрагмент кода упаковщика, на рис. 11 — обычный UPX). Также стоит отметить отличительные и характерные для UPX вызовы push и pop соответственно в начале и конце функции распаковки. После распаковки управление передается на полезную нагрузку.
![Рисунки 10 и 11. Фрагменты кода рассматриваемого упаковщика (слева) и обычного UPX (справа) Рисунки 10 и 11. Фрагменты кода рассматриваемого упаковщика (слева) и обычного UPX (справа)](https://habrastorage.org/getpro/habr/upload_files/bc7/339/c6f/bc7339c6f71dc3ca33b4dd7a0a659dff.png)
Разбор полезной нагрузки
На первом этапе создается мьютекс с именем YandexDisk, а вредонос прописывает себя в автозагрузку через ключ реестра.
![Рисунок 12. Создание мьютекса и обеспечение закрепления в системе Рисунок 12. Создание мьютекса и обеспечение закрепления в системе](https://habrastorage.org/getpro/habr/upload_files/d3f/7b9/d92/d3f7b9d92c0bcf53e58c436148523cd3.png)
Далее ВПО формирует строковые запросы к Яндекс.Диску с параметром Authorization: OAuth, к которому конкатенируется токен для этого аккаунта. Сам токен вшит в код. Мы обнаружили несколько ключей, принадлежащих трем аккаунтам — jethroweston, Poslova.Marian, upy4ndexdate.
![Рисунок 13. Формирование запроса к Яндекс.Диску Рисунок 13. Формирование запроса к Яндекс.Диску](https://habrastorage.org/getpro/habr/upload_files/84f/af1/60e/84faf160e81a0269f1a57677f1dc3467.png)
После этого формируются две строки по паттерну: 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-запроса и его передача на сервер](https://habrastorage.org/getpro/habr/upload_files/e0c/a4b/7e5/e0ca4b7e5e74b9a4063aec667fb1da85.png)
В случае успешного соединения вредонос скачивает файл (рис. 15) с именем, состоящим из следующих строк: имени, сгенерированного на предыдущем этапе, и строкового модификатора «a.psd», который завершает (конкатенируется в конец) строку-имя. К примеру, https://cloud-api.yandex.net/v1/disk/resources/download?path=DESKTOP-IM5NM8R%2Fa.psd.
![Рисунок 15. Содержимое загруженного с C2 файла Рисунок 15. Содержимое загруженного с C2 файла](https://habrastorage.org/getpro/habr/upload_files/c95/37c/316/c9537c31683390b74e9ab742dc8ba44f.png)
Загруженный файл содержит список команд, которые необходимо будет исполнить ВПО с целью получения базовой информации о зараженном компьютере.
Команды исполняются в стандартном шелле Windows (cmd.exe), ВПО конкатенирует их результаты, а также формирует их как ответ и отправляет на Яндекс.Диск как файл b.psd. Стоит отметить, что результат исполнения каждой команды отделен от других строкой ==============\r\n (на рис. 16 отчетливо видны результаты исполнения, разделенные этой строкой).
![Рисунок 16. Содержимое файла с собранными данными Рисунок 16. Содержимое файла с собранными данными](https://habrastorage.org/getpro/habr/upload_files/766/4ca/22a/7664ca22a7a6bfa3282bec0798bc0efd.png)
Далее ВПО переходит в режим исполнения команд. Команды, исполняемые ВПО:
DIR — получение списка файлов каталога;
EXEC — исполнение команды (по факту, вызов функции WinExec библиотеки kernel32.dll);
SLEEP — вызов функции Sleep с параметром (0x3E8 умножить на переданную константу);
UPLOAD — скачать файл с Яндекс.Диска;
DOWNLOAD — загрузить файл на Яндекс.Диск.
Вся сетевая коммуникация осуществляется при помощи curl. В свою очередь, передача данных осуществляется в формате JSON, для работы с ним используется библиотека nlohmann/json. Обе библиотеки статически скомпилированы с проектом.
Широкий модельный ряд: вторая модификация YaRAT
Был также найден ряд образцов, «накрытых» VMProtect и неупакованных описанным выше пакером. Отличительной особенностью всех образцов является то, что «накрыта» протектором лишь DllEntryPoint, в то время как экспорты, в которых находится основная функциональность, виртуализации не подверглись (кроме некоторых WinAPI-вызовов).
Также отличительной чертой подобных экземпляров ВПО является шифрование токена шифром Blowfish со встроенным в код ключом.
![Рисунок 17. Ключ расшифровки внутри ВПО Рисунок 17. Ключ расшифровки внутри ВПО](https://habrastorage.org/getpro/habr/upload_files/1c9/4a3/1ed/1c94a31edc060812a9d6c3562a337898.png)
Несмотря на виртуализацию API-вызовов, приложение поддается статическому анализу и имеет функциональность, достаточно схожую с рассмотренной выше. Имена встроенных команд не изменились, некоторые команды при этом могут отсутствовать.
При этом коммуникация, как и в предыдущем случае, осуществляется при помощи curl, для обработки JSON используется та же самая библиотека.
Смотрим внимательно на Stealer0x3401
Механизм заражения в этом случае идентичен рассмотренному в нашем отчете: легитимный бинарный файл dot1xtray.exe подгружает вредоносную msvcr110.dll. В этом случае вредоносным был экспорт __crtGetShowWindowMode.
Что интересно: на первом этапе ВПО проверяет имя запущенного процесса: оно не должно быть qip.exe, aim.exe, icq.exe. В противном случае управление не будет передано на основную функциональность.
Далее расшифровывается адрес контрольного сервера (рис. 18). Очевидна идентичность этого алгоритма рассмотренному в предыдущем отчете. Неизменным остались как ключ шифрования, так и формат его расположения.
![Рисунок 18. Алгоритм расшифровки адреса контрольного сервера Рисунок 18. Алгоритм расшифровки адреса контрольного сервера](https://habrastorage.org/getpro/habr/upload_files/430/4e5/dab/4304e5dabca20a7d10cb318a39bf9420.png)
Далее ВПО собирает необходимую информацию о системе по определенным группам. Перечень этих групп представлен на рис. 20. Стоит отметить, что этот перечень весьма детальный и ранее такого перечня мы не встречали, также более ранние инструменты группировки собирали другие данные. Кроме того, любопытен факт наличия в ВПО строк на русском языке (рис. 19).
![Рисунок 19. Пример команды, содержащейся в ВПО Рисунок 19. Пример команды, содержащейся в ВПО](https://habrastorage.org/getpro/habr/upload_files/ac7/d40/297/ac7d40297fa96b74e8cba7d72dc29283.png)
![Рисунок 20. Собираемая информация о системе Рисунок 20. Собираемая информация о системе](https://habrastorage.org/getpro/habr/upload_files/2fe/878/841/2fe8788412d0c4d0de99bebbdc1c542e.png)
Все собранные данные перед отправкой шифруются RC4 и кодируются Base64. В отличие от того, что мы видели ранее, ключ шифрования генерируется для каждого нового запуска, алгоритм формирования ключа следующий (рис. 21): на основе текущего времени генерируется 16 псевдослучайных чисел типа qword (цикл заполняет 64-разрядными числами до конкретного адреса, разность между ними 128 байт, соответственно по типу данных получится 16 qword-значений), к которым после будет применена стандартная для RC4 процедура расширения ключа. После этого расширенным ключом происходит шифрование собранных данных.
![Рисунок 21. Формирование ключа шифрования Рисунок 21. Формирование ключа шифрования](https://habrastorage.org/getpro/habr/upload_files/057/2aa/b62/0572aab62d2deb3471a6021977c00883.png)
Что интересно: при передаче шифрованных данных ключ шифрования передается не в явном виде, для его обфускации применяется ранее не встречавшаяся процедура вычисления так называемой контрольной суммы (рис. 22) для каждого qword-значения, использованного в процедуре расширения ключа.
Сама процедура состоит из двух этапов: формирование таблицы расчета хеша и непосредственный подсчет результата. На первом этапе циклически рассчитываются остатки от деления инициализирующей константы (в этом случае 0x3401) по модулю 2 (пока она не станет нулем), то есть число раундов на каждом этапе подсчета контрольной суммы будет идентичным.
На втором этапе производится модификация исходного значения (на рис. 22 _inputVal) в соответствии с двумя переменными, изначально равными 0 и 1 (на рис. 22 temValDword_1 и tempvalDword2), из которых на каждом этапе формируется значение типа __int64 по модулю 0x90c9bff (на рис. 22 result_x64Val). Сами константы также модифицируются на каждом раунде.
Как видно, исходное значение модифицируется на конкретном раунде в соответствии с таблицей остатков, сформированной на первом этапе. Eсли остаток равен 1, то происходит модификация как хеша, так и самих переменных, участвующих в подсчете промежуточных значений и итогового значения. Таким образом, за указанные 14 раундов (заранее известных в плане модификации исходного значения, так как таблица для всех раундов одна и та же) формируется итоговое значение.
Сформированный хеш для каждого из qword-составляющих ключа шифрования и будет передаваться на сторону сервера вредоносной программой.
![Рисунок 22. Процедура обфускации ключа шифрования Рисунок 22. Процедура обфускации ключа шифрования](https://habrastorage.org/getpro/habr/upload_files/2aa/ea9/92f/2aaea992f43d4132d7e5efd37b125456.png)
Таким образом, структура, описывающая кодируемые данные, достаточно проста:
![](https://habrastorage.org/getpro/habr/upload_files/48c/5f6/dbc/48c5f6dbc1c6d6131836708ae7d637b8.png)
Сформированные данные кодируются Base64, после чего предваряются строкой data= и в таком виде передаются на сервер (рис. 23).
![Рисунок 23. Отправляемые данные Рисунок 23. Отправляемые данные](https://habrastorage.org/getpro/habr/upload_files/4e9/3ad/1b9/4e93ad1b98838cbcf1406bfb81c1a89e.png)
Сформированные данные ВПО отсылает на контрольный сервер ramblercloud[.]com, который маскируется под легитимный облачный диск Rambler, однако таковым не является.
Атрибуция
В ходе исследования документа, использующего Template Injection, в результате запуска которого происходило заражение системы, мы выявили трафик, описанный нами в предыдущем отчете (рис. 24).
![Рисунок 24. Фрагмент выявленного трафика (характерна схожесть формата передачи с рассмотренным ранее ВПО) Рисунок 24. Фрагмент выявленного трафика (характерна схожесть формата передачи с рассмотренным ранее ВПО)](https://habrastorage.org/getpro/habr/upload_files/eae/48a/a87/eae48aa87f3e3eabd38e05376f9af92a.png)
После заражения системы ВПО производит обмен данными с С2, затем происходит выполнение команд с сервера управления.
В ходе анализа распакованного образца были выявлены сходства с образцами, выявленными нами ранее. В частности, идентичными оказались имена RTTI-объектов (в том числе и имена таблиц vtbl, используемых для имплементации коммуникации с сервером управления), а также функциональность обоих приложений. Каких-либо изменений архитектуры, исполняемых команд или способов формирования пакетов не выявлено, не изменился и ключ шифрования трафика, вшитый в код программы. Единственным отличием образцов ВПО является частичная виртуализация API-вызовов внутри защищенного приложения (что характерно для любой программы, накрытой VMProtect). Фрагмент функции, выполняющей обработку команд с сервера, приведен на рис. 25.
![Рисунок 25. Функция, отвечающая за исполнение команд Рисунок 25. Функция, отвечающая за исполнение команд](https://habrastorage.org/getpro/habr/upload_files/84b/dfa/905/84bdfa9054882bb1b8742ec7cc595452.png)
Не претерпели изменений служебные строки, форматные строки, используемые для формирования пакетов и структур данных внутри приложения, имена используемых API, порядок их вызова.
В ходе анализа различных вредоносных компонентов был выявлен характерный признак, предположительно указывающий на единую кодовую базу. Во всех случаях ВПО собирали информацию о сетевых адаптерах, причем код функций, последовательность вызовов во всех случаях идентичны: вызов GetAdaptersInfo и затем получение значения ключей NetCfgInstanceId и Characteristics ветки реестра SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}.
Сами по себе эти вызовы достаточно стандартны, тем не менее каких-либо других примеров использования этой техники мы не нашли.
Также идентичен код, генерируемый компилятором, фрагменты которого (пример на рис. 26) мы нашли во всех распакованных вредоносных компонентах, использованных в рамках кампании.
![Рисунок 26. Фрагмент кода, присутствующий во всем найденном ВПО Рисунок 26. Фрагмент кода, присутствующий во всем найденном ВПО](https://habrastorage.org/getpro/habr/upload_files/bae/441/bcd/bae441bcd28111760c4c7c923621b7fb.png)
Таким образом, можно подтвердить наше предположение, что это ВПО относится к группировке APT31.
Все найденные нами вредоносные компоненты можно разделить на несколько групп:
документы с одинаковой заглушкой;
исходные документы имеют идентичное поле «Автор»;
вредоносные компоненты имеют уникальные (в рамках нашего покрытия) фрагменты кода, ранее нам нигде не встречавшиеся;
ВПО использует облачный сервис в качестве контрольного сервера.
Первое, на что стоит обратить внимание, — внешнее сходство заглушки в документах, которые мы чуть выше отнесли к группировке APT31, и заглушки в документе, который извлекал вредоносные компоненты, взаимодействующие с Яндекс.Диском. Второе — это идентичный код, получающий информацию о сетевых адаптерах, который мы встретили как в атрибутированных инструментах, так и в инструментах, описанных в этом отчете.
Отдельно стоит отметить ВПО, которое собирало информацию о зараженной системе. Этот вредоносный компонент содержит в себе код, который мы видели в предыдущем отчете о деятельности группировки APT31, причем сам код идентичен тому, который был там. Также это ВПО устанавливало в системе документ с полем «Автор», которое мы видели в остальных найденных нами вредоносах.
Таким образом, это ВПО является связующим элементом для всех рассмотренных выше вредоносных компонентов.
Проанализировав рассмотренные выше инструменты, мы можем с большой долей уверенности отнести исследованные нами образцы ВПО к одной группировке. А с учетом использования облачных сервисов в качестве серверов управления (в этом случае Яндекс.Диска), которые уже были в арсенале этой группировки (ранее она использовала Dropbox), можно сделать предположение о единой кодовой базе, используемой для написания вредоносных компонентов.
Схожие техники заражения, закрепления, многочисленные пересечения в коде, артефакты используемых средств компиляции позволяют сделать вывод, что исследованная нами группировка может продолжить свои атаки на организации в России.
Ознакомиться с полной версией нашего исследования и получить индикаторы компрометации (файловые и сетевые индикаторы, а также MITRE TTPs) можно по ссылке. Еще больше отчетов PT ESC об актуальных киберугрозах, новых образцах ВПО, активности APT-группировок, техниках и инструментах хакеров и о расследованных инцидентах вы найдете в нашем блоге.
Авторы:
Даниил Колосков
Старший специалист отдела исследования угроз PT Expert Security Center
Денис Кувшинов
Руководитель отдела исследования угроз ИБ PT Expert Security Center