Tarefas Agendadas no Windows
Introdução
As tarefas agendadas (Scheduled Tasks) permitem executar automaticamente programas ou scripts conforme gatilhos definidos.
Conceitos Fundamentais
Componentes de uma tarefa
- Gatilho (Trigger): Quando a tarefa é executada
- Ação: O que a tarefa faz
- Condições: Critérios adicionais
- Parâmetros: Opções de execução
Tipos de gatilhos
| Tipo | Descrição |
|---|---|
| AtStartup | Na inicialização do sistema |
| AtLogOn | No login de um usuário |
| Once | Uma única vez |
| Daily | Diariamente |
| Weekly | Semanalmente |
| OnEvent | Em um evento específico |
| OnIdle | Quando o sistema está ocioso |
Gerenciamento via GUI
Task Scheduler (taskschd.msc)
Win+R > taskschd.msc
Estrutura:
- Task Scheduler Library
- Microsoft (tarefas do sistema)
- Pastas personalizadas
Criar uma tarefa básica
- Action > Create Basic Task
- Siga o assistente
- Defina nome, gatilho, ação
Criar uma tarefa avançada
- Action > Create Task
- Aba General: Nome, conta, privilégios
- Aba Triggers: Gatilhos
- Aba Actions: Programas a serem executados
- Aba Conditions: Critérios
- Aba Settings: Opções
Gerenciamento via PowerShell
Listar tarefas
# Todas as tarefas
Get-ScheduledTask
# Tarefas ativas
Get-ScheduledTask | Where-Object {$_.State -eq "Ready"}
# Buscar por nome
Get-ScheduledTask -TaskName "*Update*"
# Detalhes de uma tarefa
Get-ScheduledTask -TaskName "NomTache" | Get-ScheduledTaskInfo
Criar uma tarefa
# Definir a ação
$action = New-ScheduledTaskAction `
-Execute "powershell.exe" `
-Argument "-File C:\Scripts\MonScript.ps1"
# Definir o gatilho
$trigger = New-ScheduledTaskTrigger -Daily -At "08:00"
# Definir o principal (quem executa)
$principal = New-ScheduledTaskPrincipal `
-UserId "SYSTEM" `
-RunLevel Highest
# Opções
$settings = New-ScheduledTaskSettingsSet `
-AllowStartIfOnBatteries `
-DontStopIfGoingOnBatteries
# Criar a tarefa
Register-ScheduledTask `
-TaskName "MaTache" `
-Action $action `
-Trigger $trigger `
-Principal $principal `
-Settings $settings `
-Description "Descrição da minha tarefa"
Tipos de gatilhos
# Na inicialização
$trigger = New-ScheduledTaskTrigger -AtStartup
# No login
$trigger = New-ScheduledTaskTrigger -AtLogOn
# Uma vez
$trigger = New-ScheduledTaskTrigger -Once -At "2025-01-15 10:00"
# Diário
$trigger = New-ScheduledTaskTrigger -Daily -At "08:00"
# Semanal
$trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Monday -At "09:00"
# Em um evento
$trigger = New-ScheduledTaskTrigger -AtStartup
# (para eventos específicos, use schtasks.exe)
Modificar uma tarefa
# Alterar o gatilho
$newTrigger = New-ScheduledTaskTrigger -Daily -At "10:00"
Set-ScheduledTask -TaskName "MaTache" -Trigger $newTrigger
# Ativar/Desativar
Enable-ScheduledTask -TaskName "MaTache"
Disable-ScheduledTask -TaskName "MaTache"
Excluir uma tarefa
Unregister-ScheduledTask -TaskName "MaTache" -Confirm:$false
Executar manualmente
Start-ScheduledTask -TaskName "MaTache"
Gerenciamento via CMD
Comando SCHTASKS
:: Listar tarefas
schtasks /query
:: Detalhes de uma tarefa
schtasks /query /tn "NomTache" /v /fo LIST
:: Criar uma tarefa
schtasks /create /tn "MaTache" /tr "C:\programme.exe" /sc daily /st 08:00
:: Executar
schtasks /run /tn "MaTache"
:: Excluir
schtasks /delete /tn "MaTache" /f
:: Modificar
schtasks /change /tn "MaTache" /st 10:00
Opções comuns
/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)
Segurança das Tarefas Agendadas
Riscos
As tarefas agendadas são um vetor de persistência muito utilizado por atacantes:
- Executam automaticamente
- Podem ter privilégios elevados
- Frequentemente ignoradas em auditorias
Verificações de segurança
# Tarefas executando como 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
# Tarefas com executáveis em caminhos suspeitos
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
# Tarefas criadas recentemente (últimas 24h)
Get-ScheduledTask | Where-Object {
$_.Date -gt (Get-Date).AddDays(-1)
}
Indicadores de Comprometimento (IOC)
| Indicador | Descrição |
|---|---|
| Tarefa com nome aleatório | Possível malware |
| Executável em Temp | Suspeito |
| PowerShell codificado | Muito suspeito |
| Tarefa oculta | Técnica de evasão |
| SYSTEM executando scripts de usuário | Alto risco |
Hardening
- Auditar regularmente as tarefas agendadas
- Limitar quem pode criar tarefas
- Monitorar a criação de tarefas (Event ID 4698)
- Utilizar contas de serviço dedicadas
Persistência via Tarefas Agendadas
Técnica de ataque (para conhecimento defensivo)
# Exemplo de persistência maliciosa (NÃO UTILIZAR)
# Demonstra como atacantes procedem
$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
Detecção
# Script para detectar tarefas suspeitas
$suspicious = @()
Get-ScheduledTask | ForEach-Object {
$task = $_
$isSuspicious = $false
$reasons = @()
# Verificar as ações
foreach ($action in $task.Actions) {
# PowerShell com comandos codificados
if ($action.Arguments -match "-[Ee]ncoded") {
$isSuspicious = $true
$reasons += "EncodedCommand"
}
# Executáveis em caminhos suspeitos
if ($action.Execute -match "\\(Temp|Downloads|AppData)\\") {
$isSuspicious = $true
$reasons += "Caminho suspeito"
}
# Nomes que imitam serviços do Windows
if ($task.TaskName -match "^(WindowsUpdate|MicrosoftEdge|Chrome|Adobe).*\d{4,}") {
$isSuspicious = $true
$reasons += "Nome suspeito"
}
}
if ($isSuspicious) {
$suspicious += [PSCustomObject]@{
TaskName = $task.TaskName
TaskPath = $task.TaskPath
Raisons = ($reasons -join ", ")
}
}
}
if ($suspicious) {
Write-Host "Tarefas suspeitas detectadas:" -ForegroundColor Red
$suspicious | Format-Table -AutoSize
} else {
Write-Host "Nenhuma tarefa suspeita detectada." -ForegroundColor Green
}
Registro de Eventos
Event IDs
| Event ID | Log | Descrição |
|---|---|---|
| 4698 | Security | Tarefa criada |
| 4699 | Security | Tarefa excluída |
| 4700 | Security | Tarefa ativada |
| 4701 | Security | Tarefa desativada |
| 4702 | Security | Tarefa atualizada |
| 106 | TaskScheduler/Operational | Tarefa registrada |
| 140 | TaskScheduler/Operational | Tarefa atualizada |
| 141 | TaskScheduler/Operational | Tarefa excluída |
| 200 | TaskScheduler/Operational | Ação iniciada |
| 201 | TaskScheduler/Operational | Ação finalizada |
Ativar auditoria
# Ativar auditoria de tarefas agendadas (GPO ou comando)
auditpol /set /subcategory:"Other Object Access Events" /success:enable /failure:enable
Consultar os logs
# Eventos de criação de tarefa
Get-WinEvent -FilterHashtable @{
LogName = 'Security'
ID = 4698
} -MaxEvents 10 | Format-Table TimeCreated, Message -Wrap
# Logs operacionais
Get-WinEvent -LogName 'Microsoft-Windows-TaskScheduler/Operational' -MaxEvents 20
Exercícios
- Crie uma tarefa que execute um script PowerShell todos os dias às 9h
- Crie uma tarefa que inicie na inicialização do sistema
- Audite as tarefas existentes para identificar suspeitas
- Consulte os logs de criação de tarefas dos últimos 7 dias