Первый MSI вымогатель: Magniber. История и анализ сложнейшего шифровальщика. Часть 2

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!

Приветствую, читатели, эта статья является логическим продолжением анализа одного из самых сложных вымогателей — Magniber. В прошлой статье нам удалось разобраться с хронологией появления этого зловреда, а также провести статистический анализ первой ступени. 

Напомню, что Magniber является достаточно старым вирусом, который пришел к нам из Южной Кореи. Если раньше вредоносная кампания была сосредоточена в основном на мелких и средних компаниях, то сейчас злоумышленники атакуют всех и вся. На данный момент вымогатель маскируется под разные типы файлов ( .Ink, .iso, .js, .exe), но в рамках анализа у нас классический представитель, подражающий Установщику Windows.

Magniber.msi —  статистический анализ

Итак, в прошлой статье мы выяснили основные этапы работы вредоноса: 

  • Первичная полезная нагрузка, отвечающая за уход от обнаружения и создание дочерних процессов.

  • Вторичная полезная нагрузка отвечает за внедрение вредоносных функций в легальные процессы Windows.

  • Ядро вредоноса, отвечающее за процесс шифрования данных.

Все это вполне возможно отследить, пусть и будет очень трудно, поэтому разделим статью на следующие подсекции: 

  1. Отслеживание полезной нагрузки первого этапа и её последующий анализ.

  2. Отслеживание полезной нагрузки второго этапа и её последующий анализ.

  3. Анализ ядра Magniber.

Отслеживание полезной нагрузки второго этапа и её последующий анализ

Стоит отметить, что после запуска вредоносного .vbs скрипта, наш отслеживаемый процесс завершил свою работу. Но если судить по диспетчеру задач и нагрузке на диск виртуальной машины, то выполнение Magniber’a не прекратилось.Также если создать новый файл, к примеру, с расширением .jpg, то он будет моментально зашифрован. 

Это может свидетельствовать лишь об успешном выполнении первого этапа, то есть вымогатель внедрил шелл код в другие процессы и продолжает свою работу. 

Подтверждение этому мы можем также увидеть на этом скриншоте, где отчетливо виден цикл процесса записи, который повторяется несколько десятков раз:

Значит, нашей первоочередной задачей является поиск этих самых шелл кодов, но прежде — позвольте мне представить список используемых утилит, все они являются бесплатными и находятся в открытом доступе: 

  1. DIE — Detect it Easy: многофункциональный инструмент, имеющий просто огромный арсенал. Позволит нам опередить тип компилятора вредоноса, язык, библиотеки и таблицы импорта/экспорта с последующим дизассемблированием. 

  2. PE Bear  — неплохой инструмент для просмотра и редактирования составляющих PE файла. 

  3. Tiny Tracer  — утилита для динамического отслеживания исполнения бинарных элементов. Так называемый трейсер.

  4. IDA PRO — инструмент для реверс-инжиниринга. Изначально рассматривался как дополнительный инструмент, но в этой статье его роль была почти что основной. 

  5. Reko — декомпилятор, также знаком нам с прошлых статей.

  6. Orca — простой и хороший обозреватель таблиц входящих в пакеты Microsoft Installer (.msi). 

  7. HollowHunter —  утилита, распознает и сбрасывает множество потенциально вредоносных имплантов (замененные/имплантированные PE, шелл-коды, перехватчики, патчи в памяти).

  8. BareTail — инструмент для мониторинга файла журнала в режиме реального времени. А также поможет нам просмотреть содержимое шеллкода. 

  9. Floss — утилита, которая использует передовые методы статического анализа для автоматического деобфускации строк из двоичных файлов вредоносных программ.

Итак, чтобы обнаружить необходимые нам шелл коды мы воспользуемся утилитой HollowHunter. Использовать будем один единственный параметр — /shellc, который отвечает за захват необходимой нам информации. 

Результат меня порядком удивил, ведь оказалось в 21 системный процесс был импортирован один и тот же шелл. Давайте рассмотрим это более детально.

В качестве примера возьмем процесс svchost.exe, так как ранее мы отчетливо видели, как именно этот процесс шифровал данные.

При просмотре отчета можно ещё раз убедиться в том, что в этот процесс был вставлен шелл код, утилита определила его имя как 2d7897c0000.shc и сохранила.  

Чтобы убедиться, что именно этот шелл является полезной нагрузкой нашего второго этапа, мы можем запустить HollowHunter с параметром /kill и указать имя нашего шеллкода. Как можно было уже догадаться, эта манипуляция прекращает его выполнение. Далее мы создадим какой-нибудь рисунок или документ и увидим, что зашифрован он уже не будет, а это значит, что выполнение Магнибера прекратилось и этот модуль действительно принадлежит ему. 

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

Во-первых, здесь имеется подтверждение моего предположения по поводу алгоритма шифрования файлов. Судя по этим строкам, можно с уверенностью сказать, что это AES-CBC:

Во-вторых, в конце шелл кода имеется вставленное изображение, скорее всего, то, на которое меняется фон рабочего стола после окончания процесса шифрования, а также немного HTML и JavaScript:

Для более детального анализа полезной нагрузки второго этапа мы воспользуемся утилитой Floss, чтобы отфильтровать ненужные строки и выудить интересующую нас информацию. Запустим утилиту следующей командой, указывая в параметре, что это шелл код:

floss.exe -f sc64 2d7897c0000.shc 

Далее нам осталось немного подождать и получить следующий вывод:

В основном полученная информация лишь подтверждает то, что это действительно шелл код Магнибера. Также здесь присутствуют строки, отвечающие за удаление .vbs скрипта и информация о расширении зашифрованных файлов .vasqdyc. 

Что ж, теперь мы можем приступить к более детальному анализу. Сперва нам нужно понять, что и как здесь работает, какие функции этот шелл выполняет. Логичней всего будет воспользоваться Tiny Tracer из прошлой части статьи. Но сперва нам нужно превратить .shc в исполняемый файл или внедрить его в уже готовый PE.

Танцы с бубном: немного о преобразовании .shc в исполняемый файл

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

Многие используют для этого разные приемы, некоторые пишут код на C или используют python. Ниже я привожу, пожалуй, самый простой и короткий способ, чтобы после провести быструю трассировку или полноценный анализ с IDA.

Для реализации этого способа нам понадобятся следующие компоненты: 

  1. Yasm — ассемблер, который полностью копирует код ассемблера NASM. 

  2. GoLink — обычный компоновщик файлов.

Сперва поместим все необходимые файлы в одну директорию для удобства и переименуем наш шелл код на shellcode.bin. 

Далее воспользуемся ассемблером, чтобы создать .asm файл со следующими инструкциями:

Global Start
Start:
incbin "shellcode.bin"

Затем с помощью того же ассемблера и командной строки мы соберем код в .obj, чтобы после воспользоваться линкером:

yasm.exe -f win 64 -o shellcode.obj shellcode.asm 

А теперь задействуем GoLink, чтобы преобразовать это все в исполняемый файл:

golink /ni /entry Start shellcode.obj

Сгенерированный .exe полностью автономен и теперь с ним можно делать абсолютно все. Но давайте проведем несколько тестов, чтобы убедиться, что мы все сделали правильно. 

Переносим результат нашей работы на виртуальную машину и создаем какой-нибудь рисунок в Paint. Запускаем shellcode.exe и наш рисунок моментально превращается в зашифрованный файл с расширением .vasqdyc. А это значит, что все было сделано верно, и это действительно шеллкод Магнибера.

Возвращаемся к анализу.

Анализ шеллкода второй ступени

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

К моему удивлению, спустя некоторое время утилита выдала ошибку о том, что ей не удалось проследить за процессом. Если более детально просмотреть журнал, то можно обнаружить, что выполнение этого процесса оборвалось на функции 1fe4;ntdll.ZwCreateUserProcess. 

