0x0 Введение в предмет исследования
Работа аналитика киберразведки часто подбрасывает интересные задачи из совершенно разных областей жизни. Иногда мы в Jet CSIRT анализируем очередное ВПО, которое еще никто не разбирал «по косточкам», или того, что уже было написано, оказывается мало, и приходится выкручиваться как можем находить решения и проводить настоящую исследовательскую работу. Так произошло и в нашем случае, когда коллеги из «Лаборатории Касперского» сообщили о возобновившем активность вредоносе DarkGate практически в тот же момент, когда мы проводили анализ семпла. Выяснилось, что существовавшие с 2017 года «Темные Врата» не просто оживили в 2023-м, но и оснастили дополнительным мощным инструментарием.
Изначально ничем не примечательный инцидент привел к исследованию, результатами которого мы решили поделиться с комьюнити.
Обо всем по порядку. В Jet CSIRT поступил запрос: пользователям заказчика на электронную почту начали приходить подозрительные письма с вложенным архивом с паролем. В архиве находился VBS-скрипт, причем в ходе исследования было выявлено несколько вариаций доставки вредоноса:
Темы электронных писем менялись (чего там только не было): «Просьба ознакомиться с последними изменениями!», «Перечень вопросов, поступивших из редакции для подготовки интервью», «Вопросы для интервью», «Запрос по бланкам ОСАГО».
0x1 Анализ вредоносного вложения
Первым логичным шагом было проанализировать содержимое VBS-скрипта, который, как оказалось, включал в себя обфусцированный код:
Обфускация была выполнена через вставку символов «oj» в произвольных местах команды. После деобфускации код приобрел следующий вид:
По тексту статьи файл .au3 представлен условно как «script.au3» для упрощения восприятия, так как фактическое наименование файла представляет из себя строку из семи случайных символов.
Мы исследовали все доступные варианты фишинговых писем и выяснили, что, хотя там и были разные VBS-скрипты, в них сохранялся единый принцип обфускации, и должна была запуститься одна и та же команда:
В результате выполнения команды происходит следующее:
Создается новая директория ucet на диске C и осуществляется переход в эту директорию.
Файл curl.exe копируется из системной директории Windows в директорию ucet с новым именем ucet.exe с помощью команды copy. Предположительно, это действие производится для обхода систем мониторинга, контролирующих запуск команды curl.
Запускается исполняемый файл ucet.exe (который, по факту, стандартный curl.exe) с параметром «-o Autoit3.exe» и URL’ом http://45.89.65[.]198:80 — таким образом в директорию ucet загружается исполняемый файл autoit3.exe.
Посредством ucet.exe в ту же директорию загружается файл script.au3 с адреса http://45.89.65[.]198:80/msidkbkejlq.
Запускается программа Autoit3.exe с параметром script.au3, что приводит к выполнению указанного скрипта.
AutoIt — это свободно распространяемый язык для автоматизации выполнения задач в Microsoft Windows. Он позволяет создавать скрипты автоматизации, способные имитировать действия пользователя, такие как текстовый ввод и воздействия на элементы управления системы и программ, а также реагировать на события.
В нашем случае au3-скрипт используется как дроппер, который разворачивает исполняемый файл-инжектор внутри оперативной памяти. Но обо всём по порядку.
0x2 Первый запуск
Во время первого запуска вредоносный скрипт изучает систему на предмет того, запускался ли он в ней ранее, путем анализа директорий, файлов и ключей реестра.
Во время чтения реестра формируется уникальный ID компьютера жертвы, который представляет из себя хеш строки «{ID процессора}{характеристики процессора}{активная учетная запись}{имя компьютера}».
В нашем случае из строки «00326-10000-00000-AA479Intel(R) Xeon(R) CPU E5-2683 v4 @ 2.10GHz @ 20 CoresdoomieWINLAB» формируется ID «CeHhCeaHGKdHBKACdFbfBKHcCEffEFcc»:
Записей в реестр было обнаружено три, причем они весьма схожи — следующие ключи устанавливаются в значение «1» и полностью отключают работу WER:
HKCU\SOFTWARE\Microsoft\Windows\Windows Error Reporting\DontShowUI
HKCU\Software\Microsoft\Windows\Windows Error Reporting\DontShowUI
HKEY_CURRENT_USER\Software\Microsoft\Windows\Windows Error Reporting\DontShowUI
После этого скрипт создает свою собственную копию, а также копию интерпретатора AutoIt в директориях C:\Temp и C:\ProgramData\{random_chars}\.
Закрепление происходит достаточно просто, что странно, учитывая предпринятые попытки сокрытия выполняемых действий в ходе первичного запуска: в автозагрузку добавляется lnk-файл, указывающий на копию скрипта в C:\Temp.
Вишенкой на торте выступает BSOD зараженной машины. После всех подготовительных действий скрипт вызывает «синий экран смерти», который вынуждает заново включать машину. Вероятно, такой способ перезагрузки вызывает меньше подозрений у жертвы, чем стандартный shutdown.exe.
0x3 Второй запуск
После перезапуска виртуальной машины вредонос запускается из автозагрузки и начинает свою активность. При это наблюдаем следующие действия:
1. Запущен какой-либо легитимный исполняемый MZ-файл, который выбирается случайным образом:
2. Запущенный процесс хоть и выглядит легитимным, но при этом осуществляет сетевое взаимодействие с C2-сервером 45.89.65[.]198:
3. Всё тот же процесс пишет некие данные в файл C:\Temp\{random_chars}\{random_chars}\dd-mm-yyyy.log. На данном этапе логично предположить, что раз запись ведется в файл .log, то это логи вредоноса:
0x3 Содержимое вредоносного скрипта
Настало время открыть содержимое script.au3 и разобраться в логике его работы:
При первом открытии скрипта нас встретили сотни килобайт совершенно нечитаемых символов, и лишь примерно в середине листинга файла нашлась директива AU3!EA06, которая сигнализирует о том, что скрипт был скомпилирован.
В ходе анализа, взяв данную директиву за точку отсчета, мы определили структуру данного файла:
AU3-скрипт в данном случае выступает лоадером MZ-файла, который расшифровывает полезную нагрузку вредоноса и запускает ее.
Рассмотрим расшифровку полезной нагрузки:
1. Ключ представляет из себя 10 символов английского алфавита, отделенных «пайпами» от других блоков файла:
2. Расшифровать MZ-блок можно следующим образом:
qdzndqZGvF // исходный ключ
dzndqZGv // убираем первый и последний символы ключа
100 122 110 100 113 90 71 118 // переводим байты ключа в целые числа
100^122^110^100^113^90^71^118=14 // выполняем XOR всех байтов между собой
14^151=153 // выполняем XOR на 151 (MAGIC INT)
153 // однобайтовый ключ от MZ-файла
3. Теперь можно взять все оставшиеся после второго «пайпа» данные и выполнить XOR на 153. Следует отметить, что байты MZ-файла предварительно зашифрованы base64, так что перед операцией XOR следует расшифровать байты в RAW-формат. Для автоматизации расчета ключа и дальнейшего формирования MZ-файла был разработан Python-скрипт, принимающий на вход файл.au3 и генерирующий одноименный файл .exe:
В результате у нас в руках появилась полезная нагрузка вредоноса в формате .exe, которую намного удобнее анализировать, нежели au3-скрипт:
При анализе артефактов MZ-файла утилитой strings были обнаружены интересные строки, например, /c cmdkey /generic:"127.0.0.2" /user:"SafeMode" /pass:"darkgatepassword0". Также удалось понять, что полезная нагрузка написана на языке Borland Delphi, но большинство строк зашифрованы и представляют собой нечитабельные последовательности, отдаленно напоминающие base64 с символом «=» в середине строки:
При дальнейшем анализе в отладчике была найдена функция, отвечающая за расшифровку. Команды shift left и shift right дают понять, что мы имеем дело с base64, а строка «NSxKgEmCs9wpXUdc86keG1rRQbODy7uFjMIqnZAHlLvWi40V3fJtzY5a2hPoT=B+» выступает в качестве перемешанного алфавита, которым кодируются строки:
Благодаря полученной информации разработан (снова на Python'е) скрипт-дешифровщик:
Новые артефакты содержат большое количество интересных строк, например, упоминание функционалов майнера, стиллера, RAT и многое другое. Отдельная благодарность разработчику DarkGate за подробное дебаг-логирование:
Для упрощения анализа был написан IDAPython-скрипт для дизассемблера IDAPro:
К нашему разочарованию, функционалы майнера, стиллера, шифровальщика и т. д. не были реализованы в этом конкретном билде вредоноса. Возможно, кому-то повезет больше, чем нам.
0x4 Логирование вредоноса
Как упоминалось ранее, вредонос пишет некие данные (логи?) в файл C:\Temp\{random_chars}\{random_chars}\dd-mm-yyyy.log. Этот файл содержит зашифрованную информацию, которая похожа на классический base64. Однако при попытке расшифровать файл читабельного текста мы не нашли.
В артефактах MZ-файла были найдены строки Rijndael и masteroflog:
Стало очевидно, что полученную после расшифровки base64 строку необходимо расшифровать шифром Rijndael (AES) с ключом «masteroflog». Все попытки реализовать это на Python не увенчались успехом, поэтому было принято решение писать декриптор на том же языке, на котором реализован вредонос — Borland Delphi.
Подходящая реализация была обнаружена по первой ссылке в Гугле и представляется следующими строками:
DCP_rijndael1: TDCP_rijndael;
DCP_rijndael1 := TDCP_rijndael.Create(Self);
DCP_rijndael1.InitStr(Password, TDCP_sha1);
Result := DCP_rijndael1.DecryptString(Source);
После такого преобразования информацию из файла можно прочитать. Оказалось, что DarkGate всё это время работал как кейлогер с функцией сохранения содержимого буфера обмена:
Между префиксов и суффиксов «encwindow» располагается название окна (в HEX), из которого был осуществлен перехват:
0x5 Сетевое взаимодействие
Нам не повезло: не получилось подробно зафиксировать взаимодействие злоумышленника с нашей виртуальной машиной — мы получали только ответные пакеты от C2-сервера в виде скромного «Ok».
Поэтому в ходе исследования были рассмотрены только исходящие пакеты, их всего два вида, и они отличаются друг от друга значением передаваемого параметра «act» (полагаем, это сокращение от action).
При первом запуске скрипта на С2-сервер злоумышленника отправляется следующий POST-запрос:
id=CeHhCeaHGKdHBKACdFbfBKHcCEffEFcc&data=lKo7XHfp%2B9DfXHd&act=3021
После перезапуска виртуальной машины каждые четыре секунды отправляются пакеты с act=1000, которые отличаются содержимым параметра «data»:
id=CeHhCeaHGKdHBKACdFbfBKHcCEffEFcc&data=tvhsMsB7MsMfFpMstv8sMsvfMsMfDjMsMq%3DsMs%3DEMsMEDpMstj8sMsBuMsMftpMsMb5sMs%3D3MsM7tjMsMqysMs%3DEMsMEMsMstpMsMsBEMsMfDjMstqMsMsvKMsM3MjMstqhsMsvUMsMftpMstq%3DsMQxWCshRtJ3EC3fOCz&act=1000
Значение «id» мы уже встречали ранее, идея параметра «act» тоже ясна (разделение типов сообщений), а вот параметр «data» в очередной раз зашифрован.
На самом деле это очередной base64 с «кастомным» алфавитом (но уже другим, обнаруженным неподалеку от первого), который предварительно прошел через операцию однобайтового XOR (разный байт для разных значений «act»).
Таким образом удалось расшифровать оба сообщения (главное — не забыть про URL decode):
Первым пакетом вредонос сообщает C2-серверу о запуске процедуры вызова BSOD, а все последующие пакеты несут в себе информацию о названии активного окна, номере пакета, версии DarkGate и, предположительно, статусе работы какого-либо из модулей (вероятно, майнера).
Оба декриптора также написаны на Python:
0x6 Противодействие
Профилактика
Для профилактики заражения вредоносом DarkGate (впрочем, как и многими другими вредоносами) целесообразно применять комплекс мероприятий, таких как повышение осведомленности сотрудников с целью противодействия фишинговым атакам, корректная конфигурация доменных политик (в частности, запрет на прямое исполнение VBS-, batch-, PowerShell-скриптов), а также реализация непрерывного мониторинга.
Аналитики центра кибербезопасности Jet CSIRT уже подготовили и внедрили корреляционный контент для выявления активности DarkGate в SIEM-системах своих заказчиков. Для того чтобы каждый мог настроить мониторинг в своей инфраструктуре, прикладываем частичный список условий в виде псевдо-кода:
Проверка компрометации
Способов выявления внедренных в инфраструктуру экземпляров DarkGate можно придумать довольно много, вплоть до поиска аномалий сетевой активности, но наиболее простой и эффективный способ — провести проверку наличия файлов .au3 в директории C:\Temp, например, с помощью следующей команды:
powershell.exe Test-Path C:\temp\*.au3
Эту же команду можно поместить в batch-скрипт для массовой проверки автоматизированными средствами.
45.89.65[.]198
317fb87555e7136e415b1762cda88beb9161d69220ac39b5c62851386ad14639
2095c0c7d5fa33244ce6637beeafa3f2b2cb3b2ae85e285eaea4ddecb83189a6
20428847c85a5286dbe5316f76905c3be49e47d510429b7bd9f9a785bac12033
MITRE ATT&CK:
T1010
T1012
T1027
T1033
T1036
T1055
T1056
T1057
T1059
T1071
T1078
T1082
T1083
T1087
T1095
T1112
T1113
T1115
T1129
T1222
T1497
T1518
T1547
T1548
T1571
T1614
0x7 Выводы
Вредоносное ПО DarkGate имеет серьезный функционал: злоумышленник может украсть чувствительную информацию с помощью стиллера (файлы cookie, пароли, токены дискорда, пароли криптокошельков), добывать криптовалюту посредством встроенного майнера, получать удаленный доступ до зараженного узла, запускать кейлогеры, снимать скриншоты с машины жертвы, а также инжектировать любую полезную нагрузку вплоть до вируса-шифровальщика, выявить которую будет затруднительно благодаря двойному шифрованию. Создатели DarkGate не сидят на месте и постоянно совершенствуют свое детище, усложняя его выявление.
В наших кейсах злоумышленники используют проверенный временем метод доставки вредоносного ПО — фишинг. Способ всё еще остается действенным: пользователи продолжают попадаться на эту удочку. Не хочется повторять очевидное, но этот факт лишний раз доказывает необходимость профилактики: нужно обучать сотрудников цифровой гигиене и безопасной работе с электронной почтой.
Автор: Александр Перевалов, аналитик Jet CSIRT, "Инфосистемы Джет"
CBET_TbMbI
Интересно, разные антивирусы и прочие защитники могут увидеть и вовремя поймать эту штуку?