Lab 10.1: Named Pipes Windows
Objetivos de Aprendizaje
Al final de este laboratorio, usted será capaz de:
- Comprender el mecanismo de los named pipes en Windows
- Crear un servidor y cliente de pipe en PowerShell
- Enumerar los pipes existentes en un sistema
- Comprender los riesgos de impersonation a través de pipes
- Detectar ataques que utilizan pipes
Duración Estimada
45 minutos
Prerrequisitos
- VM Windows 10/11
- Conocimientos básicos de PowerShell
- Derechos de administrador
Contexto Profesional
Los named pipes son utilizados por:
- Aplicaciones Windows para comunicación local
- Servicios para recibir comandos
- Malware para comunicación sigilosa (Cobalt Strike, etc.)
- Técnicas de escalada de privilegios (ataques Potato)
Parte 1: Enumeración de Named Pipes
Paso 1.1: Listar los pipes activos
PowerShell:
# Método 1: Get-ChildItem
Get-ChildItem \\.\pipe\ | Select-Object Name
# Método 2: .NET
[System.IO.Directory]::GetFiles("\\.\pipe\")
Preguntas:
- ¿Cuántos pipes están activos en su sistema?
- ¿Reconoce algunos nombres de pipes?
Paso 1.2: Identificar los pipes del sistema
Los siguientes pipes son normales en Windows:
| Pipe | Servicio |
|---|---|
| lsarpc | Local Security Authority |
| samr | Security Account Manager |
| netlogon | Autenticación de dominio |
| srvsvc | Servicio de servidor |
| wkssvc | Servicio de estación de trabajo |
| spoolss | Servicio de impresión |
Compare su lista con estos pipes estándar.
Paso 1.3: Usar PipeList (Sysinternals)
Si está disponible:
pipelist.exe /accepteula
Preguntas: 3. ¿PipeList muestra más información que PowerShell? 4. ¿Puede ver qué proceso utiliza cada pipe?
Parte 2: Creación de un Servidor Pipe
Paso 2.1: Comprender el flujo
[Servidor Pipe] [Cliente Pipe]
| |
|<-- 1. Crea el pipe -->|
| |
|<-- 2. Espera conexión |
| |
|<-- 3. Cliente se conecta
| |
|<-- 4. Intercambio de datos -->|
| |
|<-- 5. Cierre |
Paso 2.2: Script servidor
Cree un archivo serveur_pipe.ps1:
# Servidor de Named Pipe
$pipeName = "TestLabPipe"
Write-Host "=== SERVIDOR NAMED PIPE ===" -ForegroundColor Cyan
Write-Host "Creando el pipe: \\.\pipe\$pipeName" -ForegroundColor Yellow
# Crear el pipe servidor
Add-Type -AssemblyName System.Core
$pipe = New-Object System.IO.Pipes.NamedPipeServerStream(
$pipeName,
[System.IO.Pipes.PipeDirection]::InOut
)
Write-Host "Esperando una conexión de cliente..." -ForegroundColor Yellow
$pipe.WaitForConnection()
Write-Host "¡Cliente conectado!" -ForegroundColor Green
# Crear los flujos de lectura/escritura
$reader = New-Object System.IO.StreamReader($pipe)
$writer = New-Object System.IO.StreamWriter($pipe)
$writer.AutoFlush = $true
# Bucle de comunicación
Write-Host "Listo para recibir mensajes (escriba 'exit' para salir)" -ForegroundColor Yellow
Write-Host ""
while ($true) {
# Leer el mensaje del cliente
$message = $reader.ReadLine()
if ($message -eq "exit" -or $message -eq $null) {
Write-Host "Cerrando la conexión..." -ForegroundColor Red
break
}
Write-Host "Recibido: $message" -ForegroundColor White
# Enviar una respuesta
$response = "Echo: $message"
$writer.WriteLine($response)
Write-Host "Enviado: $response" -ForegroundColor Gray
}
# Limpieza
$reader.Close()
$writer.Close()
$pipe.Close()
Write-Host "Pipe cerrado." -ForegroundColor Red
Paso 2.3: Ejecutar el servidor
.\serveur_pipe.ps1
El servidor ahora está esperando una conexión.
Parte 3: Creación de un Cliente Pipe
Paso 3.1: Script cliente
Cree un archivo client_pipe.ps1:
# Cliente de Named Pipe
$pipeName = "TestLabPipe"
$serverName = "." # Local
Write-Host "=== CLIENTE NAMED PIPE ===" -ForegroundColor Cyan
Write-Host "Conectando a: \\$serverName\pipe\$pipeName" -ForegroundColor Yellow
# Crear el pipe cliente
Add-Type -AssemblyName System.Core
$pipe = New-Object System.IO.Pipes.NamedPipeClientStream(
$serverName,
$pipeName,
[System.IO.Pipes.PipeDirection]::InOut
)
try {
# Conectarse con timeout de 5 segundos
$pipe.Connect(5000)
Write-Host "¡Conectado al servidor!" -ForegroundColor Green
# Crear los flujos
$reader = New-Object System.IO.StreamReader($pipe)
$writer = New-Object System.IO.StreamWriter($pipe)
$writer.AutoFlush = $true
# Bucle de envío
Write-Host "Escriba sus mensajes (escriba 'exit' para salir):" -ForegroundColor Yellow
Write-Host ""
while ($true) {
$message = Read-Host ">"
if ($message -eq "exit") {
$writer.WriteLine("exit")
break
}
# Enviar el mensaje
$writer.WriteLine($message)
# Leer la respuesta
$response = $reader.ReadLine()
Write-Host "Respuesta: $response" -ForegroundColor Gray
}
# Limpieza
$reader.Close()
$writer.Close()
$pipe.Close()
} catch {
Write-Host "Error: $_" -ForegroundColor Red
}
Write-Host "Conexión cerrada." -ForegroundColor Red
Paso 3.2: Probar la comunicación
-
Terminal 1: Ejecute el servidor
.\serveur_pipe.ps1 -
Terminal 2: Ejecute el cliente
.\client_pipe.ps1 -
Envíe mensajes desde el cliente
Preguntas: 5. ¿Funciona la comunicación? 6. Verifique que el pipe aparezca en la lista mientras está activo
Parte 4: Análisis de Seguridad
Paso 4.1: Permisos sobre los pipes
Por defecto, los pipes heredan los permisos del proceso creador.
Verificar los permisos (requiere accesschk de Sysinternals):
accesschk.exe -accepteula \\.\pipe\TestLabPipe
Paso 4.2: Riesgo de Impersonation
Concepto: Un servidor pipe puede "impersonar" al cliente que se conecta, es decir, usar su token de seguridad.
Por qué es peligroso:
- Si un usuario privilegiado se conecta a un pipe malicioso
- El servidor puede robar su token
- Y ejecutar comandos con sus privilegios
Paso 4.3: Demostración de impersonation (solo lectura)
# Este código muestra cómo un servidor PODRÍA impersonar a un cliente
# NO USAR EN PRODUCCIÓN - SOLO CON FINES EDUCATIVOS
# En el servidor, después de WaitForConnection():
# $pipe.RunAsClient({
# whoami # Mostraría la identidad del cliente
# })
Preguntas: 7. ¿Por qué es peligrosa la impersonation? 8. ¿Cómo podría un atacante explotar esto?
Parte 5: Detección y Defensa
Paso 5.1: Detectar pipes sospechosos
# Script para detectar pipes inusuales
$knownPipes = @(
"lsarpc", "samr", "netlogon", "srvsvc", "wkssvc",
"spoolss", "browser", "eventlog", "ntsvcs"
)
$currentPipes = Get-ChildItem \\.\pipe\ | Select-Object -ExpandProperty Name
$suspiciousPipes = $currentPipes | Where-Object {
$pipe = $_
-not ($knownPipes | Where-Object { $pipe -like "*$_*" })
}
if ($suspiciousPipes) {
Write-Host "Pipes potencialmente sospechosos:" -ForegroundColor Yellow
$suspiciousPipes | ForEach-Object {
Write-Host " - $_" -ForegroundColor Red
}
} else {
Write-Host "No se detectaron pipes sospechosos." -ForegroundColor Green
}
Paso 5.2: Monitoreo con Sysmon
Si Sysmon está instalado:
- Event ID 17: Pipe Created
- Event ID 18: Pipe Connected
# Ver eventos recientes de pipes
Get-WinEvent -FilterHashtable @{
LogName = 'Microsoft-Windows-Sysmon/Operational'
ID = 17, 18
} -MaxEvents 20 | Format-Table TimeCreated, Message -Wrap
Preguntas: 9. ¿Su pipe de prueba fue registrado? 10. ¿Qué información captura Sysmon?
Entregables
-
Capturas de pantalla:
- Lista de pipes de su sistema
- Servidor y cliente en comunicación
- Script de detección ejecutado
-
Respuestas a las 10 preguntas
-
Análisis: (1 página)
- Explique cómo funcionan los named pipes
- Describa los riesgos de seguridad asociados
- Proponga medidas de detección
Criterios de Evaluación
| Criterio | Puntos |
|---|---|
| Enumeración de pipes | 20% |
| Servidor/cliente funcional | 30% |
| Análisis de seguridad | 25% |
| Script de detección | 25% |
Comandos de Referencia
# Enumeración
Get-ChildItem \\.\pipe\
[System.IO.Directory]::GetFiles("\\.\pipe\")
# Sysinternals
pipelist.exe /accepteula
accesschk.exe \\.\pipe\NomPipe
# Sysmon
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Sysmon/Operational';ID=17,18}
Solución de Problemas
El pipe no se crea
- Verifique que el nombre sea único
- Ejecute como administrador
El cliente no puede conectarse
- Verifique que el servidor esté iniciado primero
- Verifique el nombre del pipe (sensible a mayúsculas/minúsculas)
- Verifique el firewall
Timeout de conexión
- El servidor debe estar esperando ANTES de que el cliente se conecte
- Aumente el timeout si es necesario
Lab desarrollado en el marco del curso Sistemas Operativos - MÓDULO 10