
Herramienta de monitorización en vivo para sesiones remotas de PowerShell que utiliza ETW para capturar y decodificar el protocolo WinRM/PSRP, proporcionando trazas de ejecución de comandos y registro para análisis de seguridad.
RemotePSpy proporciona monitorización en vivo de sesiones remotas de PowerShell, lo que resulta especialmente útil para versiones antiguas (anteriores a la 5.0) de PowerShell que no disponen de funciones integrales de registro integradas.
Utiliza Event Tracing for Windows (ETW) para obtener datos de mensajes del protocolo WinRM, que se emplea como transporte para PowerShell remoto, y decodifica las distintas capas del protocolo para ofrecer un rastro de los comandos de script ejecutados y su entrada/salida.
Actualmente es un prototipo de investigación temprano, por lo que no admite todos los aspectos del Protocolo Remoto de PowerShell (PSRP). Aun así, puede proporcionar información útil sobre lo que ocurre en una sesión remota de PowerShell.
La forma más sencilla de instalarlo es mediante pip:
pip install remotepspy
Las dependencias deberían instalarse automáticamente al instalar mediante pip, pero en caso de que desees instalarlas desde el código fuente, se enumeran aquí:
La libwim-15.dll solo es necesaria si se utiliza el proveedor ETW de Microsoft-Windows-WinRM (recomendado y predeterminado) como fuente de datos. Se usa para descomprimir ciertos objetos de flujo en el protocolo WinRM/WSMan que contienen fragmentos de mensajes PSRP. Solo tienes que colocarla en el mismo directorio que el script principal de Python.
Simplemente ejecuta RemotePSpy para comenzar la monitorización y el registro, y pulsa Retorno cuando hayas terminado. El registro se escribirá en el directorio de trabajo actual, con el nombre RemotePSpy.log.
La herramienta también imprimirá en stdout una réplica aproximada de lo que el usuario de PowerShell remoto vería en su pantalla, junto con la información más detallada del archivo de registro. Hay disponible un registro más complejo; consulta "Registro" más abajo.
Si has instalado Python para que esté en tu PATH, los scripts ejecutables de RemotePSpy también estarán en tu PATH. De lo contrario, puede que necesites buscarlos en tu directorio de site-packages de Python.
El RemotePSpy predeterminado utiliza el proveedor ETW de WinRM (recomendado) como fuente de datos. Si deseas usar el proveedor ETW de PowerShell en su lugar, puedes ejecutar RemotePSpy_powershell_prov.
Esta versión puede producir algunas advertencias innecesarias debido a la complejidad añadida de rastrear ciertos estados según cómo se proporcionan los datos en este proveedor ETW concreto.
El código consta de varias clases bastante modulares que pueden aceptar entrada en diferentes capas de la pila del protocolo. Esto permite conectarlas de formas ligeramente distintas según de dónde se obtengan los datos y en qué formato. La mayoría de las clases aceptan una función de devolución de llamada que utilizan para transmitir el resultado que producen a la siguiente capa de la pila.
A continuación se ofrece una descripción de las clases principales utilizadas, seguida de algunos flujos de procesamiento que muestran qué clase alimenta a cuál en diferentes escenarios.
ETWWinRM: obtiene eventos ETW del proveedor WinRM.
ETWPowerShell: obtiene eventos ETW del proveedor PowerShell.
PowerShellETWParser: identifica el contexto de Shell para los eventos ETW de PowerShell, transmitiendo los datos de fragmentos a PSRPDefragmenter. También proporciona sincronización de hilos.
SoapDefragmenter: vuelve a ensamblar mensajes SOAP WSMan completos a partir de eventos ETW de WinRM, transmitiendo el SOAP completo a WSManPS.
WSManPS: filtra el WinRM no relacionado con PowerShell, rastrea el contexto de Shell, extrae los datos de fragmentos PSRP del SOAP WSMan y transmite los datos de fragmentos a PSRPDefragmenter.
PSRPDefragmenter: vuelve a ensamblar fragmentos PSRP en mensajes PSRP completos. Los fragmentos se ensamblan por ObjectID, y la unicidad del ObjectID se garantiza teniendo en cuenta el contexto de Shell. Transmite los mensajes PSRP finales a PSRPParser.
PSRPParser: decodifica el mensaje PSRP binario sin procesar, extrayendo detalles del encabezado como RPID, ID de canalización y MessageType. Transmite los mensajes decodificados a SimpleCommandTracer.
SimpleCommandTracer: interpreta los mensajes PSRP mediante MessageType, y extrae e imprime/registra comandos, argumentos y su salida. Incluye decodificación parcial de objetos PowerShell serializados. No es una implementación completa de todas las funciones posibles, pero intenta cubrir la mayoría de los casos comunes para permitir el rastreo de ejecución.
Flujo de procesamiento al usar el proveedor ETW de Microsoft-Windows-WinRM:
ETWWinRM -> SoapDefragmenter -> WSManPS -> PSRPDefragmenter -> PSRPParser -> SimpleCommandTracer
Flujo de procesamiento al usar el proveedor ETW de Microsoft-Windows-PowerShell:
ETWPowerShell -> PowerShellETWParser -> PSRPDefragmenter -> PSRPParser -> SimpleCommandTracer
Hay un registro exhaustivo en cada capa de la pila del protocolo. Esto permite la depuración en varios niveles y fue especialmente útil durante el desarrollo. Con suerte, también puede resultar útil para cualquiera que desee investigar PowerShell remoto en acción, ya que es posible obtener un rastro completo del protocolo en todas las capas clave.
Actualmente, el código fuente al final del script donde se configuran los registradores debe editarse para cambiar el registro. Las versiones futuras deberían proporcionar, con suerte, un método mejor para dicha configuración.
Cada nombre de registrador se define mediante una constante, LOGGER_NAME, en la clase que lo utiliza. Cada registrador se define como hijo de "RemotePSpy" (p. ej., RemotePSpy.etw). Programáticamente, los registradores pueden configurarse usando logging.getLogger() con el nombre de registro adecuado.
Para referencia rápida, los siguientes registradores y niveles te proporcionarán rastros del protocolo en diferentes capas del mismo:
| Datos clave del registro | Constante de nombre de registrador | Nivel |
|---|---|---|
| Rastro de comandos | SimpleCommandTracer.LOGGER_NAME | INFO |
| Rastro completo de eventos ETW | ETWWinRM.LOGGER_NAME | DEBUG |
| Rastro completo de mensajes SOAP WSMan | SoapDefragmenter.LOGGER_NAME | INFO |
| Rastro completo de cada fragmento PSRP | PSRPDefragmenter.LOGGER_NAME | DEBUG |
| Rastro completo de mensajes PSRP | PSRPParser.LOGGER_NAME | DEBUG |
Ten en cuenta que SimpleCommandTracer también genera un rastro en stdout, y este intenta replicar en cierta medida la visualización tal como la vería el usuario de PowerShell remoto. Esto es diferente del registro de rastro de comandos, que registra cada comando, llamada de método de canalización y salida de canalización de una manera más precisa, incluyendo contexto adicional como RPID e ID de canalización.
A continuación se ofrece un resumen más completo de lo que aparece en cada registro y en qué nivel:
ERROR:
WARNING:
INFO:
DEBUG:
DEBUG:
ERROR:
WARNING:
INFO:
DEBUG:
ERROR:
WARNING:
INFO:
DEBUG:
INFO:
DEBUG:
DEBUG:
ERROR:
DEBUG:
INFO: