Détecter les tâches planifiées malveillantes (persistance)
Checklist pour repérer les tâches planifiées malveillantes : chemins inscriptibles, PowerShell encodé, LOLBins, SYSTEM, tâches cachées, écarts XML/registre.
En bref. Classez chaque tâche à l'aide de quelques questions : où se trouve la commande (chemin inscriptible par l'utilisateur ?), de quoi s'agit-il (PowerShell -EncodedCommand, rundll32, mshta, certutil...), qui l'exécute (SYSTEM, privilèges les plus élevés, pour une tâche non Microsoft ?), se cache-t-elle (Hidden, pas de SD, nom aléatoire, dossier racine), est-elle récente (enregistrement proche de l'incident) et les copies concordent-elles (XML contre TaskCache, hash). Ce sont des pistes de triage, pas des verdicts. Corroborez avant d'écrire « malveillant ».
Cet article fait partie de la série consacrée aux investigations et suppose que vous avez analysé ensemble le XML et TaskCache, comme décrit dans le guide d'analyse forensique des tâches planifiées. Les tâches planifiées figurent régulièrement parmi les techniques de persistance les plus fréquemment observées dans les rapports de réponse à incident, par exemple dans le Threat Detection Report de Red Canary, et MITRE les référence sous T1053.005.
Étape 0 : isoler la référence
Une installation Windows par défaut compte largement plus d'une centaine de tâches, presque toutes sous \Microsoft\Windows\, dont beaucoup sont cachées et beaucoup s'exécutent en SYSTEM. Chaque indicateur ci-dessous se déclenche sur certaines d'entre elles. Avant de chercher le malveillant :
- Triez par chemin et par auteur. Les tâches Microsoft se trouvent sous
\Microsoft\Windows\et ont généralement un auteur Microsoft ou une chaîne de ressource du type$(@%SystemRoot%\system32\...). - Vérifiez que leurs actions pointent toujours là où elles le devraient : des binaires
%windir%\system32\...ou un CLSIDComHandler. Un attaquant qui modifie une tâche Microsoft existante conserve le chemin et l'auteur mais change l'action. - Comparez avec une machine saine de la même build si vous le pouvez. Une tâche absente de la référence est la première à lire.
Les indicateurs
| Indicateur | Pourquoi c'est important | Faux positifs courants |
|---|---|---|
| Commande dans un chemin inscriptible par l'utilisateur | Les attaquants déposent leurs charges là où ils peuvent écrire | Programmes de mise à jour par utilisateur (Teams, OneDrive, navigateurs) |
| PowerShell encodé | Masque la vraie commande | Outils de gestion, certains scripts d'éditeurs |
| LOLBin ou hôte de scripts comme commande | Des binaires signés servent de relais à la charge | Scripts d'administration utilisant cscript, wscript |
SYSTEM ou HighestAvailable pour une tâche non Microsoft | Persistance avec un maximum de privilèges | Agents de sécurité, logiciels de sauvegarde, utilitaires de pilotes |
| Tâche non Microsoft cachée | Moins visible dans la console | Certaines tâches d'éditeurs sont cachées |
| Entrée Tree sans SD | Dissimulation de type Tarrask | Aucun courant |
| Tâche présente uniquement dans le registre ou sur le disque | Nettoyage ou altération | Ruche « dirty », désinstallation partielle |
| Hash discordant | XML ou registre modifié après l'enregistrement | Rare ; modifications manuelles par des administrateurs |
| Nom d'apparence aléatoire, dossier racine | Nom généré ou choisi sans soin | Tâches d'éditeurs nommées par GUID |
| Enregistrement récent | Proche de la fenêtre de l'incident | Jour de patch, installations de logiciels |
Chemin réseau (\\server\share) | Charge hébergée à distance | Scripts d'ouverture de session dans les parcs gérés |
Action .job héritée | Outillage ancien sur un OS moderne | Applications très anciennes |
Chemins inscriptibles par l'utilisateur
Examinez la Command et les chemins de fichiers présents dans Arguments : C:\Users\Public\, C:\ProgramData\, C:\Users\<user>\AppData\ (Local, Roaming, Temp), C:\Windows\Temp\, C:\Perflogs\ et la racine d'un lecteur. C:\ProgramData\Intel\m64.exe a l'air d'appartenir à un éditeur, mais c'est un dossier dans lequel n'importe quel utilisateur peut créer des fichiers par défaut. Développez les variables d'environnement avant de juger : %LOCALAPPDATA% dans une tâche SYSTEM renvoie au profil système.
PowerShell encodé
powershell.exe -EncodedCommand <base64> (ou ses abréviations comme -enc, -e) prend une chaîne Base64 d'un texte en UTF-16LE. Décodez-la avant de la lire ; l'entrée de glossaire PowerShell encodé explique comment. Par exemple, VwByAGkAdABlAC0ATwB1AHQAcAB1AHQAIAAnAHMAeQBuAHQAaABlAHQAaQBjACAAcwBhAG0AcABsAGUAJwA= se décode en Write-Output 'synthetic sample'. Relevez aussi -WindowStyle Hidden, -NoProfile, -ExecutionPolicy Bypass et -NonInteractive : fréquents ensemble dans les tâches malveillantes, mais aussi dans l'automatisation légitime. Le Scheduled Tasks Parser décode les commandes encodées à l'affichage : vous lisez le script, pas le Base64.
LOLBins et hôtes de scripts
Des binaires Windows signés capables d'exécuter ou de récupérer d'autre code (LOLBins) : rundll32.exe, regsvr32.exe, mshta.exe, wscript.exe, cscript.exe, certutil.exe, bitsadmin.exe, msiexec.exe, cmd.exe /c, et powershell.exe lui-même. Le projet LOLBAS documente les capacités de chacun. Une tâche dont la commande est l'un d'eux n'est pas suspecte en soi ; ce sont les arguments qui tranchent. rundll32.exe C:\Users\Public\x.dll,Start l'est ; rundll32.exe avec une DLL de System32 et un auteur Microsoft ne l'est généralement pas.
Principal et privilèges
Lisez UserId/GroupId, LogonType et RunLevel dans le XML (ou le principal tiré de l'en-tête Triggers de TaskCache quand le XML a disparu). S-1-5-18 (SYSTEM) avec HighestAvailable sur une tâche dont l'auteur est un utilisateur local, c'est la combinaison classique : quelqu'un disposant de droits administrateur a fait tourner quelque chose en SYSTEM au démarrage. Un LogonType Password signifie que des identifiants ont été stockés pour la tâche, ce qui justifie une alerte selon les recommandations de Microsoft (recommandations sur l'événement 4698). S4U s'exécute sans mot de passe stocké, mais aussi sans identifiants réseau.
Dissimulation
<Hidden>true</Hidden>sur une tâche non Microsoft.- Une clé
TreesansSD, ou un SD qui interdit la lecture : voir Tarrask et les tâches planifiées cachées. - Des noms qui imitent Microsoft (
\Microsoft\Windows\UpdateOrchestrator\...avec une action non Microsoft), ou des chaînes aléatoires (\a8Xq2LmZ). - Des tâches à la racine de la bibliothèque : les propres recommandations de Microsoft sur l'événement 4698 les signalent comme l'endroit où atterrissent souvent les tâches manuelles et malveillantes.
Cohérence entre les copies
C'est le contrôle que la plupart des scripts de triage oublient, et celui où l'analyse hors ligne fait la différence :
- TaskCache sans XML : le fichier a été supprimé, la tâche n'a pas été désenregistrée. Décodez le blob
Actions. - XML sans TaskCache : déposé mais jamais enregistré, ou registre nettoyé ; vérifiez d'abord l'état de la ruche.
- Hash discordant : le
Hashne correspond plus au XML. L'une des copies a été modifiée en dehors du service. - Action discordante : le XML indique une commande, le blob
Actionsune autre.
Chronologie
Comparez l'enregistrement (Date avec le bon décalage UTC, création dans DynamicInfo) avec la fenêtre de l'incident, et regardez la dernière exécution et le dernier résultat dans DynamicInfo. Une tâche enregistrée vingt minutes après une ouverture de session suspecte, et dont la dernière exécution a réussi, est plus intéressante qu'une tâche enregistrée le jour de l'installation. Rappelez-vous que les dates du XML sont généralement des heures locales sans fuseau : voir l'anatomie du XML des tâches.
Corroborer avant de conclure
Une tâche signalée est une hypothèse. Voici ce qui la confirme ou l'infirme :
- S'est-elle exécutée ? Dernière exécution et dernier résultat dans
DynamicInfo; événements 200 et 201 de TaskScheduler/Operational ; Prefetch pour la commande ; Amcache pour le hash du binaire et sa première exécution. - Qui l'a créée ? Événement Security 4698 (avec le XML) et événement 106 de TaskScheduler/Operational, s'ils sont journalisés. Le EVTX parser et son article sur la persistance par tâche planifiée et l'événement 4698 couvrent ce volet.
- Qu'est-ce que le binaire ? Calculez son hash, vérifiez sa signature, examinez les horodatages de la
$MFTet du journal USN autour de l'heure d'enregistrement. - Est-elle présente sur d'autres machines ? La même tâche sur cinquante postes de travail relève du déploiement logiciel ; sur un seul, elle devient intéressante.
Rédigez vos constats en termes observés : « la tâche \Microsoft\Windows\UPnP\UPnPHostConfigSync exécute powershell.exe avec une commande encodée qui se décode en ... en tant que SYSTEM, enregistrée le 2026-09-14 à 10:12:40 UTC, dernière exécution réussie à 10:42:41 UTC ». Laissez la corroboration porter le mot « malveillant ».
Pour un exemple fictif de bout en bout réunissant plusieurs de ces indicateurs, voir comment analyser les tâches planifiées dans votre navigateur.
FAQ
Qu'est-ce qui rend une tâche planifiée suspecte ?
Des commandes dans des dossiers inscriptibles par l'utilisateur, du PowerShell encodé, des hôtes de scripts et des LOLBins, des tâches non Microsoft exécutées en SYSTEM ou avec les privilèges les plus élevés, des tâches non Microsoft cachées, des noms d'apparence aléatoire, des chemins réseau, un enregistrement récent, et tout désaccord entre le fichier XML et l'entrée de registre TaskCache.
Ces indicateurs prouvent-ils une activité malveillante ?
Non. Chacun a des explications légitimes : programmes de mise à jour d'éditeurs dans ProgramData, scripts d'administration utilisant -EncodedCommand, agents exécutés en SYSTEM. Ils servent à prioriser les tâches à examiner. Un constat doit être corroboré par des traces d'exécution, les journaux d'événements ou le binaire lui-même.
Comment réduire le bruit des tâches Microsoft ?
Triez par auteur et par chemin, mettez de côté les tâches sous \Microsoft\Windows\ dont l'auteur est Microsoft après avoir vérifié que leurs actions pointent vers des binaires de System32, et comparez le reste avec une référence issue d'une machine saine de la même build.