Статья EntryPoint Hijacking: process injection техники нового поколения для обхода EDR

Тёмная лаборатория с изогнутым монитором, отображающим карту памяти PE-формата с перезаписанной точкой входа. Второй экран показывает структуры LDR процесса в янтарном свечении.


На последнем внутреннем пентесте финтех-проекта я собрал кастомный загрузчик с indirect syscalls - NtCreateThreadEx через ручной маппинг SSN всё равно улетел в алерт CrowdStrike Falcon за 800 миллисекунд. Проблема не в обёртке над syscall. Проблема в подходе: любая инъекция процессов, которая явно создаёт поток в чужом адресном пространстве, - красный флаг для EDR с kernel-телеметрией. EntryPoint Hijacking меняет правила игры: payload записывается в целевой процесс через WriteProcessMemory, но выполняется только тогда, когда процесс сам создаёт легитимный поток. Без CreateRemoteThread, без APC-очередей, без SetThreadContext. Разберём механику на уровне PEB и LDR-структур, два доступных PoC и то, где техника ломается.

Бизнес-логика: зачем атакующему скрытое внедрение кода​

Process Injection (T1055, Defense Evasion / Privilege Escalation) - одна из самых эксплуатируемых техник как APT-группами, так и операторами commodity-малвари. Цель: запустить произвольный код от имени легитимного процесса, унаследовать его привилегии, сетевые подключения и репутацию в глазах EDR. По данным Red Canary (Tier-2), process injection остаётся "a versatile tool that adversaries lean on to evade defensive controls and gain access to sensitive systems""универсальный инструмент, который противники используют для обхода средств защиты и получения доступа к чувствительным системам." Подробнее - в нашем материале про living off the land атаки windows.

На стадии post-exploitation инъекция в долгоживущий системный процесс (например, svchost.exe) даёт стабильный beacon для C2-канала. При lateral movement - запуск credential-dumping payload в контексте lsass.exe без подозрительного дочернего процесса. При exfiltration - сетевые соединения из процесса браузера, который и так генерирует исходящий трафик.

Классические process injection техники - DLL Injection (T1055.001), Process Hollowing (T1055.012), Thread Execution Hijacking (T1055.003) - опираются на API-вызовы, которые EDR мониторят на уровне ядра. EntryPoint Hijacking предлагает обход именно этого ограничения.

Место в kill chain: от foothold до persistence​

[Применимо: внутренний пентест, grey box / white box, Windows 10/11/Server 2019+]

EntryPoint Hijacking - техника post-exploitation. Для применения нужен полученный foothold: RCE на хосте, сессия через начальный загрузчик или физический доступ. Типичная цепочка:
  1. Initial access - фишинг, эксплуатация уязвимости, supply chain
  2. Foothold - первичный загрузчик с минимальным функционалом
  3. EntryPoint Hijacking - миграция payload в легитимный процесс (текущий этап)
  4. Post-exploitation - запуск beacon, credential dumping, lateral movement
  5. Exfiltration - вывод данных через C2-канал из контекста доверенного процесса
Техника не даёт persistence сама по себе - после перезагрузки патч LDR-структур сбрасывается. Для закрепления нужна связка с отдельным механизмом (scheduled task, registry run key, COM hijacking).

Почему классические process injection техники детектируются EDR​

1783055114786.webp

CreateRemoteThread и DLL Injection (T1055.001)​

Цепочка VirtualAllocEx -> WriteProcessMemory -> CreateRemoteThread с адресом LoadLibrary - учебник по stealth process injection, и детектится соответственно. По данным Elastic (Tier-1), эта техника "it is tracked and flagged by many security products""отслеживалась и помечалась множеством продуктов безопасности". CrowdStrike Falcon и SentinelOne регистрируют kernel callback через PsSetCreateThreadNotifyRoutine, который срабатывает при создании любого потока. В обработчике EDR определяет cross-process создание (PID создателя != PID владельца потока) и генерирует телеметрию, которую из userland не обойти. В SigmaHQ по тегу T1055.001 - 10 правил, включая детект Cobalt Strike beacon через паттерны Sysmon EventID 8 (CreateRemoteThread) (create_remote_thread_win_hktl_cobaltstrike.yml).

Process Hollowing (T1055.012)

Паттерн CreateProcess(CREATE_SUSPENDED) -> NtUnmapViewOfSection -> WriteProcessMemory -> SetThreadContext -> ResumeThread ловится по последовательности вызовов. Elastic описывает: подозрительна уже комбинация создания suspended-процесса с последующим изменением контекста потока. SentinelOne детектирует подмену entrypoint через сравнение содержимого секций PE на диске и в памяти.

APC Injection (T1055.004)

