Aller au contenu

07 · Persistance

Chasser la persistance Windows : registre, tâches, WMI

Détecter la persistance d'un attaquant sous Windows : clés Run, services, tâches planifiées, WMI, Winlogon, IFEO, COM et BITS, avec MITRE ATT&CK et outils.

Publié le 11 min de lecture

Une fois entrés, les attaquants s'assurent de pouvoir revenir après un redémarrage, un changement de mot de passe ou le correctif d'une vulnérabilité. Ce guide passe en revue les emplacements de démarrage automatique les plus utilisés dans les intrusions Windows, rattache chacun à sa technique MITRE ATT&CK et indique où regarder sur un hôte vivant ou sur une image disque. Vous repartirez avec une méthode de triage reproductible et un moyen de distinguer une vraie persistance des centaines d'autostarts légitimes d'une machine ordinaire.

Cartographie de la persistance

MécanismeATT&CKEmplacement principalJournaux clés
Clés Run / RunOnceT1547.001SOFTWARE et NTUSER.DAT : ...\CurrentVersion\Run, RunOnceSysmon 13
Dossiers StartupT1547.001...\Start Menu\Programs\Startup (par utilisateur et tous utilisateurs)Sysmon 11
Services WindowsT1543.003SYSTEM\ControlSet00x\Services\<nom>7045, 4697
Tâches planifiéesT1053.005C:\Windows\System32\Tasks, TaskCache dans SOFTWARE4698, TaskScheduler 106/140/200
Abonnement d'événements WMIT1546.003C:\Windows\System32\wbem\Repository\OBJECTS.DATAWMI-Activity 5861, Sysmon 19-21
Winlogon Userinit / ShellT1547.004SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinlogonSysmon 13
IFEO Debugger, SilentProcessExitT1546.012...\Image File Execution Options\<exe>, ...\SilentProcessExit\<exe>Sysmon 13
AppInit_DLLsT1546.010SOFTWARE\Microsoft\Windows NT\CurrentVersion\WindowsSysmon 13
Détournement COMT1546.015UsrClass.dat : Software\Classes\CLSID\{GUID}Sysmon 13
Jobs BITST1197C:\ProgramData\Microsoft\Network\Downloader\Bits-Client 3/59/60
Fonctions d'accessibilitéT1546.008System32\sethc.exe, utilman.exe ou leurs clés IFEOPrefetch, hashes de fichiers, Sysmon 1
Création de compte localT1136.001Ruche SAM4720, 4722, 4732
Détournement de l'ordre de recherche des DLLT1574.001Dossiers applicatifs, entrées du PATH accessibles en écritureSysmon 7

Les IDs ATT&CK sont à jour au moment de la rédaction, mais MITRE renomme ou fusionne parfois des sous-techniques (les versions récentes ont par exemple élargi T1574.001 pour y inclure le DLL side-loading). Vérifiez sur attack.mitre.org avant de citer des IDs dans un rapport.

Autostarts dans le registre

Clés Run et RunOnce

Le grand classique. Les valeurs sous ces clés se lancent à l'ouverture de session :

  • HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run et \RunOnce (tous les utilisateurs)
  • HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run et \RunOnce (vue 32 bits sur Windows 64 bits)
  • HKCU\Software\Microsoft\Windows\CurrentVersion\Run et \RunOnce, stockées dans le NTUSER.DAT de chaque utilisateur
  • ...\Policies\Explorer\Run, normalement écrite uniquement par les stratégies de groupe

Les valeurs RunOnce sont supprimées avant leur exécution (sauf si elles sont préfixées par !) : une charge à usage unique peut donc ne laisser aucune trace dans la ruche. Les valeurs elles-mêmes n'ont pas d'horodatage ; la seule date disponible est le last write time de la clé, qui reflète la dernière modification de n'importe quelle valeur de cette clé. Depuis Windows 8, Explorer\StartupApproved\Run indique si une entrée est activée ou désactivée dans le Gestionnaire des tâches. Le détail est sur la fiche clés Run et dossiers Startup.

