• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья Анализ вымогателя MountLocker

yashechka

Генератор контента.Фанат Ильфака и Рикардо Нарвахи
Эксперт
Регистрация
24.11.2012
Сообщения
2 344
Реакции
3 563
Программа-вымогатель MountLocker

Обзор


Это мой отчет по образцу MountLocker Ransomware v5.0, который используется группой вымогателей XingLocker.

Эта программа-вымогатель использует схему гибридной криптографии RSA-2048 и ChaCha20 для шифрования файлов и защиты своих ключей. В отличие от других программ-вымогателей, MountLocker шифрует все ключи ChaCha20 с помощью глобального ключа ChaCha20, прежде чем шифровать этот глобальный ключ с помощью открытого ключа RSA-2048. Зашифрованный глобальный ключ и соответствующий зашифрованный ключ ChaCha20 добавляются в конце каждого зашифрованного файла.

Эта версия включает в себя новую функцию червя, позволяющую ему самостоятельно распространяться на другие компьютеры в сети с помощью COM-интерфейсов IDirectorySearch и IWbemServices.

MountLocker имеет сложную схему многопоточности, но ее производительность страдает от нехватки потоков из-за рекурсивного обхода файлов.

Я больше не буду тратить свое время на объяснение того, почему рекурсивный обход файлов ужасен, потому что я высказал свое мнение в последних нескольких отчетах. Пожалуйста, не стесняйтесь прочитайте мой анализ Darkside, если вы хотите лучше понять теорию, стоящую за ним!

1643038674237.png


IOCS

Этот образец версии 5.0 представляет собой 64-разрядный файл .exe.

MD5: 3808f21e56dede99bc914d90aeabe47a

SHA256: 4a5ac3c6f8383cc33c795804ba5f7f5553c029bbb4a6d28f1e4d8fb5107902c1

Сэмпл: https://bazaar.abuse.ch/sample/4a5ac3c6f8383cc33c795804ba5f7f5553c029bbb4a6d28f1e4d8fb5107902c1/

1643038693255.png


Записка с требованием выкупа

Записка о выкупе записывается в формате HTML и помещается в файлы RecoveryManual.html в системе.

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

1643038710533.png


Производительность

MountLocker имеет довольно среднюю производительность и не полностью использует вычислительную мощность машины.

1643038725875.png


Статический анализ кода

Параметры командной строки


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

1643038739795.png


Ниже приведен список аргументов, которые могут быть предоставлены операторами:

1643038814988.png


Логирование

Программа-вымогатель имеет два разных способа ведения журнала своих операций, и каждый из них можно включить, установив для аргументов командной строки /CONSOLE значение 1 и /NOLOG на 0.

В этом конкретном примере значение флага /NOLOG жестко запрограммировано равным 0, поэтому он всегда записывает и удаляет файл журнала в системе жертвы.

Когда флаг /NOLOG равен 0, MountLocker извлекает путь к текущему исполняемому файлу, добавляет .log в конец и использует его в качестве пути к файлу журнала.

1643038828745.png


Если флаг /CONSOLE равен 1, MountLocker также будет вести журнал через стандартный поток вывода консоли. Он вызывает AllocConsole и GetStdHandle(STD_OUTPUT_HANDLE), чтобы выделить консоль и получить дескриптор стандартного потока вывода. Для записи в эту консоль он вызывает WriteConsoleW с этим дескриптором.

1643038902451.png


В начале журнала сообщается версия конкретного образца MountLocker, и в данном случае это версия 5.0.

Он также извлекает и записывает информацию о системе жертвы, такую как количество процессоров, общий объем системной памяти, версию Windows, архитектуру системы и т.д.

1643038886379.png


Таким образом записываются все файловые и сетевые операции (перебор, пропуск, шифрование, ошибка).

1643038860331.png


Терминация сервисов

Если аргумент /NETWORK не указан, вредоносное ПО будет работать в локальном режиме.

