Process Injection — техника выполнения произвольного кода в адресном пространстве другого живого процесса. В Windows она эксплуатирует легитимные API операционной системы, что делает её одновременно мощным инструментом атаки и сложной целью для детектирования: выполнение маскируется под деятельность доверенного процесса.
Каждый процесс в Windows обладает собственным виртуальным адресным пространством. Операционная система предоставляет набор API, позволяющих одному процессу взаимодействовать с памятью другого — при наличии соответствующих прав. Именно эти API становятся основой инъекции.
Обобщённая последовательность действий при классической DLL-инъекции:
После завершения этих шагов код выполняется в контексте чужого процесса, наследуя его привилегии, сетевые ресурсы и репутацию.
Ниже разобран наиболее распространённый вариант — DLL Injection через
Для поиска цели используется
Когда нужный процесс найден по имени, вызывается
Сам по себе вызов
В адресном пространстве целевого процесса выделяется область памяти через
Финальный шаг —
После этого целевой процесс загружает указанную DLL, и её код начинает выполняться в его контексте.
MITRE ATT&CK классифицирует Process Injection как технику T1055. Основные причины применения:
Анализ задокументированных кампаний показывает устойчивые паттерны выбора целей:
| Целевой процесс | Примеры использования |
|---|---|
|
|
|
| Браузеры (Chrome, Firefox, Edge) | AppleJeus/VEILEDSIGNAL (атака на цепочку поставок 3CX) — инъекция C2-модуля в первый найденный экземпляр браузера |
|
|
|
|
|
Выбор цели не случаен: атакующие предпочитают процессы, которые редко вызывают подозрение у аналитиков, имеют сетевой доступ или работают с высокими привилегиями.
Детектирование строится на корреляции нескольких событий, каждое из которых по отдельности может быть легитимным.
Ключевой индикатор — цепочка вызовов в рамках одного процесса, направленная на другой процесс:
EDR-решения отслеживают эту последовательность как единый паттерн. Вызов
Если в процессе появляется DLL, загруженная из нестандартного пути (временные каталоги, AppData, сетевые шары), это повод для проверки. Особенно подозрительно, когда DLL загружается в процесс, который обычно не использует динамические библиотеки из пользовательских каталогов.
Некоторые реализации используют альтернативные API:
При расследовании подозрительной активности проверяйте:
Концептуальная модель
Каждый процесс в Windows обладает собственным виртуальным адресным пространством. Операционная система предоставляет набор API, позволяющих одному процессу взаимодействовать с памятью другого — при наличии соответствующих прав. Именно эти API становятся основой инъекции.
Обобщённая последовательность действий при классической DLL-инъекции:
- Найти целевой процесс и получить его дескриптор с достаточными правами.
- Выделить область памяти в адресном пространстве цели.
- Записать в эту область полезные данные (например, путь к DLL).
- Создать поток в целевом процессе, который выполнит записанный код.
После завершения этих шагов код выполняется в контексте чужого процесса, наследуя его привилегии, сетевые ресурсы и репутацию.
Классическая последовательность API-вызовов
Ниже разобран наиболее распространённый вариант — DLL Injection через
LoadLibraryW. Понимание этой цепочки необходимо для построения правил детектирования.Перечисление процессов
Для поиска цели используется
CreateToolhelp32Snapshot с флагом TH32CS_SNAPPROCESS, который создаёт снимок всех выполняющихся процессов. Далее через Process32First и Process32Next происходит итерация по снимку. Каждый процесс описывается структурой PROCESSENTRY32, содержащей идентификатор процесса (th32ProcessID), имя исполняемого файла (szExeFile) и другие поля.
C:
PROCESSENTRY32 Proc = { .dwSize = sizeof(PROCESSENTRY32) };
HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
Process32First(hSnapShot, &Proc);
// итерация через Process32Next...
Получение дескриптора целевого процесса
Когда нужный процесс найден по имени, вызывается
OpenProcess с флагом PROCESS_ALL_ACCESS. Этот флаг запрашивает максимальные права на процесс, включая запись в память и создание потоков.
C:
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Proc.th32ProcessID);
Сам по себе вызов
OpenProcess с PROCESS_ALL_ACCESS к чужому процессу — уже подозрительный сигнал для EDR.Выделение памяти и запись данных
В адресном пространстве целевого процесса выделяется область памяти через
VirtualAllocEx с флагами MEM_COMMIT | MEM_RESERVE и защитой PAGE_READWRITE. Затем через WriteProcessMemory в эту область записывается путь к DLL, которую нужно загрузить.
C:
LPVOID pAddress = VirtualAllocEx(hProcess, NULL, dwSizeToWrite,
MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
WriteProcessMemory(hProcess, pAddress, DllName, dwSizeToWrite,
&lpNumberOfBytesWritten);
Создание удалённого потока
Финальный шаг —
CreateRemoteThread. Точкой входа потока указывается адрес функции LoadLibraryW (полученный через GetProcAddress из kernel32.dll), а аргументом — адрес выделенной памяти с путём к DLL.
C:
LPVOID pLoadLibraryW = GetProcAddress(GetModuleHandle(L"kernel32.dll"),
"LoadLibraryW");
HANDLE hThread = CreateRemoteThread(hProcess, NULL, NULL,
pLoadLibraryW, pAddress, NULL, NULL);
После этого целевой процесс загружает указанную DLL, и её код начинает выполняться в его контексте.
Зачем атакующие используют инъекцию
MITRE ATT&CK классифицирует Process Injection как технику T1055. Основные причины применения:
- Обход защитных механизмов. Код выполняется внутри легитимного процесса, что затрудняет обнаружение сигнатурными и поведенческими средствами.
- Доступ к ресурсам процесса. Внедрённый код получает доступ к памяти, сетевым соединениям и дескрипторам целевого процесса.
- Повышение привилегий. Если целевой процесс работает с повышенными правами (например, системный сервис), внедрённый код наследует эти привилегии.
- Сегментация модулей. Продвинутые образцы выполняют множественные инъекции, распределяя компоненты по разным процессам и используя именованные каналы или другие механизмы IPC для связи между ними.
Типичные целевые процессы в реальных атаках
Анализ задокументированных кампаний показывает устойчивые паттерны выбора целей:
| Целевой процесс | Примеры использования |
|---|---|
|
svchost.exe | BlackEnergy (Sandworm, атака на энергосистему Украины 2015), BlackByte, ABK, Avenger, BBK, Clambling, Pandora ||
explorer.exe | APT38, Backdoor.Oldrea, Kimsuky (Win7Elevate), Mis-Type, QakBot ||
iexplore.exe | Sandworm (через svchost → iexplore для C2), APT41 (TIDYELF → WINTERLOVE), Egregor, Smoke Loader || Браузеры (Chrome, Firefox, Edge) | AppleJeus/VEILEDSIGNAL (атака на цепочку поставок 3CX) — инъекция C2-модуля в первый найденный экземпляр браузера |
|
wuauclt.exe | ANDROMEDA, BlackByte, NOOPLDR ||
notepad.exe | ROKRAT (через VirtualAlloc + WriteProcessMemory + CreateRemoteThread), NETWIRE ||
lsass.exe | JPIN — загрузка модуля в процесс аутентификации ||
regsvcs.exe, msbuild.exe, installutil.exe | TA2541 — инъекция в .NET-процессы ||
wermgr.exe | TrickBot (через Native API функции Nt*), QakBot |Выбор цели не случаен: атакующие предпочитают процессы, которые редко вызывают подозрение у аналитиков, имеют сетевой доступ или работают с высокими привилегиями.
Артефакты для детектирования
Детектирование строится на корреляции нескольких событий, каждое из которых по отдельности может быть легитимным.
Последовательность API-вызовов
Ключевой индикатор — цепочка вызовов в рамках одного процесса, направленная на другой процесс:
VirtualAllocEx— выделение памяти в удалённом процессе.
WriteProcessMemory— запись данных в эту память.
CreateRemoteThread— создание потока с точкой входа в выделенной области.
EDR-решения отслеживают эту последовательность как единый паттерн. Вызов
CreateRemoteThread сам по себе встречается в легитимном ПО (например, отладчики), но в сочетании с VirtualAllocEx и WriteProcessMemory он становится высокоспецифичным индикатором.Подозрительные параметры вызовов
OpenProcessсPROCESS_ALL_ACCESSк процессу, не являющемуся дочерним.
VirtualAllocExс защитойPAGE_READWRITEв чужом процессе — особенно если выделенная область затем используется как аргумент дляCreateRemoteThread.
CreateRemoteThread, где адрес точки входа указывает на только что выделенную память, а не на код загруженного модуля.
Аномальная загрузка DLL
Если в процессе появляется DLL, загруженная из нестандартного пути (временные каталоги, AppData, сетевые шары), это повод для проверки. Особенно подозрительно, когда DLL загружается в процесс, который обычно не использует динамические библиотеки из пользовательских каталогов.
Поведенческие признаки
- Процесс-донор и целевой процесс не связаны родительско-дочерним отношением.
- Целевой процесс внезапно начинает сетевую активность, нехарактерную для его обычной функции.
- Множественные инъекции из одного источника в разные процессы за короткий промежуток времени.
Специфичные варианты API
Некоторые реализации используют альтернативные API:
RtlCreateUserThread вместо CreateRemoteThread (задокументировано для BADHATCH), VirtualAllocExNuma вместо VirtualAllocEx (Bazar), Native API функции Nt* вместо Win32-обёрток (TrickBot). Правила детектирования должны покрывать и эти варианты.Меры снижения риска
- Attack Surface Reduction (ASR). На Windows 10 правила ASR способны блокировать инъекцию кода из офисных приложений. Это не универсальная защита, но она закрывает один из распространённых векторов начального доступа.
- Ограничение прав процессов. Минимизация привилегий, с которыми работают пользовательские приложения, снижает вероятность успешного вызова
OpenProcessсPROCESS_ALL_ACCESS.
- Мониторинг и корреляция. Ни один отдельный артефакт не даёт надёжного детектирования. Эффективная защита строится на корреляции событий: последовательность API-вызовов, аномальные загрузки DLL, сетевое поведение процесса после инъекции.
Чек-лист для аналитика
При расследовании подозрительной активности проверяйте:
- [ ] Есть ли в логах последовательность
VirtualAllocEx→WriteProcessMemory→CreateRemoteThread(или их Native API аналоги)?
- [ ] Какой процесс является источником вызовов и какой — целью? Связаны ли они родительско-дочерним отношением?
- [ ] Загружена ли в целевой процесс DLL из нестандартного расположения?
- [ ] Появилась ли у целевого процесса новая сетевая активность после момента инъекции?
- [ ] Использовались ли альтернативные API (
RtlCreateUserThread,VirtualAllocExNuma,Nt*-функции)?
- [ ] Наблюдаются ли множественные инъекции из одного источника в разные процессы?
