Get-ScheduledTask: achar tarefas agendadas suspeitas no Windows

Um malware que roda uma vez e some não preocupa tanto quanto o que volta depois do reinício. Uma das formas mais baratas de garantir esse retorno é criar uma tarefa agendada: ela dispara no logon, de hora em hora ou toda segunda-feira, sem pedir nada ao usuário. Se você nunca olhou a lista de tarefas do seu Windows, provavelmente não sabe o que está lá. O PowerShell resolve isso em uma linha.
Por que tarefas agendadas importam pra segurança?
O Agendador de Tarefas é um recurso legítimo do Windows e roda com os privilégios que a tarefa definir, inclusive SYSTEM. Por isso aparece como técnica de persistência e de execução no MITRE ATT&CK, catalogada como T1053.005 (Scheduled Task). A tarefa maliciosa costuma ter nome parecido com o de algo do sistema, e o que ela executa é um powershell.exe com argumentos longos, um script em %APPDATA% ou um binário numa pasta temporária.
O cmdlet Get-ScheduledTask faz parte do módulo ScheduledTasks, disponível desde o Windows 8 e o Windows Server 2012, segundo a documentação da Microsoft. Ele devolve a definição das tarefas registradas no computador, e a execução (último resultado, próxima hora) vem de outro cmdlet, o Get-ScheduledTaskInfo.
Como listar todas as tarefas agendadas pelo PowerShell?
Como ver as tarefas agendadas do Windows com PowerShell?
Rode Get-ScheduledTask em um PowerShell elevado. Ele lista nome, caminho, estado e descrição de todas as tarefas registradas. Sem filtro, o resultado passa de uma centena de linhas, quase todas da própria Microsoft.
# Todas as tarefas, ordenadas por estado
Get-ScheduledTask | Sort-Object State | Format-Table TaskName, TaskPath, State -AutoSize
# Só as que estão habilitadas e prontas para rodar
Get-ScheduledTask | Where-Object State -eq 'Ready'
O campo TaskPath é o que mais ajuda. As tarefas nativas ficam em \Microsoft\Windows\.... O que sobra fora disso é software de terceiros (Chrome, Office, drivers) ou algo que merece olhar.
# Tarefas fora da pasta da Microsoft
Get-ScheduledTask |
Where-Object { $_.TaskPath -notlike '\Microsoft\*' } |
Format-Table TaskName, TaskPath, State -AutoSize
Atenção: um atacante pode registrar a tarefa dentro de \Microsoft\Windows\ justamente para se misturar. Filtrar por caminho é um primeiro corte, não uma garantia.
O que cada tarefa executa de verdade
O nome da tarefa não diz nada. O que interessa é a ação: qual programa roda e com quais argumentos. Essa informação está na propriedade Actions, e a conta usada está em Principal.
Get-ScheduledTask | ForEach-Object {
[PSCustomObject]@{
Tarefa = $_.TaskName
Caminho = $_.TaskPath
Executa = ($_.Actions | ForEach-Object { "$($_.Execute) $($_.Arguments)" }) -join ' | '
Conta = $_.Principal.UserId
Elevacao = $_.Principal.RunLevel
}
} | Where-Object { $_.Caminho -notlike '\Microsoft\*' } | Format-List
Preste atenção nestes sinais na coluna Executa:
- powershell.exe ou cmd.exe com argumentos codificados (
-enc,-EncodedCommand) ou com-WindowStyle Hidden; - binários em pastas graváveis pelo usuário:
%TEMP%,%APPDATA%,C:\Users\Public,C:\ProgramData; - mshta.exe, wscript.exe, regsvr32.exe, rundll32.exe chamando algo remoto ou um arquivo estranho;
- conta SYSTEM com
RunLevelHighestnuma tarefa que você não reconhece; - nome que imita o sistema com um erro sutil, ou descrição vazia.
Quando a tarefa rodou pela última vez?
Combine com Get-ScheduledTaskInfo para ver o histórico recente. A documentação do cmdlet descreve que ele traz as informações da última execução, e o resultado aceita pipeline direto do Get-ScheduledTask.
Get-ScheduledTask |
Where-Object { $_.TaskPath -notlike '\Microsoft\*' } |
Get-ScheduledTaskInfo |
Select-Object TaskName, LastRunTime, LastTaskResult, NextRunTime |
Sort-Object LastRunTime -Descending
Um LastTaskResult igual a 0 significa que a última execução terminou sem erro. Uma tarefa desconhecida que roda com sucesso a cada hora é mais suspeita do que uma que nunca rodou.
Como saber quando uma tarefa foi criada?
O Windows registra a criação de tarefas no Log de Segurança com o Event ID 4698, desde que a auditoria de "Outros Eventos de Acesso a Objetos" esteja ligada. Sem essa política, não há registro e você só descobre a tarefa olhando a lista.
# Criação de tarefas agendadas nos últimos 30 dias
Get-WinEvent -FilterHashtable @{
LogName = 'Security'
Id = 4698
StartTime = (Get-Date).AddDays(-30)
} | Select-Object TimeCreated, Message
O campo de mensagem traz o nome da tarefa, a conta que a criou e o XML completo com a ação. Se esse comando não retornar nada, vale ativar a auditoria. O post sobre auditoria de logs de segurança com PowerShell mostra como, e o de Get-WinEvent explica os filtros usados acima.
Desativar, exportar e remover com segurança
Achou uma tarefa estranha? Antes de apagar, preserve a evidência. O Export-ScheduledTask devolve o XML da definição, e você guarda em arquivo:
# 1. Guardar a definição (evidência)
Export-ScheduledTask -TaskName "NomeDaTarefa" -TaskPath "\" | Out-File "$env:USERPROFILE\Desktop\tarefa-suspeita.xml"
# 2. Desativar sem apagar
Disable-ScheduledTask -TaskName "NomeDaTarefa" -TaskPath "\"
# 3. Só depois de investigar: remover
Unregister-ScheduledTask -TaskName "NomeDaTarefa" -TaskPath "\" -Confirm:$false
Apagar a tarefa não resolve o problema se o arquivo que ela executa continua no disco, nem se existem outras formas de persistência. Calcule o hash do binário com o Get-FileHash, consulte no VirusTotal e revise também os serviços com o Get-Service. Se a máquina for importante, trate como incidente: isole da rede e troque as senhas usadas nela.
Checklist de auditoria rápida
- Liste as tarefas fora de
\Microsoft\e identifique cada uma. - Confira o
Executee osArgumentsde todas, inclusive das que estão dentro da pasta da Microsoft. - Desconfie de qualquer ação apontando para pasta gravável pelo usuário.
- Cruze com o
LastRunTimee com o Event ID 4698. - Exporte o XML, desative, investigue e só então remova.
Conclusão
Tarefa agendada é persistência barata, silenciosa e legítima aos olhos do sistema, e é justamente por isso que vale revisar a lista de vez em quando. Três cmdlets (Get-ScheduledTask, Get-ScheduledTaskInfo e Export-ScheduledTask) cobrem a auditoria inteira. Se quiser o outro lado da moeda, criando tarefas legítimas pelo terminal, leia o guia de schtasks para agendar tarefas no Windows.




Comentários