Skip to content

Le XML d'une tâche planifiée Windows, élément par élément

Lire le XML d'une tâche planifiée en enquêteur : RegistrationInfo, Triggers, Principals, Settings, Actions, et les heures locales sans fuseau de Date et StartBoundary.

Publié le 7 min de lecture

En bref. Le XML d'une tâche comporte cinq sections qui comptent : RegistrationInfo (qui et quand, selon ses propres dires), Triggers (quand elle se déclenche), Principals (quel compte, quels privilèges), Settings (cachée, activée, limites) et Actions (ce qui s'exécute). Deux pièges : Date et StartBoundary sont généralement en heure locale sans décalage, et Author est un texte libre. Lisez le fichier comme un ensemble d'affirmations et confrontez-les à TaskCache et aux journaux d'événements.

Le format est documenté dans le Task Scheduler Schema de Microsoft, avec l'espace de noms http://schemas.microsoft.com/windows/2004/02/mit/task. Cet article le lit du point de vue de l'enquêteur. L'emplacement des fichiers est traité dans emplacements et acquisition des tâches planifiées.

Un exemple minimal

Une tâche enregistrée avec schtasks sur un poste de travail ressemble généralement à ceci. L'exemple est un extrait du jeu de données fictif FIN-WKS-07 utilisé sur l'ensemble de ce site, configuré en UTC+02:00 :

<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <RegistrationInfo>
    <Date>2026-09-14T12:09:58.4413872</Date>
    <Author>FIN-WKS-07\svc_backup</Author>
    <Description>Intel graphics telemetry</Description>
    <URI>\IntelGfxTelemetry</URI>
  </RegistrationInfo>
  <Triggers>
    <BootTrigger><Enabled>true</Enabled></BootTrigger>
    <TimeTrigger>
      <Repetition><Interval>PT1H</Interval></Repetition>
      <StartBoundary>2026-09-14T12:15:00</StartBoundary>
      <Enabled>true</Enabled>
    </TimeTrigger>
  </Triggers>
  <Principals>
    <Principal id="Author">
      <UserId>S-1-5-18</UserId>
      <RunLevel>HighestAvailable</RunLevel>
    </Principal>
  </Principals>
  <Settings>
    <Hidden>true</Hidden>
    <Enabled>true</Enabled>
  </Settings>
  <Actions Context="Author">
    <Exec>
      <Command>C:\ProgramData\Intel\m64.exe</Command>
      <Arguments>-svc</Arguments>
    </Exec>
  </Actions>
</Task>

Le fichier sur disque est généralement en UTF-16LE avec indicateur d'ordre des octets (BOM), même si la déclaration XML circule parfois en UTF-8. Un parser qui suppose de l'UTF-8 affichera des caractères illisibles ; c'est déjà une raison suffisante d'utiliser un outil conçu pour ce format.

RegistrationInfo : les métadonnées déclarées

ÉlémentCe qu'il indiqueQuel crédit lui accorder
URIChemin de la tâche dans la bibliothèque, par ex. \Microsoft\Windows\Defrag\ScheduledDefragDoit correspondre au chemin du fichier et à la clé Tree de TaskCache ; toute divergence mérite d'être notée
AuthorQui a enregistré la tâcheTexte libre. La console et schtasks écrivent DOMAIN\user ; les programmes d'installation écrivent souvent un nom d'éditeur ; certaines tâches Microsoft utilisent une référence de ressource comme $(@%SystemRoot%\system32\...)
DateDate d'enregistrementGénéralement en heure locale, sans décalage (voir plus bas)
DescriptionDescription lisibleTexte libre ; les attaquants recopient les formulations de Microsoft
SecurityDescriptorSDDL facultatif pour la tâcheRare dans le XML ; le descripteur effectif est la valeur SD de TaskCache
Source, Version, DocumentationFacultatifsParfois utiles pour attribuer une tâche à un éditeur

Des notes de praticiens comme les Windows forensic artifacts de Psmths relèvent que l'Author d'une tâche créée à distance peut révéler le compte d'origine, mais rien n'empêche un XML importé de porter un auteur falsifié. Comparez avec le SubjectUserName de l'événement 4698 ou 106 lorsque vous en disposez.

Triggers : quand elle se déclenche

Le schéma autorise jusqu'à 48 déclencheurs par tâche : BootTrigger, LogonTrigger, RegistrationTrigger, IdleTrigger, TimeTrigger, CalendarTrigger, EventTrigger et SessionStateChangeTrigger. Tous partagent Enabled, StartBoundary, EndBoundary, Repetition et ExecutionTimeLimit.

Lecture côté enquête :

  • Les déclencheurs Boot et Logon sont de la persistance classique. Un LogonTrigger sans UserId se déclenche pour n'importe quel utilisateur.
  • RegistrationTrigger se déclenche une fois, à l'enregistrement de la tâche : un moyen courant d'exécuter quelque chose immédiatement tout en ayant l'air d'une tâche planifiée.
  • Un TimeTrigger avec un intervalle Repetition court (par exemple PT5M) évoque un comportement de beacon.
  • EventTrigger embarque une requête XPath Subscription ; il peut faire se déclencher une tâche sur un event ID précis, ce qui passe facilement inaperçu.
  • SessionStateChangeTrigger (SessionUnlock, RemoteConnect) est moins courant et mérite un second regard.

Principals : quel compte, quels privilèges

ÉlémentValeursSignification
UserIdNom de compte ou SID (S-1-5-18 pour SYSTEM, S-1-5-19 pour LOCAL SERVICE, S-1-5-20 pour NETWORK SERVICE)Le contexte de sécurité
GroupIdNom de groupe ou SIDS'exécute pour les membres d'un groupe, par ex. S-1-5-32-545 (Users)
LogonTypeInteractiveToken, Password, S4U, InteractiveTokenOrPasswordManière dont le compte est ouvert ; voir S4U
RunLevelLeastPrivilege, HighestAvailableUtilisation ou non d'un jeton administrateur ; voir niveau d'exécution

Une tâche non Microsoft qui s'exécute en S-1-5-18 avec HighestAvailable est la combinaison à trier en priorité. Un LogonType à Password signifie que des identifiants ont été stockés pour que la tâche puisse s'exécuter en l'absence de l'utilisateur ; les recommandations de Microsoft sur l'événement 4698 conseillent de lever une alerte dans ce cas, car le mot de passe stocké peut être récupéré par un administrateur.

Settings : les options qui masquent ou brident

Les éléments à lire en premier sont Hidden, Enabled, ExecutionTimeLimit (PT0S signifie aucune limite), MultipleInstancesPolicy, StartWhenAvailable, DisallowStartIfOnBatteries, WakeToRun, RunOnlyIfNetworkAvailable et DeleteExpiredTaskAfter.

Hidden=true masque seulement la tâche dans la console, sauf si "Show Hidden Tasks" est coché. Elle reste visible pour schtasks, l'API et le registre. Les techniques de dissimulation plus efficaces se jouent dans le registre, voir Tarrask et les tâches planifiées cachées. DeleteExpiredTaskAfter combiné à un EndBoundary fait qu'une tâche s'efface d'elle-même : son absence ultérieure ne prouve pas qu'elle n'a jamais existé.

Actions : ce qui s'exécute

ActionContenuRemarques
ExecCommand, Arguments, WorkingDirectoryL'immense majorité des tâches
ComHandlerClassId (CLSID), Data facultatifExécute un objet COM, généralement une DLL chargée dans taskhostw.exe ; voir action COM handler
SendEmailServeur, To, Subject...Déprécié par Microsoft ; rare sur les systèmes récents
ShowMessageTitle, BodyDéprécié ; rare

L'élément Actions possède un attribut Context qui désigne le principal. Jusqu'à 32 actions sont autorisées et elles s'exécutent dans l'ordre : lisez-les toutes, car une première action anodine peut précéder une seconde action malveillante.