В этом режиме, если аргумент /NOKILL равен 0, он перечисляет и уничтожает все службы с этими строками в их имени.

"SQL", "database", "msexchange"

Во-первых, он вызывает OpenSCManagerA для получения дескриптора диспетчера управления службами и вызывает EnumServicesStatusA для перечисления всех служб Win32 со статусом SERVICE_ACTIVE.

1643038972239.png


Если служба содержит любую из трех приведенных выше строк, MountLocker завершит ее, вызвав OpenServiceA для получения дескриптора управления службой и вызвав ControlService для отправки кода остановки управления. Затем он непрерывно зацикливается до тех пор, пока состояние службы не станет SERVICE_CONTROL_STOP, чтобы убедиться, что служба полностью завершена.

1643038984019.png


Завершение процессов

Если он работает в локальном режиме и аргумент /NOKILL равен 0, MountLocker перечислит и уничтожит все процессы с этими строками в их имени.

"msftesql.exe", "sqlagent.exe", "sqlbrowser.exe", "sqlwriter.exe", "oracle.exe", "ocssd.exe",
"dbsnmp.exe", "synctime.exe", "agntsvc.exe", "isqlplussvc.exe", "xfssvccon.exe", "sqlservr.exe",
"mydesktopservice.exe", "ocautoupds.exe", "encsvc.exe", "firefoxconfig.exe", "tbirdconfig.exe",
"mydesktopqos.exe", "ocomm.exe", "mysqld.exe", "mysqld-nt.exe", "mysqld-opt.exe", "dbeng50.exe",
"sqbcoreservice.exe", "excel.exe", "infopath.exe", "msaccess.exe", "mspub.exe", "onenote.exe",
"outlook.exe", "powerpnt.exe", "sqlservr.exe", "thebat.exe", "steam.exe", "thebat64.exe", "thunderbird.exe",
"visio.exe", "winword.exe", "wordpad.exe", "QBW32.exe", "QBW64.exe", "ipython.exe", "wpython.exe",
"python.exe", "dumpcap.exe", "procmon.exe", "procmon64.exe", "procexp.exe", "procexp64.exe"


Программа-вымогатель сначала вызывает ZwQuerySystemInformation с информационным классом SystemProcessInformation, чтобы получить массив структур SYSTEM_PROCESS_INFORMATION. Он перебирает каждый запущенный процесс, избегает своего собственного процесса и начинает завершать процессы в списке уничтожения.

1643039007693.png


Чтобы проверить и убить процесс, он проходит по списку PROCESS_TO_KILL и сравнивает имя процесса. Если имя процесса есть в списке, он вызывает OpenProcess, чтобы получить дескриптор этого процесса, и завершает его с помощью TerminateProcess.

1643039019434.png


Генерация глобального ключа ChaCha20

Затем случайным образом генерируется глобальный ключ ChaCha20. Рандомизация выполняется путем вызова инструкции rdtsc, чтобы получить отметку времени процессора, и операции xor его младшего значащего байта для генерации каждого байта в ключе.

После создания глобального ключа программа-вымогатель копирует ключ в другой глобальный буфер в памяти и шифрует этот новый буфер с помощью жестко запрограммированного ключа RSA-2048.

1643039031936.png


Позже MountLocker использует этот глобальный ключ ChaCha20 для шифрования и защиты своих ключей ChaCha20 вместо использования RSA-2048. Поскольку шифрование RSA-2048 выполняется только один раз, эта схема гибридной криптографии дает некоторое преимущество в производительности, поскольку RSA довольно медленный по сравнению с ChaCha20.

Шифрование

Создание потоков шифрования


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

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

Эта функция сначала передает перечисляющую функцию и целевое имя пользовательской структуре, прежде чем создать поток для начала шифрования.

Этот поток действует как основной поток в шифровании, который рекурсивно перечисляет и предоставляет файлы для шифрования дочерним потокам.

1643039052713.png


