Admin
Администратор
LLM-Polymorphism: Создание самоизменяющегося кода с помощью нейросетей
Введение: Конец эпохи сигнатур
Классический полиморфизм (XOR-шифрование, мутация мусорных инструкций, метаморфические движки на базе простых правил) мертв. Современные EDR/AV-решения используют глубокий эвристический анализ и ML-модели, которые легко распознают паттерны типичных «мутаторов».Проблема старых движков в том, что они меняют форму, но не логику. LLM-Polymorphism (LLM-P) — это концепция, где малварь использует возможности больших языковых моделей для динамического переписывания собственного исходного кода при каждой итерации, сохраняя семантику, но полностью меняя структуру, алгоритмы и API-вызовы.
1. Архитектурный сдвиг: От XOR к Семантической мутации
В классическом полиморфизме у нас есть неизменяемый «дешифратор» и зашифрованное тело. В LLM-P концепция меняется:
- Традиционный подход: Функция SystemInfo() всегда делает GetVersionEx. Мутатор может добавить nop или mov eax, eax.
- LLM-подход: Модель получает задачу: «Перепиши функцию сбора информации о системе, используя только нативные вызовы NTAPI, избегай прямого импорта строк и используй динамическое разрешение адресов через хэши». Каждый раз результат будет уникальным программным кодом.
2. Компоненты LLM-полиморфного билда
Для реализации работающего прототипа нам нужны три составляющие:
- The Core (Ядро): Минимальный стаб, отвечающий за связь с «мозгом» и компиляцию/запуск пришедшего кода.
- The Brain (Мозг): Локальная LLM (например, Llama 3-8B в квантовании 4-бит или Phi-3-mini). Использование облачных API (OpenAI/Anthropic) в реальном бою — это мгновенный слив данных в Threat Intelligence, поэтому только локальные модели через GGUF/llama.cpp.
- The Reflector (Компилятор): Механизм исполнения кода в памяти (In-memory compilation). Для C# — это Roslyn, для C++ — встраиваемый LLVM или TCC (Tiny C Compiler).
3. Workflow: Цикл мутации
- Infection: Жертва запускает минимальный стаб.
- Prompting: Ядро отправляет локальной модели свой текущий исходный код с промптом:
- "Ты эксперт по обфускации. Перепиши этот C++ код так, чтобы логика осталась прежней, но все циклы for были заменены на рекурсию, а строки зашифрованы уникальным алгоритмом, который ты придумаешь сейчас. Верни только код."
- Validation: Ядро проверяет полученный код на синтаксические ошибки (простой парсинг).
- Re-compilation: Код компилируется в памяти в новый исполняемый модуль.
- Self-Replacement: Старая копия удаляется (или переписывается), новая начинает работу.
4. Реализация: Пример промпта для мутации (Payload Delivery)
Предположим, наша задача — загрузить шелл-код в память. Вместо стандартного VirtualAlloc + CreateThread, мы просим LLM:
Prompt: "Напиши функцию на C# для внедрения массива байтов в сторонний процесс. Избегай использования VirtualAllocEx. Используй технику перехвата потока (Thread Hijacking) или маппинг секций. Используй метапрограммирование для скрытия имен Win32 функций."
Что мы получаем: Модель может сгенерировать код, использующий NtCreateSection и ZwMapViewOfSection, о которых твой эвристик в антивирусе может не знать в данном контексте. При следующей итерации она напишет код через SetThreadContext.
5. Проблемы и вызовы 2025
- Вес модели: Локальная модель весит от 2 Гб до 5 Гб. Это делает малварь «тяжелой».
- Решение: Использование техник Living-off-the-Land AI. Если на машине жертвы уже установлены инструменты разработчика или Python с библиотеками ИИ, малварь использует их.
- Время генерации: На обычном CPU генерация нового кода может занять 30-60 секунд.
- Решение: Мутация происходит в фоне, пока работает предыдущая версия.
- Детерминизм: Иногда LLM может выдать нерабочий код.
- Решение: Встроенный юнит-тестировщик в стабе.
6. Вектор обхода EDR
Почему это работает против топовых решений (CrowdStrike, SentinelOne)?EDR строят цепочки поведения. Если малварь меняет свои API-вызовы и способы взаимодействия с ОС каждую итерацию, EDR не может накопить достаточно данных для уверенного детектирования «поведенческого паттерна». Это «хаос» в чистом виде.