PowerShell para detectar eventos USB y ejecutar acciones

Última actualización: 27/08/2025
Autor: Isaac
  • PowerShell permite detectar conexiones y desconexiones USB en tiempo real y enviarlas a un servidor central mediante una API.
  • Habilitar canales de eventos y usar WEF aporta escala corporativa y contexto forense junto a SIEM.
  • La puesta en producción combina Programador de tareas, seguridad del endpoint y endurecimiento del backend.

Monitorizar eventos USB con PowerShell

La conexión de memorias, discos y periféricos por USB puede abrir más puertas de las que parece: desde fugas de datos a infecciones por malware sin que nadie se entere. Monitorizar y registrar los dispositivos USB que entran y salen de los equipos es, por tanto, una medida clave de ciberseguridad que muchas organizaciones ya consideran básica.

La buena noticia es que el ecosistema Windows ofrece varios enfoques, desde herramientas comerciales hasta métodos nativos como PowerShell y Windows Event Forwarding (WEF). Con un diseño bien pensado se puede detectar en tiempo real, registrar, enviar a un servidor central y correlacionar eventos USB con otras señales de seguridad, todo sin fricción para el usuario.

Panorama y herramientas para rastrear dispositivos USB

En empresas reguladas (finanzas, salud…) se exige control y trazabilidad. El objetivo es identificar rápidamente dispositivos no autorizados, prevenir exfiltraciones y detectar intentos de introducir malware desde soportes extraíbles.

Si buscas algo listo para usar, hay utilidades específicas. USB Device Tracker facilita inventario y auditoría continua, guardando identificadores, tipo de dispositivo y los momentos de conexión/desconexión, además de reportes útiles para identificar patrones o amenazas.

También existen utilidades ligeras. USBDeview (NirSoft) muestra dispositivos USB presentes y pasados; no envía datos a un servidor por sí mismo, pero se integra bien con scripts para automatizar exportaciones o notificaciones en tu infraestructura.

En escenarios a gran escala, las suites de endpoint ayudan a consolidar. Microsoft Endpoint Manager, ManageEngine Endpoint Central o Ivanti permiten políticas y registros de dispositivos USB a nivel corporativo, con reportes o envío a repositorios centralizados.

Para correlación y alertas, un SIEM como Splunk o Elastic Stack puede ingerir eventos USB y disparar detecciones en tiempo real. Estas plataformas identifican comportamientos sospechosos (conexiones fuera de horario, dispositivos no permitidos, etc.) y encajan de maravilla con un pipeline que alimente datos desde PowerShell o WEF.

Soluciones para auditar USB

Detección y respuesta con PowerShell: eventos USB y envío a servidor

Si prefieres flexibilidad, un script propio en PowerShell es muy potente. Puedes detectar conexiones y desconexiones en tiempo real, enriquecer con metadatos y publicar en una API REST para tu backend.

Primero, listar dispositivos USB conectados en un momento dado. La clase Win32_DiskDrive con InterfaceType USB es un buen punto de partida, aunque conviene complementar con datos PnP para el número de serie cuando esté disponible:

# Enumerar almacenamiento USB actual
$usb = Get-CimInstance Win32_DiskDrive | Where-Object { $_.InterfaceType -eq 'USB' }
$enriquecido = foreach ($d in $usb) {
  $serial = (Get-CimInstance Win32_PhysicalMedia | Where-Object { $_.Tag -eq $d.DeviceID }).SerialNumber
  [PSCustomObject]@{
    DeviceID   = $d.DeviceID
    Model      = $d.Model
    Interface  = $d.InterfaceType
    Serial     = ($serial -replace '\s+', '').Trim()
  }
}
$enriquecido | Format-Table -AutoSize

Además del inventario, la clave es el tiempo real. PowerShell puede suscribirse a eventos del sistema para reaccionar al instante cuando se conecte o retire un dispositivo:

# Monitorizar llegada y retirada de volúmenes (EventType 2=arrive, 3=remove)
Unregister-Event -SourceIdentifier USBMonitor -ErrorAction SilentlyContinue
$null = Register-WmiEvent -Class Win32_VolumeChangeEvent -Action {
  $e = $Event.SourceEventArgs.NewEvent
  $tipo = if ($e.EventType -eq 2) { 'Insert' } elseif ($e.EventType -eq 3) { 'Remove' } else { 'Other' }
  $payload = [PSCustomObject]@{
    Hostname = $env:COMPUTERNAME
    TimeUtc  = (Get-Date).ToUniversalTime().ToString('o')
    Action   = $tipo
    Drive    = $e.DriveName
  }
  try {
    $json = $payload | ConvertTo-Json -Depth 5
    Invoke-RestMethod -Uri 'http://SERVIDOR_CENTRAL/api/usblog' -Method Post -Body $json -ContentType 'application/json'
  } catch {
    Write-Warning ("Error enviando evento USB: {0}" -f $_.Exception.Message)
  }
} -SourceIdentifier USBMonitor

