Как стать автором
Обновить
Positive Technologies
Лидер результативной кибербезопасности

Изучаем троянскую повестку с мимикрией под XDSpy

Время на прочтение8 мин
Количество просмотров8.4K

В ходе постоянного отслеживания угроз ИБ утром, 3 октября, в одном из Telegram-чатов мы заметили промелькнувший файл со злободневным названием Povestka_26-09-2022.wsf. Беглый осмотр содержимого привлек наше внимание, и мы решили разобрать его подробней. И, как оказалось, не зря.

Разбор вредоносного скрипта

Образец представляет собой обфусцированный JavaScript WSF-файл, задачей которого является выполнение нескольких проверок на наличие виртуальной среды или песочницы (anti-vm/anti-sandbox) и запуск основной полезной нагрузки.

Все строки в скрипте зашифрованы простым XOR и представлены в виде шестнадцатеричных последовательностей.  Функция расшифровки строк представлена на рис.1.

Рисунок 1. Алгоритм расшифровки строк в скрипте
Рисунок 1. Алгоритм расшифровки строк в скрипте

При запуске скрипт сначала пытается открыть Internet Explorer для отвлечения внимания пользователя (рис. 2).

Рисунок 2. Открытие Internet Explorer
Рисунок 2. Открытие Internet Explorer

После чего он сравнивает текущее имя пользователя с захардкоженным списком (рис. 3). Если эта или одна из последующих проверок будет провалена, выставляется специальный флаг, предотвращающий дальнейшее выполнение скрипта.

Рисунок 3. Проверка имени текущего пользователя
Рисунок 3. Проверка имени текущего пользователя

Затем исследуемый скрипт проверяет установленные в системе антивирусы. Осуществляется это через перечисление всех присутствующих папок в Program Files и Program Files(x86), конкатенацию всех имен файлов в одну строку и поиск подстрок mante (Symantec) orton se (Norton Security) itdefender (Bitdefender) в ней (рис. 4).

Рисунок 4. Проверка установленных антивирусов
Рисунок 4. Проверка установленных антивирусов

В заключение проводятся проверка наличия директорий, специфичных для виртуальных сред, а также проверка имени хоста (рис. 5). Стоит отметить, что в случае VMware проверка является слишком общей и не будет пройдена, если на машине установлены любые продукты компании.

Рисунок 5. Проверка имени хоста и директорий
Рисунок 5. Проверка имени хоста и директорий

Если все проверки были успешно пройдены, то скрипт переходит к восстановлению полезной нагрузки. Алгоритм представлен на рис. 6.

Рисунок 6. Расшифровка нагрузки
Рисунок 6. Расшифровка нагрузки

Восстановленный файл записывается в %APPDATA%\Local\AnalysisManager.bin и затем переименовывается в AnalysisManager.exe, после чего запускается через объект ShellWindows (CLSID: 9BA05972-F6A8-11CF-A442-00A0C90A8F39) (рис. 7).

Рисунок 7. Запуск нагрузки
Рисунок 7. Запуск нагрузки

Анализ ВПО

Все строки и почти все API-вызовы в исследуемом образце обфусцированы. Каждая строка собирается в отдельной функции, после чего передается в обработчик, ее расшифровывающий. На каждую длину строки может быть один или несколько обработчиков. Пример приведен на рис. 8.

Рисунок 8. Запуск нагрузки
Рисунок 8. Запуск нагрузки

При запуске образец ищет в памяти адрес kernel32.dll по хешу ror13 (0x6A4ABC5B) и далее с помощью кастомной реализации GetProcAddress, получает адрес функции LoadLibrary (рис. 9). Затем он подгружает прочие требуемые для работы библиотеки.

Рисунок 9. Поиск адресов kernel32 и LoadLibrary
Рисунок 9. Поиск адресов kernel32 и LoadLibrary

Реализация GetProcAddress приведена на рис. 10.

Рисунок 10. Реализация GetProcAddress
Рисунок 10. Реализация GetProcAddress

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

Рисунок 11. Anti-vm проверки BiosVendor и файлов
Рисунок 11. Anti-vm проверки BiosVendor и файлов

