Lab 7.2: Mecanismos de Persistência no Windows
Objetivos de Aprendizagem
Ao final deste laboratório, você será capaz de:
- Compreender os mecanismos de persistência no Windows
- Criar e remover serviços de teste
- Gerenciar tarefas agendadas
- Detectar persistências maliciosas
Duração Estimada
50 minutos
Pré-requisitos
- Lab 7.1 concluído
- VM Windows 10/11
- Permissões de administrador
Contexto Profissional
A persistência é uma técnica utilizada para:
- Legitimamente: Iniciar serviços automaticamente
- Maliciosamente: Manter o acesso após uma reinicialização
Compreender esses mecanismos é essencial para a defesa.
AVISO
Este laboratório ensina técnicas de persistência para fins defensivos.
- Execute apenas em VMs de teste
- Limpe todas as criações ao final do laboratório
Parte 1: Persistência via Serviços
Etapa 1.1: Criar um serviço de teste
# Criar um script de serviço
$scriptContent = @'
# Serviço de teste - NÃO FAZ NADA
# Este script simula um serviço para o lab
Write-Output "Serviço de teste iniciado" | Out-File C:\Temp\service_log.txt -Append
while ($true) {
Start-Sleep -Seconds 60
}
'@
# Salvar o script
New-Item -Path "C:\Temp" -ItemType Directory -Force | Out-Null
$scriptContent | Out-File "C:\Temp\test_service.ps1" -Encoding UTF8
Write-Host "Script criado: C:\Temp\test_service.ps1" -ForegroundColor Green
Etapa 1.2: Registrar o serviço
# Criar o serviço com NSSM ou sc.exe
# Para este lab, usamos sc.exe com cmd.exe
# Método 1: Serviço simples com cmd.exe (para demonstração)
sc.exe create "LabTestService" `
binPath= "cmd.exe /k echo Serviço de teste" `
DisplayName= "Lab Test Service" `
start= manual
# Verificar
Get-Service "LabTestService"
sc.exe qc "LabTestService"
Etapa 1.3: Modificar o serviço
# Alterar o tipo de inicialização
sc.exe config "LabTestService" start= auto
# Adicionar uma descrição
sc.exe description "LabTestService" "Serviço criado para o lab 7.2"
# Verificar as alterações
Get-Service "LabTestService" | Select-Object *
Etapa 1.4: Detectar nosso serviço
# Nosso serviço deve aparecer como suspeito
Get-WmiObject Win32_Service | Where-Object {
$_.Name -eq "LabTestService"
} | Select-Object Name, DisplayName, PathName, StartMode, State
Pergunta 1: Por que este serviço pode ser considerado suspeito?
Etapa 1.5: Remover o serviço
# Parar e remover
Stop-Service "LabTestService" -Force -ErrorAction SilentlyContinue
sc.exe delete "LabTestService"
# Verificar a remoção
Get-Service "LabTestService" -ErrorAction SilentlyContinue
Parte 2: Persistência via Tarefas Agendadas
Etapa 2.1: Criar uma tarefa simples
# Criar uma tarefa que executa na inicialização
$action = New-ScheduledTaskAction `
-Execute "cmd.exe" `
-Argument "/c echo Tarefa de teste > C:\Temp\task_log.txt"
$trigger = New-ScheduledTaskTrigger -AtStartup
$principal = New-ScheduledTaskPrincipal `
-UserId "SYSTEM" `
-RunLevel Highest
Register-ScheduledTask `
-TaskName "LabTestTask" `
-Action $action `
-Trigger $trigger `
-Principal $principal `
-Description "Tarefa criada para o lab 7.2"
Write-Host "Tarefa criada: LabTestTask" -ForegroundColor Green
Etapa 2.2: Verificar a tarefa
# Ver a tarefa
Get-ScheduledTask -TaskName "LabTestTask"
# Detalhes completos
Get-ScheduledTask -TaskName "LabTestTask" |
Select-Object TaskName, State, @{N='Trigger';E={$_.Triggers.AtStartup}},
@{N='Action';E={$_.Actions.Execute}}
# Informações de execução
Get-ScheduledTaskInfo -TaskName "LabTestTask"
Etapa 2.3: Criar uma tarefa mais realista
# Tarefa que imita um serviço legítimo (para demonstração de detecção)
$action = New-ScheduledTaskAction `
-Execute "powershell.exe" `
-Argument "-WindowStyle Hidden -Command Start-Sleep 3600"
$trigger = New-ScheduledTaskTrigger -AtLogOn
Register-ScheduledTask `
-TaskName "WindowsUpdateHelper" `
-Action $action `
-Trigger $trigger `
-Description "Atualização do Windows (FALSO - LAB)"
Write-Host "Tarefa suspeita criada para demonstração" -ForegroundColor Yellow
Etapa 2.4: Executar a detecção
# Script de detecção de tarefas suspeitas
$suspectTasks = @()
Get-ScheduledTask | Where-Object {
$_.TaskPath -notlike "\Microsoft\*"
} | ForEach-Object {
$task = $_
foreach ($action in $task.Actions) {
$isSuspect = $false
$reasons = @()
# PowerShell oculto
if ($action.Arguments -match "-WindowStyle\s+Hidden") {
$isSuspect = $true
$reasons += "PowerShell oculto"
}
# Comandos codificados
if ($action.Arguments -match "-[Ee]ncoded") {
$isSuspect = $true
$reasons += "Comando codificado"
}
# Nossas tarefas de teste
if ($task.TaskName -match "^Lab" -or $task.TaskName -eq "WindowsUpdateHelper") {
$isSuspect = $true
$reasons += "Tarefa de teste/suspeita"
}
if ($isSuspect) {
$suspectTasks += [PSCustomObject]@{
TaskName = $task.TaskName
Execute = $action.Execute
Arguments = $action.Arguments
Reasons = ($reasons -join ", ")
}
}
}
}
Write-Host "`n=== TAREFAS SUSPEITAS DETECTADAS ===" -ForegroundColor Cyan
$suspectTasks | Format-Table -AutoSize
Pergunta 2: Quais tarefas foram detectadas como suspeitas?
Etapa 2.5: Remover as tarefas
# Remover nossas tarefas de teste
Unregister-ScheduledTask -TaskName "LabTestTask" -Confirm:$false
Unregister-ScheduledTask -TaskName "WindowsUpdateHelper" -Confirm:$false
Write-Host "Tarefas removidas" -ForegroundColor Green
Parte 3: Persistência via Registro
Etapa 3.1: Chaves Run (auto inicialização)
As chaves Run executam programas ao fazer login:
# Ver as chaves Run atuais
Write-Host "=== HKCU Run ===" -ForegroundColor Cyan
Get-ItemProperty "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" -ErrorAction SilentlyContinue
Write-Host "`n=== HKLM Run ===" -ForegroundColor Cyan
Get-ItemProperty "HKLM:\Software\Microsoft\Windows\CurrentVersion\Run" -ErrorAction SilentlyContinue
Etapa 3.2: Adicionar uma entrada de teste
# Adicionar uma entrada Run (usuário atual)
Set-ItemProperty `
-Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" `
-Name "LabTestRun" `
-Value "cmd.exe /c echo Teste > C:\Temp\run_test.txt"
Write-Host "Entrada Run adicionada" -ForegroundColor Green
# Verificar
Get-ItemProperty "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" |
Select-Object LabTestRun
Etapa 3.3: Detectar entradas suspeitas
# Script de detecção de chaves Run suspeitas
$runKeys = @(
"HKCU:\Software\Microsoft\Windows\CurrentVersion\Run",
"HKCU:\Software\Microsoft\Windows\CurrentVersion\RunOnce",
"HKLM:\Software\Microsoft\Windows\CurrentVersion\Run",
"HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce"
)
Write-Host "=== ANÁLISE DAS CHAVES RUN ===" -ForegroundColor Cyan
foreach ($key in $runKeys) {
if (Test-Path $key) {
Write-Host "`n$key" -ForegroundColor Yellow
$props = Get-ItemProperty $key -ErrorAction SilentlyContinue
$props.PSObject.Properties | Where-Object {
$_.Name -notmatch "^PS"
} | ForEach-Object {
$value = $_.Value
# Detectar suspeitos
$suspect = $false
if ($value -match "\\Temp\\" -or
$value -match "\\AppData\\Local\\" -or
$value -match "-[Ee]ncoded" -or
$_.Name -match "^Lab") {
$suspect = $true
}
if ($suspect) {
Write-Host " [SUSPEITO] $($_.Name): $value" -ForegroundColor Red
} else {
Write-Host " [OK] $($_.Name): $value" -ForegroundColor Green
}
}
}
}
Etapa 3.4: Remover a entrada de teste
Remove-ItemProperty `
-Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" `
-Name "LabTestRun"
Write-Host "Entrada Run removida" -ForegroundColor Green
Parte 4: Script de Detecção Global
Etapa 4.1: Scanner completo de persistência
# Script de detecção de persistência completo
Write-Host @"
================================================================================
SCANNER DE PERSISTÊNCIA WINDOWS
================================================================================
"@ -ForegroundColor Cyan
$findings = @()
# 1. Serviços suspeitos
Write-Host "`n[1/3] Análise dos serviços..." -ForegroundColor Yellow
Get-WmiObject Win32_Service | Where-Object {
$_.PathName -match "\\(Temp|AppData|Downloads)\\" -or
$_.Name -match "^(Lab|Test)"
} | ForEach-Object {
$findings += [PSCustomObject]@{
Type = "Service"
Name = $_.Name
Details = $_.PathName
Risk = "Médio"
}
}
# 2. Tarefas agendadas suspeitas
Write-Host "[2/3] Análise das tarefas agendadas..." -ForegroundColor Yellow
Get-ScheduledTask | Where-Object {
$_.TaskPath -notlike "\Microsoft\*"
} | ForEach-Object {
$task = $_
$action = $task.Actions | Select-Object -First 1
if ($action.Arguments -match "-Hidden|-[Ee]ncoded" -or
$task.TaskName -match "^(Lab|Test|WindowsUpdate[A-Z])") {
$findings += [PSCustomObject]@{
Type = "ScheduledTask"
Name = $task.TaskName
Details = "$($action.Execute) $($action.Arguments)"
Risk = "Alto"
}
}
}
# 3. Chaves Run
Write-Host "[3/3] Análise das chaves Run..." -ForegroundColor Yellow
$runKeys = @(
"HKCU:\Software\Microsoft\Windows\CurrentVersion\Run",
"HKLM:\Software\Microsoft\Windows\CurrentVersion\Run"
)
foreach ($key in $runKeys) {
if (Test-Path $key) {
$props = Get-ItemProperty $key -ErrorAction SilentlyContinue
$props.PSObject.Properties | Where-Object {
$_.Name -notmatch "^PS" -and
($_.Value -match "\\Temp\\" -or $_.Name -match "^Lab")
} | ForEach-Object {
$findings += [PSCustomObject]@{
Type = "RunKey"
Name = $_.Name
Details = $_.Value
Risk = "Alto"
}
}
}
}
# Relatório
Write-Host "`n================================================================================`n" -ForegroundColor Cyan
if ($findings.Count -eq 0) {
Write-Host "[OK] Nenhuma persistência suspeita detectada" -ForegroundColor Green
} else {
Write-Host "[!] $($findings.Count) persistência(s) suspeita(s) detectada(s):" -ForegroundColor Red
$findings | Format-Table -AutoSize
}
Write-Host "================================================================================" -ForegroundColor Cyan
Parte 5: Limpeza
Etapa 5.1: Verificação e limpeza final
# Verificar se não restou nada
Write-Host "=== VERIFICAÇÃO DE LIMPEZA ===" -ForegroundColor Cyan
# Serviços
$testService = Get-Service "LabTestService" -ErrorAction SilentlyContinue
if ($testService) {
Write-Host "Serviço LabTestService ainda presente - removendo..." -ForegroundColor Yellow
sc.exe delete "LabTestService"
}
# Tarefas
$testTasks = Get-ScheduledTask | Where-Object {$_.TaskName -match "^Lab|WindowsUpdateHelper"}
foreach ($task in $testTasks) {
Write-Host "Tarefa $($task.TaskName) ainda presente - removendo..." -ForegroundColor Yellow
Unregister-ScheduledTask -TaskName $task.TaskName -Confirm:$false
}
# Chaves Run
$runKey = Get-ItemProperty "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" -Name "LabTestRun" -ErrorAction SilentlyContinue
if ($runKey) {
Write-Host "Chave Run LabTestRun ainda presente - removendo..." -ForegroundColor Yellow
Remove-ItemProperty "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" -Name "LabTestRun"
}
# Arquivos
if (Test-Path "C:\Temp\test_service.ps1") {
Remove-Item "C:\Temp\test_service.ps1" -Force
}
Write-Host "`nLimpeza finalizada!" -ForegroundColor Green
Entregáveis
-
Respostas às 2 perguntas
-
Capturas de tela:
- Serviço criado
- Tarefa agendada criada
- Resultado do scanner de persistência
-
Relatório (1-2 páginas):
- Mecanismos de persistência testados
- Como detectá-los
- Recomendações de defesa
Critérios de Avaliação
| Critério | Pontos |
|---|---|
| Persistência via serviço | 25% |
| Persistência via tarefas | 30% |
| Persistência via registro | 20% |
| Script de detecção | 25% |
Lab desenvolvido no âmbito do curso Sistemas Operacionais - MÓDULO 7