И единственное, что мне пришло в голову, так это поставить на этой функции NOP через PE Bear. 

NOP — это инструкция в ассемблере, которая предписывает ничего не делать. 

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

  • ntdll;NtQueryDirectoryFile — возвращает вредоносу информацию о файле;

  • ntdll;NtQueryInformationProcess — возвращает вредоносу информацию о процессе;

  • ntdll;NtSetInformationFile — позволяет вредоносу устанавливать информацию о файле, допустим менять расширение.

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

Теперь мы будем использовать расширенные настройки Tiny,  которые можно найти на официальной странице утилиты на GitHub.   

И сразу же из журнала трассировки видим многократное использование функции NtQueryPerformanceCounter, которую можно назвать эквивалентом функции QueryPerformanceCounter, Майкрософт объясняет это так: «Извлекает текущее значение счетчика производительности, представляющее собой отметку времени с высоким разрешением (<1 мкс), которую можно использовать для измерения интервалов времени»‎. 

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

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

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

Анализ ядра Magniber

Что же, вот мы и добрались до самого интересного. Сейчас мы можем спокойно открыть наш исполняемый файл Магнибера в IDA и делать все, что душе заблагорассудится. 

Работа основного тела вымогателя сводится к следующим шагам: 

  1. Непосредственно шифрование данных, которое включает в себя несколько шагов: 

  • Генерация ключей AES. 

  • Генерация ключа AES и IV.

  • Защита ключа AES и IV.

  • Непосредственно шифрование #1. 

  • Непосредственно шифрование #2.  

  1. Вторичное повышение привилегий выполняемое между двумя этапами шифрования. 

  2. Сбор информации об устройстве жертвы и отправка статистики на C&C сервер.

Шифрование данных

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

Генерация ключей AES

И здесь все дело начинается с генератора случайных чисел, если Магнибер образца 2017 года использовал функцию GetTickCount, то в новом образце все завязано на вышеупомянутой функции NtQueryPerformanceCounter. 

Генератор поставляется с таблицей из 100 псевдослучайных индексов DWORD. Затем выполняется простой алгоритм с использованием NtQueryPerformanceCounter для выбора случайного индекса из этой таблицы.

На основе значений из таблицы для этого индекса и заданных значений min и max вычисляется окончательное псевдослучайное значение. В случае, если рассчитанное значение не укладывается в диапазон, делается новая попытка.

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

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

Также кроме ключа AES генерируется ещё одно случайное число, которое используется в качестве второго ключа IV. 

Initialization vector (IV) — вектор инициализации, представляет собой произвольное число, которое может быть использовано вместе с секретным ключом для шифрования данных.

Защита ключа AES и IV

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

Для его защиты используется пользовательская модификация RSA, как и в большинстве программ вымогателей, но вот ключ RSA жестко задан в коде самого ядра Магнибер и закодирован в обычный Base64. Далее он копируется и передается в функцию assymmetric_crypto:

Затем с помощью этого ключа шифруются два предыдущих ключа. Слишком здесь много слова “ключ”, но иначе и не сказать.

Непосредственно шифрование #1

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

Так злоумышленники использовали относительно новый способ под названием AES-NI, который использует инструкции Intel для шифрования, а не стандартные библиотеки, как Windows Crypto, стоит отметить, что прошлые версии этого зловреда использовали именно его. 

Здесь, наверное, стоит пояснить, что такое вообще этот алгоритм AES и чем отличается от него AES-NI. 

AES (Advanced Encryption Standard) — это стандарт шифрования, принятый правительством США с 2001 года. Он широко используется в программной экосистеме для защиты сетевого трафика, личных данных и корпоративной ИТ-инфраструктуры. AES — это симметричный блочный шифр, который шифрует/дешифрует данные в несколько раундов.

