Работа аналитика киберразведки часто подбрасывает интересные задачи из совершенно разных областей жизни. Иногда мы в Jet CSIRT анализируем очередное ВПО, которое еще никто не разбирал «по косточкам», или того, что уже было написано, оказывается мало, и приходится выкручиваться как можем  находить решения и проводить настоящую исследовательскую работу. Так произошло и в нашем случае, когда коллеги из «Лаборатории Касперского» сообщили о возобновившем активность вредоносе DarkGate практически в тот же момент, когда мы проводили анализ семпла. Выяснилось, что существовавшие с 2017 года «Темные Врата» не просто оживили в 2023-м, но и оснастили дополнительным мощным инструментарием.  Изначально ничем не примечательный инцидент привел к исследованию, результатами которого мы решили поделиться с комьюнити.  Обо всем по порядку. В Jet CSIRT поступил запрос: пользователям заказчика на электронную почту начали приходить подозрительные письма с вложенным архивом с паролем. В архиве находился VBS-скрипт, причем в ходе исследования было выявлено несколько вариаций доставки вредоноса: Темы электронных писем менялись (чего там только не было): «Просьба ознакомиться с последними изменениями!», «Перечень вопросов, поступивших из редакции для подготовки интервью», «Вопросы для интервью», «Запрос по бланкам ОСАГО».  Первым логичным шагом было проанализировать содержимое 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-скрипт используется как дроппер, который разворачивает исполняемый файл-инжектор внутри оперативной памяти. Но обо всём по порядку. Во время первого запуска вредоносный скрипт изучает систему на предмет того, запускался ли он в ней ранее, путем анализа директорий, файлов и ключей реестра.  Во время чтения реестра формируется уникальный 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. После перезапуска виртуальной машины вредонос запускается из автозагрузки и начинает свою активность. При это наблюдаем следующие действия: 1. Запущен какой-либо легитимный исполняемый MZ-файл, который выбирается случайным образом: 2. Запущенный процесс хоть и выглядит легитимным, но при этом осуществляет сетевое взаимодействие с C2-сервером 45.89.65[.]198: 3. Всё тот же процесс пишет некие данные в файл C:\Temp\{random_chars}\{random_chars}\dd-mm-yyyy.log. На данном этапе логично предположить, что раз запись ведется в файл .log, то это логи вредоноса: Настало время открыть содержимое 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: К нашему разочарованию, функционалы майнера, стиллера, шифровальщика и т. д. не были реализованы в этом конкретном билде вредоноса. Возможно, кому-то повезет больше, чем нам. Как упоминалось ранее, вредонос пишет некие данные (логи?) в файл 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), из которого был осуществлен перехват: Нам не повезло: не получилось подробно зафиксировать взаимодействие злоумышленника с нашей виртуальной машиной — мы получали только ответные пакеты от 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: Для профилактики заражения вредоносом DarkGate (впрочем, как и многими другими вредоносами) целесообразно применять комплекс мероприятий, таких как повышение осведомленности сотрудников с целью противодействия фишинговым атакам, корректная конфигурация доменных политик (в частности, запрет на прямое исполнение VBS-, batch-, PowerShell-скриптов), а также реализация непрерывного мониторинга. Аналитики центра кибербезопасности Jet CSIRT уже подготовили и внедрили корреляционный контент для выявления активности DarkGate в SIEM-системах своих заказчиков. Для того чтобы каждый мог настроить мониторинг в своей инфраструктуре, прикладываем частичный список условий в виде псевдо-кода: Способов выявления внедренных в инфраструктуру экземпляров DarkGate можно придумать довольно много, вплоть до поиска аномалий сетевой активности, но наиболее простой и эффективный способ — провести проверку наличия файлов .au3 в директории C:\Temp, например, с помощью следующей команды: powershell.exe Test-Path C:\temp\*.au3 Эту же команду можно поместить в batch-скрипт для массовой проверки автоматизированными средствами. Вредоносное ПО DarkGate имеет серьезный функционал: злоумышленник может украсть чувствительную информацию с помощью стиллера (файлы cookie, пароли, токены дискорда, пароли криптокошельков), добывать криптовалюту посредством встроенного майнера, получать удаленный доступ до зараженного узла, запускать кейлогеры, снимать скриншоты с машины жертвы, а также инжектировать любую полезную нагрузку вплоть до вируса-шифровальщика, выявить которую будет затруднительно благодаря двойному шифрованию. Создатели DarkGate не сидят на месте и постоянно совершенствуют свое детище, усложняя его выявление. В наших кейсах злоумышленники используют проверенный временем метод доставки вредоносного ПО — фишинг. Способ всё еще остается действенным: пользователи продолжают попадаться на эту удочку. Не хочется повторять очевидное, но этот факт лишний раз доказывает необходимость профилактики: нужно обучать сотрудников цифровой гигиене и безопасной работе с электронной почтой.  Автор: Александр Перевалов, аналитик Jet CSIRT, "Инфосистемы Джет"  Центр мониторинга и реагирования на инциденты ИБ