BumbleCrypt
Криптер, вдохновлённый Bumblebee
Предыстория
BumbleCrypt вдохновлён криптером Bumblebee. В случае Bumblebee основной DLL Bumblebee загружается в память и выполняется следующим образом:
- Расшифровывает и записывает пейлоад в кучу (Heap)
- Хукает три NT API: NtOpenFile, NtCreateSection и NtMapViewOfSection
- Вызывает LoadLibraryW("gdiplus.dll"), что запускает инлайн-хуки, поскольку упомянутые три API используются LoadLibrary() для загрузки любой библиотеки.
- Затем инлайн-хуки и сама LoadLibrary загружают основной DLL Bumblebee вместо "gdiplus.dll"
- Наконец, управление передаётся экспортируемой функции "SetPath" основного DLL Bumblebee
Принцип работы BumbleCrypt
Анализируя криптер BumbleBee, я понял, что расшифрованный DLL можно загрузить всего с одним инлайн-хуком на "NtMapViewOfSection" вместо трёх инлайн-хуков, используемых в криптере Bumblebee.
В результате был разработан "BumbleCrypt".
BumbleCrypt:
-
Сначала BumbleCrypt загружает зашифрованный ресурс из секции .rsrc, а затем расшифровывает итоговый DLL-пейлоад: зашифрованный ресурс -> декодирование Base64 -> расшифровка Rc4 -> xor-расшифровка
-
Криптер использует кучу (Heap) для хранения расшифрованного DLL-пейлоада, так же как и криптер Bumblebee
-
Как только итоговый пейлоад расшифрован, BumbleCrypt хукает NT API "NtMapViewOfSection", который используется для отображения представления секции в виртуальное адресное пространство.
-
Затем BumbleCrypt вызывает LoadLibraryW("msimg32.dll"). Теперь давайте разберёмся, как срабатывает инлайн-хук:
- Сначала LoadLibraryW() вызывает NtOpenFile, чтобы получить дескриптор модуля, переданного в качестве аргумента
- Затем она создаёт объект секции с помощью дескриптора модуля, используя NtCreateSection
- Когда секция создана, LoadLibrary вызывает NtMapViewOfSection, чтобы отобразить представление секции в память
- Здесь срабатывает наш хук на NtMapViewOfSection, и прокси-функция выполняет следующие действия:
- Сначала снимает хук с NtMapViewOfSection
- Создаёт секцию требуемого размера с помощью NtCreateSection()
- Затем отображает представление созданной секции в виртуальное адресное пространство с помощью NtMapViewOfSection (с которого ранее был снят хук)
- Наконец, вручную отображает ранее расшифрованный итоговый DLL по базовому адресу memory-mapped секции, затем возвращает NTSTATUS_SUCCESS в LoadLibraryW и выходит из прокси-функции
- Затем LoadLibraryW получает NTSTATUS_SUCCESS в качестве ответа на NtMapViewOfSection и базовый адрес memory-mapped секции, где в памяти находится расшифрованный вредоносный DLL. Далее LoadLibrary загружает DLL в соответствии с возвращёнными значениями, и в итоге среди загруженных модулей виден msimg32.dll, который указывает на расшифрованный пейлоад. Затем криптер передаёт управление расшифрованному DLL, выполняя экспортируемую функцию "CallPath".
-
Если теперь взглянуть на скриншот загруженных модулей BumbleCrypt, можно увидеть, что в нём есть "msimg32.dll", но базовый адрес указывает на расшифрованный вредоносный пейлоад.
Скриншот


PoC - BumbleCrypter

Спасибо большое! Надеюсь, вам понравилось =D
Чао.
Вы можете связаться со мной в Twitter, если у вас есть отзывы или комментарии
Twitter: https://twitter.com/knight0x07
Примечание
Только в образовательных целях. Это личный проект на выходные =)