Lab 7.2: Mecanismos de Persistencia en Windows
Objetivos de Aprendizaje
Al final de este laboratorio, usted será capaz de:
- Comprender los mecanismos de persistencia en Windows
- Crear y eliminar servicios de prueba
- Gestionar tareas programadas
- Detectar persistencias maliciosas
Duración Estimada
50 minutos
Requisitos Previos
- Lab 7.1 completado
- VM Windows 10/11
- Derechos de administrador
Contexto Profesional
La persistencia es una técnica utilizada para:
- Legítimamente: Iniciar servicios automáticamente
- Maliciosamente: Mantener el acceso después de un reinicio
Comprender estos mecanismos es esencial para la defensa.
ADVERTENCIA
Este laboratorio enseña técnicas de persistencia con fines defensivos.
- Ejecute únicamente en VMs de prueba
- Elimine todas las creaciones al finalizar el laboratorio
Parte 1: Persistencia mediante Servicios
Paso 1.1: Crear un servicio de prueba
# Crear un script de servicio
$scriptContent = @'
# Servicio de prueba - NO HACE NADA
# Este script simula un servicio para el laboratorio
Write-Output "Servicio de prueba iniciado" | Out-File C:\Temp\service_log.txt -Append
while ($true) {
Start-Sleep -Seconds 60
}
'@
# Guardar el script
New-Item -Path "C:\Temp" -ItemType Directory -Force | Out-Null
$scriptContent | Out-File "C:\Temp\test_service.ps1" -Encoding UTF8
Write-Host "Script creado: C:\Temp\test_service.ps1" -ForegroundColor Green
Paso 1.2: Registrar el servicio
# Crear el servicio con NSSM o sc.exe
# Para este laboratorio, usamos sc.exe con cmd.exe
# Método 1: Servicio simple con cmd.exe (para demo)
sc.exe create "LabTestService" `
binPath= "cmd.exe /k echo Servicio de prueba" `
DisplayName= "Lab Test Service" `
start= manual
# Verificar
Get-Service "LabTestService"
sc.exe qc "LabTestService"
Paso 1.3: Modificar el servicio
# Cambiar el tipo de inicio
sc.exe config "LabTestService" start= auto
# Agregar una descripción
sc.exe description "LabTestService" "Servicio creado para el lab 7.2"
# Verificar los cambios
Get-Service "LabTestService" | Select-Object *
Paso 1.4: Detectar nuestro servicio
# Nuestro servicio debería aparecer como sospechoso
Get-WmiObject Win32_Service | Where-Object {
$_.Name -eq "LabTestService"
} | Select-Object Name, DisplayName, PathName, StartMode, State
Pregunta 1: ¿Por qué este servicio podría considerarse sospechoso?
Paso 1.5: Eliminar el servicio
# Detener y eliminar
Stop-Service "LabTestService" -Force -ErrorAction SilentlyContinue
sc.exe delete "LabTestService"
# Verificar la eliminación
Get-Service "LabTestService" -ErrorAction SilentlyContinue
Parte 2: Persistencia mediante Tareas Programadas
Paso 2.1: Crear una tarea simple
# Crear una tarea que se ejecute al inicio
$action = New-ScheduledTaskAction `
-Execute "cmd.exe" `
-Argument "/c echo Tarea de prueba > 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 "Tarea creada para el lab 7.2"
Write-Host "Tarea creada: LabTestTask" -ForegroundColor Green
Paso 2.2: Verificar la tarea
# Ver la tarea
Get-ScheduledTask -TaskName "LabTestTask"
# Detalles completos
Get-ScheduledTask -TaskName "LabTestTask" |
Select-Object TaskName, State, @{N='Trigger';E={$_.Triggers.AtStartup}},
@{N='Action';E={$_.Actions.Execute}}
# Información de ejecución
Get-ScheduledTaskInfo -TaskName "LabTestTask"
Paso 2.3: Crear una tarea más realista
# Tarea que imita un servicio legítimo (para demo de detección)
$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 "Actualización de Windows (FALSO - LAB)"
Write-Host "Tarea sospechosa creada para demo" -ForegroundColor Yellow
Paso 2.4: Ejecutar la detección
# Script de detección de tareas sospechosas
$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"
}
# Nuestras tareas de prueba
if ($task.TaskName -match "^Lab" -or $task.TaskName -eq "WindowsUpdateHelper") {
$isSuspect = $true
$reasons += "Tarea de prueba/sospechosa"
}
if ($isSuspect) {
$suspectTasks += [PSCustomObject]@{
TaskName = $task.TaskName
Execute = $action.Execute
Arguments = $action.Arguments
Reasons = ($reasons -join ", ")
}
}
}
}
Write-Host "`n=== TAREAS SOSPECHOSAS DETECTADAS ===" -ForegroundColor Cyan
$suspectTasks | Format-Table -AutoSize
Pregunta 2: ¿Qué tareas han sido detectadas como sospechosas?
Paso 2.5: Eliminar las tareas
# Eliminar nuestras tareas de prueba
Unregister-ScheduledTask -TaskName "LabTestTask" -Confirm:$false
Unregister-ScheduledTask -TaskName "WindowsUpdateHelper" -Confirm:$false
Write-Host "Tareas eliminadas" -ForegroundColor Green
Parte 3: Persistencia mediante Registro
Paso 3.1: Claves Run (auto-inicio)
Las claves Run ejecutan programas al iniciar sesión:
# Ver las claves Run actuales
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
Paso 3.2: Agregar una entrada de prueba
# Agregar una entrada Run (usuario actual)
Set-ItemProperty `
-Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" `
-Name "LabTestRun" `
-Value "cmd.exe /c echo Test > C:\Temp\run_test.txt"
Write-Host "Entrada Run agregada" -ForegroundColor Green
# Verificar
Get-ItemProperty "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" |
Select-Object LabTestRun
Paso 3.3: Detectar entradas sospechosas
# Script de detección de claves Run sospechosas
$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ÁLISIS DE CLAVES 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 sospechosos
$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 " [SOSPECHOSO] $($_.Name): $value" -ForegroundColor Red
} else {
Write-Host " [OK] $($_.Name): $value" -ForegroundColor Green
}
}
}
}
Paso 3.4: Eliminar la entrada de prueba
Remove-ItemProperty `
-Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" `
-Name "LabTestRun"
Write-Host "Entrada Run eliminada" -ForegroundColor Green
Parte 4: Script de Detección Global
Paso 4.1: Escaneo completo de persistencia
# Script de detección de persistencia completo
Write-Host @"
================================================================================
ESCÁNER DE PERSISTENCIA WINDOWS
================================================================================
"@ -ForegroundColor Cyan
$findings = @()
# 1. Servicios sospechosos
Write-Host "`n[1/3] Análisis de servicios..." -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 = "Medio"
}
}
# 2. Tareas programadas sospechosas
Write-Host "[2/3] Análisis de tareas programadas..." -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. Claves Run
Write-Host "[3/3] Análisis de claves 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"
}
}
}
}
# Reporte
Write-Host "`n================================================================================`n" -ForegroundColor Cyan
if ($findings.Count -eq 0) {
Write-Host "[OK] No se detectó persistencia sospechosa" -ForegroundColor Green
} else {
Write-Host "[!] $($findings.Count) persistencia(s) sospechosa(s) detectada(s):" -ForegroundColor Red
$findings | Format-Table -AutoSize
}
Write-Host "================================================================================" -ForegroundColor Cyan
Parte 5: Limpieza
Paso 5.1: Verificación y limpieza final
# Verificar que no quede nada
Write-Host "=== VERIFICACIÓN DE LIMPIEZA ===" -ForegroundColor Cyan
# Servicios
$testService = Get-Service "LabTestService" -ErrorAction SilentlyContinue
if ($testService) {
Write-Host "Servicio LabTestService aún presente - eliminando..." -ForegroundColor Yellow
sc.exe delete "LabTestService"
}
# Tareas
$testTasks = Get-ScheduledTask | Where-Object {$_.TaskName -match "^Lab|WindowsUpdateHelper"}
foreach ($task in $testTasks) {
Write-Host "Tarea $($task.TaskName) aún presente - eliminando..." -ForegroundColor Yellow
Unregister-ScheduledTask -TaskName $task.TaskName -Confirm:$false
}
# Claves Run
$runKey = Get-ItemProperty "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" -Name "LabTestRun" -ErrorAction SilentlyContinue
if ($runKey) {
Write-Host "Clave Run LabTestRun aún presente - eliminando..." -ForegroundColor Yellow
Remove-ItemProperty "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" -Name "LabTestRun"
}
# Archivos
if (Test-Path "C:\Temp\test_service.ps1") {
Remove-Item "C:\Temp\test_service.ps1" -Force
}
Write-Host "`n¡Limpieza terminada!" -ForegroundColor Green
Entregables
-
Respuestas a las 2 preguntas
-
Capturas de pantalla:
- Servicio creado
- Tarea programada creada
- Resultado del escáner de persistencia
-
Informe (1-2 páginas):
- Mecanismos de persistencia probados
- Cómo detectarlos
- Recomendaciones de defensa
Criterios de Evaluación
| Criterio | Puntos |
|---|---|
| Persistencia mediante servicio | 25% |
| Persistencia mediante tareas | 30% |
| Persistencia mediante registro | 20% |
| Script de detección | 25% |
Laboratorio desarrollado en el marco del curso Sistemas Operativos - MÓDULO 7