
Движок перехвата в пользовательском режиме и инструментирования телеметрии на основе аппаратных точек останова (DR0-DR7) без модификации кода (AMSI, WLDP и ETW PoC).
Proof-of-Concept (POC) для исследования в области безопасности, демонстрирующий перехват функций на основе аппаратных точек останова (отладочных регистров CPU) как альтернативу традиционному патчингу кода в памяти.
Назначение и область применения
Этот репозиторий публикуется исключительно для защитных исследований в области безопасности, обучения red-team/purple-team, разработки средств обнаружения и академического изучения внутреннего устройства Windows. Он демонстрирует, как злоумышленник мог бы злоупотребить отладочными регистрами процессора для нейтрализации пользовательской телеметрии безопасности — и, что не менее важно, на что следует обращать внимание защитникам, чтобы обнаруживать подобные техники. Автор не несёт ответственности за любое неправомерное использование этого кода. Применение данной техники к системам без явного разрешения незаконно и нарушает соответствующие законы о компьютерном мошенничестве и злоупотреблениях в большинстве юрисдикций. Не развёртывайте это в любой среде, которой вы не владеете или на тестирование в которой у вас нет явного письменного разрешения.
mora_hwbp.c реализует DLL, которая после загрузки/внедрения в целевой процесс (например, хост PowerShell) перехватывает четыре пользовательские функции исключительно через аппаратные точки останова CPU, хранящиеся в архитектурных отладочных регистрах (DR0–DR7) каждого потока процесса:
| Регистр | Перехватываемая функция | Модуль | Назначение |
|---|---|---|---|
DR0 | AmsiScanBuffer | amsi.dll | Нейтрализация сканирования содержимого AMSI |
DR1 | WldpQueryDynamicCodeTrust | wldp.dll | Принудительное доверие динамическому коду WLDP (Device Guard / WDAC) |
DR2 | WldpIsClassInApprovedList | wldp.dll | Принудительное одобрение класса WLDP (Device Guard / WDAC) |
DR3 | NtTraceEvent | ntdll.dll | Отсечение всего пользовательского потока ETW |
Векторизованный обработчик исключений (VEH) на уровне процесса принимает исключения EXCEPTION_SINGLE_STEP (0x80000004), вызываемые отладочными регистрами, имитирует успешный путь возврата исходной функции путём перезаписи контекста исключения и возобновляет выполнение — всё это без изменения единого байта исполняемой памяти.
Это делает технику особенно интересной как с наступательной, так и с оборонительной точки зрения:
.text (классический inline-хукинг, патчинг EAT/IAT или заглушки Etwp*).GetThreadContext/SetThreadContext), которые можно использовать для обнаружения.Традиционные подходы к пользовательскому хукингу — inline-детуры (перезапись 5–14 байт), хукинг таблицы адресов импорта (IAT) и хукинг таблицы адресов экспорта (EAT) — имеют общую слабость: они изменяют память, которую могут наблюдать сканеры целостности и ETW.
Современные продукты AV/EDR реализуют:
pageguard/guard-page, переходы VirtualProtect в PAGE_EXECUTE_READWRITE и несоответствия хэшей секций.Аппаратные точки останова обходят всё это:
.text нечего сканировать.SetThreadContext, который не вызывает классические сигналы «память изменена», используемые сканерами целостности.Этот POC исследует эффективность и обнаруживаемость данной техники против AMSI (Antimalware Scan Interface), WLDP (Windows Lockdown Policy) и ETW (Event Tracing for Windows) — трёх наиболее широко используемых примитивов безопасности пользовательского режима в современном стеке безопасности Windows.
AMSI — это точка интеграции платформы Windows, позволяющая приложениям (PowerShell, Office, VBScript, хосты .NET и т. д.) запрашивать сканирование содержимого у зарегистрированных антивирусных провайдеров. Основная интересующая точка входа:
AmsiScanBuffer(HANDLE hamsiContext, PVOID buffer, ULONG length, LPCWSTR contentName, HANDLE hamsiSession, AMSI_RESULT *pResult)Принудительно устанавливая возвращаемое значение AMSI_RESULT в AMSI_RESULT_CLEAN (0), движок сценариев считает, что содержимое было проверено и признано безопасным, поэтому выполнение продолжается без прерываний.
WLDP реализует оценку политик для Windows Defender Application Control (WDAC / Device Guard). Этот POC перехватывает две точки входа WLDP:
WldpIsClassInApprovedList отвечает, разрешён ли данный COM-класс (идентифицируемый по GUID) в рамках текущей политики. AMSI внутренне обращается к WLDP, чтобы решить, считаются ли определённые классы сценариев/содержимого «доверенными» (входящими в список разрешённых). Если функция сообщает, что класс одобрен, AMSI может пропустить дополнительную проверку для этого типа содержимого.WldpQueryDynamicCodeTrust отвечает, является ли данный фрагмент динамически сгенерированного кода (например, вывод .NET JIT или иная сгенерированная исполняемая память) доверенным в рамках текущей политики блокировки.DLL устанавливает выходной параметр isApproved (RDX) функции WldpIsClassInApprovedList в TRUE и возвращает S_OK, а также принудительно заставляет WldpQueryDynamicCodeTrust возвращать S_OK (0) — делая как оцениваемый класс содержимого, так и запрашиваемый динамический код доверенными.
NtTraceEvent в ntdll.dll — это самая низкоуровневая точка входа пользовательского режима в подсистему ETW — практически вся генерация событий ETW проходит через неё (включая EtwEventWrite и высокоуровневые API Etw*). Поэтому её перехват обрывает весь поток ETW из пользовательского режима, что имеет широкие побочные эффекты, значимые для мониторинга безопасности: