Статья подготовлена командой BI.ZONE Cyber Threat Research
Мы не первый раз натыкаемся на киберпреступные группировки, которые прикидываются легальными организациями и маскируют свою малварь под инструменты для анализа защищенности. Сотрудники таких компаний могут даже не подозревать, что работают на злоумышленников и используют самый настоящий вредоносный пакет.
FIN7 (также именуемая как Carbanak и Navigator Group), одна из знаменитых АРТ-группировок, для разведки и закрепления на зараженных системах разработала Lizar якобы инструмент для пентеста сетей Windows. Мы заинтересовались им и провели исследование, результатами которого поделимся в статье.
Раньше инструмент назывался Tirion, но дальше по тексту мы будем использовать только новое название Lizar
Немного о FIN7
APT-группировка FIN7, предположительно, основана еще в 2013 году, однако мы сосредоточимся на анализе ее деятельности с 2020 года: именно тогда киберпреступники сфокусировались на атаках с использованием шифровальщиков.
FIN7 составляла список жертв, фильтруя компании по доходу с помощью сервиса Zoominfo. В 20202021 годах мы наблюдали атаки на американские фармацевтические компании, 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://personeltest.ru/away/www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://personeltest.ru/away/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 Agentaexswdusr.exe|Altiris|Altiris Express NS Client ManagerALERT.EXE|eTrust|CA eTrust Integrated Threat Management 8.1/CA Jinchen KillALUNotify.exe|Symantec|Symantecavcenter.exe|Avira|Avira
data.db
файл с базой данных, содержащей информацию обо всех лоадерах (эта информация подгружается в приложение клиента).server.exe
приложение сервера.server.ini.xml
конфигурационный файл приложения сервера.
<?xml version="1.0" encoding="utf-8"?> <Params xmlns:xsi="http://personeltest.ru/away/www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://personeltest.ru/away/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.
Тело плагинов содержится в переменной
vServerDataServerData
после расшифровывания (еще раз
взгляните на рис. 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:
166b0c5e49c44f87886ecaad46e60b496b6b7512d1c57db41d9cf752fada95c8188d76c31fa7f500799762237508203bdd1927ec4d5232cc189d46bc76b7a30d1e5514e8f95dcf6dd7289acef6f6b88c460105660cb0c5b86ec7b854f70ee85721850bb5d8df021e850e740c1899353f40af72f119f2cd71ad234e91c2ccb7723b63eb184bea5b6515697ae3f13a57365f04e6a3309c79b18773291e62a64fcb4d933b6b60a097ad5ce5876a66c569e6f46707b934ebd3c442432711af195124515b94290111b7be80e001bfa2335d2f494937c8619cfdaafb2077d9d6af06fe61cfe83259640df9f19df2be4b67bb1c6e5816ac52b8a5a02ee8b79bde4b2b70fbd2d816147112bd408e26b1300775bbaa482342f9b33924d93fd71a5c312ccea3b3f56a61c6dc8ba2aa25bdd9bd7dc2c5a4602c2670431c5cbc59a76e2b4c54e908f99c6753a56440127e54ce990adbc5128d10edc11622d548ddd67e6662ac7d48362091d710935726ab4d32bf594b363683e8335f1ee70ae2ae81f4ee36cae894dedb4658e006c8a85f02fa5bbab7ecd234331b92be41ab708fa22a246e25b8691a33aa99af0f0c1a86321b70437efcf358ace1cf3f91e4cb8793228d1a62bd1e5ea9556cb6cba9a509eab8442bf37ca40006c0894c5a98ce77f6d84b03c798fbccd9c2e925d2f7b8bcfa247790a681497dfb9f7f8745c0327c43db10952f552c00bb5fd5f10b105ca247b0a78082bd6a63e2bab590040788e52634f96d1121db55edc9df9e096fc994972498cbd9da128f8f3959a462d04091634a569a96