Winlogon : Userinit et Shell

HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon contient Userinit (par défaut C:\Windows\system32\userinit.exe, avec une virgule finale) et Shell (par défaut explorer.exe). Tout ce qui est ajouté à ces valeurs s'exécute à chaque ouverture de session interactive. Une valeur Shell propre à l'utilisateur, dans NTUSER.DAT sous le même chemin, est aussi prise en compte. Comparez les chaînes exactes : un chemin supplémentaire séparé par une virgule dans Userinit passe facilement inaperçu dans une interface graphique.

IFEO Debugger et SilentProcessExit

Image File Execution Options (HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\<nom.exe>) sert au débogage. Une valeur Debugger fait lancer le débogueur à la place de la cible, avec le chemin de la cible en argument : Debugger = C:\ProgramData\x.exe sur notepad.exe exécute la charge à chaque lancement du Bloc-notes.

La variante plus discrète est SilentProcessExit : on positionne GlobalFlag à 0x200 sur la clé IFEO, puis on crée ...\CurrentVersion\SilentProcessExit\<nom.exe> avec ReportingMode = 1 et MonitorProcess pointant vers la charge. Celle-ci s'exécute quand le processus surveillé se termine. Les deux clés sont décrites sur la fiche IFEO et Winlogon.

AppInit_DLLs

AppInit_DLLs sous HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows (et son jumeau WOW6432Node), avec LoadAppInit_DLLs = 1, charge les DLL listées dans chaque processus qui charge user32.dll. Depuis Windows 8, le mécanisme est désactivé quand Secure Boot est actif : sa présence sur une machine moderne avec Secure Boot traduit donc davantage une intention qu'une persistance fonctionnelle. Toute valeur non vide mérite malgré tout une explication.

Détournement COM

Quand un programme instancie un objet COM, Windows cherche le CLSID dans HKCU\Software\Classes\CLSID avant HKLM\SOFTWARE\Classes\CLSID. Un attaquant sans droits administrateur peut enregistrer le même CLSID dans la ruche utilisateur avec un InprocServer32 (DLL) ou un LocalServer32 (EXE) pointant vers sa charge, qui se charge ensuite chaque fois qu'Explorer ou une tâche planifiée instancie l'objet. Sur disque, HKCU\Software\Classes se trouve dans UsrClass.dat, pas dans NTUSER.DAT : collectez les deux. Cherchez les CLSID présents dans le UsrClass.dat d'un utilisateur qui existent aussi dans HKLM avec un chemin de serveur différent, et les serveurs situés dans des dossiers accessibles en écriture par l'utilisateur comme AppData.

Services

Les services sont définis sous HKLM\SYSTEM\CurrentControlSet\Services\<nom> ; sur une ruche hors ligne, retrouvez le control set actif via Select\Current. Les valeurs importantes :

  • ImagePath : l'exécutable ou le pilote, arguments compris. Cherchez cmd.exe /c, powershell, des chemins dans Temp, ProgramData ou les profils utilisateurs, et les noms aléatoires.
  • Parameters\ServiceDll (parfois directement sous la clé du service) : la DLL chargée par un service svchost.exe partagé. La remplacer sur un service légitime est plus discret que d'en créer un nouveau.
  • Start : 0 boot, 1 system, 2 automatique, 3 manuel, 4 désactivé.
  • ObjectName : le compte d'exécution, généralement LocalSystem.
  • FailureActions et FailureCommand : une commande de récupération peut elle-même servir de point de persistance.

L'installation laisse un 7045 dans le journal System (nom du service, chemin, type de démarrage, compte) et, si Audit Security System Extension est activé, un 4697 dans Security. Le mouvement latéral façon PsExec produit les mêmes événements, d'où leur place centrale dans le guide mouvement latéral. Voir la fiche services.

# Sur hôte vivant : services avec leur binaire et leur compte
Get-CimInstance Win32_Service |
  Select-Object Name, State, StartMode, StartName, PathName |
  Sort-Object PathName

Tâches planifiées

Depuis Vista, une tâche laisse trois traces :

  1. Une définition XML dans C:\Windows\System32\Tasks\<dossier>\<nom> (sans extension), avec Actions, Triggers, Principals et RegistrationInfo.
  2. Des clés dans la ruche SOFTWARE sous Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache : Tree\<chemin> (valeurs Id, Index, SD) et Tasks\{GUID} (Path, Actions, Triggers, DynamicInfo).
  3. Des événements : Security 4698 (création, avec le XML de la tâche, si Audit Other Object Access Events est activé), 4702 (modification), 4699 (suppression), et dans Microsoft-Windows-TaskScheduler/Operational 106 (enregistrement), 140 (modification), 141 (suppression), 200 (action démarrée) et 201 (action terminée).

La technique « Tarrask » attribuée à HAFNIUM masque une tâche en supprimant sa valeur SD sous TaskCache\Tree. La tâche continue de s'exécuter mais disparaît de schtasks /query et de la console du Planificateur. Toute sous-clé Tree sans valeur SD est une trouvaille ; comparez aussi entre elles les listes Tree, Tasks et fichiers XML, car une incohérence signale une manipulation. Les champs Author et Date du XML sont écrits par le créateur et peuvent être falsifiés. Détails sur la fiche tâches planifiées.

# Sur hôte vivant : toutes les tâches avec leur action, y compris celles marquées Hidden
Get-ScheduledTask | ForEach-Object {
  [pscustomobject]@{
    Path    = $_.TaskPath + $_.TaskName
    State   = $_.State
    Hidden  = $_.Settings.Hidden
    Execute = ($_.Actions | ForEach-Object { "$($_.Execute) $($_.Arguments)" }) -join ' | '
  }
}

# Entrées Tree sans valeur SD (masquage façon Tarrask)
Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree' -Recurse |
  Where-Object { $_.GetValue('Id') -and ($_.GetValueNames() -notcontains 'SD') } |
  Select-Object Name

Get-ScheduledTask n'affiche pas une tâche dont le SD a été supprimé : c'est précisément pour cela que la vérification dans le registre compte.

Abonnements d'événements WMI