Si además quieres capturar detalles del hardware del disco USB recién insertado, combina Win32_VolumeChangeEvent con un refresco de Win32_DiskDrive y cruza por volumen/letra montada según corresponda. También puedes monitorizar Win32_DeviceChangeEvent para eventos genéricos de dispositivo:

# Alternativa: evento genérico de dispositivo
Unregister-Event -SourceIdentifier USBGeneric -ErrorAction SilentlyContinue
$null = Register-WmiEvent -Class Win32_DeviceChangeEvent -Action {
  $e = $Event.SourceEventArgs.NewEvent
  $payload = [PSCustomObject]@{
    Hostname = $env:COMPUTERNAME
    TimeUtc  = (Get-Date).ToUniversalTime().ToString('o')
    EventType= $e.EventType  # 2 insert, 3 remove
  }
  try {
    Invoke-RestMethod -Uri 'http://SERVIDOR_CENTRAL/api/usblog' -Method Post -Body ($payload|ConvertTo-Json) -ContentType 'application/json'
  } catch {}
} -SourceIdentifier USBGeneric

Para un volcado puntual y envío inmediato en JSON a tu servidor, la tubería es directa. El siguiente patrón recoge discos USB actuales, los transforma a JSON y los publica en una API:

Get-CimInstance Win32_DiskDrive | Where-Object { $_.InterfaceType -eq 'USB' } |
  ForEach-Object {
    $serial = (Get-CimInstance Win32_PhysicalMedia | Where-Object { $_.Tag -eq $_.DeviceID }).SerialNumber
    [PSCustomObject]@{ DeviceID = $_.DeviceID; Model = $_.Model; Serial = ($serial -replace '\s+', '').Trim() }
  } |
  ConvertTo-Json |
  Invoke-RestMethod -Uri 'http://SERVIDOR_CENTRAL/api/usblog' -Method Post -ContentType 'application/json'

Más allá del inventario y las inserciones/retiros, Windows registra actividad de controladores de usuario vinculada a USB. Habilita el canal Microsoft-Windows-DriverFrameworks-UserMode/Operational y revisa eventos clave: conexión (p. ej., 2003, 2004, 2006, 2010) y desconexión (2102, 2105, 2106), con metadatos útiles como fabricante, modelo o rutas de instancia.

  Directivas de grupo avanzadas en Windows 11: Guía completa y práctica para administradores y usuarios avanzados

Detección en tiempo real de USB con PowerShell

API REST en Flask para centralizar los registros

Necesitas un receptor sencillo para almacenar y explotar los datos. Con Flask puedes levantar un endpoint /api/usblog que valide, guarde y deje listo el material para posteriores análisis o envío al SIEM:

from flask import Flask, request, jsonify
from datetime import datetime

app = Flask(__name__)
API_TOKEN = 'cambia-este-token-seguro'

@app.route('/api/usblog', methods=['POST'])
def log_usb():
    if request.headers.get('X-Api-Token') != API_TOKEN:
        return jsonify({'error': 'Unauthorized'}), 401
    data = request.get_json(silent=True)
    if not data:
        return jsonify({'error': 'No payload'}), 400
    line = f"{datetime.utcnow().isoformat()}Z\t{data}\n"
    with open('usb_log.txt', 'a', encoding='utf-8') as f:
        f.write(line)
    return jsonify({'status': 'ok'}), 200

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

Para ponerlo en marcha, instala Flask con pip, guarda el script (por ejemplo, server.py) y ejecútalo. A partir de ahí, tu script en PowerShell puede enviar eventos a http://IP_SERVIDOR:5000/api/usblog añadiendo un encabezado X-Api-Token si lo has activado.

Aunque aquí escribimos en un fichero para simplificar, puedes enviar a una base de datos o a tu SIEM, o incluso bifurcar: a SIEM para analítica online y a un lago de datos (Hadoop/HDInsight) para retención prolongada y análisis forense de gran volumen.

API REST para eventos USB

Puesta en producción: arranque automático, seguridad, WEF y analítica

