Pular para o conteúdo principal

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​

  1. Respostas às 2 perguntas

  2. Capturas de tela:

    • Serviço criado
    • Tarefa agendada criada
    • Resultado do scanner de persistência
  3. Relatório (1-2 páginas):

    • Mecanismos de persistência testados
    • Como detectá-los
    • Recomendações de defesa

Critérios de Avaliação​

CritérioPontos
Persistência via serviço25%
Persistência via tarefas30%
Persistência via registro20%
Script de detecção25%

Lab desenvolvido no âmbito do curso Sistemas Operacionais - MÓDULO 7