В ходе постоянного отслеживания угроз ИБ утром, 3 октября, в одном из Telegram-чатов мы заметили промелькнувший файл со злободневным названием Povestka_26-09-2022.wsf. Беглый осмотр содержимого привлек наше внимание, и мы решили разобрать его подробней. И, как оказалось, не зря.
Разбор вредоносного скрипта
Образец представляет собой обфусцированный JavaScript WSF-файл, задачей которого является выполнение нескольких проверок на наличие виртуальной среды или песочницы (anti-vm/anti-sandbox) и запуск основной полезной нагрузки.
Все строки в скрипте зашифрованы простым XOR и представлены в виде шестнадцатеричных последовательностей. Функция расшифровки строк представлена на рис.1.
При запуске скрипт сначала пытается открыть Internet Explorer для отвлечения внимания пользователя (рис. 2).
После чего он сравнивает текущее имя пользователя с захардкоженным списком (рис. 3). Если эта или одна из последующих проверок будет провалена, выставляется специальный флаг, предотвращающий дальнейшее выполнение скрипта.
Затем исследуемый скрипт проверяет установленные в системе антивирусы. Осуществляется это через перечисление всех присутствующих папок в Program Files и Program Files(x86), конкатенацию всех имен файлов в одну строку и поиск подстрок mante (Symantec) orton se (Norton Security) itdefender (Bitdefender) в ней (рис. 4).
В заключение проводятся проверка наличия директорий, специфичных для виртуальных сред, а также проверка имени хоста (рис. 5). Стоит отметить, что в случае VMware проверка является слишком общей и не будет пройдена, если на машине установлены любые продукты компании.
Если все проверки были успешно пройдены, то скрипт переходит к восстановлению полезной нагрузки. Алгоритм представлен на рис. 6.
Восстановленный файл записывается в %APPDATA%\Local\AnalysisManager.bin и затем переименовывается в AnalysisManager.exe, после чего запускается через объект ShellWindows (CLSID: 9BA05972-F6A8-11CF-A442-00A0C90A8F39) (рис. 7).
Анализ ВПО
Все строки и почти все API-вызовы в исследуемом образце обфусцированы. Каждая строка собирается в отдельной функции, после чего передается в обработчик, ее расшифровывающий. На каждую длину строки может быть один или несколько обработчиков. Пример приведен на рис. 8.
При запуске образец ищет в памяти адрес kernel32.dll по хешу ror13 (0x6A4ABC5B) и далее с помощью кастомной реализации GetProcAddress, получает адрес функции LoadLibrary (рис. 9). Затем он подгружает прочие требуемые для работы библиотеки.
Реализация GetProcAddress приведена на рис. 10.
Затем образец действует аналогично скрипту, собирая информацию о содержимом Program Files и Program Files (x86). Далее идет получение текущего пути запуска через вызов GetModuleFileName(0) и проверяется наличие подстроки ata\Loc в нем (с учетом регистра). Если проверка пройдена, запускается новый поток со следующим этапом anti-vm проверок.
Проверяется наличие директории C:\\Windows\\DataManagerVbox, а также наличие файлов и pipe, связанных с VirtualBox и VMware. Помимо этого, также проверяется имя хоста на соответствие SSADFU, а значение HKLM\HARDWARE\DESCRIPTION\System\BIOS\BiosVendor на наличие подстрок SeaBIOS, VMWare, VirtualBox. Эти проверки приведены на рис. 11.
Также проверяется наличие нескольких специфичных директорий (рис. 12) и текущее имя пользователя (список аналогичен тому, что использовался в скрипте). Дополнительно проверяется наличие подстроки vast (Avast) в ранее собранном списке содержимого Program Files и Program Files (x86).
Особый интерес представляет проверка директории C:\\guest – utils\\, поскольку она служит индикатором для обнаружения старых версий PT Sandbox.
Если все проверки были успешно пройдены, сэмпл закрепляется в HKCU\Environment\UserInitLogonScript (рис. 13).
После закрепления создается еще один поток, где идет сбор информации о хосте и начинается взаимодействие с командным сервером.
В процессе образец получает версию ОС, номер билда и разрядность, а также проверяет наличие установленных антивирусов Kasperky и ESET. Проверка приведена на рис. 14.
Далее собранная информация конкатенируется в одну строку в следующем формате:
OS;Build;Arch;v25286;DesktopName;UserName;[K1|E1]
Где:
OS — версия ОС;
Build — номер билда;
Arch — архитектура ОС (32/64);
v25286 — константная строка, вероятно, версия ВПО;
DesktopName — имя хоста;
UserName — имя текущего пользователя;
K1| E1 — информация о найденном антивирусе, если Kaspersky — K1, если ESET — E1. Иначе подстрока остается пустой.
Затем последняя побайтово ксорится с ключом nirgrun895tg9nsvjnwiv12309ASHDbibvenibowrvREXVYBUNIiugycm898y42irwubuv94nabdRDU, кодируется в Base64 и преобразуется для HTTP-запроса заменой символов + / = на эквиваленты %2B, %2F, %3D.
Генерация ID агента:
Берется хеш (рис. 15) от строки имя хоста + значение реестра BIOSVendor + v25286.
Берется хеш от строки имя хоста + имя текущего пользователя + строка текущей временной зоны + v25286.
Оба хеша преобразуются в hex-строки по 8 байтов.
К первой строке добавляются первые 4 байта от второй.
Перед обращением к серверу также идет проверка наличия файла конфигурации. Имя файла собирается из нескольких параметров и в несколько этапов:
Создается директория %APPDATA%\AppInfo\.
Конкатенируются строки v25286 + ID агента + hiuhgnywervg9837kjfbhnwuier.
Результат хешируется функцией на рис. 16, преобразуется в десятичный формат и затем в строку.
К полученной строке конкатенируется строка LKolkijhkUI и расширение .zxtu.
Если файл конфигурации был найден, то далее он читается и расшифровывается по алгоритму RC4 с ключом OP789hqedoevrn68f34byicw@#njsunodejwdn023ejcwfedwf3t5hbcuibwegv. Из него образец может получить информацию о новом С2 и используемом протоколе (http/https). Если файл не был найден, будет использован захардкоженный адрес С2.
Затем ВПО переходит в цикл обращения к контрольному серверу. Между запросами идет случайная задержка (рис. 17).
Для обращения к серверу ВПО собирает POST-запрос с тремя параметрами:
hr&u=3a7319bb710f — 12-байтный ID агента;
&sduyviop=5XpOmZ0bT43Q035YY — ID запроса, может иметь длину от 10 до 20 символов;
&sfin=X1lcV0lEVwgMA09RDVUFRF9cT19NdXdge20OA2UPKS43TyEjUhccEgBNGXQ%3 — собранная ранее информация о хосте.
Итоговый запрос может выглядеть так:
https[://]my1businessconnection[.]com/hr&u=3a7319bb710f&sduyviop=5XpOmZ0bT43Q035YY&sfin=X1lcV0lEVwgMA09RDVUFRF9cT19NdXdge20OA2UPKS43TyEjUhccEgBNGXQ%3
В ответ ВПО получает накрытый RC4 блок данных от сервера, который содержит в себе одну из девяти команд и дополнительные данные к ней (если требуются). Поддерживаются следующие команды:
watghber — сон 1500мс через комбинацию вызовов CreateEventW + WaitForSingleObject;
r4g3rf — аналогично предыдущему, но через CreateSemaphoreW + WaitForSingleObject;
56uhj544getr — увеличивает внутренний счетчик на 100 (его значение нигде не используется);
gfdfgdfgsfuilkyuj — вызывает функцию GetUserNameW, результат также не используется;
ccsv — обновляет информацию о С2 и используемом протоколе (http/https) и сохраняет ее в файл (рис. 18);
plug — создает отдельный поток, где расшифровывает (RC4), размещает в памяти и вызывает полученную библиотеку. Название и функционал намекают, что команда отвечает за установку плагинов.
bwtp — похоже на plug, но в отличие от него не создает новый поток, а размещает в памяти и вызывает библиотеку в том же потоке. Результат работы накрывается RC4 и отправляется на С2. После вызова библиотека выгружается из памяти. Пример вызова приведен на рис. 19;
rstpg — проходит по адресам библиотек, загруженных командой plug, и вызывает второй экспорт для каждой. Скорее всего, команда отвечает за выгрузку всех установленных плагинов (рис. 20).
sysinfo — собирает и шлет отдельным POST-запросом расширенную информацию о системе и агенте. Перед отправкой также накрывается RC4.
Помимо описанного ранее (за исключением информации об антивирусах), сюда входит:
полный список директорий из Program Files и Program Files (x86);
информация о подключенных дисках и их типе;
текущий С2;
ID агента.
Итого: исследуемый образец представляет собой модульное ВПО, где основной функционал находится в получаемых от С2 модулях.
Атрибуция
Что говорит в пользу XDSpy:
Вредоносные кампании XDSpy всегда были ориентированы на русскоязычные страны. Фишинговые письма составлялись с учетом актуальных событий в России. В частности, вредоносные кампании, проводимые в 2020 г., были ориентированы на COVID-19 и волнения в Республике Беларусь. Кроме того, тематика писем также была связана с работой отдельных государственных учреждений (рис. 21).
В качестве вредоносного модуля на первом этапе заражения в данной кампании используется WSF-скрипт. Этот подход также использовался группировкой XDSpy в рамках вредоносных кампаний 2020 г.
При глубоком анализе образцов 2020 и 2022 гг. выявлены следующие схожие функции:
обращение к ресурсу-приманке через метод Navigate объекта InternetExplorer.Appplication (рис. 22);
формирование списка всех директорий, содержащихся в папках Program Files и Program Files (x86) одной строкой через разделитель (рис. 23);
проверка перечня защитных решений, установленных на зараженном компьютере, с использованием ранее сформированного перечня директорий (рис. 24);
проверка работы в виртуальной среде (рис. 25);
запуск полезной нагрузки через объект класса ShellWindows (рис. 26).
Кроме того, в обоих образцах используется схожий алгоритм расшифрования полезной нагрузки и ее развертывания. Последовательность размещения функций в скриптах также практически идентична.
Однако стоит также отметить сходство алгоритма хеширования, используемого для генерации ID агента с тем, что ранее использовался в Trickbot (рис. 27).
Вывод
Первый этап заражения похож на ранее описанные подходы XDSpy, однако в основной нагрузке есть некоторые различия. Для закрепления в системе был выбран менее популярный ключ реестра, а также изменился метод шифрования коммуникации с командным сервером. Другим интересным моментом является использование одного из алгоритмов хеширования, аналогичного тому, что ранее был замечен в Trickbot. У нас нет достаточных фактов для атрибутирования атаки к активности XDSpy, а обнаруженный фрагмент кода из зловреда Trickbot, не связанного с XDSpy, дает основания полагать, что это может быть примером использования тактик действия XDSpy с целью мимикрии под APT-группу, а не лишь только заимствования фрагментов кода. Кроме того, отметим, что это был первый известный нам случай попытки уклонения ВПО от обнаружения нашей песочницей.
Александр Тюков
Специалист отдела обнаружения вредоносного ПО экспертного центра безопасности Positive Technologies (PT Expert Security Center)