Para que no dependa de la mano de nadie tras un reinicio, automatiza el arranque del script de PowerShell con el Programador de tareas o la carpeta Inicio, y blinda el despliegue con buenas prácticas de seguridad.

Arranque automático en Windows

Con el Programador de tareas: crea una tarea con privilegios máximos y desencadenador al iniciar sesión o al iniciar el sistema. Como acción, ejecuta powershell.exe con NoProfile y ExecutionPolicy Bypass apuntando a tu .ps1.

Si prefieres la carpeta Inicio: crea un .bat que lance el script y colócalo en %APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup. Es sencillo y funciona bien en puestos de usuario.

Ejemplo de .bat: powershell.exe -NoProfile -ExecutionPolicy Bypass -File «C:\ruta\script.ps1», ajustando la ruta a tu entorno y asegurando que el script esté firmado o provenga de origen confiable.

Recomendaciones de seguridad

Protege la API: filtra por firewall, exige token o mTLS y aplica límites de tasa. Evita exponer el endpoint más allá de la red necesaria y registra con detalle el mínimo de datos personales imprescindible.

  ¿Qué hace Ctrl + Z y cómo sacarle el máximo provecho?

Endurece el cliente: usa cuentas de servicio con privilegios mínimos, rota el token, valida TLS donde aplique y controla la ExecutionPolicy con GPO si procede; si puedes, firma el script y valida integridad.

Haz auditorías periódicas: revisa los registros del servidor y del cliente, compara patrones inusuales y cruza con políticas de control de dispositivos para detectar desvíos o accesos no autorizados.

Windows Event Forwarding (WEF) para cobertura corporativa

Cuando quieres escala y resiliencia en Windows, WEF reenvía eventos a un servidor Windows Event Collector (WEC) sin instalar agentes adicionales. Es pasivo respecto al logging: no habilita canales ni cambia auditorías; esas configuraciones deben aplicarse vía GPO.

Modelo de doble suscripción: línea base (para todos los equipos) y sospechosa (para un subconjunto tras una alerta). La de sospechosos recoge más señales para contexto forense y puede actualizarse sin tocar al resto.

Destino de datos recomendado: línea base a SEM/SIEM o SQL; sospechosa a MapReduce/HDInsight/Data Lake por volumen y menor relación señal/ruido. El SIEM correlaciona y alerta “a velocidad de máquina”; el lago retiene años y permite análisis complejos.

Escalabilidad orientativa: hasta 5.000 eventos/s en SQL/SEM; 5.000-50.000 en SEM; por encima, lago de datos. En servidores WEC estándar, la cifra práctica ronda 3.000 eventos/s en total según hardware y discos.

Push vs Pull: lo más flexible es suscripción iniciada por el origen (push) configurada por GPO. Pull exige predefinir clientes en WEC y permisos remotos de lectura de eventos (agregar la credencial al grupo Lectores de registro de eventos).

Cifrado y autenticación: en dominio, Kerberos cifra por defecto (NTLM opcional); HTTPS se usa con autenticación por certificados cuando no hay Kerberos. La autenticación es mutua en ambos casos.

Formato y frecuencia: por defecto “Rendered Text”; alternativo “Events” (binario XML) más compacto. Modos de entrega: Normal, Minimizar ancho de banda (push, lotes cada ~6h), Minimizar latencia (push, lotes ~30s) o personalizado mediante WECUTIL con DeliveryMaxItems y DeliveryMaxLatencyTime.

Límites prácticos de WEC: disco de registro EVTX (E/S), conexiones TCP simultáneas y tamaño del registro (claves persistentes por cada origen). Con grandes volúmenes, wecutil.exe es preferible a la consola del Visor de eventos.

Habilitar canales clave y dimensionar logs: DriverFrameworks-UserMode/Operational (habilitar y ampliar a ~50 MB), CAPI2/Operational (100 MB y permisos para Lectores de registro de eventos), AppLocker (EXE/DLL y MSI/Script, ~100 MB). Usa GPO con wevtutil para scriptar:

%SystemRoot%\System32\wevtutil.exe sl Microsoft-Windows-DriverFrameworks-UserMode/Operational /e:true
%SystemRoot%\System32\wevtutil.exe sl "Microsoft-Windows-DriverFrameworks-UserMode/Operational" /ms:52432896
%SystemRoot%\System32\wevtutil.exe sl Microsoft-Windows-CAPI2/Operational /e:true
%SystemRoot%\System32\wevtutil.exe sl Microsoft-Windows-CAPI2/Operational /ms:102432768
%SystemRoot%\System32\wevtutil.exe sl Microsoft-Windows-CAPI2/Operational /ca:"O:BAG:SYD:(A;;0x7;;;BA)(A;;0x2;;;AU)(A;;0x1;;;S-1-5-32-573)"
%SystemRoot%\System32\wevtutil.exe sl "Microsoft-Windows-AppLocker/EXE and DLL" /ms:102432768

