
Moteur de hooking en mode utilisateur sans patch et d'instrumentation de télémétrie basé sur les points d'arrêt matériels (DR0-DR7) (PoC AMSI, WLDP et ETW).
Une preuve de concept (POC) de recherche en sécurité démontrant le hooking de fonctions basé sur des points d'arrêt matériels (registres de débogage du CPU) comme alternative au patchage de code en mémoire traditionnel.
Objectif et portée
Ce dépôt est publié strictement à des fins de recherche en sécurité défensive, d'éducation red-team/purple-team, d'ingénierie de détection et d'étude académique des internals de Windows. Il démontre comment un attaquant pourrait abuser des registres de débogage du processeur pour neutraliser la télémétrie de sécurité en mode utilisateur — et, tout aussi important, ce que les défenseurs doivent surveiller afin de détecter de telles techniques. L'auteur n'est pas responsable de tout usage abusif de ce code. L'utilisation de cette technique contre des systèmes sans autorisation explicite est illégale et viole les lois pertinentes relatives à la fraude informatique et aux abus dans la plupart des juridictions. Ne déployez pas ceci dans un environnement que vous ne possédez pas ou pour lequel vous ne disposez pas d'une autorisation écrite explicite de tester.
mora_hwbp.c implémente une DLL qui, une fois chargée/injectée dans un processus cible (par exemple, un hôte PowerShell), hooke quatre fonctions en mode utilisateur exclusivement au moyen de points d'arrêt matériels du CPU stockés dans les registres de débogage architecturaux (DR0–DR7) de chaque thread du processus :
| Registre | Fonction hookée | Module | Objectif |
|---|---|---|---|
DR0 | AmsiScanBuffer | amsi.dll | Neutraliser l'analyse de contenu AMSI |
DR1 | WldpQueryDynamicCodeTrust | wldp.dll | Forcer la confiance du code dynamique WLDP (Device Guard / WDAC) |
DR2 | WldpIsClassInApprovedList | wldp.dll | Forcer l'approbation de classe WLDP (Device Guard / WDAC) |
DR3 | NtTraceEvent | ntdll.dll | Couper l'intégralité du flux ETW en mode utilisateur |
Un gestionnaire d'exceptions vectorisées (VEH) par processus reçoit les fautes EXCEPTION_SINGLE_STEP (0x80000004) déclenchées par les registres de débogage, simule le chemin de retour réussi de la fonction d'origine en réécrivant le contexte d'exception, et reprend l'exécution — le tout sans modifier un seul octet de mémoire exécutable.
Cela rend la technique particulièrement intéressante d'un point de vue à la fois offensif et défensif :
.text modifiées (hooking inline classique, patchage de l'EAT/IAT, ou stubbing des Etwp*).GetThreadContext/SetThreadContext) qui peuvent être utilisés à des fins de détection.Les approches traditionnelles de hooking en mode utilisateur — les détours inline (écrasements de 5 à 14 octets), le hooking de la table d'adresses d'import (IAT) et le hooking de la table d'adresses d'export (EAT) — partagent une faiblesse commune : elles modifient de la mémoire que les scanners d'intégrité et ETW peuvent observer.
Les produits AV/EDR modernes implémentent :
pageguard/guard-page, les transitions VirtualProtect vers PAGE_EXECUTE_READWRITE et les incohérences de hachage de section.Les points d'arrêt matériels contournent tout cela :
.text.SetThreadContext, qui ne déclenche pas les signaux classiques de « mémoire modifiée » utilisés par les analyseurs d'intégrité.Ce POC explore l'efficacité et la détectabilité de cette technique contre AMSI (Antimalware Scan Interface), WLDP (Windows Lockdown Policy) et ETW (Event Tracing for Windows) — les trois primitives de sécurité en mode utilisateur les plus largement utilisées dans la pile de sécurité Windows moderne.
AMSI est le point d'intégration de la plateforme Windows qui permet aux applications (PowerShell, Office, VBScript, hôtes .NET, etc.) de demander l'analyse de contenu auprès des fournisseurs antimalware enregistrés. Le principal point d'entrée concerné est :
AmsiScanBuffer(HANDLE hamsiContext, PVOID buffer, ULONG length, LPCWSTR contentName, HANDLE hamsiSession, AMSI_RESULT *pResult)En forçant le AMSI_RESULT retourné à AMSI_RESULT_CLEAN (0), le moteur de script croit que le contenu a été inspecté et jugé bénin, l'exécution se poursuit donc sans interruption.
WLDP implémente l'évaluation de stratégie pour Windows Defender Application Control (WDAC / Device Guard). Ce POC intercepte deux points d'entrée WLDP :
WldpIsClassInApprovedList indique si une classe COM donnée (identifiée par GUID) est autorisée selon la stratégie en vigueur. AMSI consulte en interne WLDP pour décider si certaines classes de script/contenu sont « approuvées » (dans la liste approuvée). Si la fonction signale la classe comme approuvée, AMSI peut ignorer les vérifications supplémentaires pour ce type de contenu.WldpQueryDynamicCodeTrust indique si un élément de code généré dynamiquement (par exemple une sortie JIT .NET ou toute autre mémoire exécutable générée) est approuvé selon la stratégie de verrouillage en vigueur.La DLL définit le paramètre de sortie isApproved (RDX) de WldpIsClassInApprovedList à TRUE et retourne S_OK, et force WldpQueryDynamicCodeTrust à retourner S_OK (0) — faisant apparaître comme approuvés à la fois la classe de contenu évaluée et le code dynamique interrogé.