Также проверяется наличие нескольких специфичных директорий (рис. 12) и текущее имя пользователя (список аналогичен тому, что использовался в скрипте). Дополнительно проверяется наличие подстроки vast (Avast) в ранее собранном списке содержимого Program Files и Program Files (x86).

Особый интерес представляет проверка директории C:\\guest – utils\\, поскольку она служит индикатором для обнаружения старых версий PT Sandbox.

Рисунок 12. Anti-sandbox проверки директорий
Рисунок 12. Anti-sandbox проверки директорий

Если все проверки были успешно пройдены, сэмпл закрепляется в HKCU\Environment\UserInitLogonScript (рис. 13).

Рисунок 13. Закрепление в реестре
Рисунок 13. Закрепление в реестре

После закрепления создается еще один поток, где идет сбор информации о хосте и начинается взаимодействие с командным сервером.

В процессе образец получает версию ОС, номер билда и разрядность, а также проверяет наличие установленных антивирусов Kasperky и ESET. Проверка приведена на рис. 14.

Рисунок 14. Получение информации об антивирусах
Рисунок 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 агента:

  1. Берется хеш (рис. 15) от строки имя хоста + значение реестра BIOSVendor + v25286.

  2. Берется хеш от строки имя хоста + имя текущего пользователя + строка текущей временной зоны + v25286.

  3. Оба хеша преобразуются в hex-строки по 8 байтов.

  4. К первой строке добавляются первые 4 байта от второй.

Рисунок 15. Алгоритм, используемый при генерации ID агента
Рисунок 15. Алгоритм, используемый при генерации ID агента

Перед обращением к серверу также идет проверка наличия файла конфигурации. Имя файла собирается из нескольких параметров и в несколько этапов:

  1. Создается директория %APPDATA%\AppInfo\.

  2. Конкатенируются строки v25286 + ID агента + hiuhgnywervg9837kjfbhnwuier.

  3. Результат хешируется функцией на рис. 16, преобразуется в десятичный формат и затем в строку.

  4. К полученной строке конкатенируется строка LKolkijhkUI и расширение .zxtu.

Рисунок 16. Алгоритм хеширования, используемый при генерации пути конфига
Рисунок 16. Алгоритм хеширования, используемый при генерации пути конфига

Если файл конфигурации был найден, то далее он читается и расшифровывается по алгоритму RC4 с ключом OP789hqedoevrn68f34byicw@#njsunodejwdn023ejcwfedwf3t5hbcuibwegv. Из него образец может получить информацию о новом С2 и используемом протоколе (http/https). Если файл не был найден, будет использован захардкоженный адрес С2.

Затем ВПО переходит в цикл обращения к контрольному серверу. Между запросами идет случайная задержка (рис. 17).

Рисунок 17. Случайная задержка между обращениями к контрольному серверу
Рисунок 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);

Рисунок 18. Обновление конфигурации агента
Рисунок 18. Обновление конфигурации агента
  • plug — создает отдельный поток, где расшифровывает (RC4), размещает в памяти и вызывает полученную библиотеку. Название и функционал намекают, что команда отвечает за установку плагинов.

  • bwtp — похоже на plug, но в отличие от него не создает новый поток, а размещает в памяти и вызывает библиотеку в том же потоке. Результат работы накрывается RC4 и отправляется на С2. После вызова библиотека выгружается из памяти. Пример вызова приведен на рис. 19;

Рисунок 19. Запуск полученной библиотеки
Рисунок 19. Запуск полученной библиотеки
  • rstpg — проходит по адресам библиотек, загруженных командой plug, и вызывает второй экспорт для каждой. Скорее всего, команда отвечает за выгрузку всех установленных плагинов (рис. 20).

Рисунок 20. Выгрузка всех плагинов
Рисунок 20. Выгрузка всех плагинов
  • sysinfo — собирает и шлет отдельным POST-запросом расширенную информацию о системе и агенте. Перед отправкой также накрывается RC4.

Помимо описанного ранее (за исключением информации об антивирусах), сюда входит:

  • полный список директорий из Program Files и Program Files (x86);

  • информация о подключенных дисках и их типе;

  • текущий С2;

  • ID агента.

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

Атрибуция

Что говорит в пользу XDSpy:

  1. Вредоносные кампании XDSpy всегда были ориентированы на русскоязычные страны. Фишинговые письма составлялись с учетом актуальных событий в России. В частности, вредоносные кампании, проводимые в 2020 г., были ориентированы на COVID-19 и волнения в Республике Беларусь. Кроме того, тематика писем также была связана с работой отдельных государственных учреждений (рис. 21).

Рисунок 21. Пример фишингового письма вредоносных кампаний XDSpy за 2020 г.
Рисунок 21. Пример фишингового письма вредоносных кампаний XDSpy за 2020 г.
  1. В качестве вредоносного модуля на первом этапе заражения в данной кампании используется WSF-скрипт. Этот подход также использовался группировкой XDSpy в рамках вредоносных кампаний 2020 г.

При глубоком анализе образцов 2020 и 2022 гг. выявлены следующие схожие функции:

  • обращение к ресурсу-приманке через метод Navigate объекта InternetExplorer.Appplication (рис. 22);

Рисунок 22. Обращение к ресурсу-приманке в образце 2020 г. (слева) и 2022 г. (справа)
Рисунок 22. Обращение к ресурсу-приманке в образце 2020 г. (слева) и 2022 г. (справа)
  • формирование списка всех директорий, содержащихся в папках Program Files и Program Files (x86) одной строкой через разделитель (рис. 23);

Рисунок 23. Формирование списка директорий одной строкой в образце 2020 г. (слева) и 2022 г. (справа)
Рисунок 23. Формирование списка директорий одной строкой в образце 2020 г. (слева) и 2022 г. (справа)
  • проверка перечня защитных решений, установленных на зараженном компьютере, с использованием ранее сформированного перечня директорий (рис. 24);

Рисунок 24. Поиск защитных решений в образце 2020 г. (слева) и 2022 г. (справа)
Рисунок 24. Поиск защитных решений в образце 2020 г. (слева) и 2022 г. (справа)
  • проверка работы в виртуальной среде (рис. 25);

Рисунок 25. Проверка работы в виртуальной среде в образце 2020 г. (слева) и 2022 г. (справа)
Рисунок 25. Проверка работы в виртуальной среде в образце 2020 г. (слева) и 2022 г. (справа)
  • запуск полезной нагрузки через объект класса ShellWindows (рис. 26).

Рисунок 26. Запуск полезной нагрузки в образце 2020 г. (слева) и 2022 г. (справа)
Рисунок 26. Запуск полезной нагрузки в образце 2020 г. (слева) и 2022 г. (справа)

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

Однако стоит также отметить сходство алгоритма хеширования, используемого для генерации ID агента с тем, что ранее использовался в Trickbot (рис. 27).

Рисунок 27. Алгоритм хеширования строк в Trickbot (слева) и исследуемом образце (справа)
Рисунок 27. Алгоритм хеширования строк в Trickbot (слева) и исследуемом образце (справа)

Вывод

Первый этап заражения похож на ранее описанные подходы XDSpy, однако в основной нагрузке есть некоторые различия. Для закрепления в системе был выбран менее популярный ключ реестра, а также изменился метод шифрования коммуникации с командным сервером. Другим интересным моментом является использование одного из алгоритмов хеширования, аналогичного тому, что ранее был замечен в Trickbot. У нас нет достаточных фактов для атрибутирования атаки к активности XDSpy, а обнаруженный фрагмент кода из зловреда Trickbot, не связанного с XDSpy, дает основания полагать, что это может быть примером использования тактик действия XDSpy с целью мимикрии под APT-группу, а не лишь только заимствования фрагментов кода. Кроме того, отметим, что это был первый известный нам случай попытки уклонения ВПО от обнаружения нашей песочницей.


Александр Тюков

Специалист отдела обнаружения вредоносного ПО экспертного центра безопасности Positive Technologies (PT Expert Security Center)

Теги:
Хабы:
Всего голосов 17: ↑17 и ↓0+17
Комментарии8

Публикации

Информация

Сайт
www.ptsecurity.com
Дата регистрации
Дата основания
2002
Численность
1 001–5 000 человек
Местоположение
Россия