В апреле 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) с удаленного сервера.
Что интересно: макрос шаблона, фрагмент которого изображен на рис. 2, создает файлы по пути C:\ProgramData\KasperskyOneDrive. Основная задача легитимного файла — передача управления вредоносной библиотеке с помощью техники DLL Side-Loading и формирование инициализирующего пакета, который отправляется на контрольный сервер.
В ходе дальнейшего поиска схожих угроз был найден ряд документов, с полем «Автор», равным pc1q213 (рис. 3), содержащих идентичный код декодирования Base64.
Анализ найденных документов наглядно продемонстрировал их внешнее сходство (рис. 4). Кроме того, код содержащихся в них макросов идентичен вплоть до имен функций и переменных (рис. 5 и 6).
Характерные особенности всех документов — сохранение компонентов, эксплуатирующих DLL Side-Loading для запуска вредоносной нагрузки, которая находится в них, внешнее сходство встроенных в документы макросов, а также кодирование содержащейся внутри документов нагрузки Base64.
Извлекаемая нагрузка также имеет ряд сходств:
большинство бинарных файлов упакованы VMProtect;
все выявленные легитимные исполняемые файлы являются какими-либо компонентами Яндекс.Браузера и подписаны действительной цифровой подписью;
в качестве вредоносных библиотек использовались winhttp.dll, wtsapi.dll, замаскированные под легитимные (в частности, наличием, количеством и именами экспортов).
Разбираем вредоносное ПО: как использовались Яндекс.Диск и Яндекс.Браузер
В ходе анализа вредоносного ПО мы выявили две новых разновидности ВПО, которые мы назвали YaRAT (потому что оно обладает функциональностью RAT и в качестве контрольного сервера использует Яндекс.Диск) и Stealer0x3401 (по константе, используемой при обфускации ключа шифрования). При этом YaRAT мы встречали в двух модификациях — с шифрованием токена внутри кода программы и без него.
YaRAT
В качестве легитимного файла, уязвимого для DLL Side-Loading, использовался инсталлятор Яндекс.Браузера, подписанный действительной цифровой подписью «Яндекса», либо его portable-версия. Файл загружает и вызывает одну из функций вредоносной winhttp.dll.
А вот пример вызовов функций внутри легитимного бинарного файла.
Сама вредоносная библиотека упакована и зашифрована, ее распаковка производится при вызове DllEntryPoint, который происходят всякий раз при загрузке библиотеки. В этом случае DllEntryPoint содержит код, близкий к UPX, вероятно заимствованный, однако немного модифицированный.
На первом этапе также происходит распаковка LZMA, после чего дважды происходит расшифровка распакованных данных (отдельно расшифровываются секции кода и прочие секции — импорты, данные и т. д.).
Расшифровка данных производится алгоритмом RC4, оба ключа шифрования вшиты в код. Отличительной особенностью обоих блоков расшифровки данных является характерный тип обфускации кода (Control Flow Flattening), затрудняющий статический анализ. Наряду с этой техникой внутри тела функции вставлен лишний байт 0xB9, который сбивает дизассемблер с толку и не дает сгенерировать декомпилированный вид функции.
Пример кода, отвечающего за расшифровку данных после этапа PRNG, приведен на рис. 9.
Последующий код, отвечающий за восстановление импортов, их адресов (разрешение адресов функций и библиотек), а также за изменение атрибутов на блоки виртуальной памяти (вызовы VirtualProtect), идентичны обычному UPX (на рис. 10 — фрагмент кода упаковщика, на рис. 11 — обычный UPX). Также стоит отметить отличительные и характерные для UPX вызовы push и pop соответственно в начале и конце функции распаковки. После распаковки управление передается на полезную нагрузку.
Разбор полезной нагрузки
На первом этапе создается мьютекс с именем YandexDisk, а вредонос прописывает себя в автозагрузку через ключ реестра.
Далее ВПО формирует строковые запросы к Яндекс.Диску с параметром Authorization: OAuth, к которому конкатенируется токен для этого аккаунта. Сам токен вшит в код. Мы обнаружили несколько ключей, принадлежащих трем аккаунтам — jethroweston, Poslova.Marian, upy4ndexdate.
После этого формируются две строки по паттерну: 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). Его можно рассматривать как инициализирующий запрос, на основе которого будет создан каталог на Яндекс.Диске (рабочий удаленный каталог).
В случае успешного соединения вредонос скачивает файл (рис. 15) с именем, состоящим из следующих строк: имени, сгенерированного на предыдущем этапе, и строкового модификатора «a.psd», который завершает (конкатенируется в конец) строку-имя. К примеру, https://cloud-api.yandex.net/v1/disk/resources/download?path=DESKTOP-IM5NM8R%2Fa.psd.
Загруженный файл содержит список команд, которые необходимо будет исполнить ВПО с целью получения базовой информации о зараженном компьютере.
Команды исполняются в стандартном шелле Windows (cmd.exe), ВПО конкатенирует их результаты, а также формирует их как ответ и отправляет на Яндекс.Диск как файл b.psd. Стоит отметить, что результат исполнения каждой команды отделен от других строкой ==============\r\n (на рис. 16 отчетливо видны результаты исполнения, разделенные этой строкой).
Далее ВПО переходит в режим исполнения команд. Команды, исполняемые ВПО:
DIR — получение списка файлов каталога;
EXEC — исполнение команды (по факту, вызов функции WinExec библиотеки kernel32.dll);
SLEEP — вызов функции Sleep с параметром (0x3E8 умножить на переданную константу);
UPLOAD — скачать файл с Яндекс.Диска;
DOWNLOAD — загрузить файл на Яндекс.Диск.
Вся сетевая коммуникация осуществляется при помощи curl. В свою очередь, передача данных осуществляется в формате JSON, для работы с ним используется библиотека nlohmann/json. Обе библиотеки статически скомпилированы с проектом.
Широкий модельный ряд: вторая модификация YaRAT
Был также найден ряд образцов, «накрытых» VMProtect и неупакованных описанным выше пакером. Отличительной особенностью всех образцов является то, что «накрыта» протектором лишь DllEntryPoint, в то время как экспорты, в которых находится основная функциональность, виртуализации не подверглись (кроме некоторых WinAPI-вызовов).
Также отличительной чертой подобных экземпляров ВПО является шифрование токена шифром Blowfish со встроенным в код ключом.
Несмотря на виртуализацию API-вызовов, приложение поддается статическому анализу и имеет функциональность, достаточно схожую с рассмотренной выше. Имена встроенных команд не изменились, некоторые команды при этом могут отсутствовать.
При этом коммуникация, как и в предыдущем случае, осуществляется при помощи curl, для обработки JSON используется та же самая библиотека.
Смотрим внимательно на Stealer0x3401
Механизм заражения в этом случае идентичен рассмотренному в нашем отчете: легитимный бинарный файл dot1xtray.exe подгружает вредоносную msvcr110.dll. В этом случае вредоносным был экспорт __crtGetShowWindowMode.
Что интересно: на первом этапе ВПО проверяет имя запущенного процесса: оно не должно быть qip.exe, aim.exe, icq.exe. В противном случае управление не будет передано на основную функциональность.
Далее расшифровывается адрес контрольного сервера (рис. 18). Очевидна идентичность этого алгоритма рассмотренному в предыдущем отчете. Неизменным остались как ключ шифрования, так и формат его расположения.
Далее ВПО собирает необходимую информацию о системе по определенным группам. Перечень этих групп представлен на рис. 20. Стоит отметить, что этот перечень весьма детальный и ранее такого перечня мы не встречали, также более ранние инструменты группировки собирали другие данные. Кроме того, любопытен факт наличия в ВПО строк на русском языке (рис. 19).
Все собранные данные перед отправкой шифруются RC4 и кодируются Base64. В отличие от того, что мы видели ранее, ключ шифрования генерируется для каждого нового запуска, алгоритм формирования ключа следующий (рис. 21): на основе текущего времени генерируется 16 псевдослучайных чисел типа qword (цикл заполняет 64-разрядными числами до конкретного адреса, разность между ними 128 байт, соответственно по типу данных получится 16 qword-значений), к которым после будет применена стандартная для RC4 процедура расширения ключа. После этого расширенным ключом происходит шифрование собранных данных.
Что интересно: при передаче шифрованных данных ключ шифрования передается не в явном виде, для его обфускации применяется ранее не встречавшаяся процедура вычисления так называемой контрольной суммы (рис. 22) для каждого qword-значения, использованного в процедуре расширения ключа.
Сама процедура состоит из двух этапов: формирование таблицы расчета хеша и непосредственный подсчет результата. На первом этапе циклически рассчитываются остатки от деления инициализирующей константы (в этом случае 0x3401) по модулю 2 (пока она не станет нулем), то есть число раундов на каждом этапе подсчета контрольной суммы будет идентичным.
На втором этапе производится модификация исходного значения (на рис. 22 _inputVal) в соответствии с двумя переменными, изначально равными 0 и 1 (на рис. 22 temValDword_1 и tempvalDword2), из которых на каждом этапе формируется значение типа __int64 по модулю 0x90c9bff (на рис. 22 result_x64Val). Сами константы также модифицируются на каждом раунде.
Как видно, исходное значение модифицируется на конкретном раунде в соответствии с таблицей остатков, сформированной на первом этапе. Eсли остаток равен 1, то происходит модификация как хеша, так и самих переменных, участвующих в подсчете промежуточных значений и итогового значения. Таким образом, за указанные 14 раундов (заранее известных в плане модификации исходного значения, так как таблица для всех раундов одна и та же) формируется итоговое значение.
Сформированный хеш для каждого из qword-составляющих ключа шифрования и будет передаваться на сторону сервера вредоносной программой.
Таким образом, структура, описывающая кодируемые данные, достаточно проста:
Сформированные данные кодируются Base64, после чего предваряются строкой data= и в таком виде передаются на сервер (рис. 23).
Сформированные данные ВПО отсылает на контрольный сервер ramblercloud[.]com, который маскируется под легитимный облачный диск Rambler, однако таковым не является.
Атрибуция
В ходе исследования документа, использующего Template Injection, в результате запуска которого происходило заражение системы, мы выявили трафик, описанный нами в предыдущем отчете (рис. 24).
После заражения системы ВПО производит обмен данными с С2, затем происходит выполнение команд с сервера управления.
В ходе анализа распакованного образца были выявлены сходства с образцами, выявленными нами ранее. В частности, идентичными оказались имена RTTI-объектов (в том числе и имена таблиц vtbl, используемых для имплементации коммуникации с сервером управления), а также функциональность обоих приложений. Каких-либо изменений архитектуры, исполняемых команд или способов формирования пакетов не выявлено, не изменился и ключ шифрования трафика, вшитый в код программы. Единственным отличием образцов ВПО является частичная виртуализация API-вызовов внутри защищенного приложения (что характерно для любой программы, накрытой VMProtect). Фрагмент функции, выполняющей обработку команд с сервера, приведен на рис. 25.
Не претерпели изменений служебные строки, форматные строки, используемые для формирования пакетов и структур данных внутри приложения, имена используемых API, порядок их вызова.
В ходе анализа различных вредоносных компонентов был выявлен характерный признак, предположительно указывающий на единую кодовую базу. Во всех случаях ВПО собирали информацию о сетевых адаптерах, причем код функций, последовательность вызовов во всех случаях идентичны: вызов GetAdaptersInfo и затем получение значения ключей NetCfgInstanceId и Characteristics ветки реестра SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}.
Сами по себе эти вызовы достаточно стандартны, тем не менее каких-либо других примеров использования этой техники мы не нашли.
Также идентичен код, генерируемый компилятором, фрагменты которого (пример на рис. 26) мы нашли во всех распакованных вредоносных компонентах, использованных в рамках кампании.
Таким образом, можно подтвердить наше предположение, что это ВПО относится к группировке APT31.
Все найденные нами вредоносные компоненты можно разделить на несколько групп:
документы с одинаковой заглушкой;
исходные документы имеют идентичное поле «Автор»;
вредоносные компоненты имеют уникальные (в рамках нашего покрытия) фрагменты кода, ранее нам нигде не встречавшиеся;
ВПО использует облачный сервис в качестве контрольного сервера.
Первое, на что стоит обратить внимание, — внешнее сходство заглушки в документах, которые мы чуть выше отнесли к группировке APT31, и заглушки в документе, который извлекал вредоносные компоненты, взаимодействующие с Яндекс.Диском. Второе — это идентичный код, получающий информацию о сетевых адаптерах, который мы встретили как в атрибутированных инструментах, так и в инструментах, описанных в этом отчете.
Отдельно стоит отметить ВПО, которое собирало информацию о зараженной системе. Этот вредоносный компонент содержит в себе код, который мы видели в предыдущем отчете о деятельности группировки APT31, причем сам код идентичен тому, который был там. Также это ВПО устанавливало в системе документ с полем «Автор», которое мы видели в остальных найденных нами вредоносах.
Таким образом, это ВПО является связующим элементом для всех рассмотренных выше вредоносных компонентов.
Проанализировав рассмотренные выше инструменты, мы можем с большой долей уверенности отнести исследованные нами образцы ВПО к одной группировке. А с учетом использования облачных сервисов в качестве серверов управления (в этом случае Яндекс.Диска), которые уже были в арсенале этой группировки (ранее она использовала Dropbox), можно сделать предположение о единой кодовой базе, используемой для написания вредоносных компонентов.
Схожие техники заражения, закрепления, многочисленные пересечения в коде, артефакты используемых средств компиляции позволяют сделать вывод, что исследованная нами группировка может продолжить свои атаки на организации в России.
Ознакомиться с полной версией нашего исследования и получить индикаторы компрометации (файловые и сетевые индикаторы, а также MITRE TTPs) можно по ссылке. Еще больше отчетов PT ESC об актуальных киберугрозах, новых образцах ВПО, активности APT-группировок, техниках и инструментах хакеров и о расследованных инцидентах вы найдете в нашем блоге.
Авторы:
Даниил Колосков
Старший специалист отдела исследования угроз PT Expert Security Center
Денис Кувшинов
Руководитель отдела исследования угроз ИБ PT Expert Security Center