В ходе постоянного отслеживания угроз ИБ утром 3 октября в одном из Telegram-чатов мы заметили промелькнувший файл со злободневным названием Povestka_26-09-2022.wsf. Беглый осмотр содержимого привлек наше внимание, и мы решили разобрать его подробней. И, как оказалось, не зря.
Разбор вредоносного скрипта
Исходный файл представляет собой обфусцированный JavaScript WSF файл, задачей которого является выполнение нескольких anti-vm/anti-sandbox и запуск основной полезной нагрузки.
Все строки в скрипте зашифрованы простым XOR и представлены в виде шестнадцатеричных последовательностей. Функция расшифрования строк представлена на рис.1.
При запуске скрипт сначала пытается открыть Internet Explorer для отвлечения внимания пользователя (рис. 2).
После чего сравнивает текущее имя пользователя с захардкоженным списком (рис. 3). Если эта или одна из последующих проверок будет провалена, выставится специальный флаг, предотвращающий дальнейшее выполнение скрипта.
Затем исследуемый скрипт проверяет установленные на системе AV. Осуществляется это через перечисление всех присутствующих папок в 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 по crc32 хэшу (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).
После закрепления создается еще один поток, где идет сбор информации о хосте и начинается взаимодействие с С2.
В процессе образец получает версию ОС, номер билда и разрядность. А также проверяет наличие установленных AV Kasperky и ESET. Проверка приведена на рис. 14.
Далее собранная информация конкатенируется в одну строку, в формате:
OS;Build;Arch;v25286;DesktopName;UserName;[K1|E1]
Где:
OS — версия ОС
Build — номер билда
Arch — архитектура ос (32/64)
v25286 — константная строка, вероятно версия ВПО.
DesktopName — имя хоста
UserName — имя текущего пользователя
K1|E1 — информация о найденном AV, если Kaspersky — K1, если ESET — E1. Иначе остается пустой.
Затем последняя побайтово XOR’ится с ключом 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. После вызова библиотека выгружается из памяти. Пример вызова приведен на рис. 20;
rstpg — проходит по адресам загруженных библиотек из команды plug и вызывает второй экспорт для каждой. Скорее всего, команда отвечает за выгрузку всех установленных плагинов (рис. 20);
sysinfo — собирает и шлет отдельным POST-запросом расширенную информацию о системе и агенте. Перед отправкой также накрывается RC4.
Помимо описанного ранее (за исключением информации об AV), сюда входит:
полный список директорий из 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, однако в основной нагрузке есть некоторые различия. Для закрепления на системе был выбран менее популярный ключ реестра, а также изменился метод шифрования коммуникации с С2. Также интересным моментом является использование одного из алгоритмов хэширования, аналогичному тому, что ранее был замечен в Trickbot. У нас нет достаточных фактов для атрибутирования атаки к активности XDSpy, а обнаруженный фрагмент кода из зловреда Trickbot, не связанного с XDSpy, дает основания полагать, что это может быть примером переиспользования тактик действия с мимикрией под группу, а не только заимствования фрагментов кода. Кроме того, отметим, это был первый известный нам случай попытки уклонения ВПО от обнаружения нашей песочницей.
Александр Тюков
Специалист отдела обнаружения вредоносного ПО экспертного центра безопасности Positive Technologies (PT Expert Security Center)
Комментарии (4)
rivitna
11.10.2022 13:21Все очень хорошо, мне лично только атрибуция и вывод не очень понравились.
А функция хеширования на рис. 16 - это Chromium SuperFastHash ;-)
kolabaister
Нет ли общего списка признаков, характерных для виртуальных сред и песочниц? Раз вредоносы часто завершаются, обнаруживая себя в песочнице, напрашивается простой перестраховочный способ - снабдить компьютер признаками песочницы.
IDDQDesnik
Количество признаков и вариантов их проверки стремится к бесконечности, но не проще ли тогда работать в настоящей виртуальной машине?
k1k
Один из самых лучших таких детектеров тут https://github.com/hfiref0x/VMDE/blob/master/src/vmde/detect.c . Однако, мимикрировать под такие признаки сложнее, чем создавать просто папки в "Program Files".