Функция основного потока вызывает CreateEventA, чтобы создать обработчик событий для каждого дочернего потока, чтобы позже отправить им информацию о файле посредством вызова SetEvent.

Создаются только 2 дочерних рабочих потока, и эти потоки зацикливаются и ждут получения файлов из основного потока для шифрования. Основной поток начнет подавать им файлы, вызвав функцию перечисления в пользовательской структуре выше и перечислив целевую папку.

1643039068456.png


Дочерние рабочие потоки

После создания каждый рабочий поток получает общую структуру с основным потоком и постоянно проверяет наличие сигнала шифрования 1 в этой общей структуре.

Из-за синхронизации посредством совместного использования общей структуры среди потоков дочерний поток вызывает _InterlockedExchange для атомарного извлечения сигнала шифрования, чтобы проверить, разрешено ли ему шифрование.

Когда он находит файлы для шифрования, основной поток добавляет имя файла в общую структуру и устанавливает сигнал шифрования для дочернего потока для обработки этого файла.

1643039083254.png


После получения информации о файле рабочий поток создает структуру для хранения такой информации о файле, как имя файла, зашифрованное имя файла, дескриптор файла, размер файла и т. д.

Затем он проверит, есть ли у него права на открытие файла и получение размера файла.

1643039103498.png


Затем он случайным образом генерирует ключ файла ChaCha20 и добавляет его к файловой структуре выше. Рандомизация выполняется вызовом инструкции rdtsc аналогично генерации глобального ключа ChaCha20.

1643039114973.png


После генерации ключа файла ChaCha20 рабочий поток создает 313-байтовый буфер, в котором хранится строка маркера файла "lock2" с прямым порядком байтов, размер быстрого шифрования, зашифрованный глобальный ключ ChaCha20 и зашифрованный ключ файла ChaCha20. Этот буфер добавляется в конец зашифрованного файла.

1643039139851.png


Вот макет буфера ключей в конце зашифрованного файла.

1643039159473.png


Шифрование файлов довольно стандартное. Рабочий поток шифрует фрагмент размером 0x100000 байт за раз, пока он не зашифрует байты FAST_CRYPT_SIZE или не закончатся байты для шифрования.

Он использует ReadFile для чтения содержимого файла в буфер, шифрует его с помощью файлового ключа ChaCha20 и записывает обратно с помощью WriteFile. Поскольку шифрование выполняется для одного и того же файла, вызывается SetFilePointerEx для настройки указателя файла после чтения и записи.

1643039179059.png


