Taches Planifiees Windows
Introduction
Les taches planifiees (Scheduled Tasks) permettent d'executer automatiquement des programmes ou scripts selon des declencheurs definis.
Concepts Fondamentaux
Composants d'une tache
- Declencheur (Trigger): Quand la tache s'execute
- Action: Ce que la tache fait
- Conditions: Criteres supplementaires
- Parametres: Options d'execution
Types de declencheurs
| Type | Description |
|---|---|
| AtStartup | Au demarrage du systeme |
| AtLogOn | A la connexion d'un utilisateur |
| Once | Une seule fois |
| Daily | Quotidiennement |
| Weekly | Hebdomadairement |
| OnEvent | Sur un evenement specifique |
| OnIdle | Quand le systeme est inactif |
Gestion via GUI
Task Scheduler (taskschd.msc)
Win+R > taskschd.msc
Structure:
- Task Scheduler Library
- Microsoft (taches systeme)
- Dossiers personnalises
Creer une tache basique
- Action > Create Basic Task
- Suivre l'assistant
- Definir nom, declencheur, action
Creer une tache avancee
- Action > Create Task
- Onglet General: Nom, compte, privileges
- Onglet Triggers: Declencheurs
- Onglet Actions: Programmes a executer
- Onglet Conditions: Criteres
- Onglet Settings: Options
Gestion via PowerShell
Lister les taches
# Toutes les taches
Get-ScheduledTask
# Taches actives
Get-ScheduledTask | Where-Object {$_.State -eq "Ready"}
# Rechercher par nom
Get-ScheduledTask -TaskName "*Update*"
# Details d'une tache
Get-ScheduledTask -TaskName "NomTache" | Get-ScheduledTaskInfo
Creer une tache
# Definir l'action
$action = New-ScheduledTaskAction `
-Execute "powershell.exe" `
-Argument "-File C:\Scripts\MonScript.ps1"
# Definir le declencheur
$trigger = New-ScheduledTaskTrigger -Daily -At "08:00"
# Definir le principal (qui execute)
$principal = New-ScheduledTaskPrincipal `
-UserId "SYSTEM" `
-RunLevel Highest
# Options
$settings = New-ScheduledTaskSettingsSet `
-AllowStartIfOnBatteries `
-DontStopIfGoingOnBatteries
# Creer la tache
Register-ScheduledTask `
-TaskName "MaTache" `
-Action $action `
-Trigger $trigger `
-Principal $principal `
-Settings $settings `
-Description "Description de ma tache"
Types de declencheurs
# Au demarrage
$trigger = New-ScheduledTaskTrigger -AtStartup
# A la connexion
$trigger = New-ScheduledTaskTrigger -AtLogOn
# Une fois
$trigger = New-ScheduledTaskTrigger -Once -At "2025-01-15 10:00"
# Quotidien
$trigger = New-ScheduledTaskTrigger -Daily -At "08:00"
# Hebdomadaire
$trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Monday -At "09:00"
# Sur un evenement
$trigger = New-ScheduledTaskTrigger -AtStartup
# (pour les evenements specifiques, utiliser schtasks.exe)
Modifier une tache
# Changer le declencheur
$newTrigger = New-ScheduledTaskTrigger -Daily -At "10:00"
Set-ScheduledTask -TaskName "MaTache" -Trigger $newTrigger
# Activer/Desactiver
Enable-ScheduledTask -TaskName "MaTache"
Disable-ScheduledTask -TaskName "MaTache"
Supprimer une tache
Unregister-ScheduledTask -TaskName "MaTache" -Confirm:$false
Executer manuellement
Start-ScheduledTask -TaskName "MaTache"
Gestion via CMD
Commande SCHTASKS
:: Lister les taches
schtasks /query
:: Details d'une tache
schtasks /query /tn "NomTache" /v /fo LIST
:: Creer une tache
schtasks /create /tn "MaTache" /tr "C:\programme.exe" /sc daily /st 08:00
:: Executer
schtasks /run /tn "MaTache"
:: Supprimer
schtasks /delete /tn "MaTache" /f
:: Modifier
schtasks /change /tn "MaTache" /st 10:00
Options courantes
/sc Schedule type (minute, hourly, daily, weekly, monthly, once, onstart, onlogon)
/st Start time (HH:MM)
/sd Start date (MM/DD/YYYY)
/ru Run as user
/rp Run as password
/rl Run level (LIMITED, HIGHEST)
Securite des Taches Planifiees
Risques
Les taches planifiees sont un vecteur de persistence tres utilise par les attaquants:
- S'executent automatiquement
- Peuvent avoir des privileges eleves
- Souvent ignorees lors des audits
Verifications de securite
# Taches s'executant en tant que SYSTEM
Get-ScheduledTask | ForEach-Object {
$task = $_
$principal = $task.Principal
if ($principal.UserId -eq "SYSTEM" -or $principal.UserId -like "*SYSTEM*") {
[PSCustomObject]@{
Name = $task.TaskName
Path = $task.TaskPath
User = $principal.UserId
}
}
} | Format-Table
# Taches avec executables dans des chemins suspects
Get-ScheduledTask | ForEach-Object {
$actions = $_.Actions
foreach ($action in $actions) {
if ($action.Execute -like "*\Temp\*" -or
$action.Execute -like "*\AppData\*" -or
$action.Execute -like "*\Downloads\*") {
[PSCustomObject]@{
Task = $_.TaskName
Execute = $action.Execute
Arguments = $action.Arguments
}
}
}
} | Format-Table
# Taches creees recemment (dernieres 24h)
Get-ScheduledTask | Where-Object {
$_.Date -gt (Get-Date).AddDays(-1)
}
Indicators of Compromise (IOC)
| Indicateur | Description |
|---|---|
| Tache avec nom aleatoire | Possible malware |
| Executable dans Temp | Suspect |
| PowerShell encode | Tres suspect |
| Tache cachee | Technique d'evasion |
| SYSTEM executant des scripts utilisateur | Risque eleve |
Hardening
- Auditer regulierement les taches planifiees
- Limiter qui peut creer des taches
- Surveiller les creations de taches (Event ID 4698)
- Utiliser des comptes de service dedies
Persistence via Taches Planifiees
Technique d'attaque (a connaitre pour la defense)
# Exemple de persistence malveillante (NE PAS UTILISER)
# Montre comment les attaquants procedent
$action = New-ScheduledTaskAction `
-Execute "powershell.exe" `
-Argument "-WindowStyle Hidden -EncodedCommand <base64>"
$trigger = New-ScheduledTaskTrigger -AtStartup
Register-ScheduledTask `
-TaskName "WindowsUpdateHelper" `
-Action $action `
-Trigger $trigger `
-Principal (New-ScheduledTaskPrincipal -UserId "SYSTEM" -RunLevel Highest) `
-Force
Detection
# Script de detection de taches suspectes
$suspicious = @()
Get-ScheduledTask | ForEach-Object {
$task = $_
$isSuspicious = $false
$reasons = @()
# Verifier les actions
foreach ($action in $task.Actions) {
# PowerShell avec commandes encodees
if ($action.Arguments -match "-[Ee]ncoded") {
$isSuspicious = $true
$reasons += "EncodedCommand"
}
# Executables dans des chemins suspects
if ($action.Execute -match "\\(Temp|Downloads|AppData)\\") {
$isSuspicious = $true
$reasons += "Chemin suspect"
}
# Noms qui imitent des services Windows
if ($task.TaskName -match "^(WindowsUpdate|MicrosoftEdge|Chrome|Adobe).*\d{4,}") {
$isSuspicious = $true
$reasons += "Nom suspicieux"
}
}
if ($isSuspicious) {
$suspicious += [PSCustomObject]@{
TaskName = $task.TaskName
TaskPath = $task.TaskPath
Raisons = ($reasons -join ", ")
}
}
}
if ($suspicious) {
Write-Host "Taches suspectes detectees:" -ForegroundColor Red
$suspicious | Format-Table -AutoSize
} else {
Write-Host "Aucune tache suspecte detectee." -ForegroundColor Green
}
Journalisation
Event IDs
| Event ID | Log | Description |
|---|---|---|
| 4698 | Security | Tache creee |
| 4699 | Security | Tache supprimee |
| 4700 | Security | Tache activee |
| 4701 | Security | Tache desactivee |
| 4702 | Security | Tache mise a jour |
| 106 | TaskScheduler/Operational | Tache enregistree |
| 140 | TaskScheduler/Operational | Tache mise a jour |
| 141 | TaskScheduler/Operational | Tache supprimee |
| 200 | TaskScheduler/Operational | Action demarree |
| 201 | TaskScheduler/Operational | Action terminee |
Activer l'audit
# Activer l'audit des taches planifiees (GPO ou commande)
auditpol /set /subcategory:"Other Object Access Events" /success:enable /failure:enable
Consulter les logs
# Evenements de creation de tache
Get-WinEvent -FilterHashtable @{
LogName = 'Security'
ID = 4698
} -MaxEvents 10 | Format-Table TimeCreated, Message -Wrap
# Logs operationnels
Get-WinEvent -LogName 'Microsoft-Windows-TaskScheduler/Operational' -MaxEvents 20
Exercices
- Creez une tache qui execute un script PowerShell tous les jours a 9h
- Creez une tache qui demarre au boot du systeme
- Auditez les taches existantes pour identifier les suspectes
- Consultez les logs de creation de taches des 7 derniers jours