Cómo encontrar un proceso sospechoso en Windows con Get-Process

Cómo encontrar un proceso sospechoso en Windows con Get-Process

El PC va lento, el ventilador no para y el Administrador de tareas muestra una lista de nombres que parecen todos legítimos: svchost.exe aparece quince veces, y uno de ellos puede ser un impostor. El Administrador muestra el nombre, pero no responde lo que importa: de dónde salió ese ejecutable, quién lo firmó y quién lo inició. El Get-Process de PowerShell, combinado con dos cmdlets más, responde las tres preguntas en pocos minutos.

Qué te entrega Get-Process

Según la documentación de Microsoft, Get-Process lista los procesos del equipo local y devuelve objetos System.Diagnostics.Process, con decenas de propiedades. Funciona en Windows PowerShell 5.1 y en PowerShell 7. Las que interesan para la revisión inicial:

  • Id: el PID del proceso.
  • ProcessName: el nombre, sin la extensión.
  • Path: la ruta completa del ejecutable.
  • StartTime: cuándo empezó el proceso.
  • CPU: tiempo total de procesador usado, en segundos (acumulado, no es el porcentaje actual).
  • WorkingSet: memoria en uso, en bytes.

Abre PowerShell como administrador. Sin elevación, el Path de los procesos protegidos puede salir vacío, y la documentación recuerda que los parámetros -Module y -FileVersionInfo exigen ejecutar como administrador para procesos que no son tuyos.

¿Cómo ver los procesos que más CPU consumen en PowerShell?

Ejecuta Get-Process | Sort-Object CPU -Descending | Select-Object -First 10 para listar los diez procesos con más tiempo de CPU acumulado.

Get-Process |
  Sort-Object CPU -Descending |
  Select-Object -First 10 Name, Id, CPU, StartTime,
    @{n='MB';e={[math]::Round($_.WorkingSet/1MB)}}, Path

Como CPU es acumulado, un servicio antiguo del sistema siempre aparece arriba. Fíjate en lo reciente: compara el StartTime con el momento en que empezó la lentitud. Un proceso desconocido, iniciado de madrugada y con mucho tiempo de CPU, merece investigación.

Paso 1: ¿desde dónde se ejecuta el archivo?

Los programas legítimos viven en C:\Windows o C:\Program Files. El malware suele ejecutarse desde carpetas donde un usuario común puede escribir: AppData, Temp, Downloads, ProgramData. Este filtro muestra todo lo que está fuera de los dos lugares esperados:

Get-Process |
  Where-Object { $_.Path -and $_.Path -notmatch '^C:\\(Windows|Program Files)' } |
  Select-Object Name, Id, StartTime, Path |
  Sort-Object Path

La expresión regular cubre Program Files y Program Files (x86). Aquí aparece mucho software legítimo, como Chrome, Discord y Teams, que se instalan en AppData. Por eso la lista es un punto de partida, no un veredicto. La señal de alerta es un nombre que imita un proceso del sistema (svchost.exe, explorer.exe, lsass.exe) ejecutándose fuera de C:\Windows\System32.

Paso 2: ¿el ejecutable tiene una firma digital válida?

Get-AuthenticodeSignature lee la firma Authenticode de un archivo. Según la documentación, solo está disponible en Windows, y cuando el archivo tiene firma incrustada y de catálogo, usa la de catálogo. Cruza los datos con los procesos:

Get-Process | Where-Object Path | Select-Object -Unique Path |
  ForEach-Object {
    $s = Get-AuthenticodeSignature -LiteralPath $_.Path
    [pscustomobject]@{
      Status = $s.Status
      Signer = $s.SignerCertificate.Subject
      Path   = $_.Path
    }
  } | Where-Object Status -ne 'Valid' | Format-Table -AutoSize

El resultado son los ejecutables en memoria sin firma válida (NotSigned, HashMismatch, NotTrusted). El software pequeño y las herramientas internas de una empresa suelen no estar firmados, así que no todo es malware. Pero un HashMismatch, que indica un archivo modificado después de firmarse, pide atención inmediata.

Una advertencia importante: una firma válida no significa un archivo seguro. Prueba que el archivo no se alteró después de firmarse y que el certificado es de confianza, nada más. Los atacantes usan certificados robados y abusan de binarios legítimos de la propia Microsoft. La firma sirve para descartar lo obvio, no para dar el proceso por inocente.

Paso 3: ¿quién inició el proceso?

Get-Process no muestra el proceso padre ni la línea de comandos. Para eso, usa la clase Win32_Process de WMI:

Get-CimInstance Win32_Process |
  Select-Object ProcessId, ParentProcessId, Name, CommandLine |
  Sort-Object ParentProcessId

Con el ParentProcessId reconstruyes el árbol de procesos. Algunas relaciones son normales y otras sospechosas:

  • Normal: el svchost.exe legítimo lo inicia services.exe y se ejecuta desde C:\Windows\System32.
  • Sospechoso: powershell.exe o cmd.exe como hijo de winword.exe, excel.exe o del navegador. Es el patrón clásico de una macro maliciosa o de un documento que dispara un comando.
  • Sospechoso: una CommandLine con -EncodedCommand, -WindowStyle Hidden o descarga desde una URL.

Cuidado al pegar esta salida en un ticket o foro: la línea de comandos puede contener contraseñas y tokens pasados como argumento.

Paso 4: ¿el proceso está hablando con internet?

Une el PID con las conexiones de red mediante Get-NetTCPConnection:

Get-NetTCPConnection -State Established |
  Select-Object RemoteAddress, RemotePort, OwningProcess,
    @{n='Processo';e={(Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue).ProcessName}} |
  Sort-Object Processo

Un proceso que no reconoces, con una conexión establecida hacia una IP externa en un puerto poco común, completa el cuadro. El post sobre auditoría de puertos abiertos con Get-NetTCPConnection detalla este cmdlet.

Encontré algo raro. ¿Y ahora?

Antes de terminar el proceso, anota las evidencias: el Path, el CommandLine y el hash del archivo, que generas con Get-FileHash para consultarlo en un servicio de reputación como VirusTotal. Después, termínalo:

Stop-Process -Id 1234 -Force

Matar el proceso es solo el primer paso. Si es malware, probablemente tiene forma de volver: una tarea programada, un servicio o una clave de inicio. Si el proceso reaparece tras terminarlo, es señal de persistencia. En un equipo de trabajo, avisa al equipo de seguridad antes de tocar nada más, y en un PC personal considera desconectarlo de la red y ejecutar un análisis completo con Microsoft Defender.

La lección de fondo

El nombre de un proceso no prueba nada, porque cualquiera puede llamar svchost.exe a un ejecutable. Lo que lo identifica es el conjunto: ruta, firma, proceso padre y comportamiento de red. Para dejar un registro permanente de este tipo de actividad, configura los registros de auditoría de PowerShell y, si quieres profundizar en la rutina de revisión, sigue con la revisión de tareas programadas y persistencia.

Comentarios