Но новое семейство процессоров Intel с 2010 года включает набор новых инструкций, которые так и назвали New Instruction AES (AES-NI).

Эти инструкции были разработаны для реализации некоторых сложных и требовательных к производительности шагов алгоритма AES с использованием аппаратных средств и, таким образом, ускорения выполнения алгоритмов AES. AES-NI можно использовать для повышения производительности реализации алгоритма. Если сравнивать процесс шифрования на чисто программном уровне и шифрование с использованием аппаратных средств, то второе выполняется быстрее от 5 до 10 раз. Более подробно об этом можно узнать вот здесь.

Правда, существует и обратная сторона медали, использование этого метода в вымогателе приводит к полной его неработоспособности на старых машинах. Проще говоря, он не будет шифровать там, где нет технологии AES-NI. Поэтому владельцы Intel Pentium могут спокойно запускать вредонос у себя на устройстве и ничего не бояться.

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

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

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

И здесь важно отметить, что вымогатель проводит этот процесс в два этапа. 

В первом шифруя стандартные типы данных:

arc asf avi bak bmp fla flv gif gz iso jpeg jpg mid mkv mov mpeg mpg paq png rar swf tar tbk tgz tif tiff vcd vmdk vob wav wma wmv zip. 

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

Вторичное повышение привилегий

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

Сбор информации об устройстве жертвы и отправка статистики на C&C сервер

Ещё перед самым запуском вредонос проверит номер сборки Windows c помощью системного вызова NtBuildNumber. Если этот номер меньше, чем тот, который указан в коде, вымогатель вовсе не будет запущен. Так как количество системных вызовов может отличаться в зависимости от сборки. 

Если бы злоумышленники хотели бы сделать Магнибера универсальным, то им пришлось бы экспортировать каждую функцию из собственного .dll, что повлекло за собой огромные усилия. Поэтому вредонос актуален только для Windows 10 & 11. 

После того, как шифрование было закончено, вирус свяжется с C&C сервером для передачи статистики, прежде сгенерировав рандомное число в качестве идентификатора устройства жертвы.

И на этом работа Магнибера закончена.

Выводы

На этом выслеживание и анализ вымогателя Magniber подходит к концу. 

Несмотря на все эти хитромудрые манипуляции и невообразимую дальновидность злоумышленников, Magniber использует достаточно простой алгоритм шифрования, а именно AES-128 в режиме CBC, что делает процесс расшифровки достаточно легкой задачей. 

Как я и говорил уже в прошлой статье, на данный момент имеется несколько десятков эффективных расшифровщиков, которые вы можете найти на портале NO MORE RANSOM. 

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

Автор статьи @DeathDay


НЛО прилетело и оставило здесь промокод для читателей нашего блога:

— 15% на все тарифы VDS (кроме тарифа Прогрев) — HABRFIRSTVDS.

Источник: https://habr.com/ru/companies/first/articles/730634/


Интересные статьи

Интересные статьи

25 февраля автор курса «Разработчик C++» в Яндекс.Практикуме Георгий Осипов рассказал о новом этапе языка C++ — Стандарте C++20. В лекции сделан обзор всех основных нововведений Станд...
Нелегкая ситуация, сложившаяся на рынке видеокарт, — отличный повод вспомнить о том, что компьютерные игры — это вовсе не 4K, не «волшебные лучи» RTX и тем более не колич...
Значимость анализа сторонних компонентов ПО (англ. Software Composition Analysis — SCA) в процессе разработки растет по мере выхода ежегодных отчетов об уязвимостях open source библио...
Перевод статьи подготовлен специально для студентов курса «Android-разработчик. Продвинутый курс». И хотя в данном материале речь пойдет преимущественно о Java, материал будет полезен Android-раз...
C 2014 года, когда в Python появилась поддержка аннотаций типов, программисты работают над их внедрением в свой код. Автор материала, первую часть перевода которого мы публикуем сегодня, говорит,...