Pour ComHandler, résolvez le CLSID dans la ruche SOFTWARE (Classes\CLSID\{...}\InprocServer32) pour retrouver la DLL. Détourner un CLSID déjà utilisé par une tâche légitime est une forme de persistance plus discrète que la création d'une nouvelle tâche.

Le temps : des valeurs locales sans fuseau

Le schéma type Date, StartBoundary et EndBoundary en xs:dateTime. L'API de scripting documente le format YYYY-MM-DDTHH:MM:SS(+-)HH:MM avec un décalage (Trigger.StartBoundary). En pratique, les tâches créées dans la console ou avec schtasks n'enregistrent aucun décalage, et l'heure est l'heure locale de la machine au moment où la tâche a été enregistrée. Certaines tâches stockent un Z ou un décalage explicite ; la plupart non.

Cela devient important dès que vous comparez avec des sources en UTC. Dans l'exemple 4698 de Microsoft, le TimeCreated de l'événement vaut 2015-09-23T02:03:06Z et le Date du XML 2015-09-22T19:03:06.9258653 : le même instant, à sept heures d'écart.

Plusieurs moyens de retrouver le décalage :

  1. TaskCache : DynamicInfo contient un FILETIME de création en UTC pour la même tâche ; l'écart avec Date donne le décalage, arrondi au quart d'heure le plus proche. Voir l'analyse forensique du registre TaskCache.
  2. Ruche SYSTEM : TimeZoneInformation indique le fuseau configuré ; n'oubliez pas que l'heure d'été s'applique à la date de l'événement, pas à celle de la collecte.
  3. Événement 4698 : TimeCreated en UTC face au Date embarqué.

Le Scheduled Tasks Parser applique automatiquement la première méthode : il compare les dates d'enregistrement du XML aux FILETIME de TaskCache, propose un décalage et vous laisse le modifier.

StartBoundary présente une subtilité supplémentaire : c'est le moment où le déclencheur devient actif, qui peut se situer dans le passé (les tâches créées « maintenant » reçoivent souvent la minute de création) ou loin dans le futur. Ce n'est pas une heure d'exécution. Les heures d'exécution proviennent du DynamicInfo de TaskCache et des événements 200/201.

FAQ

Dans quel fuseau horaire est exprimé le Date du XML d'une tâche planifiée ?

Généralement aucun. Le schéma autorise un décalage, mais les tâches créées dans la console ou avec schtasks enregistrent en principe l'heure locale sans aucun décalage. Déduisez le décalage d'une source UTC, comme les FILETIME de TaskCache ou le TimeCreated de l'événement 4698, avant de comparer avec d'autres traces.

Le champ Author prouve-t-il qui a créé la tâche ?

Non. Author est un texte libre écrit par ce qui a enregistré la tâche. La console et schtasks y inscrivent le compte créateur, mais un script ou un XML importé peut y mettre n'importe quoi. Considérez-le comme une affirmation à vérifier dans les journaux d'événements.

Que signifie Hidden=true ?

La tâche n'apparaît pas dans la console du Planificateur de tâches, sauf si l'utilisateur active Show Hidden Tasks. Elle reste listée par schtasks et par l'API. De nombreuses tâches Microsoft sont cachées : ce drapeau compte donc surtout pour les tâches non Microsoft.

Articles liés

Pas à pas : chargez XML, fichiers .job et ruche SOFTWARE dans un parser gratuit, lisez tâches cachées et registre seul, corrigez le fuseau et exportez. Cas fictif.
Checklist pour repérer les tâches planifiées malveillantes : chemins inscriptibles, PowerShell encodé, LOLBins, SYSTEM, tâches cachées, écarts XML/registre.
Lire les fichiers .job hérités : sections fixe et variable de MS-TSCH, déclencheurs, SYSTEMTIME de dernière exécution en heure locale, présence sur Windows récent.