NtQueueApcThread / QueueUserAPC в alertable-поток - техника, которую Atomic Red Team тестирует тремя вариантами: через C#, EarlyBird в Go и NtQueueApcThreadEx. Elastic Defend через ETW-TI (провайдер Microsoft-Windows-Threat-Intelligence, требует PPL-подписки) получает события ThreatIntQueueApcThread для вызовов NtQueueApcThread(Ex). По D3FEND, ключевые контрмеры - System Call Analysis (D3-SCA) и Process Spawn Analysis (D3-PSA).

Общий паттерн детекта​

Все перечисленные malware injection techniques объединяет одно: они явно инициируют выполнение кода в целевом процессе через API-вызов. EDR перехватывают момент передачи управления - создание потока, вызов APC, изменение контекста. Именно этот паттерн EntryPoint Hijacking разрывает.

Механика EntryPoint Hijacking: инъекция процессов через точку входа DLL​

1783055138745.webp

EntryPoint Hijacking принципиально отличается от классических методов тем, что не вызывает API для запуска кода. Вместо этого техника модифицирует внутренние структуры загрузчика Windows, чтобы код выполнился при следующем легитимном событии создания потока.

Как Windows вызывает DllMain​

Каждый загруженный модуль (DLL) имеет функцию DllMain(), которую ОС автоматически вызывает при создании и завершении потоков (DLL_THREAD_ATTACH / DLL_THREAD_DETACH). Загрузчик Windows хранит информацию о каждом модуле в списках PEB_LDR_DATA (структуры LDR_DATA_TABLE_ENTRY), включая поле EntryPoint - адрес DllMain(). При событиях DLL_THREAD_ATTACH функция ntdll!LdrpCallInitRoutine обходит эти списки и вызывает EntryPoint каждого модуля.

Когда процесс создаёт новый поток, загрузчик проходит по списку загруженных модулей и дёргает DllMain() каждого с параметром DLL_THREAD_ATTACH. Именно эту механику эксплуатирует EntryPoint Hijacking.

Последовательность атаки​

  1. Атакующий получает handle к целевому процессу (OpenProcess с правами PROCESS_VM_WRITE | PROCESS_VM_READ)
  2. Через NtQueryInformationProcess получает адрес PEB целевого процесса
  3. Обходит список InMemoryOrderModuleList в PEB_LDR_DATA, находит подходящую DLL (обычно kernelbase.dll)
  4. Записывает shellcode или runner-функцию в память процесса через WriteProcessMemory
  5. Подменяет поле EntryPoint в LDR_DATA_TABLE_ENTRY на адрес записанного кода
  6. Ждёт - код выполнится автоматически, когда процесс создаст новый поток
  7. После выполнения EntryPoint восстанавливается до оригинального значения для стабильности
Ключевой момент: единственный "агрессивный" API-вызов - WriteProcessMemory. Никаких CreateRemoteThread, NtQueueApcThread, SetThreadContext. Shellcode injection происходит скрыто, а EDR, строящие детект на перехвате потоковых API, пропускают технику.

Что видно в WinDbg​

Для анализа LDR-структур в отладчике (по данным iPurple Team):
Код:
lm m kernelbase
dt ntdll!_LDR_DATA_TABLE_ENTRY <адрес_из_PEB>
Поле EntryPoint покажет текущий адрес точки входа модуля. Если он не совпадает с DllBase + IMAGE_NT_HEADERS.OptionalHeader.AddressOfEntryPoint - структура модифицирована. Тут всё просто: несовпадение = кто-то уже побывал.

PoC-инструменты: EPI и LdrShuffle - обход антивируса инъекцией​

Сейчас доступны два публичных PoC, реализующих EntryPoint Hijacking с разными подходами к исполнению.

EPI - EntryPoint Injection (2023)​

Автор: Kurosh Dabbagh Escalante. Репозиторий: Kudaes/EPI/.

EPI патчит EntryPoint загруженной kernelbase.dll. При создании нового потока целевым процессом перехваченная DllMain выполняется в контексте этого потока; чтобы не упереться в loader lock, EPI сразу через QueueUserWorkItem передаёт основной payload в системный thread pool, где он и исполняется. После выполнения PEB восстанавливается к предыдущему состоянию. Запуск: epi.exe -p <PID>.

LdrShuffle (x33fcon 2025)​

Автор: Hugo Valette. Репозиторий: RWXstoned/LdrShuffle.

LdrShuffle реализует ту же идею, но с другим механизмом исполнения - Runner-функцией, которая хранится в heap и определяет, какой Windows API вызвать. Ключевое условие выбора DLL для хайджека (из исходного кода LdrShuffle):
C:
(pDte->EntryPoint != NULL && pDte->DontCallForThreads == 0 && i > 5)
DontCallForThreads == 0 проверяет, что DLL принимает thread-уведомления, а i > 5 пропускает первые пять модулей - их патч вызывает нестабильность процесса. Логично: первые пять - это ntdll, kernel32 и компания, трогать которые себе дороже. LdrShuffle работает в двух режимах: локальная инъекция (LdrShuffle.exe) и удалённая (LdrInject.exe <PID> <shellcode>.bin).

Ограничения обоих PoC​

  • Deadlock при сложных API. InternetOpenW и аналогичные функции из wininet/winhttp вызывают deadlock из-за thread-синхронизации внутри DllMain (loader lock). Для C2-callback нужен отдельный поток - что частично снижает преимущество техники
  • Race condition. Между записью shellcode и патчем EntryPoint есть окно, в котором другой поток может вызвать DllMain с уже изменённым, но ещё не готовым EntryPoint
  • Целостность процесса. Некорректный патч или невосстановленный EntryPoint приводят к краху процесса. На реальном engagement crash целевого процесса - это инцидент, который SOC заметит мгновенно

Сравнение инструментов​

КритерийEPILdrShuffle
Год выхода20232025 (x33fcon)
Режим работыУдалённый процессЛокальный + удалённый
Механизм исполненияQueueUserWorkItem (thread pool)Runner-структура в heap
Целевая DLLkernelbase.dllЛюбая после 5-й в списке
СтабильностьСредняяСредняя (пропуск первых 5 DLL)

Практика: запуск EntryPoint Hijacking в лабораторной среде​

1783055232152.webp

Требования к окружению​

  • ОС: Windows 10 21H2+ / Windows 11 / Server 2019+ (x64)
  • RAM: минимум 4 ГБ (8 ГБ рекомендуется при одновременной работе отладчика)
  • Инструменты: Visual Studio 2022 Build Tools, WinDbg, Process Hacker 2
  • Зависимости: Windows SDK 10.0.22621+
  • Сетевые условия: offline-среда допустима, интернет не требуется
  • EDR для валидации evasion: изолированная VM с CrowdStrike Falcon, SentinelOne или Microsoft Defender for Endpoint

Пошаговый сценарий с LdrShuffle​

📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме

При верификации через Process Hacker: в целевом процессе не появляется новых потоков с подозрительным стартовым адресом. Shellcode выполняется в контексте существующего потока DllMain, который загрузчик вызвал штатно.

Детект и ограничения: когда EDR bypass не работает​

Детектирование через целостность LDR-структур​

По данным iPurple Team, надёжный детект строится на проверке:
Код:
LDR_DATA_TABLE_ENTRY.EntryPoint == DllBase + OptionalHeader.AddressOfEntryPoint
Если значения не совпадают - EntryPoint модифицирован. Загвоздка: после выполнения кода EntryPoint восстанавливается, и окно детекта сужается до миллисекунд.

LdrShuffleDetect​

Вместе с LdrShuffle опубликована утилита LdrShuffleDetect: каждые 10 секунд сканирует все процессы через CreateToolhelp32Snapshot, открывает каждый через OpenProcess, читает LDR-структуры через ReadProcessMemory и сверяет EntryPoint. Инструмент демонстрирует подход, но 10-секундный интервал - ловушка: если hijack + restore занимают менее секунды, point-in-time сканирование пропускает событие. По сути это как ставить камеру, которая делает снимок раз в 10 секунд, и надеяться поймать кого-то на пробежке.

Вендор-специфика обнаружения​

EDRМеханизм детектаПрименимость к EntryPoint Hijacking
CrowdStrike FalconKernel callbacks на CreateThread + user-mode hooksФиксирует cross-process WriteProcessMemory, но не коррелирует с LDR-модификацией. Специфичного правила нет
SentinelOneBehavioral AI + user-mode hooksПотенциально детектирует аномальный cross-process write, но без правила для LDR-патча
Microsoft Defender for EndpointETW-TI + kernel sensorsETW-TI фиксирует NtAllocateVirtualMemory / NtProtectVirtualMemory в cross-process контексте; прямой телеметрии NtWriteVirtualMemory нет, детект строится на аллокации RW/RWX страниц в чужом процессе. Встроенного детекта нет
Elastic 8.x+ с kernel ETW-TISystem Call Analysis (D3-SCA)Самый перспективный вектор: мониторинг цепочки WriteProcessMemory + ReadProcessMemory к PEB/LDR без последующего CreateThread

В SigmaHQ по тегу T1055 - 54 правила, но ни одно не таргетирует модификацию LDR EntryPoint. Ближайшие аналоги - правила на mavinject (proc_creation_win_lolbin_mavinject_process_injection.yml), ловящие совсем другой вектор.

Когда техника НЕ работает​

  • Процесс не создаёт потоков. Если целевой процесс однопоточный и не порождает новых потоков - DllMain с DLL_THREAD_ATTACH не вызовется, shellcode не выполнится. Просто будет лежать в памяти мёртвым грузом
  • DontCallForThreads == 1. У выбранной DLL установлен флаг, запрещающий thread-уведомления - загрузчик пропустит EntryPoint
  • Protected Processes Light (PPL). OpenProcess с правами записи в PPL-процессы (csrss.exe, lsass.exe с RunAsPPL) невозможен без kernel-level эксплойта
  • HVCI (Hypervisor-protected Code Integrity). Credential Guard и HVCI ограничивают модификацию исполняемых страниц памяти
  • Блокирующие операции в DllMain. Любой сетевой вызов, ожидание мьютекса - deadlock из-за loader lock. C2-callback из DllMain-контекста невозможен без выноса в отдельный поток

EntryPoint Hijacking vs process hollowing альтернативы: сравнение​

КритерийDLL Injection (T1055.001)Process Hollowing (T1055.012)Thread Hijacking (T1055.003)EntryPoint Hijacking
API для запуска кодаCreateRemoteThreadResumeThread + SetThreadContextSuspendThread + SetThreadContext + ResumeThreadНет (легитимный поток)
Требует создания потокаДаНет (возобновляет suspended)Нет (перехватывает существующий)Нет
Артефакт на дискеDLL-файлНетНетНет
СтабильностьВысокаяСредняяНизкая (crash при неверном контексте)Низкая-Средняя (race conditions)
Детектируемость (2025)Высокая - все EDRВысокая - паттерн CREATE_SUSPENDEDСредняя - зависит от EDRНизкая - нет встроенных правил
Контроль момента исполненияПолныйПолныйПолныйОтсутствует (ждём поток)
Поддержка C2 из контекстаДаДаДаНет (deadlock в DllMain)

Главный trade-off EntryPoint Hijacking - стелс в обмен на контроль. Нет способа точно определить, когда код выполнится. Для time-sensitive операций (credential dumping в окне между аутентификацией и ротацией) это ограничение критично.

EntryPoint Hijacking - не серебряная пуля и не замена отлаженным AV bypass техникам. Это ещё один примитив в арсенале, который работает именно потому, что EDR-вендоры пока не добавили специфичный детект. CrowdStrike Falcon, SentinelOne, MDE - ни один из них на момент публикации не имеет встроенного правила на патч LDR EntryPoint. Но "пока не имеет" - ключевое слово. После публикации LdrShuffle на x33fcon 2025 - вопрос времени, когда PEB/LDR integrity check станет стандартом в endpoint-телеметрии.

На практике я вижу два сценария, где техника оправдана. Первый - миграция из начального загрузчика в долгоживущий процесс (svchost.exe, RuntimeBroker.exe) на этапе post-exploitation, когда нужен устойчивый beacon без лишних алертов. Второй - инъекция в процесс с нужными сетевыми подключениями для маскировки C2-трафика, при условии что C2-вызов вынесен в отдельный поток из Runner-контекста.

Рассчитывать на эту технику как на единственный evasion-вектор - ошибка. WriteProcessMemory в cross-process контексте уже мониторится большинством EDR. Вопрос только в корреляции: EDR видит запись, но не видит последующего запуска потока - и это само по себе выглядит подозрительно. Когда вендоры начнут коррелировать cross-process write с LDR-аномалиями, окно закроется. Если хочешь повторить шаги в контролируемой инфре - задачи по memory injection techniques ждут на HackerLab (https://hackerlab.pro).
 
Последнее редактирование модератором:
Мы в соцсетях:

Взломай свой первый сервер и прокачай скилл — Начни игру на HackerLab

Похожие темы

🚀 Первый раз на Codeby?
Гайд для новичков: что делать в первые 15 минут, ключевые разделы, правила
Начать здесь →
🧭 Навигатор · ИБ 2026
Не знаешь, какой трек твой?
5 направлений ИБ, реальные зарплаты и точка входа для каждого — в одном треде.
JuniorSenior+
100K → 600K+ ₽ /мес
Открыть навигатор →
🔴 Свежие CVE, 0-day и инциденты
То, о чём ChatGPT ещё не знает — обсуждаем в реальном времени
Threat Intel →
💼 Вакансии и заказы в ИБ
Pentest, SOC, DevSecOps, bug bounty — работа и проекты от проверенных компаний
Карьера в ИБ →

HackerLab