![Так ли мёртв Emotet?! Технический анализ экземпляра. Распаковка основной нагрузки.](https://cert.by/wp-content/uploads/2022/11/people-g54ea8792b_1920-edited.jpg)
В продолжение предыдущей статьи (Так ли мёртв emotet?!) хотели бы рассказать о технических особенностях процесса распаковки основной нагрузки ВПО семейства «Еmotet».
Напоминаем, основная нагрузка представляет собой «Dll» файлы, запускаемые через системную утилиту regsvr32.exe.
![Так ли мёртв Emotet?! Технический анализ экземпляра. Распаковка основной нагрузки.](https://cert.by/wp-content/uploads/2022/11/image.png)
В библиотеке есть несколько экспортируемых функций, основные используемые:
«DllMain» – вызывается при использовании библиотеки, как правило, при событии DLL_PROCESS_ATTACH, в контексте работы данного ВПО восстанавливает основную нагрузку в памяти процесса;
«DllRegisterServer» – вызываемая утилитой regsvr32.exe при регистрации библиотеки. Основная задача – передать управление на восстановленный код в памяти.
Процесс восстановления основной нагрузки в функции «DllMain» делится на два этапа.
Первый этап восстановления основной нагрузки.
На первом этапе восстанавливается бинарный код. Исходный бинарный код записывается в стек и имеет размер 0xbd9.
![Так ли мёртв Emotet?! Технический анализ экземпляра. Распаковка основной нагрузки.](https://cert.by/wp-content/uploads/2022/11/image-1.png)
Для восстановления, исходные байты бинкода проходят операцию xor фиксированным ключом, по три байта за цикл. В качестве ключа используется следующая строка:
«N1kj^H<M1vf@$_yiXP+o*hH*fZQl5vC5qjfXErgxjcCb4v_e75<edkge!z$U9k+h»
Указанная выше строка является идентификатором экземпляра, может изменяться от версии к версии и используется далее для получения кода основной нагрузки.
После восстановления бинкода ему передаётся управление. В качестве параметра передаётся указатель на ключ – идентификатор экземпляра.
![Так ли мёртв Emotet?! Технический анализ экземпляра. Распаковка основной нагрузки.](https://cert.by/wp-content/uploads/2022/11/image-2.png)
Бинкод использует интересный способ получения адресов функций, проще говоря, собственную реализацию системной функции «GetProcAddress». Схожий алгоритм был обнаружен в «payload WarzoneRAT».
Первый этап работы функции заключается в получении структуры PPE_LDR_DATA их PEB (Process envoriment block). Из структуры PPE_LDR_DATA получается указатель на начало связного списка импортированных модулей, структура LDR_DATA_TABLE_ENTRY.
Полную информацию об указанных структурах можно найти в официальной документации:
(https://learn.microsoft.com/en-us/windows/win32/api/winternl/ns-winternl-peb_ldr_data)
Функция использует два поля из структуры LDR_DATA_TABLE_ENTRY:
- «DllBase» – базовый адрес загрузки модуля в память.
- «FullDllName» – поле, в которое записывается имя импортируемого модуля. Функция парсит
MZ-PE заголовок модуля, и проверяет его на наличие ExportTable. Если модуль содержит таблицу экспорта, то переходит к следующему этапу.
Второй этап восстановления основной нагрузки.
Следующий этап работы функции заключается в построении кодового значения по имени модуля.
![Так ли мёртв Emotet?! Технический анализ экземпляра. Распаковка основной нагрузки.](https://cert.by/wp-content/uploads/2022/11/image-3.png)
Каждый байт циклически сдвигается вправо на 0xd, полученное значение добавляется к результату. Также используется корректировка на регистр букв в имени модуля. У байт, которые соответствуют нижнему регистру, отнимается значение 0x20, что приводит к соответствующему символу в нижнем регистре. То есть, код от NTDLL.DLL и ntdll.dll будет одинаковый.
Далее считываются имена экспортируемых функций модуля по PE заголовку. Для каждого имени функция по схожему алгоритму строит кодовое значение. Однако в алгоритме расчёта кода для имени функции нет коррекции на регистр символов. Код имени модуля и код имени функции суммируются между собой и сравниваются с аргументом функции. Если они совпадают, то возвращается адрес функции.
![Так ли мёртв Emotet?! Технический анализ экземпляра. Распаковка основной нагрузки.](https://cert.by/wp-content/uploads/2022/11/image-4.png)
Первые две импортируемые функции бинкодом – это недокументированные функции «ntdll – LdrLoadDll» – загрузка модуля в память процесса; «LdrGetProcedureAddress» – получение адреса функции из модуля. Далее бинкод получает адреса основных функций – «VirtualAlloc», «VirtualProtect», «FlushInstructionCahe», «GetNativeSystemInfo», «Sleep», «RtlAddFunctionTable», «LoadLibraryA», «FindResourceW», «LoadResource», «SizeofResource», «LockResource», «FreeResource».
Бинкод, используя последовательность функции работы с ресурсами приложения «FindResourceW», «LoadResource», «SizeofResource», – получается доступ к байтам ресурса.
![Так ли мёртв Emotet?! Технический анализ экземпляра. Распаковка основной нагрузки.](https://cert.by/wp-content/uploads/2022/11/image-5.png)
Исходный код основной нагрузки проходит операцию xor с ключом-идентификатором экземпляра для расшифровки данных.
![Так ли мёртв Emotet?! Технический анализ экземпляра. Распаковка основной нагрузки.](https://cert.by/wp-content/uploads/2022/11/image-6.png)
Корректность расшифровки проверяется через magic значение PE заголовка.
ВПО делает следующие проверки:
- поле Machine заголовка file проверяется на соответствие значению 0x8664 (флаг x64).
- Поле sectionaligment проверяется на соответствие значению 0x1000.
- количество секций проверяется п оусловию больше 0.
![Так ли мёртв Emotet?! Технический анализ экземпляра. Распаковка основной нагрузки.](https://cert.by/wp-content/uploads/2022/11/image-7.png)
Память выделяется по смещению 0x180000000. Этот адрес соответствует значению из «ImageBase» библиотеки. Таким способом ВПО пытается скрыть основную нагрузку. В область памяти 0x180000000 посекционно переносится код основной нагрузки. Очищает часть MZ-PE заголовка.
![Так ли мёртв Emotet?! Технический анализ экземпляра. Распаковка основной нагрузки.](https://cert.by/wp-content/uploads/2022/11/image-8.png)
Бинкод и функция «DllMain» завершают свою работу. Управление передаётся на функцию «DllRegisterServer» основная функция которой – парсинг заголовка MZ-PE основной нагрузки. Базовый адрес загрузки передаётся первым аргументом.
«DllRegisterServer» возвращает адрес экспортируемой функции, имя которой передаётся вторым аргументом.
![Так ли мёртв Emotet?! Технический анализ экземпляра. Распаковка основной нагрузки.](https://cert.by/wp-content/uploads/2022/11/image-9.png)
Проанализировав алгоритм распаковки основной нагрузки ВПО семейства «Emotet» можем сделать вывод, что разработчики данного ВПО используют следующие тактики:
— Native API (https://attack.mitre.org/techniques/T1106/);
— Dynamic-link Library Injection (https://attack.mitre.org/techniques/T1055/001/).
Национальный центр реагирования на компьютерные инциденты (CERT.BY) благодарит за взаимодействие контактных лиц и оперативное предоставление информации!!!
Для удобства и своевременного оповещения о новостях подписывайтесь на нас в социальных сетях: