Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
Статья подготовлена командой BI.ZONE Cyber Threat Research
Мы не первый раз натыкаемся на киберпреступные группировки, которые прикидываются легальными организациями и маскируют свою малварь под инструменты для анализа защищенности. Сотрудники таких компаний могут даже не подозревать, что работают на злоумышленников и используют самый настоящий вредоносный пакет.
FIN7 (также именуемая как Carbanak и Navigator Group), одна из знаменитых АРТ-группировок, для разведки и закрепления на зараженных системах разработала Lizar — якобы инструмент для пентеста сетей Windows. Мы заинтересовались им и провели исследование, результатами которого поделимся в статье.
Раньше инструмент назывался Tirion, но дальше по тексту мы будем использовать только новое название Lizar
Немного о FIN7
APT-группировка FIN7, предположительно, основана еще в 2013 году, однако мы сосредоточимся на анализе ее деятельности с 2020 года: именно тогда киберпреступники сфокусировались на атаках с использованием шифровальщиков.
FIN7 составляла список жертв, фильтруя компании по доходу с помощью сервиса Zoominfo. В 2020–2021 годах мы наблюдали атаки на американские фармацевтические компании, IT-компанию со штаб-квартирой в Германии, один из ключевых финансовых институтов Панамы, игорное заведение и образовательные учреждения в США.
Довольно долго для целей разведки и закрепления на зараженных системах члены FIN7 использовали набор инструментов Carbanak Backdoor, почитать о котором можно в отчете FireEye (посты в блоге: 1, 2, 3, 4). Мы неоднократно наблюдали, как организаторы пытались маскироваться под представительство компании Check Point Software Technologies и Forcepoint. Пример этого — интерфейс инструмента Carbanak Backdoor версии 3.7.4 с отсылкой к компании Check Point Software Technologies (рис. 1).
Рис. 1. Интерфейс инструмента Carbanak Backdoor версии 3.7.4
Недавно у преступников появился новый вредоносный пакет — Lizar. В сети ранее публиковался отчет об исследовании Lizar версии 1.6.4, а мы решили изучить функциональные возможности компонентов более новой версии, 2.0.4 (дата и время компиляции Fri Jan 29 03:27:43 2021
), обнаруженных нами в феврале 2021 года.
Архитектура набора инструментов Lizar
По структуре набор инструментов Lizar похож на Carbanak Backdoor. Краткая характеристика обнаруженных нами компонентов представлена в табл. 1.
Табл. 1. Сущность и назначение компонентов Lizar
Название компонента | Описание компонента | Процесс работы компонента |
---|---|---|
Lizar client | Программа с графическим интерфейсом, с помощью которой участники группы FIN7 управляют лоадерами на зараженных устройствах. Предназначена для работы под управлением ОС Windows | Программа общается с сервером, отправляет через него команды загрузчику на зараженной машине (лоадеру) и получает результат выполнения команд |
Lizar server | Программа, которая обеспечивает связь между клиентом и лоадером | Программа работает на удаленном сервере |
Lizar loader | Лоадер, который предназначен для загрузки плагинов | Лоадер общается с управляющим сервером и запускает необходимые плагины по команде с сервера |
Lizar plugins | Плагины, расположенные на стороне сервера | Результат работы каждого плагина отправляется на сервер, а с сервера передается клиенту |
Lizar plugins/extra | Плагины, расположенные на стороне клиента | Плагины из директории plugins/extra передаются от клиента к серверу, после чего — от сервера к лоадеру (на зараженную систему) |
Lizar loader и Lizar plugins работают на зараженной системе и логически могут быть объединены в компонент Lizar bot.
То, как функционируют и взаимодействуют инструменты Lizar, можно увидеть на рис. 2.
Рис. 2. Схема работы набора инструментов Lizar
Lizar client
Lizar client состоит из следующих компонентов:
client.ini.xml
— конфигурационный файл в формате XML;client.exe
— основной исполняемый файл клиента;libwebp_x64.dll
— 64-битная версия библиотекиlibwebp
;libwebp_x86.dll
— 32-битная версия библиотекиlibwebp
;keys
— директория с ключами, необходимыми для шифрования трафика между клиентом и сервером;plugins/extra
— директория с плагинами (на практике в ней лежат лишь некоторые плагины, остальные расположены на сервере);rat
— директория с публичным ключом из комплекта Carbanak Backdoor (этот компонент добавлен в последней версии Lizar).
Ниже представлено содержимое и описание конфигурационного XML-файла (табл. 2).
<?xml version="1.0" encoding="utf-8"?>
<Params xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Servers>
<Server>
<Name>test</Name>
<IP>XX.XX.XX.XX</IP>
<Port>443</Port>
<FileKey>file.key</FileKey>
</Server>
</Servers>
<JumperApp>
<App>
<Name>svchost.exe</Name>
</App>
<App>
<Name>rundll32.exe</Name>
</App>
</JumperApp>
<HidePassedMinutes>1</HidePassedMinutes>
<ClientName>client-test</ClientName>
<TrafficLog>0</TrafficLog>
<Rats>
<RatConfig>
<Name>RatServer</Name>
<IP>XX.XX.XX.XX</IP>
<Port>443</Port>
<FileKey>rat\test.public.key</FileKey>
</RatConfig>
</Rats>
</Params>
Табл. 2. Характеристика элементов структуры конфигурационного XML-файла
Группа элементов | Название элемента | Описание элемента |
Servers → Server Настройки сервера |
Name | Имя сервера, отображаемое клиентом |
IP | IP-адрес сервера | |
Port | Порт, который слушает сервер | |
FileKey | Файл с ключом, используемым для шифрования трафика между клиентом и сервером | |
JumperApp → App Конфигурация приложения на зараженной ОС, в процесс которого будет произведена миграция |
Name | Имя процесса, в который может мигрировать лоадер |
Самостоятельные элементы | HidePassedMinutes | Конфигурационный параметр, от которого зависит отображение прошедших минут в графическом интерфейсе клиента. Принимает два значения: 0 (прошедшие минуты скрываются) и 1 (прошедшие минуты отображаются) |
ClientName | Имя клиента | |
TrafficLog | Конфигурационный параметр, от которого зависит логирование сетевого взаимодействия с сервером. Принимает два значения: 0 (сетевое взаимодействие логируется) и 1 (сетевое взаимодействие не логируется) | |
Rats → RatConfig Настройки плагина Rat, представляющего собой урезанную версию бота из набора инструментов Carbanak Backdoor |
Name | Имя сервера или панели администратора из набора инструментов Carbanak Backdoor |
IP | IP-адрес сервера или панели администратора из набора инструментов Carbanak Backdoor | |
Port | Порт сервера Carbanak Backdoor | |
FileKey | Файл, который содержит необходимый для работы Carbanak Backdoor публичный ключ RSA |
В табл. 3 представлены характеристики обнаруженного файла client.exe.
Табл. 3. Файл client.exe
Характеристики | Значение |
---|---|
Имя файла | client.exe |
SHA-256 | 78a744a64d3afec117a9f5f11a9926d45d0064c5a46e3c0df5204476a1650099 (нет на VT) |
Тип файла | PE32 executable for MS Windows (GUI) Intel 80386 Mono/.Net assembly |
Размер | 238 080 байт |
На рис. 3 — скриншот интерфейса последней обнаруженной нами версии клиента.
Рис. 3. Интерфейс версии 2.0.4 Lizar client
Название колонки | Содержимое колонки |
---|---|
Id |
Информация о боте в виде {имя бота}:{идентификатор бота}:{pid} , где:
|
Pid |
Такое же значение, как pid из колонки Id |
Platform |
Битность и тип процесса, в котором функционирует лоадер:
|
External IP |
Внешний IP-адрес зараженной системы, на которой запущен лоадер (не всегда отображается корректно) |
Local IP |
Внутренний IP-адрес зараженной системы, на которой запущен лоадер |
Country |
Страна, на территории которой находится зараженная система |
AV |
Название антивирусного продукта |
First , Last |
Временные метки первого и последнего отстука лоадера |
Passed |
Количество минут, прошедших с момента последнего отстука до текущего момента |
Next |
Количество секунд, через которое произойдет следующее взаимодействие клиента с сервером (если лоадер неактивен, значение становится отрицательным) |
Company |
Пустая колонка, где в будущем, вероятно, будет отображаться имя зараженной компании, полученное из домена |
Info |
Базовая информация о зараженной системе: домен, имя пользователя, версия зараженной системы |
Protocol |
Протокол общения с сервером (может принимать значения unknown и tcp ) |
Server |
Имя сервера, значение которого берется из конфигурации |
Comment , Outer string |
Дополнительная информация, которая сейчас не используется |
Клиент поддерживает несколько команд для бота. То, как они выглядят в графическом интерфейсе, можно увидеть на рис. 4.
Рис. 4. Список команд, поддерживаемых Lizar client
Вот что позволяет сделать каждая из команд:
Info
— получить информацию о системе. Плагин для данной команды расположен на сервере. При получении от плагина результата информация записывается в колонкуInfo
.
Kill
— завершить работу плагина.
Period
— изменить период отстука (рис. 5).
Рис. 5. КомандаPeriod
в графическом интерфейсе Lizar client
Screenshot
— сделать скриншот (рис. 6). Плагин для данной команды расположен на сервере. Если удалось сделать скриншот, он отобразится в отдельном окне.
Рис. 6. КомандаScreenshot
в графическом интерфейсе Lizar client
List Processes
— получить список процессов (рис. 7). Плагин для данной команды расположен на сервере. В случае успешной работы плагина список процессов отображается в отдельном окне.
Рис. 7. КомандаList Processes
в графическом интерфейсе Lizar client
Command Line
— получить CMD на зараженной системе. Плагин для данной команды расположен на сервере. Если плагин успешно выполнил команду, результат отобразится в отдельном окне.
Executer
— запустить дополнительный модуль (рис. 8).
Рис. 8. КомандаExecuter
в графическом интерфейсе Lizar client
Jump to
— осуществить миграцию лоадера в другой процесс. Плагин для данной команды расположен на сервере. Параметры команды передаются через файлclient.ini.xml
.
New session
— создать еще одну сессию лоадера (запустить копию лоадера на зараженной системе).
Mimikatz
— запустить mimikatz.
Grabber
— запустить один из плагинов, собирающих пароли в браузерах и ОС. Во вкладкеGrabber
есть две кнопки:Passwords + Screens
иRDP
(рис. 9). При использовании каждой из них отправляется команда на запуск соответствующего плагина.
Рис. 9. КомандаGrabber
в графическом интерфейсе Lizar client
Network analysis
— запустить один из плагинов для получения информации об Active Directory и информации о сети (рис. 10).
Рис. 10. Команда
Network analysis
в графическом интерфейсе Lizar clientRat
— запустить Carbanak Backdoor (RAT
). IP-адрес и порт сервера и панели администратора задаются через конфигурационный файл client.ini.xml
(рис. 11).
Рис. 11. Команда
Rat
в графическом интерфейсе Lizar clientМы перепрыгнули команду в общем списке Company computers
— она в настоящее время не обрабатывается. В коде образца нет обработчика для данной команды, так что мы не можем точно определить, что она делает.
Lizar server
Приложение Lizar server, как и Lizar client, написано на платформе .Net Framework. В отличие от клиента, сервер запускается на удаленном Linux-хосте. Дата и время компиляции последней обнаруженной нами версии сервера: Fri Feb 19 16:16:25 2021
. Приложение запускается при помощи утилиты wine с предустановленным wine-mono (wine-mono-5.0.0-x86.msi
).
Директория приложения сервера включает в себя следующие компоненты:
client/keys
— директория с ключами шифрования для корректного взаимодействия с клиентом.loader/keys
— директория с ключами шифрования для корректного взаимодействия с лоадером.logs
— директория с логами работы сервера (client-traffic
,error
,info
).plugins
— директория с плагинами.- ThirdScripts — директория со скриптом
ps2x.py
и вспомогательным модулемps2p.py
. Скриптps2x.py
предназначен для исполнения файлов на удаленном хосте и реализован с использованием проекта impacket. Заготовки команд для этого скрипта отображаются в приложении клиента при выборе соответствующей опции.
self.parser = argparse.ArgumentParser(description='ps2exec python module')
self.parser.add_argument('rhost', help='remote host and SMB-port like this: <host ip or name>[:port]')
self.parser.add_argument(
'rfile', help='remote (payload) file specification like this: <share>[[:<path>]:<file>]')
self.parser.add_argument('lfile', help='local (payload) file specification')
self.parser.add_argument('-c', '--cmd', help='command to execute on RHOST')
self.parser.add_argument('-o', '--output', help='remote file to collect output', default='', nargs='?')
self.parser.add_argument('-u', '--user', help='user name', default='')
self.parser.add_argument('-p', '--password', help='user password', default='')
self.parser.add_argument('-d', '--domain', help='user domain', default='')
self.parser.add_argument('-n', '--sockshost', help='socks5 server name or ip', default='localhost')
self.parser.add_argument('-k', '--socksport', help='socks5 server port number', type=int, default=8129)
self.parser.add_argument('-s', '--hash',
help='user password hash like this: <LM-Hash>:<NT-Hash>', default='')
self.parser.add_argument('-l', '--loglevel', type=int, default=3,
help='logging level from 0 to 5 (NONE, CRITICAL, ERROR, WARNING, INFO, DEBUG)')
x64
— директория с файлом вспомогательной библиотекиSQLite.Interop.dll
(64-битная версия).x86
— директория с файлом вспомогательной библиотекиSQLite.Interop.dll
(32-битная версия).AV.lst
— CSV-файл, содержащий имя процесса, который ассоциируется с антивирусным продуктом, название и описание антивирусного продукта. Несколько строк из файлаAV.lst
:
aexnsagent.exe|Altiris|Altiris Agent
aexswdusr.exe|Altiris|Altiris Express NS Client Manager
ALERT.EXE|eTrust|CA eTrust Integrated Threat Management 8.1/CA Jinchen Kill
ALUNotify.exe|Symantec|Symantec
avcenter.exe|Avira|Avira
data.db
— файл с базой данных, содержащей информацию обо всех лоадерах (эта информация подгружается в приложение клиента).server.exe
— приложение сервера.server.ini.xml
— конфигурационный файл приложения сервера.
<?xml version="1.0" encoding="utf-8"?>
<Params xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<protocols>
<PP>
<protocol>TCP</protocol>
<port>443</port>
</PP>
</protocols>
<TrafficLog>0</TrafficLog>
</Params>
System.Data.SQLite.dll
— файл вспомогательной библиотеки.
Обмен данными между клиентом и сервером
Перед отправкой на сервер данные шифруются на сессионном ключе размером от 5 до 15 байт, затем — на ключе, указанном в конфигурации (31 байт). Используемая функция шифрования представлена ниже.
public static void EncodeData(byte[] data, int szdata, byte[] key, int szkey)
{
byte b = 0;
int num = 0;
for (int i = 0; i < szdata; i++)
{
byte b2 = data[i];
data[i] = (data[i] ^ b ^ key[num]);
b = b2;
num = (num + 1) % szkey;
}
}
Если ключ, указанный в конфигурации (31 байт), не совпадает с ключом на сервере, данные с сервера не отправляются.
Для проверки ключа на стороне сервера клиент отправляет контрольную сумму от ключа, рассчитанную по следующему алгоритму:
public static uint CalcHash(byte[] m, int offset, int size)
{
uint num = 0U;
for (int i = 0; i < size; i++)
{
num ^= (uint)m[offset + i];
num *= 16777619U;
}
return num;
}
Данные, полученные с сервера, расшифровываются на сессионном ключе размером от 5 до 15 байт, затем — на ключе, указанном в конфигурации (31 байт). Функция для расшифровывания:
public static void DecodeData(byte[] data, int szdata, byte[] key, int szkey)
{
byte b = 0;
int num = 0;
for (int i = 0; i < szdata; i++)
{
data[i] = (data[i] ^ b ^ key[num]);
b = data[i];
num = (num + 1) % szkey;
}
}
Данные, передаваемые от клиента серверу и от сервера клиенту, имеют бинарный формат. Расшифрованные данные представляют собой список ботов (рис. 12).
Рис. 12. Пример расшифрованных данных, переданных от сервера клиенту
Lizar loader
Lizar loader предназначен для выполнения команд посредством запуска плагинов, а также для запуска дополнительных модулей. Он работает на стороне зараженного компьютера.
Как мы уже отметили, Lizar loader и Lizar plugins работают на зараженной системе и логически могут быть объединены в компонент Lizar bot. Модульная архитектура бота обеспечивает расширяемость инструмента и возможность вести независимую разработку всех компонентов.
Мы обнаружили три вида ботов: DLL, EXE и PowerShell-скрипты, которые в результате исполняют DLL в адресном пространстве процесса PowerShell.
Псевдокод главной функции лоадера вместе с восстановленной структурой функций представлены на рис. 13.
Рис. 13. Псевдокод главной функции лоадера
Вот что происходит в функции x_Init
:
Генерация случайного ключа
g_ConfigKey31
при помощи функцииSystemFunction036
. Данный ключ используется в дальнейшем для расшифровывания конфигурационных данных.
Получение системной информации и подсчет контрольной суммы от полученной информации (рис. 14).
Рис. 14. Псевдокод для получения системной информации и подсчета контрольной суммы от нее
Получение идентификатора текущего процесса (контрольная сумма и
PID
процесса лоадера отображаются в колонкеId
в приложении клиента).
Подсчет контрольной суммы от ранее полученной контрольной суммы и идентификатора текущего процесса (на рис. 13 обозначено как
g_BotId
).
Расшифровывание конфигурационных данных: списка IP-адресов, списка портов для каждого сервера. Конфигурационные данные расшифровываются на 31-байтовом ключе
g_LoaderKey
алгоритмомXOR
. После расшифровывания данные повторно зашифровываются на ключеg_ConfigKey31
алгоритмомXOR
. Ключg_LoaderKey
также используется при шифровании данных, отправляемых на сервер, и при расшифровывании данных, получаемых с сервера.
Инициализация глобальных переменных и критических секций для некоторых переменных. Это нужно для доступа к данным из различных потоков.
Инициализация исполняемой памяти для выполнения плагинов.
Запуск пяти потоков, в которых происходит обработка очереди сообщений с сервера. Этот механизм реализован с помощью функций
PostQueuedCompletionStatus
иGetQueuedCompletionStatus
. Данные, полученные с сервера, расшифровываются и отправляются обработчику (рис. 15).
Рис. 15. Псевдокод алгоритма расшифровывания данных, полученных с сервера, и передачи этих данных обработчику
При этом обработчик принимает данные с помощью функции GetQueuedCompletionStatus.
Тело плагинов содержится в переменной vServerData→ServerData
после расшифровывания (еще раз взгляните на рис. 15). Псевдокод алгоритма, которым расшифровываются данные, полученные с сервера, представлен на рис. 16.
Рис. 16. Псевдокод алгоритма расшифровывания данных, полученных с сервера
Перед отправкой на сервер структура данных формируется так, как показано на рис. 17.
Рис. 17. Псевдокод функции, в которой генерируется структура, отправляемая серверу
Плагины из директории plugins
Плагины из директории plugins
отправляются с сервера лоадеру и исполняются лоадером при осуществлении определенного действия в приложении Lizar Сlient.
Механизм работы плагинов в общем виде можно представить так:
- Пользователь выбирает команду в интерфейсе приложения Lizar client.
- Информация о выбранной команде отправляется на Lizar server.
- В зависимости от команды и битности лоадера сервер находит подходящий плагин из директории
plugins
и отправляет лоадеру запрос, содержащий команду и тело плагина (например,Screenshot{битность лоадера}.dll
). - Лоадер выполняет плагин и сохраняет результат выполнения плагина в специально выделенной области памяти на куче.
- Результат выполнения плагина отправляется на сервер, а с сервера — клиенту.
- В приложении клиента отображается результат работы плагина.
- CommandLine32.dll
- CommandLine64.dll
- Executer32.dll
- Executer64.dll
- Grabber32.dll
- Grabber64.dll
- Info32.dll
- Info64.dll
- Jumper32.dll
- Jumper64.dll
- ListProcess32.dll
- ListProcess64.dll
- mimikatz32.dll
- mimikatz64.dll
- NetSession32.dll
- NetSession64.dll
- rat32.dll
- rat64.dll
- Screenshot32.dll
- Screenshot64.dll
CommandLine32.dll/CommandLine64.dll
Плагин предназначен для предоставления злоумышленникам доступа к интерфейсу командной строки на зараженной системе.
Отправка команд процессу cmd.exe
и получение результата выполнения команд реализованы через пайпы (рис. 18).
Рис. 18. Псевдокод главной функции CommandLine32.dll/CommandLine64.dll
Executer32.dll/Executer64.dll
С помощью Executer32.dll/Executer64.dll запускаются дополнительные компоненты, указанные в интерфейсе приложения Lizar client.
Плагин поддерживает запуск следующих компонентов:
- файла EXE из директории
%TEMP%;
- PowerShell-скрипта из директории
%TEMP%
, который запускается при помощи следующей команды:{путь к файлу powershell.exe} -ex bypass -noprof -nolog -nonint -f {путь к PowerShell-скрипту};
- DLL в памяти;
- шелл-кода.
Код плагина, который запускает шелл-код, представлен на рис. 19.
Рис. 19. Код Executer32.dll/Executer64.dll, запускающий шелл-код
Следует отметить, что файл плагина Executer64.dll
содержит путь к PDB: M:\paal\Lizar\bin\Release\Plugins\Executer64.pdb
.
Grabber32.dll/Grabber64.dll
Вопреки своему названию, данный плагин не содержит функциональности граббера и представляет собой типичный загрузчик PE-файла.
Хотя злоумышленники и называют его граббером, на деле загруженный PE-файл выполняет функции других инструментов, например стилера.
Обе версии плагина используются в качестве загрузчиков грабберов, расположенных на стороне клиента: PswRdInfo64 и PswInfoGrabber64.
Info32.dll/Info64.dll
Плагин предназначен для получения информации о зараженной системе.
Плагин выполняется при использовании команды Info
в приложении Lizar client. На сервер отправляется структура данных, содержащая версию ОС, имя пользователя и имя компьютера.
На стороне сервера полученная структура приводится к специальной строке (рис. 20).
Рис. 20. Приведение полученной структуры к специальной строке на стороне сервера
Jumper32.dll/Jumper64.dll
Плагин предназначен для миграции лоадера в адресное пространство другого процесса. Параметры инжекта выставляются в конфигурационном файле Lizar client. Следует отметить, что данный плагин может быть использован не только для инжекта лоадера, но и для выполнения других PE-файлов в адресном пространстве указанного процесса. На рис. 21 представлен участок главной функции плагина.
Рис. 21. Псевдокод главной функции Jumper32.dll/Jumper64.dll
Из представленного псевдокода видно, что миграция лоадера в адресное пространство указанного процесса может происходить тремя способами:
- по идентификатору процесса, в который осуществляется инжект;
- по имени исполняемого файла, в который осуществляется инжект;
- путем миграции в такой же процесс.
Рассмотрим каждый из них подробнее.
Алгоритм инжекта по идентификатору процесса
OpenProcess
— плагин получает хендл процесса для указанного идентификатора процесса (PID
).VirtualAllocEx
+WriteProcessMemory
— плагин выделяет память в виртуальном адресном пространстве указанного процесса и записывает туда содержимое, которое впоследствии будет исполнено.CreateRemoteThread
— плагин создает поток в виртуальном адресном пространстве указанного процесса, в качестве адресаlpStartAddress
выступает главная функция лоадера. ЕслиCreateRemoteThread
не отработал, плагин использует функциюRtlCreateUserThread
(рис. 22).
Рис. 22. Псевдокод функции для создания потока в виртуальном адресном пространстве указанного процесса
Алгоритм инжекта по имени исполняемого файла
- Плагин находит путь к системному исполняемому файлу, в который необходимо осуществить инжект. Расположение этого файла зависит от разрядности лоадера. 64-битный файл размещается в директории
%SYSTEMROOT%\System32
, а 32-битный — в директории%SYSTEMROOT%\SysWOW64
. - Плагин создает процесс для полученного системного исполняемого файла, а также получает идентификатор созданного процесса. В зависимости от параметров плагина есть два способа реализации этого шага:
- Если в структуре, передаваемой плагину, выставлен соответствующий флаг, то плагин создает процесс в контексте безопасности процесса
explorer.exe
(рис. 23).
Рис. 23. Запуск исполняемого файла в контексте безопасности процессаexplorer.exe
- Если флаг не выставлен, исполняемый файл запускается посредством вызова функции
CreateProcessA
(рис. 24).
Рис. 24. Вызов функцииCreateProcessA
- Если в структуре, передаваемой плагину, выставлен соответствующий флаг, то плагин создает процесс в контексте безопасности процесса
- Плагин выделяет память в виртуальном адресном пространстве созданного процесса и записывает туда содержимое, которое впоследствии будет исполнено (
VirtualAllocEx
+WriteProcessMemory
). - Плагин запускает функции в виртуальном адресном пространстве созданного процесса одним из следующих способов в зависимости от разрядности процесса:
- для 64-битного процесса запуск осуществляется при помощи функции, псевдокод которой изображен на рис. 25;
Рис. 25. Псевдокод алгоритма инжекта в 64-битный процесс - для 32-битного процесса запуск функции в виртуальном адресном пространстве созданного процесса осуществляется при помощи функций
CreateRemoteThread
иRtlCreateUserThread
, которые создают поток в виртуальном адресном пространстве заданного процесса.
- для 64-битного процесса запуск осуществляется при помощи функции, псевдокод которой изображен на рис. 25;
Алгоритм инжекта в такой же процесс
- Плагин получает путь к исполняемому файлу для процесса, в адресном пространстве которого он функционирует.
- Плагин запускает данный исполняемый файл и осуществляет инжект в созданный процесс.
Псевдокод для данного метода представлен на рис. 26.
Рис. 26. Псевдокод алгоритма инжекта Jumper32.dll/Jumper64.dll в такой же процесс
ListProcesses32.dll/ListProcesses64.dll
Данный плагин предназначен для получения информации о запущенных процессах (рис. 27 и рис. 28).
Рис. 27. Получение информации о каждом активном процессе
Рис. 28. Добавление полученной информации для последующей отправки на сервер
Для каждого процесса могут быть получены:
- идентификатор процесса;
- путь к исполняемому файлу;
- информация о пользователе, от имени которого запущен процесс.
mimikatz32.dll/mimikatz64.dll
Плагин mimikatz — обертка для модулей powerkatz, расположенных на стороне клиента:
powerkatz_full32.dll
powerkatz_full64.dll
powerkatz_short32.dll
powerkatz_short64.dll
NetSession32.dll/NetSession64.dll
Плагин предназначен для получения информации обо всех сеансах, установленных на зараженном сервере. Для каждого сеанса может быть получен адрес хоста, с которого производится подключение, а также имя пользователя, инициирующего подключение.
Псевдокод функции, в которой происходит получение информации, представлен на рис. 29 и 30.
Рис. 29. Получение информации о сетевых сеансах с помощью функций из WinAPI
Рис. 30. Добавление информации, полученной плагином, для отправки на сервер
rat32.dll/rat64.dll
Плагин представляет собой урезанную версию бота из набора инструментов Carbanak Backdoor. Как мы писали в начале статьи, этот набор инструментов активно используется группировкой FIN7.
Screenshot32.dll/Screenshot64.dll
Плагин позволяет сделать скриншот на зараженной системе в формате JPEG. Ниже показан участок функции, используемый для сохранения полученного изображения в стрим (рис. 31).
Рис. 31. Участок функции, используемый для сохранения скриншота, сделанного плагином, в стрим
Далее полученный стрим передается лоадеру для отправки на сервер.
Плагины из директории plugins/extra
Плагины из директории plugins/extra
передаются от клиента к серверу, после чего — от сервера к лоадеру (на зараженную систему).
- ADRecon.ps1
- GetHash32.dll
- GetHash64.dll
- GetPass32.dll
- GetPass64.dll
- powerkatz_full32.dll
- powerkatz_full64.dll
- powerkatz_short32.dll
- powerkatz_short64.dll
- PswInfoGrabber32.dll
- PswInfoGrabber64.dll
- PswRdInfo64.dll
ADRecon
Файл ADRecon.ps1
— это инструмент для генерации отчета, содержащего информацию из среды Active Directory. Исходный код проекта доступен ADRecon доступен на GitHub. Отметим, что этот плагин не является разработкой FIN7, однако активно используется группировкой для атак в рамках исследуемого набора инструментов.
GetHash32/GetHash64
Плагин предназначен для получения NTLM-/LM-хешей пользователей. В основе плагина лежит код компонента lsadump
из mimikatz.
На рис. 32 представлен скриншот с псевдокодом экспортируемой функции Entry
(имена функций выбраны в соответствии с названиями функций из mimikatz).
Рис. 32. Псевдокод экспортируемой функции Entry
для плагина GetHash
Возвращаемое значение функции Execute
(значение переменной g_outputBuffer
) содержит указатель на буфер с данными, полученными в результате работы плагина.
Если плагин не удалось запустить с правами SYSTEM
, в результате его работы буфер заполнится данными, представленными на рис. 33.
Рис. 33. Содержимое буфера при запуске плагина без прав пользователя SYSTEM
Содержимое буфера в данном случае аналогично выводу mimikatz при запуске модуля lsadump::sam
без прав SYSTEM
(рис. 34).
Рис. 34. Вывод mimikatz при запуске lsadump::sam
без прав пользователя SYSTEM
Если плагин запущен с правами SYSTEM
, в результате его работы в буфер попадет вся искомая информация (рис. 35).
Рис. 35. Содержимое буфера при запуске плагина с правами пользователя SYSTEM
Такие же данные можно получить при выполнении команды lsadump::sam
из mimikatz с правами пользователя SYSTEM
(рис. 36).
Рис. 36. Результат выполнения команды lsadump::sam
из mimikatz с правами пользователя SYSTEM
GetPass32/GetPass64
Плагин предназначен для получения паролей пользователей. В его основе лежит код компонента sekurlsa
из mimikatz. Псевдокод экспортируемой функции Entry
представлен на рис. 37.
Рис. 37. Псевдокод экспортируемой функции Entry
По результатам работы плагина мы увидим в значении переменной g_outputBuffer
указатель на буфер с данными, которые можно получить при выполнении команды sekurlsa::logonpasswords
в mimikatz (рис. 38).
Рис. 38. Результат выполнения команды sekurlsa::logonpasswords
powerkatz_full32/powerkatz_full64
Плагин представляет собой версию mimikatz, собранную в конфигурации Second_Release_PowerShell. Эта версия может быть загружена в адресное пространство процесса PowerShell посредством рефлексивной загрузки DLL — так, как это реализовано в модуле Exfiltration
из PowerSploit.
Псевдокод экспортируемой функции powershell_reflective_mimikatz
(названия переменных и функций в декомпилированном выводе изменены в соответствии с названиями соответствующих переменных и функций из mimikatz):
HLOCAL __fastcall powershell_reflective_mimikatz(const WCHAR *input)
{
unsigned __int16 **argv; // rbx
int pNumArgs; // [rsp+38h] [rbp+10h] BYREF
pNumArgs = 0;
argv = CommandLineToArgvW(input, &pNumArgs);
if ( argv )
{
outputBufferElementsPosition = 0i64;
outputBufferElements = 255i64;
outputBuffer = LocalAlloc(0x40u, 0x1FEui64);
if ( outputBuffer )
wmain(pNumArgs, argv);
LocalFree(argv);
}
return outputBuffer;
}
Через параметр input
передается список команд, разделенных пробелом. Через глобальную переменную outputBuffer
передается результат выполнения команд. Декомпилированный вид функции wmain
представлен ниже:
__int64 __fastcall wmain(int argc, unsigned __int16 **argv)
{
__int64 vNumArgs; // rbx
int status; // edi
__int64 numArgs; // rbp
__int64 i; // rbx
int res; // eax
vNumArgs = argc;
status = 0;
kprintf(L"\n"
" .#####. mimikatz 2.2.0 (x64) #18362 Apr 8 2020 18:33:39\n"
" .## ^ ##. \"A La Vie, A L'Amour\" - (oe.eo)\n"
" ## / \\ ## /*** Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )\n"
" ## \\ / ## > http://blog.gentilkiwi.com/mimikatz\n"
" '## v ##' Vincent LE TOUX ( vincent.letoux@gmail.com )\n"
" '#####' > http://pingcastle.com / http://mysmartlogon.com ***/\n");
mimikatz_initOrClean(1);
numArgs = vNumArgs;
if ( vNumArgs > 0 )
{
i = 0i64;
do
{
if ( status == 0x40000015 )
break;
kprintf(L"\nmimikatz(powershell) # %s\n", argv[i]);
res = mimikatz_dispatchCommand(argv[i++]);
status = res;
}
while ( i < numArgs );
}
mimikatz_initOrClean(0);
return 0i64;
}
powerkatz_short32/powerkatz_short64
Плагин powerkatz_short
— это модифицированная версия стандартной библиотеки powerkatz
, описанной в предыдущем пункте.
kuhl_m_acr_clean
;kuhl_m_busylight_clean
;kuhl_m_c_rpc_clean
;kuhl_m_c_rpc_init
;kuhl_m_c_service_clean
;kuhl_m_crypto_clean
;kuhl_m_crypto_init
;kuhl_m_kerberos_clean
;kuhl_m_kerberos_init
;kuhl_m_vault_clean
;kuhl_m_vault_init
;kull_m_busylight_devices_get
;kull_m_busylight_keepAliveThread
.
PswInfoGrabber32.dll/PswInfoGrabber64.dll
Плагин позволяет получить из зараженной системы историю браузеров Firefox, Google Chrome, Microsoft Edge, Internet Explorer, сохраненные в них логины и пароли пользователей, а также учетные записи почтовых клиентов Microsoft Outlook и Mozilla Thunderbird.
Для получения конфиденциальных данных из браузера Firefox используется библиотека nss3.dll
, подгружаемая из директории с установленным браузером (рис. 39).
Рис. 39. Динамическое получение адресов функций из библиотеки nss3.dll
С помощью функций, представленных на рис. 39, учетные данные извлекаются из файла logins.json
, а история браузера — из базы данных places.sqlite
.
Атакуя Google Chrome, плагин получает историю браузера из базы %LOCALAPPDATA%\Google\Chrome\User Data\Default\History
, а пароли — из базы %LOCALAPPDATA%\Google\Chrome\User Data\Default\Login Data
(данные зашифрованы с использованием DPAPI).
History,
places.sqlite, Login Data
— файлы базы данных sqlite3
. Для работы с базами данных sqlite3
в плагине используются функции из библиотеки sqlite
, статически слинкованные с результирующей DLL, то есть самим плагином.
Для браузеров Internet Explorer и Microsoft Edge плагин получает учетные данные пользователей с использованием функций из библиотеки vaultcli.dll,
реализующей функции утилиты vaultcmd.exe
.
PswRdInfo64.dll
PswRdInfo64.dll предназначен преимущественно для сбора доменных учетных записей и получения учетных данных для доступа к другим хостам через RDP. Плагин активируется из приложения клиента с помощью вкладки Grabber → RDP
.
Алгоритм работы плагина зависит от следующих условий.
При запуске пользователем SYSTEM плагин перечисляет все активные консольные сессии (WTSGetActiveConsoleSessionId
) и получает имена пользователей для данных сессий:
(WTSQuerySessionInformationW)(0i64, SessionId, WTSUserName, &vpSessionInformationUserName, &pBytesReturned))
Затем плагин получает приватные ключи из директории C:\Users\{SessionInformationUserName}AppData\Local\Microsoft\Credentials
для каждого пользователя и осуществляет инжект в процесс lsass.exe
для извлечения доменных учетных записей.
При запуске другим пользователем (не SYSTEM
) плагин пытается собрать учетные данные для доступа по RDP к другим хостам. Сбор учетных данных осуществляется с помощью функции CredEnumerateW
, при этом в качестве цели используется строка TERMSRV
.
Заключение
Исследуемый набор инструментов разнообразен и сложен. Сейчас инструмент Lizar находится на стадии активной разработки и тестирования, при этом его уже вовсю используют для управления зараженными компьютерами. Сегодня Lizar используется в основном на территории США. Но, судя по всему, группировка не остановится на достигнутом, и мы совсем скоро узнаем о новых АРТ-атаках с применением данного инструмента по всему миру.
IoC
IP:
108.61.148.97
136.244.81.250
185.33.84.43
195.123.214.181
31.192.108.133
45.133.203.121
SHA256:
166b0c5e49c44f87886ecaad46e60b496b6b7512d1c57db41d9cf752fada95c8
188d76c31fa7f500799762237508203bdd1927ec4d5232cc189d46bc76b7a30d
1e5514e8f95dcf6dd7289acef6f6b88c460105660cb0c5b86ec7b854f70ee857
21850bb5d8df021e850e740c1899353f40af72f119f2cd71ad234e91c2ccb772
3b63eb184bea5b6515697ae3f13a57365f04e6a3309c79b18773291e62a64fcb
4d933b6b60a097ad5ce5876a66c569e6f46707b934ebd3c442432711af195124
515b94290111b7be80e001bfa2335d2f494937c8619cfdaafb2077d9d6af06fe
61cfe83259640df9f19df2be4b67bb1c6e5816ac52b8a5a02ee8b79bde4b2b70
fbd2d816147112bd408e26b1300775bbaa482342f9b33924d93fd71a5c312cce
a3b3f56a61c6dc8ba2aa25bdd9bd7dc2c5a4602c2670431c5cbc59a76e2b4c54
e908f99c6753a56440127e54ce990adbc5128d10edc11622d548ddd67e6662ac
7d48362091d710935726ab4d32bf594b363683e8335f1ee70ae2ae81f4ee36ca
e894dedb4658e006c8a85f02fa5bbab7ecd234331b92be41ab708fa22a246e25
b8691a33aa99af0f0c1a86321b70437efcf358ace1cf3f91e4cb8793228d1a62
bd1e5ea9556cb6cba9a509eab8442bf37ca40006c0894c5a98ce77f6d84b03c7
98fbccd9c2e925d2f7b8bcfa247790a681497dfb9f7f8745c0327c43db10952f
552c00bb5fd5f10b105ca247b0a78082bd6a63e2bab590040788e52634f96d11
21db55edc9df9e096fc994972498cbd9da128f8f3959a462d04091634a569a96