Eventos relevantes para USB y actividad de dispositivo: DriverFrameworks-UserMode: 2003, 2004, 2006, 2010, 2100, 2101, 2105, 2106 y 2102 (desconexión). En el canal de Seguridad y Sistema, amplía auditoría para creación de procesos (4688), cambios de registro (4657), sesiones RDP (4778/4779), recursos compartidos (5140, 5142, 5144), tiempo del sistema (4616), inicios/cierres (12/13/1074), y otros recogidos en suscripciones de línea base y sospechosa.

  Cómo proteger con contraseña la Papelera de reciclaje en Windows paso a paso

Suscripciones WEF predefinidas: “línea base” con eventos de seguridad, AppLocker, Sysmon/Operational (si aplica), SMBClient/Operational, Error Reporting, TaskScheduler/Operational, etc.; y “sospechosa” con red (logon tipo 3), DNS Client/Operational (3008, filtrando vacíos), CAPI2 (11/70/90), PowerShell/Operational (4103-4106), DriverFrameworks-UserMode/Operational (2004) y más. Ajusta “leer eventos existentes” a true en la de sospechosos para barrer histórico.

Opciones avanzadas: forzar formato “Events” con WECUTIL para doblar capacidad y personalizar latencia/tamaño de lote:

wecutil ss "NombreSuscripcion" /cf:Events
wecutil ss "NombreSuscripcion" /cm:Custom
wecutil ss "NombreSuscripcion" /dmi:1
wecutil ss "NombreSuscripcion" /dmlt:10

Registro de PowerShell y análisis forense

PowerShell desde la v5.0 activa el registro de bloques de script (4104) por defecto, con fragmentación en múltiples eventos cuando el contenido es grande. Esto permite reconstruir scripts ejecutados, clave en respuesta a incidentes.

Para reconstrucciones, filtra por ScriptBlock ID y ordena por secuencia para concatenar el contenido original, incluso si solo recuperas parte por rotación de logs:

# Extraer eventos 4104 con un ScriptBlockID concreto
$evts = Get-WinEvent -FilterHashtable @{ Path='C:\Ruta\Microsoft-Windows-PowerShell%4Operational.evtx'; ProviderName='Microsoft-Windows-PowerShell'; Id=4104 } |
        Where-Object { $_.Message -like '*51baf005-40a5-4878-ab90-5ecc51cab9af*' }
$sorted = $evts | Sort-Object { $_.Properties[0].Value }
$sorted | Select-Object TimeCreated, ActivityId, Id, Message
# Unir el contenido del script si tuvieras todos los segmentos
# ($sorted | ForEach-Object { $_.Properties[2].Value }) -join '' | Out-File script_reconstruido.ps1 -Encoding UTF8

Regla de oro: aumenta tamaños de logs y habilita canales que no vienen activos para evitar perder artefactos por rotación. En entornos modernos, incrementar canales y tamaños de EVTX no suele impactar rendimiento de forma apreciable.

ADAudit Plus y otras integraciones

Para una visión centrada en servidores de archivos, ADAudit Plus incluye reportes de USB Storage Auditing con detalles de “file read”, “file modified”, “copy/paste” y “removable device plug-in”. También ofrece búsqueda por servidor, ruta, autor del cambio y mensaje.

En ecosistemas más amplios, Microsoft Endpoint Manager, ManageEngine Endpoint Central e Ivanti fijan políticas y consolidan señales de dispositivos extraíbles, y un SIEM (Splunk/Elastic) recolecta eventos y alerta según reglas y machine learning. Este encaje cubre tanto cumplimiento como detección temprana.

Puesta en producción y seguridad

Con todo lo anterior, tienes una ruta completa: inventario y eventos en tiempo real con PowerShell, API central con Flask, automatización al arranque, seguridad de extremo a extremo y WEF para escalar. Si además alimentas un SIEM y refuerzas auditoría de seguridad (línea base + sospechosa), obtendrás visibilidad granular, contexto forense y capacidad de reacción ante accesos no autorizados o intentos de infección por USB.

Deja un comentario