Статья подготовлена командой 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}, где:
  • идентификатор бота — контрольная сумма от системной информации (алгоритм генерации идентификатора бота описан в разделе Lizar loader)
  • pid — значение идентификатора процесса, в котором функционирует лоадер (если лоадер неактивен, pid принимает значение 0)
Pid Такое же значение, как pid из колонки Id
Platform Битность и тип процесса, в котором функционирует лоадер:
  • x86 – лоадер — 32-битный файл EXE или DLL
  • x86.net – лоадер — 32-битный файл EXE или DLL, написанный на платформе .NET Framework
  • x64 – лоадер — 64-битный файл EXE или DLL
  • x64.net – лоадер — 64-битный EXE или DLL, написанный на платформе .NET Framework
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 client

Rat — запустить 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:


  1. Генерация случайного ключа g_ConfigKey31 при помощи функции SystemFunction036. Данный ключ используется в дальнейшем для расшифровывания конфигурационных данных.


  2. Получение системной информации и подсчет контрольной суммы от полученной информации (рис. 14).

    Рис. 14. Псевдокод для получения системной информации и подсчета контрольной суммы от нее


  3. Получение идентификатора текущего процесса (контрольная сумма и PID процесса лоадера отображаются в колонке Id в приложении клиента).


  4. Подсчет контрольной суммы от ранее полученной контрольной суммы и идентификатора текущего процесса (на рис. 13 обозначено как g_BotId).


  5. Расшифровывание конфигурационных данных: списка IP-адресов, списка портов для каждого сервера. Конфигурационные данные расшифровываются на 31-байтовом ключе g_LoaderKey алгоритмом XOR. После расшифровывания данные повторно зашифровываются на ключе g_ConfigKey31 алгоритмом XOR. Ключ g_LoaderKey также используется при шифровании данных, отправляемых на сервер, и при расшифровывании данных, получаемых с сервера.


  6. Инициализация глобальных переменных и критических секций для некоторых переменных. Это нужно для доступа к данным из различных потоков.


  7. Инициализация исполняемой памяти для выполнения плагинов.


  8. Запуск пяти потоков, в которых происходит обработка очереди сообщений с сервера. Этот механизм реализован с помощью функций PostQueuedCompletionStatus и GetQueuedCompletionStatus. Данные, полученные с сервера, расшифровываются и отправляются обработчику (рис. 15).

    Рис. 15. Псевдокод алгоритма расшифровывания данных, полученных с сервера, и передачи этих данных обработчику



При этом обработчик принимает данные с помощью функции GetQueuedCompletionStatus.


Тело плагинов содержится в переменной vServerData>ServerData после расшифровывания (еще раз взгляните на рис. 15). Псевдокод алгоритма, которым расшифровываются данные, полученные с сервера, представлен на рис. 16.



Рис. 16. Псевдокод алгоритма расшифровывания данных, полученных с сервера


Перед отправкой на сервер структура данных формируется так, как показано на рис. 17.

Рис. 17. Псевдокод функции, в которой генерируется структура, отправляемая серверу


Плагины из директории plugins


Плагины из директории plugins отправляются с сервера лоадеру и исполняются лоадером при осуществлении определенного действия в приложении Lizar Сlient.


Механизм работы плагинов в общем виде можно представить так:


  1. Пользователь выбирает команду в интерфейсе приложения Lizar client.
  2. Информация о выбранной команде отправляется на Lizar server.
  3. В зависимости от команды и битности лоадера сервер находит подходящий плагин из директории plugins и отправляет лоадеру запрос, содержащий команду и тело плагина (например, Screenshot{битность лоадера}.dll).
  4. Лоадер выполняет плагин и сохраняет результат выполнения плагина в специально выделенной области памяти на куче.
  5. Результат выполнения плагина отправляется на сервер, а с сервера — клиенту.
  6. В приложении клиента отображается результат работы плагина.

Полный список плагинов (32-битных и 64-битных DLL) из директории plugins
  • 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


Из представленного псевдокода видно, что миграция лоадера в адресное пространство указанного процесса может происходить тремя способами:


  • по идентификатору процесса, в который осуществляется инжект;
  • по имени исполняемого файла, в который осуществляется инжект;
  • путем миграции в такой же процесс.

Рассмотрим каждый из них подробнее.


Алгоритм инжекта по идентификатору процесса


  1. OpenProcess — плагин получает хендл процесса для указанного идентификатора процесса (PID).
  2. VirtualAllocEx + WriteProcessMemory — плагин выделяет память в виртуальном адресном пространстве указанного процесса и записывает туда содержимое, которое впоследствии будет исполнено.
  3. CreateRemoteThread — плагин создает поток в виртуальном адресном пространстве указанного процесса, в качестве адреса lpStartAddress выступает главная функция лоадера. Если CreateRemoteThread не отработал, плагин использует функцию RtlCreateUserThread (рис. 22).


Рис. 22. Псевдокод функции для создания потока в виртуальном адресном пространстве указанного процесса


Алгоритм инжекта по имени исполняемого файла


  1. Плагин находит путь к системному исполняемому файлу, в который необходимо осуществить инжект. Расположение этого файла зависит от разрядности лоадера. 64-битный файл размещается в директории %SYSTEMROOT%\System32, а 32-битный — в директории %SYSTEMROOT%\SysWOW64.
  2. Плагин создает процесс для полученного системного исполняемого файла, а также получает идентификатор созданного процесса. В зависимости от параметров плагина есть два способа реализации этого шага:

    • Если в структуре, передаваемой плагину, выставлен соответствующий флаг, то плагин создает процесс в контексте безопасности процесса explorer.exe (рис. 23).

      Рис. 23. Запуск исполняемого файла в контексте безопасности процесса explorer.exe
    • Если флаг не выставлен, исполняемый файл запускается посредством вызова функции CreateProcessA (рис. 24).

      Рис. 24. Вызов функции CreateProcessA
  3. Плагин выделяет память в виртуальном адресном пространстве созданного процесса и записывает туда содержимое, которое впоследствии будет исполнено (VirtualAllocEx + WriteProcessMemory).
  4. Плагин запускает функции в виртуальном адресном пространстве созданного процесса одним из следующих способов в зависимости от разрядности процесса:

    • для 64-битного процесса запуск осуществляется при помощи функции, псевдокод которой изображен на рис. 25;

      Рис. 25. Псевдокод алгоритма инжекта в 64-битный процесс
    • для 32-битного процесса запуск функции в виртуальном адресном пространстве созданного процесса осуществляется при помощи функций CreateRemoteThread и RtlCreateUserThread, которые создают поток в виртуальном адресном пространстве заданного процесса.

Алгоритм инжекта в такой же процесс


  1. Плагин получает путь к исполняемому файлу для процесса, в адресном пространстве которого он функционирует.
  2. Плагин запускает данный исполняемый файл и осуществляет инжект в созданный процесс.

Псевдокод для данного метода представлен на рис. 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 передаются от клиента к серверу, после чего — от сервера к лоадеру (на зараженную систему).


Список файлов из директории 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, описанной в предыдущем пункте.


Список функций из powerkatz, которые были исключены из powerkatz_short
  • 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