Я не буду анализировать функцию ChaCha20, потому что MountLocker просто использует эту библиотеку CRYPTOGAMS от OpenSSL( https://github.com/dot-asm/cryptogams/blob/master/x86_64/chacha-x86_64.pl) .

Перечисление основного потока

MountLocker использует ту же функцию для обхода файлов для сетевых дисков, общих сетевых ресурсов и локальных дисков.

Перед обходом диска программа-вымогатель проверяет, предоставлено ли имя файла маркера из аргумента командной строки /MARKER=. Если это так, MountLocker создает пустой файл с этим именем файла маркера на зашифрованном диске перед его перечислением. Это в основном для обозначения того, какой диск был зашифрован.

1643039198398.png


Для перечисления папок MountLocker вызывает FindFirstFileW и FindNextFileW. При перечислении через сетевые серверы вместо этого будут использоваться WNetOpenEnumW и WNetEnumResourceW.

1643039211891.png


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

При обработке папки функция проверки проверяет следующие вещи. Если что-то из этого верно, папка пропускается.

1643039224995.png


Ниже приведен список FOLDER_TO_AVOID.

":\\Windows\\", ":\\System Volume Information\\", ":\\$RECYCLE.BIN\\", ":\\SYSTEM.SAV", ":\\WINNT",
":\\$WINDOWS.~BT\\", ":\\Windows.old\\", ":\\PerfLog\\", ":\\Boot", ":\\ProgramData\\Microsoft\\",
":\\ProgramData\\Packages\\", "$\\Windows\\", "$\\System Volume Information\\", "$\\$RECYCLE.BIN\\",
"$\\SYSTEM.SAV", "$\\WINNT", "$\\$WINDOWS.~BT\\", "$\\Windows.old\\", "$\\PerfLog\\", "$\\Boot",
"$\\ProgramData\\Microsoft\\", "$\\ProgramData\\Packages\\", "\\WindowsApps\\", "\\Microsoft\\Windows\\",
"\\Local\\Packages\\", "\\Windows Defender", "\\microsoft shared\\", "\\Google\\Chrome\\", "\\Mozilla Firefox\\",
"\\Mozilla\\Firefox\\", "\\Internet Explorer\\", "\\MicrosoftEdge\\", "\\Tor Browser\\", "\\AppData\\Local\\Temp\\"


Если папка действительна и в ней еще нет файла с примечанием о выкупе, MountLocker поместит в папку примечание о выкупе.

1643039247230.png


При обработке файла функция проверки проверяет следующее. Если хотя бы одно из них верно, файл пропускается.

- Если размер файла меньше MIN_CRYPT_SIZE (если указано MIN_CRYPT_SIZE) или если размер файла больше MAX_CRYPT_SIZE (если указано MAX_CRYPT_SIZE)
- Если имя файла «RecoveryManual.html», «bootmgr» или имеет зашифрованное расширение файла.
- Если расширение файла находится в списке EXTENSION_TO_AVOID


Ниже приведен список EXTENSION_TO_AVOID.

"exe", "dll", "sys", "msi", "mui", "inf", "cat", "bat", "cmd", "ps1", "vbs", "ttf", "fon", "lnk"

Если файл действителен, основной поток программы-вымогателя заполнит общую файловую структуру именем файла для шифрования своего рабочего потока.

Из-за проблем с синхронизацией основной поток также должен вызывать функции WaitForSingleObject и _InterlockedExchange, чтобы дождаться получения доступа к общей структуре.

После заполнения файловой структуры он вызывает SetEvent, чтобы сигнализировать о событии для шифрования рабочих потоков.

1643039312901.png


Свойство червя

Подобно WannaCry и Ryuk, этот образец MountLocker представляет собой комбинацию программы-вымогателя и червя с возможностью самораспространения на другие узлы в сети.

В отличие от WannaCry, эта программа-вымогатель не использует какие-либо причудливые 0-day, а вместо этого использует COM-интерфейсы, такие как IDirectorySearch и IWbemServices, для своего распространения и выполнения.

MountLocker имеет эту структуру, которая является общей для всех потоков червя.

1643039330436.png


Сначала для этой структуры выделяется память и создаются дескриптор события и дескриптор семафора. Функция запуска программы-вымогателя и ее параметр изначально оставлены нулевыми.

MountLocker создает 8 потоков для выполнения этого свойства червя.

1643039340773.png


Каждый из этих потоков ожидает, когда событие будет сигнализировано основным потоком, прежде чем вызывать функцию червя для удаленного запуска программы-вымогателя. Основной поток соответствующим образом установит эту функцию червя, прежде чем сигнализировать о событии.

1643039350565.png


После создания этих рабочих потоков основной поток начинает перечисление домена Windows, в котором находится текущий узел.

Это достигается путем вызова NetGetDCName для получения имени основного контроллера домена и добавления этого имени после строки "LDAP:// ".

1643039361493.png


Облегченный протокол доступа к каталогам (LDAP) (https://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol) — это протокол для связи и запросов к нескольким различным типам каталогов, и в этом случае MountLocker использует его для выполнения запросов Active Directory к основному контроллеру домена.

Он вызывает ADsOpenObject с новой строкой ADsPath и предоставляет учетные данные (имя пользователя и пароль) из аргументов /LOGIN= и /PASSWORD=. Предоставленный RIID — {109BA8EC-92F0-11D0-A790-00C04FD8D5A8}, и через этот вызов программа-вымогатель получает интерфейс IDirectorySearch.

Этот трюк с запросом IDirectorySearch ранее использовался Trickbot, как объяснил Витали здесь ( https://www.vkremez.com/2017/12/lets-learn-introducing-new-trickbot.html).

1643039373582.png


Этот интерфейс можно использовать для выполнения поиска всех контроллеров домена с помощью функции IDirectorySearch::ExecuteSearch, которая возвращает дескриптор поиска AD.

MountLocker вызывает IDirectorySearch::GetFirstRow и IDirectorySearch::GetNextRow для перечисления всех поисков, передавая каждый поиск в функцию для извлечения информации о контроллере домена.

1643039396048.png


Для каждого из этих дескрипторов поиска MountLocker затем вызывает IDirectorySearch::GetColumn с именем столбца "name", чтобы получить соответствующую структуру ADS_SEARCH_COLUMN в этой строке.

Эта структура содержит массив структур ADSVALUE, и каждая из этих структур содержит строку DN объекта службы каталогов в Active Directory. Эта строка отличительного имени (DN) в основном представляет собой имя для идентификации другого ПК в сети.

1643039409508.png


Когда строка DN ПК извлекается, она передается в функцию, где программа-вымогатель будет использовать ее в качестве параметра функции в структуре WORM_STRUCT. Функция структуры настроена на определенную функцию, которая удаляет и запускает образец удаленно. SetEvent вызывается для выполнения этой функции после того, как структура WORM_STRUCT полностью заполнена.

1643039421302.png


Функция дропа червя

Сначала поток червя попытается установить соединение с удаленным целевым ПК, вызвав WNetAddConnection2W и предоставив имя пользователя и пароль из аргументов /LOGIN= и /PASSWORD=.

1643039432404.png


Далее выделяется память для пользовательской структуры. Я просто называю это WORM_REMOTE_STRUCT.

1643039441599.png


Затем он заполняет эту структуру. Имя исполняемого файла — это число, полученное из GetTickCount, а путь на хосте для удаления программы-вымогателя — "C:\ProgramData".

1643039452004.png


Функция drop_ransomware проверяет, содержит ли строка DN какое-либо из имен общих ресурсов с более высокими привилегиями "\ADMIN$" и "\IPC$". Если да, то MountLocker использует его как основной путь в команде для запуска исполняемого файла. Если это не так, то он просто использует обычный путь.

Образец программы-вымогателя запускается с параметром /NOLOG и любыми аргументами, указанными в исходном аргументе /PARAMS=.

Наконец, он дропает программу-вымогатель на целевой компьютер, вызывая CopyFileW.

1643039468909.png


MountLocker не только сбрасывает исполняемый файл программы-вымогателя на целевой ПК, но также перебирает общие ресурсы ПК в сети ПК, вызывая NetShareEnum. Найдя путь к каждому общему ресурсу, программа-вымогатель вызывает drop_ransomware, чтобы удалить исполняемый файл в системе общего ресурса.

1643039483896.png


Функция запуска червя

MountLocker имеет два разных способа запуска исполняемого файла на удаленном хосте.

Если предоставленный аргумент /NETWORK имеет значение s, он запускает исполняемый файл через службу.

Сначала создается полная команда cmd.exe.

cmd.exe /c start "ransomware_path PARAMS_VALUE /NOLOG"


Затем программа-вымогатель вызывает OpenSCManagerW, чтобы установить соединение с диспетчером управления службами на целевом ПК. Используя этот дескриптор, он вызывает CreateServiceW с приведенной выше командой в качестве параметра lpBinaryPathName для создания дескриптора службы и вызывает StartServiceW для его запуска.

1643039596960.png


Если предоставленный аргумент /NETWORK имеет значение w, он запускает исполняемый файл с помощью инструментария управления Windows (WMI).

Сначала MountLocker извлекает интерфейс IWbemServices. Это делается путем вызова CoCreateInstance с CLSID {4590F811-1D3A-11D0-891F-00AA004B2E24} для получения объекта IWbemLocator.

Используя этот объект IWbemLocator, он вызывает IWbemLocator::ConnectServer для подключения к пространству имен ROOT\CIMV2 ПК и получения объекта IWbemServices.

1643039613674.png


Отсюда MountLocker устанавливает соответствующую структуру SEC_WINNT_AUTH_IDENTITY_A с заданными именем пользователя и паролем. Затем он вызывает CoSetProxyBlanket, чтобы установить информацию аутентификации для этого объекта IWbemServices.

1643039626077.png


Используя этот объект IWbemServices, программа-вымогатель вызывает функцию IWbemServices::GetObjectA с путем "Win32_Process", чтобы получить объект IWbemClassObject, соответствующий процессам Windows32.

Затем, используя этот объект "Win32_Process", он затем вызывает функцию IWbemClassObject::GetMethod с именем метода "Create", чтобы получить объект IWbemClassObject, соответствующий методу создания процесса.

С этим объектом метода он вызывает IWbemClassObject::SpawnInstance для создания нового экземпляра класса.

1643039641760.png


Поскольку Win32_Process::Create требует допустимого значения для параметра командной строки для правильного выполнения, MountLocker вызывает функцию IWbemClassObject::Put, чтобы установить значение командной строки для команды запуска, которую он построил выше.

1643039653334.png


Наконец, он вызывает IWbemServices::ExecMethod для создания процесса Win32, выполняющего приведенную выше команду "cmd.exe". Он также проверяет, успешно ли создан новый процесс, проверяя, изменился ли идентификатор процесса с помощью вызова IWbemClassObject::Get.

1643039662410.png


Если какой-либо из этих шагов по удалению и запуску исполняемого файла не удается, MountLocker просто прибегает к использованию WNetOpenEnumW и WNetEnumResourceW для перечисления через сеть жертвы и аналогичным образом удаляет программу-вымогатель.

Самоудаление

Если для аргумента /NODEL установлено значение 0, MountLocker удалит свой собственный исполняемый файл.

Во-первых, он создает в папке TEMP файл .bat со случайным именем из GetTickCount.

Он записывает эту команду в этот .bat-файл, который очищает атрибуты "Только для чтения", "Системный" и "Скрытый" от исполняемого файла программы-вымогателя, принудительно удаляет исполняемый файл, если он существует, и удаляет файл bat.

attrib -s -r -h %1
:l
del /F /Q %1
if exist %1 goto l
del %0


Затем MountLocker создает строку командной строки для выполнения файла .bat с путем к исполняемому файлу в качестве параметра и, наконец, вызывает CreateProcessW для удаления себя.

1643039689905.png


Правила для ЯРА

rule MountLocker5_0 {
meta:
description = "YARA rule for MountLocker v5.0"
reference = "http://chuongdong.com/reverse engineering/2021/05/23/MountLockerRansomware/"
author = "@cPeterr"
tlp = "white"
strings:
$worm_str = "========== WORM ==========" wide
$ransom_note_str = ".ReadManual.%0.8X" wide
$version_str = "5.0" wide
$chacha_str = "ChaCha20 for x86_64, CRYPTOGAMS by <appro@openssl.org>"
$chacha_const = "expand 32-byte k"
$lock_str = "[OK] locker.file > time=%0.3f size=%0.3f KB speed=%" wide
$bat_str = "attrib -s -r -h %1"
$IDirectorySearch_RIID = { EC A8 9B 10 F0 92 D0 11 A7 90 00 C0 4F D8 D5 A8 }
condition:
uint16(0) == 0x5a4d and all of them
}
 
MountLocker а не Diavol ))
 
Quake3 , смени плиз название на MountLocker
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх