В нашем постоянном стремлении к минимизации артефактов и обходу средств защиты, fileless-техники занимают особое место. Недавний анализ PowerShell-загрузчика, развертывающего Remcos RAT, вновь демонстрирует изящество и эффективность таких подходов. Посмотрим на механику этого загрузчика и его место в ландшафте современных угроз.
Все начинается с обфусцированного PowerShell-скрипта. Его задача - реконструкция двух бинарных блоков из закодированных (часто Base64) данных. Нередко применяется кастомная логика строковых операций для усложнения статического анализа перед непосредственным декодированием.
Получив байтовые массивы, скрипт задействует стандартные Win32 API
- VirtualAlloc для резервирования памяти под первый блок – шеллкод-загрузчик.
- Marshal.Copy (или аналоги) для переноса шеллкода в выделенную область.
- CallWindowProcW (или CreateThread, или иной механизм вызова функции по указателю) для инициации выполнения шеллкода.
Наиболее примечательная черта этого загрузчика - динамическое разрешение адресов необходимых API-функций через Process Environment Block (PEB). Это позволяет избежать явного импорта функций, что критично для обхода обнаружения по таблице импортов и затрудняет статический анализ.
Процесс выглядит следующим образом:
- Локализация PEB: Шеллкод получает доступ к структуре PEB (например, через FS:[0x30] для x86 или GS:[0x60] для x64).
- Доступ к PEB_LDR_DATA: Через поле Ldr в PEB извлекается указатель на PEB_LDR_DATA.
- Обход Списка Модулей: Итерация по списку загруженных модулей (например, InMemoryOrderModuleList) для поиска базовых библиотек (часто ntdll.dll или kernel32.dll).
- Получение Таблицы Экспорта (EAT): После нахождения базового адреса нужного модуля, парсится его PE-заголовок для обнаружения EAT.
- Разрешение Адресов Функций: Проходя по EAT, загрузчик ищет требуемые функции (например, LdrLoadDll, LdrGetProcedureAddress из ntdll.dll), сравнивая их имена (или хеши имен) с эталонными. Получив эти фундаментальные API, он может загрузить любую библиотеку и разрешить любую функцию.
Вооружившись адресами ключевых API, шеллкод-загрузчик приступает ко второму этапу:
- Выделяет память под второй бинарный блок (собственно, PE-файл, в данном случае Remcos RAT).
- Копирует PE-файл в эту область.
- Выполняет релокацию адресов (если PE не является позиционно-независимым).
- Корректно устанавливает права доступа к секциям памяти.
- Передает управление на точку входа (AddressOfEntryPoint) PE-файла, обеспечивая его выполнение целиком из памяти.
Описанный PowerShell-загрузчик - яркий пример, но не исключение. Подобные fileless-атаки с использованием Remcos RAT фиксировались и ранее. Это подчеркивает общую тенденцию: хакеры активно совершенствуют методы доставки и исполнения в памяти для уклонения от детектирования.
Так, заслуживают внимания и другие развивающиеся подходы к загрузке, например, многоступенчатые .NET-загрузчики. В некоторых их вариантах для сокрытия последующих стадий используются нетривиальные методы, такие как встраивание зашифрованных данных в ресурсы изображений (например, bitmap), что является формой стеганографии. Первая стадия извлекает, расшифровывает эти данные и запускает следующую ступень в памяти.
Подобные многоэтапные загрузчики, использующие шифрование и техники обфускации на каждом шаге (будь то PowerShell, .NET или нативные компоненты), нацелены на одну и ту же задачу: максимально затруднить анализ и обеспечить скрытное выполнение финальной полезной нагрузки.