Un abonnement WMI permanent combine trois objets, généralement dans root\subscription :

  • un __EventFilter contenant une requête WQL (par exemple un déclenchement quelques minutes après le démarrage, ou au lancement d'un processus) ;
  • une sous-classe d'__EventConsumer qui agit, typiquement CommandLineEventConsumer (exécute une commande) ou ActiveScriptEventConsumer (exécute du VBScript ou du JScript) ;
  • un __FilterToConsumerBinding qui relie les deux.

Le consumer s'exécute dans WmiPrvSE.exe en tant que SYSTEM, sans aucun fichier dans un dossier de démarrage. Tout est stocké dans le dépôt CIM, C:\Windows\System32\wbem\Repository\OBJECTS.DATA avec INDEX.BTR et les fichiers MAPPING*.MAP. Depuis Windows 10, le 5861 de Microsoft-Windows-WMI-Activity/Operational journalise chaque nouveau binding permanent avec la requête du filtre et le détail du consumer ; Sysmon 19, 20 et 21 capturent l'activité des filtres, consumers et bindings s'ils sont configurés. Des abonnements supprimés peuvent survivre dans les pages non allouées d'OBJECTS.DATA. Voir la fiche dépôt WMI.

# Énumération sur hôte vivant
Get-CimInstance -Namespace root/subscription -ClassName __EventFilter |
  Select-Object Name, Query
Get-CimInstance -Namespace root/subscription -ClassName __EventConsumer |
  Select-Object __CLASS, Name, CommandLineTemplate, ScriptText
Get-CimInstance -Namespace root/subscription -ClassName __FilterToConsumerBinding |
  Select-Object Filter, Consumer
# Hors ligne : analyser le dépôt copié depuis une image
python PyWMIPersistenceFinder.py ./Repository/OBJECTS.DATA

Autres emplacements à vérifier

Dossiers Startup

Les raccourcis ou scripts déposés dans C:\Users\<utilisateur>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup ou C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp s'exécutent à l'ouverture de session. Ces fichiers ont des horodatages NTFS normaux, ce qui fournit une date de création que les valeurs Run n'ont pas. Vérifiez aussi User Shell Folders pour repérer un dossier Startup redirigé.

Jobs BITS

Les jobs du Background Intelligent Transfer Service peuvent télécharger une charge et, via bitsadmin /SetNotifyCmdLine, exécuter une commande quand le job se termine ou échoue. Ils peuvent rester actifs longtemps et être relancés, ce qui en fait un mécanisme discret de persistance et de téléchargement. Les traces se trouvent dans la base BITS (qmgr.db depuis Windows 10, qmgr0.dat/qmgr1.dat avant) et dans Microsoft-Windows-Bits-Client/Operational (3 création, 59 début de transfert avec l'URL, 60 arrêt). Voir la fiche jobs BITS.

Portes dérobées via les fonctions d'accessibilité

Remplacer C:\Windows\System32\sethc.exe (touches rémanentes, cinq fois Maj) ou utilman.exe (Win+U) par cmd.exe, ou leur associer un Debugger IFEO, donne un shell SYSTEM depuis l'écran de connexion, y compris en RDP. Comparez les hashes et les informations de version de sethc.exe, utilman.exe, osk.exe, Magnify.exe, Narrator.exe, DisplaySwitch.exe et AtBroker.exe avec une build saine de même version, cherchez des clés IFEO à ces noms, et examinez le Prefetch pour repérer des exécutions à des heures inhabituelles.

Nouveaux comptes locaux

Un nouvel administrateur local est une persistance qui survit à tout nettoyage des malwares. Cherchez les 4720 (création), 4722 (activation) et 4732 (ajout à un groupe local comme Administrateurs) dans Security, et analysez la ruche SAM pour les dates de création, la dernière connexion et l'appartenance aux groupes (voir la fiche comptes utilisateurs SAM). Un compte peut être masqué de l'écran de connexion avec un DWORD à 0 sous HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\UserList\<nom>, et les noms se terminant par $ sont ignorés par certaines commandes d'énumération.

Détournement de l'ordre de recherche des DLL

Quand une application charge une DLL par son nom sans chemin complet, Windows parcourt une série de répertoires en commençant par le dossier de l'application. Déposer une DLL malveillante portant le nom attendu dans ce dossier, ou dans un répertoire accessible en écriture situé plus tôt dans l'ordre de recherche, la fait charger par un processus légitime et souvent signé. Les KnownDLLs (HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs) sont protégées contre ce détournement. Cherchez des DLL normalement présentes dans System32 apparaissant à côté d'exécutables dans ProgramData, AppData ou Temp, des DLL non signées à côté de binaires signés, et des chargements d'image Sysmon 7 depuis des chemins inhabituels. Amcache aide à dater la première apparition de la DLL.

Outils

Autoruns hors ligne

Autoruns (Sysinternals) couvre la plupart des autostarts du registre et du système de fichiers et signale les entrées non signées. autorunsc peut analyser un répertoire Windows hors ligne avec -z, en pointant vers le dossier Windows et un profil utilisateur d'une image montée.

# Sur hôte vivant, tous types d'entrées, CSV avec hashes et vérification des signatures
autorunsc.exe -accepteula -nobanner -a * -c -h -s > autoruns_live.csv

# Image hors ligne montée en F:
autorunsc.exe -accepteula -nobanner -a * -c -h -s -z F:\Windows F:\Users\alice > autoruns_offline.csv

Le mode hors ligne dépend des ruches qu'il peut lire : lancez-le une fois par profil utilisateur pertinent.

KAPE et RECmd

KAPE collecte en une passe les ruches, le XML des tâches, le dépôt WMI et les journaux, puis son module !EZParser lance les outils d'Eric Zimmerman. RECmd, avec un fichier batch (comme Kroll_Batch.reb fourni dans son dossier BatchExamples), extrait les clés de persistance connues de toutes les ruches dans un seul CSV, en tenant compte des journaux de transactions des ruches quand ils sont présents.

kape.exe --tsource C: --tdest E:\tout --target KapeTriage --mdest E:\mout --module !EZParser
RECmd.exe -d E:\tout\C --bn .\BatchExamples\Kroll_Batch.reb --csv E:\out\registry

Velociraptor

Sur un parc, Velociraptor exécute les mêmes vérifications partout à la fois. Artefacts utiles : Windows.Sysinternals.Autoruns, Windows.Persistence.PermanentWMIEvents, Windows.System.TaskScheduler, Windows.System.Services et Windows.Sys.StartupItems. Empiler (stacking) les résultats de nombreux hôtes est souvent plus rapide qu'examiner une machine en profondeur. Le guide acquisition et triage couvre le déploiement.

Erreurs fréquentes

  • Ne regarder que HKLM. Les clés Run de HKCU, les objets COM par utilisateur dans UsrClass.dat et les dossiers Startup utilisateur ne demandent aucun droit administrateur, et c'est pour cela qu'ils sont prisés. Traitez les ruches de chaque utilisateur, comptes de service compris.
  • Oublier WOW6432Node. Les entrées Run, IFEO et AppInit 32 bits se trouvent dans une branche distincte sur les systèmes 64 bits.
  • Faire confiance aux signatures. Les attaquants font pointer leurs autostarts vers des LOLBins signés (rundll32, mshta, regsvr32) avec des arguments malveillants. Lisez la ligne de commande, pas seulement le binaire.
  • Surinterpréter l'horodatage des clés. Un last write time date la dernière modification de la clé, pas celle de la valeur qui vous intéresse.
  • Manquer les tâches cachées à l'API. Énumérez directement TaskCache et le dossier Tasks, pas seulement schtasks.
  • S'arrêter à la première trouvaille. Les attaquants posent généralement plusieurs mécanismes : parcourez toute la liste.

Méthode de triage et comparaison à une baseline

  1. Collecter les ruches (SYSTEM, SOFTWARE, SAM, chaque NTUSER.DAT et UsrClass.dat, avec leurs journaux de transactions), System32\Tasks, le dossier Repository de WMI, la base BITS, les dossiers Startup et tous les journaux d'événements. Le guide forensique du registre explique l'organisation des ruches.
  2. Énumérer avec Autoruns (vivant ou -z), la sortie batch de RECmd, le XML des tâches plus TaskCache, et un parseur WMI.
  3. Vérifier les journaux : 7045, 4697, 4698, TaskScheduler 106/200, WMI-Activity 5861, Bits-Client 3/59, 4720/4732, en suivant le guide des journaux d'événements.
  4. Comparer à une baseline : sortie Autoruns d'une machine saine issue du même master, ou résultats empilés sur l'ensemble du parc. Les entrées présentes sur un ou deux hôtes sur plusieurs centaines remontent d'elles-mêmes.
  5. Filtrer par date : gardez les entrées dont le last write time de la clé, la date de création du fichier ou l'événement d'installation tombe dans la fenêtre d'intrusion.
  6. Valider chaque candidat : hash et signature de la cible, chemin du fichier, Prefetch ou Amcache pour l'exécution, et compte à l'origine de la création.
  7. Documenter chaque mécanisme avec son ID ATT&CK, son emplacement, sa date de création et les preuves d'exécution, puis les supprimer tous en même temps lors de la remédiation pour que l'attaquant ne puisse pas se servir de l'un pour restaurer les autres.

Domaine 07

Persistance

Les fiches artefacts derrière ce guide : emplacement selon la version de Windows, ce que prouve chacun et les outils pour l'analyser.

Articles liés