Saltar al contenido principal

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​

  1. Respuestas a las 2 preguntas

  2. Capturas de pantalla:

    • Servicio creado
    • Tarea programada creada
    • Resultado del escáner de persistencia
  3. Informe (1-2 páginas):

    • Mecanismos de persistencia probados
    • Cómo detectarlos
    • Recomendaciones de defensa

Criterios de Evaluación​

CriterioPuntos
Persistencia mediante servicio25%
Persistencia mediante tareas30%
Persistencia mediante registro20%
Script de detección25%

Laboratorio desarrollado en el marco del curso Sistemas Operativos - MÓDULO 7